fix: off-state colors, mobile audio route, iOS rail/PTR, in-place join, draggable bars (0.1.16/batch76)

Regressions I introduced, now fixed:
#8d Mic/Camera OFF went DIM — my new `.meet-ic.off` rule overrode the original RED.
    Scoped the lite style to the speaker button only; mic/cam OFF are red again.
#7  Guest "left the meeting" was unstyled (dark text on blue, no card): the card CSS was
    scoped to .guest-prejoin only. Shared with .guest-left. Rejoin no longer dead-ends —
    if the room is gone we say "This meeting has ended" and hide the button.

Reported:
#8d Speaker button no longer shows on desktop (devices already live under the mic ▾).
#8c/#8e Mobile speaker button now CYCLES Speaker → Earpiece → Bluetooth (icon follows the
    route); dropped the redundant "Audio devices" entry from the ⋮ menu.
#8a iOS gap under the bottom rail: the page rubber-band-bounced, exposing background beneath
    the fixed bar. overscroll-behavior:none + fixed body pins it.
#8b Pull-to-refresh now fires on iOS too (overscroll-behavior:contain on the lists so Safari's
    rubber band stops swallowing the gesture; scrollTop>2 tolerance for momentum).
#5  A meeting link no longer opens a whole new window: same-origin urls navigate the main
    window in the shell, and a link clicked in chat joins the meeting IN PLACE.

New observations:
1. The viewer's mic now starts MUTED on a screen session (and can actually be un/muted).
2. iOS lightbox close/download buttons moved below the Dynamic Island (safe-area insets).
3. Meeting chat: recipient picker moved to the BOTTOM next to the input; a private message
   auto-targets your reply back to that person; private vs everyone are visibly different
   (brand amber vs blue/neutral) and the compose area tints in private mode.
4. Meeting bar + screen-session bars are DRAGGABLE (position remembered) so they stop
   covering the shared screen.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-13 22:24:36 +05:30
parent 48b6a4050a
commit e8c0b1889f
5 changed files with 203 additions and 50 deletions
+26
View File
@@ -264,6 +264,31 @@ function rcGrantControl(){
rcAllowed=true; rcPost({type:'rc-arm', on:true}); showControlBanner(); updateRcBtn();
}
function rcStopControl(){ rcAllowed=false; rcPrompted=false; rcPost({type:'rc-arm', on:false}); const b=document.getElementById('rcBanner'); if(b) b.remove(); updateRcBtn(); }
// new #4: drag the floating bar off whatever it's covering. Position is remembered.
function makeBarDraggable(el,key){
if(!el||el._drag) return; el._drag=true;
let sx=0,sy=0,ox=0,oy=0,dragging=false;
const pt=(e)=>e.touches?e.touches[0]:e;
const clamp=()=>{ const w=el.offsetWidth,h=el.offsetHeight;
let x=parseFloat(el.style.left||'0'), y=parseFloat(el.style.top||'0');
x=Math.max(4,Math.min(x,window.innerWidth-w-4)); y=Math.max(4,Math.min(y,window.innerHeight-h-4));
el.style.left=x+'px'; el.style.top=y+'px'; };
const pin=(r)=>{ el.style.left=r.left+'px'; el.style.top=r.top+'px'; el.style.right='auto'; el.style.bottom='auto'; };
try{ const s=JSON.parse(localStorage.getItem(key)||'null'); if(s&&typeof s.x==='number'){ pin({left:s.x,top:s.y}); clamp(); } }catch(_){}
const move=(e)=>{ if(!dragging) return; const p=pt(e); el.style.left=(ox+(p.clientX-sx))+'px'; el.style.top=(oy+(p.clientY-sy))+'px'; clamp(); if(e.cancelable) e.preventDefault(); };
const up=()=>{ if(!dragging) return; dragging=false; el.style.opacity='';
document.removeEventListener('mousemove',move); document.removeEventListener('mouseup',up);
document.removeEventListener('touchmove',move); document.removeEventListener('touchend',up);
try{ localStorage.setItem(key, JSON.stringify({x:parseFloat(el.style.left), y:parseFloat(el.style.top)})); }catch(_){} };
const down=(e)=>{ if(e.target.closest('button,select,input,a')) return;
const r=el.getBoundingClientRect(); pin(r);
const p=pt(e); sx=p.clientX; sy=p.clientY; ox=r.left; oy=r.top; dragging=true; el.style.opacity='.92';
document.addEventListener('mousemove',move); document.addEventListener('mouseup',up);
document.addEventListener('touchmove',move,{passive:false}); document.addEventListener('touchend',up);
if(e.cancelable) e.preventDefault(); };
el.addEventListener('mousedown',down); el.addEventListener('touchstart',down,{passive:false});
el.style.cursor='move'; el.title='Drag to move';
}
function updateRcBtn(){
const b=document.getElementById('rcBtn'); if(!b) return;
b.style.background=rcAllowed?'#16a34a':'#6b7280';
@@ -328,6 +353,7 @@ function buildBar(){
document.body.appendChild(bar);
rcb.onclick=()=>{ if(rcAllowed) rcStopControl(); else rcGrantControl(); };
updateRcBtn();
makeBarDraggable(bar,'bzc_sharebar_pos'); // new #4: let the customer move the bar off their content
const setMic=(on)=>{mic.title=on?'Mute':'Unmute';mic.innerHTML='<span style="display:inline-flex">'+I(on?'mic':'micOff')+'</span>';mic.style.background=on?'#2563eb':'#6b7280';};
mic.onclick=async()=>{
if(!window.__mic){