diff --git a/src/webpage/channel.ts b/src/webpage/channel.ts index 633f2c5..f528618 100644 --- a/src/webpage/channel.ts +++ b/src/webpage/channel.ts @@ -745,7 +745,32 @@ class Channel extends SnowFlake { AVoice.noises("join"); } }; + this.voice.onUserChange = (user, change) => { + this.boxChange(user, change); + }; + this.voice.onSpeakingChange = (id, speaking) => { + const box = this.boxMap.get(id); + if (box) { + if (speaking) { + box.classList.add("speaking"); + } else { + box.classList.remove("speaking"); + } + } + const tray = this.voiceTray.get(id); + console.log("tray! :3"); + if (tray && tray.parentElement) { + const parent = tray.parentElement; + const pfp = Array.from(parent.children)[0]; + if (speaking) { + pfp.classList.add("speaking"); + } else { + pfp.classList.remove("speaking"); + } + } + }; } + voiceTray = new Map(); async updateVoiceUsers() { const voiceUsers = this.voiceUsers.deref(); if (!voiceUsers || !this.voice) return; @@ -764,16 +789,24 @@ class Channel extends SnowFlake { return array; }), ) - ).flatMap(([member, _obj]) => { + ).flatMap(([member, obj]) => { if (!member) { console.warn("This is weird, member doesn't exist :P"); return []; } const div = document.createElement("div"); - div.classList.add("voiceuser"); + div.classList.add("voiceuser", "flexltr"); const span = document.createElement("span"); span.textContent = member.name; - div.append(span); + + const tray = document.createElement("div"); + tray.classList.add("flexltr", "voiceTray"); + + div.append(member.user.buildpfp(member), span, tray); + member.user.bind(div, member.guild); + + this.voiceTray.set(member.id, tray); + this.boxChange(member.id, obj); return div; }); @@ -1093,13 +1126,30 @@ class Channel extends SnowFlake { } boxChange(id: string, change: {deaf: boolean; muted: boolean; video: boolean}) { const box = this.boxMap.get(id); - if (!box || !this.voice) return; - const vid = this.voice.videos.get(id); - if (vid) { + if (!this.voice) return; + if (box) { + const vid = this.voice.videos.get(id); + if (vid) { + if (change.video) { + this.boxVid(id, vid); + } else { + this.purgeVid(id); + } + } + } + const tray = this.voiceTray.get(id); + if (tray) { + console.warn("tray build", tray, change); + tray.innerHTML = ""; + if (change.muted) { + const span = document.createElement("span"); + span.classList.add("svg-micmute"); + tray.append(span); + } if (change.video) { - this.boxVid(id, vid); - } else { - this.purgeVid(id); + const span = document.createElement("span"); + span.classList.add("svg-video"); + tray.append(span); } } } @@ -1211,24 +1261,13 @@ class Channel extends SnowFlake { this.makeUserBox(user, users); }); this.usersDiv = new WeakRef(users); - this.voice.onSpeakingChange = (id, speaking) => { - const box = this.boxMap.get(id); - if (!box) return; - if (speaking) { - box.classList.add("speaking"); - } else { - box.classList.remove("speaking"); - } - }; voiceArea.append(users, buttonRow); this.voice.onVideo = (vid, id) => { console.warn("happened"); this.boxVid(id, vid); }; - this.voice.onUserChange = (user, change) => { - this.boxChange(user, change); - }; + this.voice.onLeave = () => { updateCallIcon(); for (const [id] of this.boxMap) { diff --git a/src/webpage/style.css b/src/webpage/style.css index 23326ab..b92baef 100644 --- a/src/webpage/style.css +++ b/src/webpage/style.css @@ -198,8 +198,7 @@ body { flex-wrap: wrap; } .speaking { - border: solid var(--green) 3px; - padding: 77px 137px !important; + outline: 3px solid var(--green); } .voiceUsers > * { background: var(--accent_color, var(--primary-bg)); @@ -434,7 +433,16 @@ textarea { #typebox:focus-visible { outline: none; } - +.voiceTray { + margin-left: auto; + span { + width: 16px; + height: 16px; + margin: 1px; + margin-left: 4px; + background: var(--primary-text-soft); + } +} /* Icons */ .pfpDiv { position: relative; @@ -1235,10 +1243,22 @@ span.instanceStatus { .addchannel:hover { background: var(--primary-text-prominent); } +.voiceuser:hover { + background: var(--channel-hover); +} .voiceuser { margin-left: 32px; - padding: 4px 0; + padding: 4px 4px; + border-radius: 4px; + margin-bottom: 2px; font-size: 0.9rem; + align-items: center; + cursor: pointer; + img { + width: 20px; + height: 20px; + margin-right: 4px; + } } .unreadDateline { color: var(--red); diff --git a/src/webpage/voice.ts b/src/webpage/voice.ts index dabeff3..2131470 100644 --- a/src/webpage/voice.ts +++ b/src/webpage/voice.ts @@ -880,7 +880,11 @@ a=rtcp-mux\r`; if (!this.userids.has(update.user_id)) { this.onMemberChange(update?.member || update.user_id, true); } - const vals = {deaf: update.deaf, muted: update.mute, video: update.self_video}; + const vals = { + deaf: update.deaf, + muted: update.mute || update.self_mute, + video: update.self_video, + }; this.onUserChange(update.user_id, vals); this.userids.set(update.user_id, vals); if (update.user_id === this.userid && this.videoStarted !== update.self_video) {