parent
a2557c0194
commit
e7c60e7c47
3 changed files with 35 additions and 21 deletions
|
|
@ -22,7 +22,7 @@ const state = {
|
|||
muted: false,
|
||||
sharingVideo: false,
|
||||
sharingScreen: false,
|
||||
watchingVideo: true,
|
||||
viewMode: 'chat', // 'chat' or 'video'
|
||||
iceServers: [{ urls: "stun:stun.l.google.com:19302" }],
|
||||
},
|
||||
voicePresencePollId: null,
|
||||
|
|
@ -66,10 +66,11 @@ const el = {
|
|||
vcChannelName: document.getElementById("vc-channel-name"),
|
||||
voiceVideoBtn: document.getElementById("voice-video-btn"),
|
||||
voiceScreenBtn: document.getElementById("voice-screen-btn"),
|
||||
voiceWatchBtn: document.getElementById("voice-watch-btn"),
|
||||
voiceMuteBtn: document.getElementById("voice-mute-btn"),
|
||||
voiceLeaveBtn: document.getElementById("voice-leave-btn"),
|
||||
videoGrid: document.getElementById("video-grid"),
|
||||
messageForm: document.getElementById("message-form"),
|
||||
messageInputWrapper: document.querySelector(".chat-input-wrapper"),
|
||||
|
||||
// Members
|
||||
memberList: document.getElementById("member-list"),
|
||||
|
|
@ -249,17 +250,20 @@ function renderChannels() {
|
|||
state.selectedDmUserId = null;
|
||||
state.selectedDmDisplayName = null;
|
||||
state.selectedTextChannelId = channel.id;
|
||||
state.voice.viewMode = 'chat';
|
||||
renderChannels();
|
||||
renderDMs();
|
||||
updateView();
|
||||
updateHeaderLabels();
|
||||
const messages = await api(`/channels/${channel.id}/messages?limit=100`);
|
||||
renderMessages(messages);
|
||||
} else {
|
||||
state.selectedDmUserId = null;
|
||||
state.selectedDmDisplayName = null;
|
||||
state.selectedVoiceChannelId = channel.id;
|
||||
state.voice.viewMode = 'video';
|
||||
renderChannels();
|
||||
renderDMs();
|
||||
updateView();
|
||||
updateHeaderLabels();
|
||||
joinVoice();
|
||||
}
|
||||
if (window.innerWidth <= 768) closeMobileMenus();
|
||||
|
|
@ -307,8 +311,10 @@ function renderDMs() {
|
|||
state.selectedDmDisplayName = dm.display_name;
|
||||
state.selectedTextChannelId = null;
|
||||
state.selectedVoiceChannelId = null;
|
||||
state.voice.viewMode = 'chat';
|
||||
renderChannels();
|
||||
renderDMs();
|
||||
updateView();
|
||||
updateHeaderLabels();
|
||||
const messages = await api(`/dms/${dm.user_id}/messages?limit=100`);
|
||||
renderMessages(messages);
|
||||
|
|
@ -380,8 +386,10 @@ function renderMembers() {
|
|||
state.selectedDmDisplayName = m.display_name;
|
||||
state.selectedTextChannelId = null;
|
||||
state.selectedVoiceChannelId = null;
|
||||
state.voice.viewMode = 'chat';
|
||||
renderChannels();
|
||||
renderDMs();
|
||||
updateView();
|
||||
updateHeaderLabels();
|
||||
const messages = await api(`/dms/${m.id}/messages?limit=100`);
|
||||
renderMessages(messages);
|
||||
|
|
@ -406,6 +414,12 @@ function updateHeaderLabels() {
|
|||
return;
|
||||
}
|
||||
|
||||
if (state.voice.viewMode === 'video' && state.selectedVoiceChannelId) {
|
||||
const channel = state.channels.find((c) => c.id === state.selectedVoiceChannelId);
|
||||
el.channelTitle.textContent = channel ? channel.name : "Voice Arena";
|
||||
return;
|
||||
}
|
||||
|
||||
const channel = state.channels.find((c) => c.id === state.selectedTextChannelId);
|
||||
el.channelTitle.textContent = channel ? channel.name : "Select a channel";
|
||||
el.messageBody.placeholder = channel ? `Message #${channel.name}` : "Select a channel";
|
||||
|
|
@ -569,7 +583,6 @@ function stopAndClearVideoPipeline() {
|
|||
state.voice.videoStream = null;
|
||||
state.voice.sharingVideo = false;
|
||||
document.getElementById(`video-${state.me.id}-camera`)?.parentElement?.remove();
|
||||
updateVideoGridVisibility();
|
||||
}
|
||||
|
||||
function stopAndClearScreenPipeline() {
|
||||
|
|
@ -579,15 +592,22 @@ function stopAndClearScreenPipeline() {
|
|||
state.voice.screenStream = null;
|
||||
state.voice.sharingScreen = false;
|
||||
document.getElementById(`video-${state.me.id}-screen`)?.parentElement?.remove();
|
||||
updateVideoGridVisibility();
|
||||
}
|
||||
|
||||
function updateVideoGridVisibility() {
|
||||
const hasVideos = el.videoGrid.children.length > 0;
|
||||
if (hasVideos && state.voice.watchingVideo) {
|
||||
// Persistence logic: we always update the grid visibility based on participants
|
||||
// however the actual container visibility in the UI is managed by updateView()
|
||||
}
|
||||
|
||||
function updateView() {
|
||||
if (state.voice.viewMode === 'video') {
|
||||
el.videoGrid.classList.remove("hidden");
|
||||
el.messageList.classList.add("hidden");
|
||||
el.messageInputWrapper.classList.add("hidden");
|
||||
} else {
|
||||
el.videoGrid.classList.add("hidden");
|
||||
el.messageList.classList.remove("hidden");
|
||||
el.messageInputWrapper.classList.remove("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -606,7 +626,6 @@ function renderVideo(peerId, displayName, stream, source) {
|
|||
videoEl = container.querySelector("video");
|
||||
}
|
||||
videoEl.srcObject = stream;
|
||||
updateVideoGridVisibility();
|
||||
}
|
||||
|
||||
async function buildAudioPipeline(rawStream) {
|
||||
|
|
@ -815,12 +834,10 @@ async function joinVoice() {
|
|||
} else if (msg.type === "video_status_changed") {
|
||||
if (!msg.is_sharing_video) {
|
||||
document.getElementById(`video-${msg.user_id}-camera`)?.parentElement?.remove();
|
||||
updateVideoGridVisibility();
|
||||
}
|
||||
} else if (msg.type === "screen_status_changed") {
|
||||
if (!msg.is_sharing_screen) {
|
||||
document.getElementById(`video-${msg.user_id}-screen`)?.parentElement?.remove();
|
||||
updateVideoGridVisibility();
|
||||
}
|
||||
}
|
||||
refreshVoicePresence().catch(() => { });
|
||||
|
|
@ -1121,7 +1138,6 @@ async function init() {
|
|||
|
||||
el.voiceVideoBtn.onclick = toggleVideo;
|
||||
el.voiceScreenBtn.onclick = toggleScreenShare;
|
||||
el.voiceWatchBtn.onclick = toggleWatchVideo;
|
||||
el.voiceMuteBtn.onclick = toggleMute;
|
||||
el.voiceLeaveBtn.onclick = leaveVoice;
|
||||
|
||||
|
|
|
|||
|
|
@ -87,7 +87,6 @@
|
|||
<div class="vc-actions">
|
||||
<button id="voice-video-btn" title="Turn on Camera"><i data-lucide="video-off"></i></button>
|
||||
<button id="voice-screen-btn" title="Share Screen"><i data-lucide="monitor-off"></i></button>
|
||||
<button id="voice-watch-btn" title="Stop Watching"><i data-lucide="eye"></i></button>
|
||||
<button id="voice-mute-btn" title="Mute"><i data-lucide="mic"></i></button>
|
||||
<button id="voice-leave-btn" title="Disconnect"><i data-lucide="phone-off"></i></button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -527,15 +527,13 @@ select {
|
|||
/* Video Grid */
|
||||
.video-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
|
||||
gap: 12px;
|
||||
padding: 12px;
|
||||
grid-template-columns: repeat(auto-fit, minmax(320px, 1fr));
|
||||
gap: 16px;
|
||||
padding: 16px;
|
||||
background: var(--bg-tertiary);
|
||||
flex-grow: 1;
|
||||
min-height: 200px;
|
||||
max-height: 100%;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow-y: auto;
|
||||
border-bottom: 1px solid rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
|
||||
.video-grid.hidden {
|
||||
|
|
@ -553,7 +551,8 @@ select {
|
|||
.video-item video {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
object-fit: contain;
|
||||
background: #000;
|
||||
}
|
||||
|
||||
.video-item .video-label {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue