1import{r as n,j as t}from"./charts-Dl5COngX.js";import{e as Q,ep as F,aY as V,ei as B,eB as T,j as z,m as Y,l as W,a5 as $,Q as H,B as G,bq as X,ej as Z,y as O,G as J,T as ee}from"./main-DIRVCRVk.js";import{C as te,N as se}from"./ChatUnavailableNotice-SX9jv8iV.js";import{r as re,R as ne,a as oe}from"./useGatedRooms-DaZ7iWXX.js";import{u as ae,G as ie,a as ce}from"./useRoomsConfig-BGxjUnK7.js";import{b as le,d as K,c as ue}from"./formatters-Dby4BLsG.js";import{H as D}from"./hash-DDSBIUfp.js";import{L as de}from"./lock-CM0FoQ46.js";import{K as me}from"./key-round-DywiHix3.js";import{A as fe}from"./arrow-left-DxuWHzGF.js";import{I as xe}from"./info-CWzdvi8a.js";import{S as he}from"./send-BZXgNHTW.js";import"./aeternity-Bb8AAdSJ.js";import"./web3-pqzLatyd.js";import"./radio-qaNOArBO.js";function pe(){const e=Q(F),s=V(F);return n.useEffect(()=>{s(o=>o==="done"||o==="error"?"prompt":o)},[s]),e}const ge=new Set([T.GroupAddUser,T.GroupRemoveUser,T.GroupLeaveRequest]);function be(e,s){return{id:`msg_${e.id}`,eventId:e.id,content:e.content,authorPubkey:e.pubkey,isFromMe:!!s&&e.pubkey===s,timestamp:e.created_at*1e3,status:"sent"}}function ye(e,s,o){const i=e.tags.filter(c=>c[0]==="p"&&!!c[1]).map(c=>c[1]);let a;if(e.kind===T.GroupAddUser)a="add";else if(e.kind===T.GroupRemoveUser)a="remove";else if(e.kind===T.GroupLeaveRequest)a="leave";else return null;return a!=="leave"&&i.length===0?null:{id:`sys_${e.id}`,eventId:e.id,content:"",authorPubkey:e.pubkey,isFromMe:!!o&&e.pubkey===o,timestamp:e.created_at*1e3,status:"sent",system:{action:a,actorPubkey:e.pubkey,targetPubkeys:i,actorIsSystem:!!s&&e.pubkey===s}}}const U=50;function ke(e,s={}){const{isPrivate:o=!1,readable:i=!1,includeSystem:a=!1}=s,{identity:c,pubkey:N,isUnlocked:l}=B(),{relayUrl:u}=ae(),[h,j]=n.useState([]),[S,b]=n.useState(null),[v,y]=n.useState("loading"),[I,L]=n.useState(!1),[R,E]=n.useState(!0),m=n.useRef(null),w=n.useRef(null),p=i,f=n.useCallback(r=>{j(d=>{if(d.some(x=>x.eventId===r.id))return d;const g=ge.has(r.kind)?ye(r,w.current,N):be(r,N);return g?[...d,g].sort((x,_)=>x.timestamp-_.timestamp):d})},[N]);n.useEffect(()=>{if(!e||!u){y("loading");return}let r=!1,d=null;j([]),b(null),y(i?"ok":"not-member"),L(!1),E(!0),w.current=null;let g;try{g=new ie(c,u)}catch{y("loading");return}return m.current=g,(async()=>{const x=await g.getGroupMetadata(e).catch(()=>null);w.current=g.relayPubkey,!r&&x&&b(x);const _=await g.fetchRoomHistory(e,{limit:U,isPrivate:o,includeSystem:a}).catch(()=>[]);r||(_.forEach(f),_.length<U&&E(!1));const k=await g.subscribeRoom(e,M=>{r||f(M)},{isPrivate:o,includeSystem:a});if(r){k.close();return}d=k})().catch(()=>{r||o&&y("auth-required")}),()=>{r=!0,d?.close(),g.close(),m.current=null}},[e,c,u,o,i,a,f]);const P=n.useCallback(async()=>{const r=m.current;if(!r||!e||I||!R)return;const d=h.reduce((x,_)=>_.timestamp<x?_.timestamp:x,Number.POSITIVE_INFINITY),g=Number.isFinite(d)?Math.floor(d/1e3)-1:void 0;L(!0);try{const x=await r.fetchRoomHistory(e,{until:g,limit:U,isPrivate:o,includeSystem:a}),_=x.filter(k=>!h.some(M=>M.eventId===k.id));_.forEach(f),(x.length<U||_.length===0)&&E(!1)}catch{}finally{L(!1)}},[e,o,a,I,R,h,f]),A=n.useCallback(async r=>{const d=r.trim(),g=m.current;if(!e||!g||!d)return;if(!p){y("not-member");return}const x=`opt_${Date.now()}_${Math.random().toString(36).slice(2)}`,_={id:x,content:d,authorPubkey:N??"",isFromMe:!0,timestamp:Date.now(),status:"sending"};j(k=>[...k,_]);try{const k=await g.sendRoomMessage(e,d);j(M=>M.map(C=>C.id===x?{...C,eventId:k,status:"sent"}:C)),y("ok")}catch(k){throw k instanceof ce&&(k.isAuthRequired?y("auth-required"):k.isNotMember&&y("not-member")),j(M=>M.map(C=>C.id===x?{...C,status:"failed"}:C)),k}},[e,p,N]),q=n.useMemo(()=>!!u,[u]);return{name:S?.name,about:S?.about,isPrivate:S?.isPrivate??o,messages:h,sendMessage:A,isReady:q,access:v,canPost:p,needsUnlock:p&&!l,loadEarlier:P,isLoadingEarlier:I,hasEarlier:R}}const Ne=5e3,je=15e3,_e=6e4,Re=10*6e4,Se=5e3,Le=24;function Ee({room:e,access:s,canPost:o,symbolLabel:i="Community",roomsLoading:a=!1}){const{activeAccount:c}=z(),N=Y(),l=c,u=e?.sale_address,[h,j]=W(F),S=n.useRef(!1),b=n.useCallback(()=>{l&&N.invalidateQueries({queryKey:re.list(l)})},[N,l]),v=n.useCallback(()=>
1{if(!l||!u){b();return}ne.recheckRoomAccess({saleAddress:u,requestBody:{address:l}}).catch(()=>{}).finally(()=>b())},[l,u,b]);n.useEffect(()=>{S.current&&(h==="done"||h==="linked")&&(S.current=!1,b())},[h,b]);const y=n.useRef(null);n.useEffect(()=>{e?.relay_state!=="pending_add"||!u||y.current!==u&&(y.current=u,v())},[e?.relay_state,u,v]),n.useEffect(()=>{if(e?.relay_state!=="pending_add"||!l)return;const p=Date.now();let f;const P=()=>{const A=Date.now()-p;if(A>=Re)return;const q=A<_e?Ne:je;f=setTimeout(()=>{b(),P()},q)};return P(),()=>clearTimeout(f)},[e?.relay_state,l,b]);const[I,L]=n.useState(!1),R=n.useCallback(()=>L(!0),[]);n.useEffect(()=>{if(!I||!l)return;if(e||o){L(!1);return}let p=0;const f=setInterval(()=>{p+=1,b(),p>=Le&&(clearInterval(f),L(!1))},Se);return()=>clearInterval(f)},[I,e,o,l,b]);const E=n.useCallback(()=>{h!=="linking"&&(S.current=!0,j("prompt"))},[h,j]),m=n.useMemo(()=>o?null:e&&e.member_pubkey===null?"link-required":e?.relay_state==="pending_add"?"provisioning":s==="auth-required"?"holder-required":"not-eligible",[o,e,s]),w=n.useMemo(()=>{if(a&&!e)return{gate:"provisioning",icon:D,tone:"info",text:"Checking accessâ¦",action:"none"};if(!m)return null;const p=le(e?.min_token_threshold),f=p?`${p} `:"1 ";switch(m){case"link-required":return{gate:m,icon:me,tone:"gate",text:"Link your Nostr key to post in this room.",action:"link"};case"provisioning":return{gate:m,icon:D,tone:"info",text:"Setting up your access⦠(this can take a moment)",action:"none"};case"holder-required":return{gate:m,icon:de,tone:"lock",text:"This is a private room â you must be a holding member to view or post.",action:"none"};default:return{gate:m,icon:D,tone:"gate",text:`Hold ⥠${f}#${i} to post in this room.`,action:"buy",tokenAddress:e?.token_address}}},[m,e,i,a]);return{gate:m,banner:w,requestLink:E,isLinking:h==="linking",notifyTokenAcquired:R,refresh:v}}function ve(e){const{system:s}=e;if(!s)return"";const o=a=>a?K(a):"someone",i=s.targetPubkeys.map(o).join(", ");switch(s.action){case"add":return s.actorIsSystem?`${i} joined`:`${o(s.actorPubkey)} added ${i}`;case"remove":return`${o(s.actorPubkey)} removed ${i}`;default:return`${o(s.actorPubkey)} left`}}const Ie=({message:e})=>
1{if(e.system)return t.jsx("div",{className:"my-1 text-center text-xs text-muted-foreground",children:ve(e)});const s=e.isFromMe;return t.jsxs("div",{className:$("flex flex-col",s?"items-end":"items-start"),children:[!s&&t.jsx("span",{className:"mb-0.5 px-1 text-xs text-muted-foreground",children:K(e.authorPubkey)}),t.jsx("div",{className:$("max-w-[80%] whitespace-pre-wrap break-words rounded-2xl px-3 py-2 text-sm",s?"rounded-br-sm bg-primary text-primary-foreground":"rounded-bl-sm bg-muted text-foreground"),children:e.content}),t.jsxs("span",{className:"mt-0.5 px-1 text-[10px] text-muted-foreground",children:[ue(e.timestamp),e.status==="sending"&&" · sendingâ¦",e.status==="failed"&&" · failed"]})]})},we=({banner:e,onLink:s,onBuy:o,onCheckAgain:i})=>{const{icon:a,tone:c,text:N,action:l,gate:u,tokenAddress:h}=e;return t.jsxs("div",{className:$("flex flex-col gap-3 rounded-xl border p-4",c==="gate"?"border-primary/40 bg-primary/5":"border-border bg-card"),children:[t.jsxs("div",{className:"flex items-start gap-3",children:[c==="info"?t.jsx(H,{className:"mt-0.5 h-5 w-5 shrink-0"}):t.jsx(a,{className:$("mt-0.5 h-5 w-5 shrink-0",c==="gate"?"text-primary":"text-muted-foreground"),"aria-hidden":!0}),t.jsx("p",{className:"text-sm text-foreground",children:N})]}),t.jsxs("div",{className:"flex flex-wrap gap-2",children:[l==="link"&&t.jsx(G,{size:"sm",onClick:s,children:"Link your Nostr key"}),l==="buy"&&t.jsx(G,{size:"sm",onClick:()=>o?.(h),children:"Buy token"}),u==="provisioning"&&i&&t.jsx(G,{size:"sm",variant:"outline",onClick:i,children:"Check again"})]})]})},Qe=()=>{const{saleAddress:e=""}=X();pe();const{room:s,isLoading:o}=oe(e),i=s?.readable??!1,a=s?.is_private??!1,{messages:c,sendMessage:N,access:l,canPost:u,needsUnlock:h,isReady:j,loadEarlier:S,hasEarlier:b,isLoadingEarlier:v}=ke(e,{isPrivate:a,readable:i}),{banner:y,requestLink:I,refresh:L}=Ee({room:s,access:l,canPost:u,symbolLabel:s?.symbol,roomsLoading:o}),R=B(),[E,m]=n.useState(""),[w,p]=n.useState(null),f=n.useRef(null);n.useEffect(()=>{const r=f.current;r&&(r.scrollTop=r.scrollHeight)},[c.length]);const P=async()=>{const r=E.trim();if(r){p(null),m("");try{await N(r)}catch(d){p(d instanceof Error?d.message:"Message failed to send.")}}},A=s?`#${s.symbol}`:"Community";if(!Z())return t.jsx(te,{});const q=()=>y?t.jsx(we,{banner:y,onLink:I,onCheckAgain:L}):h?t.jsxs("div",{className:"flex flex-col gap-2 rounded-xl border border-primary/40 bg-primary/5 p-4",children:[t.jsx("p",{className:"text-sm text-foreground",children:"Unlock chat to post in this room."}),R.error&&t.jsx("p",{className:"text-xs text-error",children:R.error.message}),t.jsx(G,{size:"sm",onClick:()=>{R.unlock()},disabled:R.isUnlocking,children:R.isUnlocking?t.jsxs(t.Fragment,{children:[t.jsx(J,{className:"mr-1 h-4 w-4 animate-spin"}),"Unlockingâ¦"]}):"Unlock chat"})]}):t.jsxs("form",{className:"flex items-center gap-2",onSubmit:r=>{r.preventDefault(),P()},children:[t.jsx(ee,{value:E,onChange:r=>m(r.target.value),placeholder:`Message #${s?.symbol??"room"}`,"aria-label":"Message"}),t.jsx(G,{type:"submit",size:"sm",disabled:!E.trim(),children:t.jsx(he,{className:"h-4 w-4"})})]});return t.jsxs("div",{className:"mx-auto flex h-[calc(100dvh-9rem)] min-h-[28rem] w-full max-w-2xl flex-col",children:[t.jsxs("header",{className:"flex items-center gap-2 border-b border-border px-3 py-3",children:[t.jsx(O,{to:"/chat",className:"rounded-md p-1 text-muted-foreground hover:text-foreground","aria-label":"Back to communities",children:t.jsx(fe,{className:"h-5 w-5"})}),t.jsx("h1",{className:"flex-1 truncate text-lg font-semibold text-foreground",children:A}),t.jsx(O,{to:`/chat/${e}/info`,className:"rounded-md p-1 text-muted-foreground hover:text-foreground","aria-label":"Room info",children:t.jsx(xe,{className:"h-5 w-5"})})]}),t.jsxs("div",{ref:f,className:"flex flex-1 flex-col gap-2 overflow-y-auto px-3 py-4",children:[!j&&t.jsxs("div",{className:"flex items-center justify-center gap-2 py-8 text-sm text-muted-foreground",children:[t.jsx(H,{className:"h-4 w-4"}),"Connectingâ¦"]}),j&&b&&c.length>0&&t.jsx("button",{type:"button",onClick:()=>{S()},disabled:v,className:"mx-auto mb-2 text-xs text-primary disabled:opacity-50",children:v?"Loadingâ¦":"Load earlier messages"}),j&&c.length===0&&t.jsx("p",{className:"py-8 text-center text-sm text-muted-foreground",children:"No messages yet."}),c.map(r=>
1t.jsx(Ie,{message:r},r.id))]}),t.jsxs("div",{className:"border-t border-border p-3",children:[q(),w&&t.jsx("p",{className:"mt-2 text-xs text-error",children:w})]}),t.jsx(se,{})]})};export{Qe as default};
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.