1import{c as Q,j as e,r,i as Z,y as _e,z as ze,C as $e,E as Ue,s as $,B as D,a as at,b as it,M as Be,ax as ot,d as ct,u as lt,ah as fe,a2 as Me,a3 as Re,L as ie,k as me,ae as he,$ as ut,o as dt,Z as Ee,a4 as ft,Y as mt,J as ht}from"./index-CSXAXRfd.js";import{C as gt}from"./card-CRHlvq_r.js";import{t as q}from"./index-BZad45JG.js";import{a as xt,p as Ae,s as ge,u as pt}from"./alarm-BvthYDmH.js";import{A as xe,a as pe,b as ve,c as be,d as ye,e as Te,f as je,g as De}from"./alert-dialog-C2A3PPcN.js";import{S as vt}from"./send-nYkGUJm_.js";import{M as bt,d as W,r as yt,a as jt,e as Nt,c as kt,b as wt,s as St,f as Ct,h as Mt}from"./push.browser-ChqR7P5a.js";import{L as Rt}from"./log-out-CYNo_vFI.js";import{r as Et,e as At,w as Tt,m as Dt,a as Lt,b as Ft,s as Ot,d as oe,h as It,g as _t,l as Le,j as zt,i as $t}from"./rooms-BhWM_wLa.js";import{S as Ut,a as Bt,b as Pt,c as Vt,d as Wt}from"./sheet-COieysFl.js";import{I as qt}from"./input-B-UKnsDV.js";import{C as Yt}from"./check-CvARLRdN.js";import{X as Ht}from"./index-Bgm0Dicm.js";import{P as Jt}from"./pencil-Cx0SJXK9.js";import{A as Kt}from"./arrow-left-CfgLDhcy.js";import"./textarea-knRjA9u8.js";import"./loader-circle-igJj3foN.js";import"./auth-middleware-Cp3bQKrs.js";import"./index-DSSpgM4M.js";const Xt=[["path",{d:"M4 22V4a1 1 0 0 1 .4-.8A6 6 0 0 1 8 2c3 0 5 2 7.333 2q2 0 3.067-.8A1 1 0 0 1 20 4v10a1 1 0 0 1-.4.8A6 6 0 0 1 16 16c-3 0-5-2-8-2a6 6 0 0 0-4 1.528",key:"1jaruq"}]],Gt=Q("flag",Xt);const Zt=[["path",{d:"M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719",key:"1sd12s"}]],Qt=Q("message-circle",Zt);const en=[["path",{d:"M12 19v3",key:"npa21l"}],["path",{d:"M15 9.34V5a3 3 0 0 0-5.68-1.33",key:"1gzdoj"}],["path",{d:"M16.95 16.95A7 7 0 0 1 5 12v-2",key:"cqa7eg"}],["path",{d:"M18.89 13.23A7 7 0 0 0 19 12v-2",key:"16hl24"}],["path",{d:"m2 2 20 20",key:"1ooewy"}],["path",{d:"M9 9v3a3 3 0 0 0 5.12 2.12",key:"r2i35w"}]],tn=Q("mic-off",en);const nn=[["path",{d:"M10.66 6H14a2 2 0 0 1 2 2v2.5l5.248-3.062A.5.5 0 0 1 22 7.87v8.196",key:"w8jjjt"}],["path",{d:"M16 16a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h2",key:"1xawa7"}],["path",{d:"m2 2 20 20",key:"1ooewy"}]],sn=Q("video-off",nn);const rn=[["path",{d:"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5",key:"ftymec"}],["rect",{x:"2",y:"6",width:"14",height:"12",rx:"2",key:"158x01"}]],an=Q("video",rn);function Fe({stream:s,label:n,muted:o,name:a,avatarUrl:u,placeholder:t}){const b=r.useRef(null);return r.useEffect(()=>{const f=b.current;f&&(f.srcObject=s,s&&f.play().catch(()=>{}))},[s]),e.jsxs("div",{className:"relative aspect-video w-full overflow-hidden rounded-lg bg-muted/30",children:[e.jsx("video",{ref:b,playsInline:!0,autoPlay:!0,muted:o,className:Z("size-full object-cover transition-opacity",s?"opacity-100":"opacity-0")}),!s&&e.jsx("div",{className:"absolute inset-0 grid place-items-center gap-2 text-center",children:e.jsxs("div",{className:"flex flex-col items-center gap-2",children:[e.jsxs(_e,{className:"size-14",children:[u?e.jsx(ze,{src:u,alt:""}):null,e.jsx($e,{className:"text-sm text-muted-foreground",children:Ue(a,null)})]}),e.jsx("p",{className:"px-4 text-xs text-muted-foreground",children:t??"Waitingâ¦"})]})}),e.jsx("span",{className:"absolute bottom-2 left-2 rounded-full bg-background/70 px-2.5 py-1 text-[11px] font-medium backdrop-blur-md",children:n})]})}function on({localStream:s,remoteStream:n,selfName:o,selfAvatar:a,partnerName:u,partnerPlaceholder:t,selfPlaceholder:b,overlay:f}){return e.jsxs("div",{className:"relative",children:[f?e.jsx("div",{className:"pointer-events-none absolute inset-x-0 top-0 z-10 flex justify-center",children:f}):null,e.jsxs("div",{className:"grid gap-3 sm:grid-cols-2",children:[e.jsx(Fe,{stream:s,label:"You",muted:!0,name:o,avatarUrl:a,placeholder:b??"Turning your camera onâ¦"}),e.jsx(Fe,{stream:n,label:u,name:u,placeholder:t??"Waiting for your focus mateâ¦"})]})]})}function cn({code:s,userId:n,displayName:o,onUnread:a,className:u}){const[t,b]=r.useState([]),[f,N]=r.useState(""),[g,R]=r.useState(!1),k=r.useRef(null),j=r.useRef(null),E=r.useRef(a);r.useEffect(()=>{E.current=a},[a]),r.useEffect(()=>{if(!s||!n)return;const d=$.channel(`together-chat:${s.toUpperCase()}`,{config:{broadcast:{self:!1}}});return k.current=d,d.on("broadcast",{event:"chat"},({payload:S})=>{const M=S;M?.text&&(b(O=>[...O.slice(-79),M]),E.current?.(1))}).subscribe(S=>R(S==="SUBSCRIBED")),()=>{R(!1),k.current=null,$.removeChannel(d)}},[s,n]),r.useEffect(()=>{j.current?.scrollIntoView({block:"end"})},[t.length]);const y=r.useCallback(async()=>{const d=f.trim().slice(0,300),S=k.current;
1if(!d||!S||!g)return;const M={id:crypto.randomUUID(),userId:n,name:o||"You",text:d,at:Date.now()};if(await S.send({type:"broadcast",event:"chat",payload:M})!=="ok"){q.error("Message not sent â try again");return}b(L=>[...L.slice(-79),M]),N("")},[g,f,n,o]);return e.jsxs("div",{className:Z("flex flex-col rounded-2xl border border-border/60 bg-card/60 p-3 backdrop-blur-xl",u),children:[e.jsx("p",{className:"text-[10px] uppercase tracking-[0.18em] text-muted-foreground",children:"Chat · disappears when the session ends"}),e.jsxs("div",{className:"mt-3 max-h-56 min-h-24 flex-1 space-y-2 overflow-y-auto text-left",children:[t.length===0?e.jsx("p",{className:"py-4 text-center text-xs text-muted-foreground",children:"Nudge each other here â messages are never stored."}):t.map(d=>e.jsxs("div",{className:"text-sm",children:[e.jsx("span",{className:Z("text-xs font-medium",d.userId===n?"text-primary":"text-muted-foreground"),children:d.userId===n?"You":d.name})," ",e.jsx("span",{className:"text-foreground/90",children:d.text})]},d.id)),e.jsx("div",{ref:j})]}),e.jsxs("form",{className:"mt-3 flex items-center gap-2",onSubmit:d=>{d.preventDefault(),y()},children:[e.jsx("input",{value:f,onChange:d=>N(d.target.value),maxLength:300,placeholder:g?"Message your focus mateâ¦":"Connecting chatâ¦",disabled:!g,className:"h-10 flex-1 rounded-full border border-border/60 bg-muted/40 px-4 text-sm outline-none focus:border-primary/60"}),e.jsx(D,{type:"submit",size:"icon",className:"rounded-full",disabled:!g||!f.trim(),children:e.jsx(vt,{className:"size-4"})})]})]})}const ln=[{urls:"stun:stun.l.google.com:19302"},{urls:"stun:stun1.l.google.com:19302"},{urls:"stun:stun2.l.google.com:19302"}];function un({code:s,userId:n,isHost:o,enabled:a=!0}){const[u,t]=r.useState(null),[b,f]=r.useState(null),[N,g]=r.useState("idle"),[R,k]=r.useState(!0),[j,E]=r.useState(!0),y=r.useRef(null),d=r.useRef(null),S=r.useRef(null),M=r.useRef(!1),O=r.useRef(!o);r.useEffect(()=>{O.current=!o},[o]);const L=r.useCallback(()=>{S.current?.getTracks().forEach(C=>C.stop()),S.current=null,t(null),f(null);try{y.current?.getSenders().forEach(C=>C.track?.stop()),y.current?.close()}catch{}y.current=null;const m=d.current;d.current=null,m&&$.removeChannel(m),g("idle")},[]);r.useEffect(()=>{if(!a)return;let m=!1;return g("requesting"),navigator.mediaDevices?.getUserMedia({video:{width:1280,height:720},audio:!0}).then(C=>{if(m){C.getTracks().forEach(F=>F.stop());return}S.current=C,t(C),g("waiting")}).catch(()=>{m||g("denied")}),()=>{m=!0}},[a]),r.useEffect(()=>()=>L(),[L]),r.useEffect(()=>{if(!a||!u||!s||!n)return;const m=$.channel(`together:${s.toUpperCase()}`,{config:{presence:{key:n},broadcast:{self:!1}}});d.current=m;const C=x=>{m.send({type:"broadcast",event:"signal",payload:x})},F=()=>{if(y.current)return y.current;const x=new RTCPeerConnection({iceServers:ln});y.current=x,u.getTracks().forEach(v=>x.addTrack(v,u));const p=new MediaStream;return x.ontrack=v=>{v.streams[0]?.getTracks().forEach(Y=>p.addTrack(Y)),v.streams[0]||p.addTrack(v.track),f(p)},x.onicecandidate=v=>{v.candidate&&C({from:n,candidate:v.candidate.toJSON()})},x.onconnectionstatechange=()=>{const v=x.connectionState;v==="connected"?g("live"):v==="connecting"||v==="new"?g("connecting"):v==="failed"?g("failed"):v==="disconnected"&&g("connecting")},x.onnegotiationneeded=async()=>{if(o)try{M.current=!0,await x.setLocalDescription(),x.localDescription&&C({from:n,description:x.localDescription.toJSON()})}catch{}finally{M.current=!1}},g("connecting"),x},I=()=>{try{y.current?.close()}catch{}y.current=null,f(null),g("waiting")};return m.on("broadcast",{event:"signal"},async({payload:x})=>{const p=x;if(!p||p.from===n)return;const v=F();try{if(p.description){const Y=p.description.type==="offer"&&(M.current||v.signalingState!=="stable");if(!O.current&&Y)return;Y&&await v.setLocalDescription({type:"rollback"}),await v.setRemoteDescription(p.description),p.description.type==="offer"&&(await v.setLocalDescription(),v.localDescription&&C({from:n,description:v.localDescription.toJSON()}))}else p.candidate&&await v.addIceCandidate(p.candidate)}catch{}}).on("presence",{event:"sync"},()=>{const x=m.presenceState();Object.keys(x).filter(v=>v!==n).length>0?F():y.current&&I()}).on("presence",{event:"leave"},({key:x})=>{x!==n&&I()}).subscribe(x=>{x==="SUBSCRIBED"&&m.track({at:Date.now()})}),()=>{const x=d.current;d.current=null,x&&$.removeChannel(x);try{y.current?.close()}catch{}y.current=null,f(null)}},[a,u,s,n,o]);const _=r.useCallback(()=>{const m=S.current?.getAudioTracks()[0];m&&(m.enabled=!m.enabled,k(m.enabled))},[]),U=r.useCallback(()=>{const m=S.current?.getVideoTracks()[0];m&&(m.enabled=!m.enabled,E(m.enabled))},[]);
1return{localStream:u,remoteStream:b,status:N,micOn:R,camOn:j,toggleMic:_,toggleCam:U,stop:L}}function dn({code:s,userId:n,isHost:o,displayName:a,selfAvatar:u,partnerName:t,partnerPresent:b,running:f,timerOverlay:N,onLeave:g,onFinish:R,onCancel:k}){const[j,E]=r.useState(!1),[y,d]=r.useState(null),[S,M]=r.useState(0),{localStream:O,remoteStream:L,status:_,micOn:U,camOn:m,toggleMic:C,toggleCam:F,stop:I}=un({code:s,userId:n,isHost:o}),x=_==="denied"?"Camera blocked â you can still use the clock and chat":_==="failed"?"Couldn't connect the video on this network â chat and the clock still work":_==="requesting"?"Turning on your cameraâ¦":L?"Focusing together":b?"Connectingâ¦":"Waiting for your focus mate";return e.jsxs("div",{className:"w-full",children:[e.jsxs("div",{className:Z("grid gap-4",j?"lg:grid-cols-[1fr_320px]":""),children:[e.jsx(on,{localStream:O,remoteStream:L,selfName:a,selfAvatar:u,partnerName:t??"Your focus mate",overlay:N,selfPlaceholder:_==="denied"?"Camera is off":"Turning your camera onâ¦",partnerPlaceholder:b?"Connectingâ¦":"Waiting for your focus mateâ¦"}),j&&e.jsx(cn,{code:s,userId:n,displayName:a,onUnread:()=>M(p=>p+1)})]}),e.jsx("p",{className:"mt-3 text-center text-[11px] uppercase tracking-[0.18em] text-muted-foreground/70",children:x}),e.jsxs("div",{className:"mt-4 flex flex-wrap items-center justify-center gap-2",children:[e.jsxs("div",{className:"inline-flex items-center gap-1.5 rounded-full border border-border/60 bg-card/70 px-2 py-1.5 backdrop-blur-xl",children:[e.jsx(Ne,{on:U,onClick:C,label:U?"Mute":"Unmute",icon:U?e.jsx(bt,{className:"size-4"}):e.jsx(tn,{className:"size-4"})}),e.jsx(Ne,{on:m,onClick:F,label:m?"Turn camera off":"Turn camera on",icon:m?e.jsx(an,{className:"size-4"}):e.jsx(sn,{className:"size-4"})}),e.jsx(Ne,{on:j,onClick:()=>{E(p=>!p),M(0)},label:"Chat",icon:e.jsx(Qt,{className:"size-4"}),badge:!j&&S>0?S:void 0})]}),e.jsxs(D,{variant:"outline",className:"rounded-full",onClick:()=>d("leave"),children:[e.jsx(Rt,{className:"size-4 mr-1.5"})," Leave"]}),e.jsxs(D,{className:"rounded-full bg-gold text-background hover:bg-gold/90",onClick:()=>d(f?"finish":"cancel"),children:[e.jsx(Gt,{className:"size-4 mr-1.5"})," ",f?"Finish":"Cancel session"]})]}),e.jsx(xe,{open:y==="leave",onOpenChange:p=>!p&&d(null),children:e.jsxs(pe,{children:[e.jsxs(ve,{children:[e.jsx(be,{children:"Leave this session?"}),e.jsxs(ye,{children:[t??"Your focus mate"," stays in the room and the clock keeps running. You can come back from Together at any time."]})]}),e.jsxs(Te,{children:[e.jsx(je,{children:"Stay"}),e.jsx(De,{onClick:()=>{d(null),I(),g()},children:"Leave"})]})]})}),e.jsx(xe,{open:y==="finish",onOpenChange:p=>!p&&d(null),children:e.jsxs(pe,{children:[e.jsxs(ve,{children:[e.jsx(be,{children:"Finish this session?"}),e.jsx(ye,{children:"This ends the session for both of you. Keep the time in Activity, or discard it if it doesnât count."})]}),e.jsxs("div",{className:"flex flex-col gap-2 sm:flex-row sm:justify-end",children:[e.jsx(je,{className:"mt-0",children:"Keep focusing"}),e.jsx(D,{variant:"outline",onClick:()=>{d(null),I(),R(!1)},children:"Discard â donât log it"}),e.jsx(D,{className:"bg-gold text-background hover:bg-gold/90",onClick:()=>{d(null),I(),R(!0)},children:"Finish and log"})]})]})}),e.jsx(xe,{open:y==="cancel",onOpenChange:p=>!p&&d(null),children:e.jsxs(pe,{children:[e.jsxs(ve,{children:[e.jsx(be,{children:"Cancel this session?"}),e.jsx(ye,{children:"The clock hasnât started, so nothing is logged. The room closes for both of you."})]}),e.jsxs(Te,{children:[e.jsx(je,{children:"Keep waiting"}),e.jsx(De,{onClick:()=>{d(null),I(),k()},children:"Cancel session"})]})]})})]})}function Ne({on:s,onClick:n,label:o,icon:a,badge:u}){return e.jsxs("button",{type:"button",onClick:n,"aria-pressed":s,"aria-label":o,title:o,className:Z("relative grid size-10 place-items-center rounded-full border transition",s?"border-primary/60 bg-primary/20 text-foreground":"border-transparent text-muted-foreground hover:bg-muted/50 hover:text-foreground"),children:[a,u?e.jsx("span",{className:"absolute -right-0.5 -top-0.5 grid size-4 place-items-center rounded-full bg-primary text-[9px] font-bold text-primary-foreground",children:u>9?"9+":u}):null]})}const fn=at({method:"GET"}).handler(it("6b655fcf9cf8ed6c5b034b93677e3a5ccf428bf187bac172ba3afd67096694cb")),mn=4e3;function hn(s,n,o){const a=n-s;if(!Number.isFinite(a)||a<0||a>mn)return null;const u=s+a/2;return{offset:o-u,rtt:a}}
1function gn(s){if(s.length===0)return null;const n=[...s].sort((t,b)=>t.rtt-b.rtt),a=n.slice(0,Math.max(3,Math.ceil(n.length/2))).map(t=>t.offset).sort((t,b)=>t-b),u=Math.floor(a.length/2);return a.length%2===1?a[u]:(a[u-1]+a[u])/2}const xn=2e3,pn=250;function vn(s,n,o=pn){const a=n-s;return Math.abs(a)>=xn||Math.abs(a)<=o?n:s+Math.sign(a)*o}function bn(s){const n=(()=>Date.now());let o=[],a=0,u=!1;return{now:()=>n()+a,offset:()=>a,reset:()=>{o=[],u=!1},ingest:(t,b,f)=>{const N=hn(t,b,f);if(!N)return a;o=[...o,N].slice(-5);const g=gn(o);return g===null||(a=u?vn(a,g):g,u=!0),a}}}function Pe(s,n){if(!s)return 0;const o=new Date(s).getTime();return Number.isFinite(o)?Math.max(0,o-n):0}function Ve(s){const n=Math.max(0,Math.floor(s)),o=Math.floor(n/60);return`${String(o).padStart(2,"0")}:${String(n%60).padStart(2,"0")}`}function yn(s,n,o){if(n==="done")return"00:00";if(n!=="running"||!s)return"â";const a=Pe(s,o);return a<=0?"00:01":Ve(Math.ceil(a/1e3))}function jn(s,n){const o=Pe(s,n);if(o<=0)return 1e3;const a=o%1e3;return a===0?1e3:a}const Nn=2;function kn(s){return s.status==="running"?{canStart:!1,reason:"Already running"}:s.isHost?s.memberCount<Nn?{canStart:!1,reason:"Waiting for someone else to join"}:{canStart:!0}:{canStart:!1,reason:"Only the host can start the room"}}function wn(s){if(s.status==="done")return"done";if(s.status!=="running")return"lobby";if(!s.endsAt)return"running";const n=new Date(s.endsAt).getTime();return Number.isFinite(n)&&n<=s.serverNowMs?"ending":"running"}function Sn(s){return s.state==="ending"&&s.joined&&!s.alreadyRequested}function We(s){return[...s].sort((n,o)=>n.joinedAt.localeCompare(o.joinedAt))}function Cn(s,n){const o=s.find(u=>u.userId===n.userId),a=o?{...n,avatarUrl:n.avatarUrl??o.avatarUrl}:n;return We([...s.filter(u=>u.userId!==n.userId),a])}function Mn(s,n){return s.filter(o=>o.userId!==n)}function Oe(s,n){return n.length===0&&s.length>0?s:We(n)}function Rn({open:s,onOpenChange:n,members:o,currentUserId:a,hostId:u,onRename:t,onLeave:b}){const[f,N]=r.useState(!1),[g,R]=r.useState(""),k=[...o].sort((j,E)=>j.joinedAt.localeCompare(E.joinedAt));return e.jsx(Ut,{open:s,onOpenChange:n,children:e.jsxs(Bt,{side:"bottom",className:"max-h-[80vh] overflow-y-auto",children:[e.jsxs(Pt,{className:"text-left",children:[e.jsx(Vt,{children:"In the room"}),e.jsxs(Wt,{children:[o.length," ",o.length===1?"person":"people"," in the room"]})]}),e.jsx("ul",{className:"mt-4 divide-y divide-border/60",children:k.map(j=>{const E=j.userId===a;return e.jsx("li",{className:"py-3 first:pt-0",children:e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsxs("div",{className:"relative shrink-0",children:[e.jsxs(_e,{className:"size-9 ring-1 ring-border/60",children:[j.avatarUrl?e.jsx(ze,{src:j.avatarUrl,alt:""}):null,e.jsx($e,{className:"text-[11px] font-medium text-muted-foreground",children:Ue(j.displayName,null)})]}),e.jsx("span",{"aria-hidden":!0,className:"absolute -bottom-0.5 -right-0.5 size-2.5 rounded-full ring-2 ring-background bg-gold"})]}),e.jsxs("div",{className:"min-w-0 flex-1",children:[E&&f?e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(qt,{autoFocus:!0,value:g,maxLength:Be,onChange:y=>R(y.target.value),onKeyDown:y=>{y.key==="Enter"&&g.trim()&&(N(!1),t(g.trim())),y.key==="Escape"&&N(!1)},className:"h-8 text-sm","aria-label":"Your name in this room"}),e.jsx(D,{size:"sm",className:"h-8 px-2",disabled:!g.trim(),onClick:()=>{N(!1),t(g.trim())},children:e.jsx(Yt,{className:"size-3.5"})}),e.jsx(D,{size:"sm",variant:"ghost",className:"h-8 px-2",onClick:()=>N(!1),children:e.jsx(Ht,{className:"size-3.5"})})]}):e.jsxs("div",{className:"text-sm font-medium truncate flex items-center",children:[e.jsx("span",{className:"truncate",children:j.displayName??"Anonymous"}),j.userId===u&&e.jsx("span",{className:"ml-2 text-[10px] uppercase tracking-wider text-muted-foreground shrink-0",children:"host"}),E&&e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"ml-2 text-[10px] uppercase tracking-wider text-gold shrink-0",children:"you"}),e.jsx("button",{type:"button","aria-label":"Edit your name",title:"Edit your name",className:"ml-1.5 p-1 rounded-md text-muted-foreground hover:text-foreground hover:bg-muted/60 transition shrink-0",onClick:()=>{R(j.displayName??""),N(!0)},children:e.jsx(Jt,{className:"size-3.5"})})]})]}),j.intention&&e.jsx("div",{className:"text-xs text-muted-foreground truncate italic",children:j.intention})]})]})},j.userId)})}),b&&e.jsx("button",{className:"mt-5 text-xs text-muted-foreground hover:text-foreground underline underline-offset-4",onClick:()=>{b()},children:"Leave room"})]})})}const qe=s=>`minutes.room.seated.${s}`;function En(s){try{localStorage.setItem(qe(s),"1")}catch{}}function Ie(s){try{localStorage.removeItem(qe(s))}catch{}}const An=yn;function Tn(s){const n=Number.isFinite(s)&&s>0?s:0;return Ve(n*60)}function Gn(){const{code:s}=ot.useParams(),{user:n,loading:o}=ct(),a=lt(),u=r.useRef(Et(s)).current,[t,b]=r.useState(u?.room??null),[f,N]=r.useState(u?.members??[]),[g,R]=r.useState(!u),[k,j]=r.useState(!1),[E,y]=r.useState(""),[d,S]=r.useState(!1),M=r.useRef(!!u),O=async i=>{const c=i.trim().slice(0,Be);if(!(!c||!t||!n)){y(c),ht(c),N(l=>l.map(h=>h.userId===n.id?{...h,displayName:c}:h));try{await zt(t.id,n.id,{displayName:c}),await $.from("profiles").update({display_name:c}
1).eq("id",n.id)}catch{}}};r.useEffect(()=>{const i=()=>pt();return window.addEventListener("pointerdown",i,{once:!0}),window.addEventListener("keydown",i,{once:!0}),()=>{window.removeEventListener("pointerdown",i),window.removeEventListener("keydown",i)}},[]);const[L,_]=r.useState(0),[U,m]=r.useState(!1),[C,F]=r.useState(null),[I,x]=r.useState(!1),[p,v]=r.useState(null),[Y,ke]=r.useState(!1),[Ye,He]=r.useState(!1),[Je,we]=r.useState(null),H=r.useRef(null),ee=r.useRef(!1),te=r.useRef(!1),Se=r.useRef(bn()),K=()=>Se.current.now();r.useEffect(()=>{let i=!1;const c=Se.current,l=async()=>{try{const T=Date.now(),A=await fn();if(i)return;c.ingest(T,Date.now(),A.now)}catch{}};l();const h=()=>{document.visibilityState==="visible"&&l()};document.addEventListener("visibilitychange",h),window.addEventListener("online",h);const w=setInterval(()=>{document.visibilityState==="visible"&&l()},3e4);return()=>{i=!0,document.removeEventListener("visibilitychange",h),window.removeEventListener("online",h),clearInterval(w)}},[]),r.useEffect(()=>{y(i=>i||fe(n?.email))},[n?.email]);const ce=r.useRef(!1),Ke=r.useRef(null),Xe=r.useRef(null),X=r.useRef(null),B=r.useRef(!1),P=r.useRef(!1),ne=r.useRef(!1),se=r.useRef(!1);r.useEffect(()=>{Ke.current=t?.id??null},[t?.id]),r.useEffect(()=>{Xe.current=n?.id??null},[n?.id]),r.useEffect(()=>{if(o)return;let i=!1;if(!n){N([]),R(!1);return}return M.current||R(!0),(async()=>{try{const{room:c,members:l,full:h,failure:w}=await At(s,fe(n.email));if(i)return;we(w),b(c),He(h),c&&(N(T=>Oe(T,l)),Tt(s,c,l),l.some(T=>T.userId===n.id)&&(En(c.id),j(!0),ce.current=!0))}catch{i||we("connection")}finally{i||(M.current=!0,R(!1))}})(),()=>{i=!0}},[s,n,o]);const z=t?.id??null;r.useEffect(()=>{if(!z)return;const i=$.channel(`room:${z}`).on("postgres_changes",{event:"*",schema:"public",table:"rooms",filter:`id=eq.${z}`},c=>{if(c.eventType==="DELETE"){q.message("Session was closed"),a({to:"/together"});return}const l=c.new;if(!l||!l.id||!l.status)return;const h=Dt(c.new);b(w=>w?{...w,...h}:h)}).on("postgres_changes",{event:"*",schema:"public",table:"room_members",filter:`room_id=eq.${z}`},c=>{if(c.eventType==="DELETE"){const l=c.old;if(l?.user_id){const h=l.user_id;N(w=>Mn(w,h))}return}if(c.new){const l=Lt(c.new);N(h=>Cn(h,l))}}).subscribe();return()=>{$.removeChannel(i)}},[z,a]),r.useEffect(()=>{if(t?.status!=="running")return;let i;const c=()=>{i=setTimeout(()=>{_(l=>l+1),c()},Math.max(50,jn(t.endsAt,K())))};return c(),()=>clearTimeout(i)},[t?.status,t?.endsAt]),r.useEffect(()=>{if(!k)return;const i=(t?.name||"").trim()||"Focus session";if(t?.status==="running"&&t.endsAt){const c=Math.max(1,(t.durationMinutes??0)*60),l=Math.max(0,Math.round((new Date(t.endsAt).getTime()-K())/1e3));Me({active:!0,owner:"room",label:"Focus",task:i,remaining:l,total:c,paused:!1,done:!1});return}if(t?.status==="done"){Me({active:!1,owner:"room",label:"Focus",task:i,remaining:0,total:0,paused:!1,done:!0});return}Re()},[k,t?.status,t?.endsAt,t?.name,t?.durationMinutes,L]),r.useEffect(()=>()=>Re(),[]),r.useEffect(()=>{if(!t?.id||!n?.id||!k)return;const i=t.id,c=n.id,l=()=>{It(i,c)};l();const h=setInterval(l,3e4),w=()=>{document.visibilityState==="visible"&&l()};return document.addEventListener("visibilitychange",w),()=>{clearInterval(h),document.removeEventListener("visibilitychange",w)}},[t?.id,n?.id,k]),r.useEffect(()=>{if(!z)return;const i=z;let c=!1;const l=async()=>{try{const J=await $t(i);if(c)return;N(ae=>Oe(ae,J))}catch{}},h=Date.now();let w;const T=()=>{const J=Date.now()-h<2e4?3e3:15e3;w=setTimeout(()=>{c||(document.visibilityState==="visible"&&l(),T())},J)};T();const A=()=>{document.visibilityState==="visible"&&l()};return document.addEventListener("visibilitychange",A),window.addEventListener("online",A),()=>{c=!0,clearTimeout(w),document.removeEventListener("visibilitychange",A),window.removeEventListener("online",A)}},[z]),r.useEffect(()=>{if(!n)return;const i=s;let c=!1;const l=async()=>{try{const A=await _t(i);!c&&A&&b(A)}catch{}},h=()=>{document.visibilityState==="visible"&&l()},w=()=>{l()};document.addEventListener("visibilitychange",h),window.addEventListener("online",w);const T=setInterval(()=>{document.visibilityState==="visible"&&l()},2e4);return()=>{c=!0,document.removeEventListener("visibilitychange",h),window.removeEventListener("online",w),clearInterval(T)}},[s,n]);const le=r.useMemo(()=>wn({status:t?.status??"lobby",endsAt:t?.endsAt,serverNowMs:K()}),[t,L]),G=le==="ending";r.useEffect(()=>{!t||!n||Sn({state:le,joined:k,alreadyRequested:se.current})&&(se.current=!0,Ft({data:{roomId:t.id}}).catch(()=>{se.current=!1}))},[le,t,n,k]),r.useEffect(()=>{t?.status==="running"&&t.startedAt&&X.current===null&&(X.current=ne
1w Date(t.startedAt).getTime(),B.current=!1,P.current=!1,ee.current=!1,te.current=!1,m(!1),x(!1)),t?.status==="lobby"&&(X.current=null,B.current=!1,P.current=!1,ee.current=!1,te.current=!1,se.current=!1,m(!1),x(!1))},[t?.status,t?.startedAt]),r.useEffect(()=>{!t||!n||t.createdBy===n.id&&t.status==="lobby"&&(f.length<2||Ot({data:{roomId:t.id}}))},[t?.id,t?.status,t?.createdBy,t?.durationMinutes,f.length,n?.id]);function ue(i){if(B.current||!n||!t)return 0;const c=X.current??(t.startedAt?new Date(t.startedAt).getTime():Date.now()),l=t.endsAt?new Date(t.endsAt).getTime():Date.now(),h=Math.min(Date.now(),l)-c,w=Math.min(h,(t.durationMinutes??0)*6e4||h),T=c+w,A=Math.max(1,Math.round(w/6e4)||(t.durationMinutes??1));B.current=!0;const J=(t.name||"Focus session").slice(0,200),ae=f.find(rt=>rt.userId!==n.id)?.displayName??null,Ce=ae?`${J} · with ${ae}`.slice(0,200):J;try{ft(Ce,"Focus Mate")}catch{}const de={id:`room-${t.id}-${c}`,task:Ce,focusMinutes:A,breakMinutes:0,startedAt:c,completedAt:T,category:"Focus Mate"};try{mt(de)}catch{}return Ee(de),v(de.id),i?.silent||q.success(`Session logged â ${A} min`),A}if(r.useEffect(()=>{if((t?.status==="done"||G)&&!(!k||!n||!t)){if(ne.current||t.endedWithoutLogging){ne.current=!0,B.current=!0,P.current=!0,W();return}if(!P.current){P.current=!0;try{xt()}catch{}}!I&&X.current&&ue({silent:!0}),m(!0),W(),t.createdBy===n.id&&t.status==="running"&&oe(t.id)}},[t?.status,G,t?.id,k,n,a]),r.useEffect(()=>{if(t?.status!=="running"||!t.endsAt||!t.startedAt)return;const i=(new Date(t.endsAt).getTime()-new Date(t.startedAt).getTime())/1e3,c=Math.max(0,(new Date(t.endsAt).getTime()-K())/1e3);if(!ee.current&&i>60&&c<=i/2&&c>i/2-2){ee.current=!0;try{Ae()}catch{}F("Halfway · keep going"),H.current&&clearTimeout(H.current),H.current=setTimeout(()=>F(null),8e3)}if(!te.current&&c<=60&&c>55){te.current=!0;try{Ae()}catch{}F("Final stretch · 1 minute left"),H.current&&clearTimeout(H.current),H.current=setTimeout(()=>F(null),9e3)}}),r.useEffect(()=>{yt();const i=jt(()=>ge());return()=>i()},[]),r.useEffect(()=>{if(!k)return;const i=t?.endsAt?`room-${t.id}-${new Date(t.endsAt).getTime()}`:"";if(t?.status!=="running"||!t.endsAt){W();return}Nt().then(h=>{h&&kt()});const c=new Date(t.endsAt).getTime(),l=t.durationMinutes??0;return wt({endsAt:c,title:"Session complete",body:`${t.name||"Focus session"}${l?` · ${l}m done`:""}`,phase:"focus",alarmId:i,task:t.name||"Focus session"}),St({firesAt:c,alarmId:i,kind:"focus",task:t.name||"Focus session"}),()=>{W(),i&&Ct(i)}},[k,t?.status,t?.endsAt,t?.id,t?.name,t?.durationMinutes]),o||n&&g)return e.jsx("div",{className:"min-h-screen flex items-center justify-center text-muted-foreground text-sm",children:"Loading sessionâ¦"});if(!n)return e.jsxs("div",{className:"min-h-screen flex flex-col items-center justify-center gap-4 px-4 text-center",children:[e.jsx("p",{className:"text-[10px] uppercase tracking-[0.22em] text-muted-foreground/70",children:"Together"}),e.jsx("h1",{className:"font-display text-3xl tracking-tight",children:"Youâve been invited to focus"}),e.jsx("p",{className:"text-muted-foreground max-w-sm text-sm",children:"Sign in to join this session â it takes a few seconds and youâll be seated automatically."}),e.jsx(D,{asChild:!0,size:"lg",className:"bg-gold text-background hover:bg-gold/90",children:e.jsx(ie,{to:"/login",search:{redirect:`/together/${s}`},children:"Sign in to join"})})]});if(!t){const i={not_found:"This session no longer exists.",invite_expired:"This invitation has expired.",full:"This one-to-one session already has two people.",ended:"This session has ended.",connection:"We couldnât open this session. Check your connection and try again."}[Je??"not_found"];return e.jsxs("div",{className:"min-h-screen flex flex-col items-center justify-center gap-4 px-4 text-center",children:[e.jsx("p",{className:"text-muted-foreground",children:i}),e.jsx(D,{asChild:!0,children:e.jsx(ie,{to:"/together",children:"Back to Together"})})]})}const re=t.createdBy===n.id,Ge=An(t.endsAt,t.status,K()),Ze=kn({status:t.status,memberCount:f.length,isHost:re}),Qe=f.find(i=>i.userId===n.id)?.avatarUrl??null,et=f.find(i=>
1i.userId!==n.id)??null;if(Ye&&!k)return e.jsxs("div",{className:"min-h-screen flex flex-col items-center justify-center gap-4 px-4 text-center",children:[e.jsx("p",{className:"text-[10px] uppercase tracking-[0.22em] text-muted-foreground/70",children:"Together"}),e.jsx("h1",{className:"font-display text-3xl tracking-tight",children:"This room is taken"}),e.jsx("p",{className:"text-muted-foreground max-w-sm text-sm",children:"Rooms are one-on-one â two people, one clock. Start your own and invite a focus mate."}),e.jsx(D,{asChild:!0,size:"lg",className:"bg-gold text-background hover:bg-gold/90",children:e.jsx(ie,{to:"/together",children:"Back to Together"})})]});const V=t;async function tt(){Ie(V.id),ce.current=!1,W(),q("You left â rejoin any time from Together"),a({to:"/together"}),n&&await Le(V.id,n.id).catch(()=>{})}async function nt(i){if(!re){i&&ue(),x(!0),Ie(V.id),ce.current=!1,W(),a({to:"/together",search:i?{complete:"1"}:{}}),n&&await Le(V.id,n.id).catch(()=>{});return}if(i){ue(),await oe(V.id).catch(()=>{q.error("Couldn't finish the session â please try again")});return}B.current=!0,ne.current=!0,P.current=!0,q("Session ended â nothing logged"),a({to:"/together"}),W(),await oe(V.id,{silent:!0}).catch(()=>{q.error("Couldn't end the session â please try again")})}async function st(){ne.current=!0,B.current=!0,P.current=!0,a({to:"/together"}),await oe(V.id,{silent:!0}).catch(()=>{})}return e.jsx("div",{className:"min-h-screen",children:e.jsxs("div",{className:"max-w-5xl mx-auto px-4 py-10 sm:py-14",children:[e.jsxs(ie,{to:"/together",className:"inline-flex items-center gap-1.5 text-sm text-muted-foreground hover:text-foreground transition mb-8",children:[e.jsx(Kt,{className:"size-4"})," Together"]}),e.jsxs("header",{className:"mb-6",children:[e.jsx("div",{children:e.jsx("h1",{className:"font-display text-3xl sm:text-4xl tracking-tight",children:t.name})}),t.category&&e.jsx("div",{className:"mt-2",children:e.jsx("span",{className:"inline-flex items-center px-2.5 py-0.5 rounded-full text-[11px] font-medium border",style:{borderColor:he(t.category),color:`color-mix(in oklch, ${he(t.category)} 88%, white 12%)`,backgroundColor:`color-mix(in oklch, ${he(t.category)} 14%, transparent)`},children:me(t.category)})})]}),e.jsx("div",{className:"flex items-center justify-center gap-2 mb-3 min-h-6",children:C&&e.jsx("span",{className:"inline-flex items-center text-[11px] uppercase tracking-widest text-gold animate-fadeUp",children:C})}),e.jsxs(gt,{className:"p-3 sm:p-4 mb-6 text-center relative overflow-hidden",children:[n&&t.status!=="done"&&!G&&e.jsx("div",{className:"text-left",children:e.jsx(dn,{code:t.code,userId:n.id,isHost:re,displayName:E||fe(n.email),selfAvatar:Qe,partnerName:et?.displayName??null,partnerPresent:f.length>=2,timerOverlay:e.jsxs("div",{className:"mt-3 rounded-full bg-background/80 px-4 py-2 text-center shadow-lg backdrop-blur-md",children:[e.jsx("div",{className:"text-[9px] uppercase tracking-[0.18em] text-muted-foreground",children:t.status==="running"?"Focusing together":"Waiting for your focus mate"}),e.jsx("div",{className:"mt-0.5 text-2xl font-semibold tabular-nums",children:t.status==="running"?Ge:Tn(t.durationMinutes)})]}),running:t.status==="running"&&!G,onLeave:()=>{tt()},onFinish:i=>{nt(i)},onCancel:()=>{st()}})}),t.status==="lobby"&&e.jsx("p",{className:"mt-6 text-xs text-muted-foreground",children:Ze.canStart?"You're both in â the clock starts in a few seconds.":re?"Waiting for your focus mate â a session is one-on-one.":"Waiting for the clock to start."}),(t.status==="done"||G)&&U&&e.jsxs("div",{className:"mt-6 space-y-4 animate-fadeUp",children:[e.jsx("div",{className:"text-4xl",children:"ð"}),e.jsx("div",{className:"font-display text-2xl tracking-tight",children:"Session complete"}),e.jsxs("p",{className:"text-sm text-muted-foreground",children:[t.durationMinutes?`${t.durationMinutes} minutes logged`:"Logged"," ·"," ",me("Focus Mate")]}),p&&!Y?e.jsx("div",{className:"text-left",children:e.jsx(Mt,{sessionId:p,focusMinutes:t.durationMinutes,task:t.name,label:me("Focus Mate"),onSave:i=>{const c=Date.now();ut(p,{reflection:i.text,reflectionAt:c,mood:i.mood,blockers:i.blockers});const l=dt().find(h=>h.id===p);l&&Ee(l),ke(!0)},onSkip:()=>ke(!0)})}):e.jsxs("div",{className:"flex items-center justify-center gap-2 flex-wrap",children:[e.jsx(D,{size:"lg",className:"bg-gold text-background hover:bg-gold/90",onClick:()=>{ge(),m(!1),a({to:"/together"})},children:"Done"}),e.jsx(D,{size:"lg",variant:"outline",onClick:()=>{ge(),m(!1)},children:"Dismiss"})]})]})]}),e.jsx(Rn,{open:d,onOpenChange:S,members:f,currentUserId:n.id,hostId:t.createdBy,onRename:O,onLeave:void 0})]})})}export{Gn as component};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.