icons
This commit is contained in:
1 parent
ec02a6ddaf
commit
aab7931142
3 files changed
+286
-90
No files matched your search
+101
-18
@@ -34,6 +34,7 @@ window.__dbg = S; // POC debug handle
|
||||
|
||||
const $ = (sel) => document.querySelector(sel);
|
||||
const els = {
|
||||
voiceView: $('#voice-view'),
|
||||
stage: $('#stage'), screens: $('#screens'),
|
||||
spatial: $('#spatial'), status: $('#voice-status'), statusDot: $('#status-dot'),
|
||||
statusRow: $('#status-row'), nick: $('#nick'),
|
||||
@@ -50,6 +51,13 @@ const shareButtons = [...document.querySelectorAll('#btn-share, .mirror-share')]
|
||||
const statusTextEls = [...document.querySelectorAll('#voice-status, #mobile-status-text')];
|
||||
const statusDotEls = [...document.querySelectorAll('#status-dot, #mobile-status-dot')];
|
||||
|
||||
function mIcon(name, extraClass = '') {
|
||||
const span = document.createElement('span');
|
||||
span.className = `material-symbols-outlined${extraClass ? ` ${extraClass}` : ''}`;
|
||||
span.textContent = name;
|
||||
return span;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// helpers
|
||||
// ---------------------------------------------------------------------------
|
||||
@@ -784,9 +792,27 @@ function renderTiles() {
|
||||
|
||||
const meBadges = document.createElement('span');
|
||||
meBadges.className = 'user-line-badges';
|
||||
if (S.muted) meBadges.innerHTML += '<span class="badge-mute" title="Muted">🎤️‍❌</span>';
|
||||
if (S.deafened) meBadges.innerHTML += '<span class="badge-deafen" title="Deafened">👂❌</span>';
|
||||
if (S.sharing) meBadges.innerHTML += '<span class="badge-share" title="Sharing screen">🖥️</span>';
|
||||
if (S.muted) {
|
||||
const b = document.createElement('span');
|
||||
b.className = 'badge-mute';
|
||||
b.title = 'Muted';
|
||||
b.appendChild(mIcon('mic_off'));
|
||||
meBadges.appendChild(b);
|
||||
}
|
||||
if (S.deafened) {
|
||||
const b = document.createElement('span');
|
||||
b.className = 'badge-deafen';
|
||||
b.title = 'Deafened';
|
||||
b.appendChild(mIcon('headset_off'));
|
||||
meBadges.appendChild(b);
|
||||
}
|
||||
if (S.sharing) {
|
||||
const b = document.createElement('span');
|
||||
b.className = 'badge-share';
|
||||
b.title = 'Sharing screen';
|
||||
b.appendChild(mIcon('present_to_all'));
|
||||
meBadges.appendChild(b);
|
||||
}
|
||||
|
||||
meItem.append(meAv, meName, meBadges);
|
||||
roster.appendChild(meItem);
|
||||
@@ -808,8 +834,20 @@ function renderTiles() {
|
||||
if (!peer.pc || peer.pc.connectionState !== 'connected') {
|
||||
badges.innerHTML += '<span class="badge-conn" title="Connecting...">…</span>';
|
||||
}
|
||||
if (peer.state.muted) badges.innerHTML += '<span class="badge-mute" title="Muted">🎤️‍❌</span>';
|
||||
if (peer.state.sharing) badges.innerHTML += '<span class="badge-share" title="Sharing screen">🖥️</span>';
|
||||
if (peer.state.muted) {
|
||||
const b = document.createElement('span');
|
||||
b.className = 'badge-mute';
|
||||
b.title = 'Muted';
|
||||
b.appendChild(mIcon('mic_off'));
|
||||
badges.appendChild(b);
|
||||
}
|
||||
if (peer.state.sharing) {
|
||||
const b = document.createElement('span');
|
||||
b.className = 'badge-share';
|
||||
b.title = 'Sharing screen';
|
||||
b.appendChild(mIcon('present_to_all'));
|
||||
badges.appendChild(b);
|
||||
}
|
||||
|
||||
// Volume hover popup
|
||||
const volPop = document.createElement('div');
|
||||
@@ -858,8 +896,20 @@ function renderTiles() {
|
||||
|
||||
const badges = document.createElement('span');
|
||||
badges.className = 'user-line-badges';
|
||||
if (user.state?.muted) badges.innerHTML += '<span class="badge-mute" title="Muted">🎤️‍❌</span>';
|
||||
if (user.state?.sharing) badges.innerHTML += '<span class="badge-share" title="Sharing screen">🖥️</span>';
|
||||
if (user.state?.muted) {
|
||||
const b = document.createElement('span');
|
||||
b.className = 'badge-mute';
|
||||
b.title = 'Muted';
|
||||
b.appendChild(mIcon('mic_off'));
|
||||
badges.appendChild(b);
|
||||
}
|
||||
if (user.state?.sharing) {
|
||||
const b = document.createElement('span');
|
||||
b.className = 'badge-share';
|
||||
b.title = 'Sharing screen';
|
||||
b.appendChild(mIcon('present_to_all'));
|
||||
badges.appendChild(b);
|
||||
}
|
||||
|
||||
item.append(av, name, badges);
|
||||
roster.appendChild(item);
|
||||
@@ -878,7 +928,9 @@ function activeShares() {
|
||||
const shares = [];
|
||||
if (S.sharing && S.screenStream) shares.push({ key: 'me', name: `${S.name} (you)`, stream: S.screenStream });
|
||||
for (const peer of S.peers.values()) {
|
||||
if (peer.screenStream) shares.push({ key: peer.id, name: peer.name, stream: peer.screenStream });
|
||||
if (peer.state.sharing && peer.screenStream) {
|
||||
shares.push({ key: peer.id, name: peer.name, stream: peer.screenStream });
|
||||
}
|
||||
}
|
||||
return shares;
|
||||
}
|
||||
@@ -893,6 +945,8 @@ function renderScreens() {
|
||||
}
|
||||
}
|
||||
|
||||
if (!els.screens) return;
|
||||
|
||||
els.screens.innerHTML = '';
|
||||
els.screens.classList.toggle('multi', activeShares().length > 1);
|
||||
for (const share of activeShares()) {
|
||||
@@ -902,7 +956,8 @@ function renderScreens() {
|
||||
ph.className = 'screen-card popped';
|
||||
const btn = document.createElement('button');
|
||||
btn.className = 'pop-btn';
|
||||
btn.textContent = '⧉ re-embed';
|
||||
btn.appendChild(mIcon('open_in_new'));
|
||||
btn.appendChild(document.createTextNode(' re-embed'));
|
||||
btn.onclick = () => closePopout(share.key);
|
||||
const label = document.createElement('div');
|
||||
label.className = 'label';
|
||||
@@ -926,11 +981,12 @@ function renderScreens() {
|
||||
label.appendChild(document.createTextNode(share.name));
|
||||
const micBadge = document.createElement('span');
|
||||
micBadge.className = 'tile-mic-badge';
|
||||
micBadge.appendChild(mIcon('mic_off'));
|
||||
label.appendChild(micBadge);
|
||||
const pop = document.createElement('button');
|
||||
pop.className = 'pop-btn';
|
||||
pop.title = 'Pop out in new window';
|
||||
pop.textContent = '⧉';
|
||||
pop.appendChild(mIcon('open_in_new'));
|
||||
pop.onclick = () => popOutShare(share);
|
||||
card.append(video, label, pop);
|
||||
els.screens.appendChild(card);
|
||||
@@ -1428,8 +1484,24 @@ function mxRenderTimeline() {
|
||||
els.mxMessages.scrollTop = els.mxMessages.scrollHeight;
|
||||
}
|
||||
|
||||
function mxShowPanel() {
|
||||
function switchToChatView() {
|
||||
if (els.voiceView) els.voiceView.classList.add('hidden');
|
||||
if (els.mxPanel) els.mxPanel.classList.remove('hidden');
|
||||
document.querySelectorAll('.channel.text').forEach((c) => c.classList.add('active'));
|
||||
if (els.mxMessages) els.mxMessages.scrollTop = els.mxMessages.scrollHeight;
|
||||
if (els.mxInput) els.mxInput.focus();
|
||||
}
|
||||
|
||||
function switchToVoiceView() {
|
||||
if (els.mxPanel) els.mxPanel.classList.add('hidden');
|
||||
if (els.voiceView) els.voiceView.classList.remove('hidden');
|
||||
document.querySelectorAll('.channel.text').forEach((c) => c.classList.remove('active'));
|
||||
// Trigger Cytoscape redraw/resize because voice-view was unhidden
|
||||
if (typeof cy !== 'undefined') cy.resize();
|
||||
}
|
||||
|
||||
function mxShowPanel() {
|
||||
switchToChatView();
|
||||
}
|
||||
|
||||
function mxSend(text) {
|
||||
@@ -1462,12 +1534,13 @@ mxInit();
|
||||
|
||||
document.querySelectorAll('.channel.text').forEach((el) => {
|
||||
el.onclick = () => {
|
||||
if (Mx.roomId) { mxShowPanel(); return; }
|
||||
closeSidebar();
|
||||
if (Mx.roomId) { switchToChatView(); return; }
|
||||
if (Mx.client) { toast('Connecting to Matrix…'); return; }
|
||||
mxStartLogin();
|
||||
};
|
||||
});
|
||||
$('#mx-close')?.addEventListener('click', () => els.mxPanel.classList.add('hidden'));
|
||||
$('#mx-close')?.addEventListener('click', () => switchToVoiceView());
|
||||
$('#mx-send')?.addEventListener('click', () => {
|
||||
mxSend(els.mxInput.value);
|
||||
els.mxInput.value = '';
|
||||
@@ -1486,12 +1559,15 @@ function updateMicButton() {
|
||||
const off = S.muted || !S.micStream;
|
||||
for (const btn of micButtons) {
|
||||
btn.classList.toggle('off', off);
|
||||
btn.textContent = off ? '\u{1F507}' : '\u{1F3A4}'; // 🔇 muted/no-mic vs 🎤 live
|
||||
btn.replaceChildren(mIcon(off ? 'mic_off' : 'mic'));
|
||||
btn.disabled = !S.micStream;
|
||||
}
|
||||
}
|
||||
function updateDeafenButton() {
|
||||
for (const btn of deafenButtons) btn.classList.toggle('off', S.deafened);
|
||||
for (const btn of deafenButtons) {
|
||||
btn.classList.toggle('off', S.deafened);
|
||||
btn.replaceChildren(mIcon(S.deafened ? 'headset_off' : 'headphones'));
|
||||
}
|
||||
}
|
||||
function sendState() {
|
||||
send({ type: 'state', state: { muted: S.muted, deafened: S.deafened, sharing: S.sharing } });
|
||||
@@ -1524,9 +1600,15 @@ $('#btn-settings').onclick = openSettings;
|
||||
|
||||
els.nick.value = S.name;
|
||||
els.nick.addEventListener('change', () => {
|
||||
const trimmed = els.nick.value.trim();
|
||||
if (!trimmed) { els.nick.value = S.name; return; } // nickname can't be blanked out
|
||||
S.name = trimmed;
|
||||
const v = els.nick.value.trim();
|
||||
if (v) S.name = v;
|
||||
els.nick.value = S.name;
|
||||
localStorage.setItem(LS_NAME, S.name);
|
||||
setAvatar(els.meAvatar, S.name, S.myId || 'me');
|
||||
if (S.ws && S.ws.readyState === 1) send({ type: 'rename', name: S.name });
|
||||
renderTiles();
|
||||
});
|
||||
els.nick.addEventListener('blur', () => {
|
||||
els.nick.value = S.name;
|
||||
localStorage.setItem(LS_NAME, S.name);
|
||||
setAvatar(els.meAvatar, S.name, S.myId || 'me');
|
||||
@@ -1536,6 +1618,7 @@ setAvatar(els.meAvatar, S.name, 'me');
|
||||
document.querySelectorAll('.channel.voice').forEach((el) => {
|
||||
el.onclick = () => {
|
||||
closeSidebar();
|
||||
switchToVoiceView();
|
||||
if (S.room === el.dataset.room) return;
|
||||
cancelReconnect();
|
||||
document.querySelectorAll('.channel.voice').forEach((c) => c.classList.remove('active'));
|
||||
|
||||
Reference in new issue
Block a user