PageSourceSearch

https://thetool.company/_next/static/chunks/2ci80hp3805fb.js

js thetool.company collected 2026-09-24 14:59:53 UTC 35,080 bytes, 1 lines download raw bytes

1(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,632036,e=>{"use strict";var t=e.i(843476),a=e.i(271645),s=e.i(920755),n=e.i(63209),i=e.i(16715),r=e.i(373375),o=e.i(245092),l=e.i(194976),d=e.i(167881),c=e.i(728231),p=e.i(158061),u=e.i(419829),m=e.i(875527),h=e.i(456174),f=e.i(414318),g=e.i(444256),x=e.i(84020),j=e.i(764355),v=e.i(572377),w=e.i(340024),y=e.i(471467),b=e.i(298489),_=e.i(582994),N=e.i(533500),S=e.i(846696),k=e.i(182352),C=e.i(923508),T=e.i(724057),I=e.i(837665),O=e.i(25257),A=e.i(416788),M=e.i(555436),L=e.i(778917),D=e.i(59377),R=e.i(522014),W=e.i(63270);function $(){return(0,t.jsxs)("div",{className:"flex items-center gap-2.5 px-1 py-1.5",children:[(0,t.jsx)("div",{className:"h-8 w-8 rounded-full bg-muted animate-pulse"}),(0,t.jsx)("div",{className:"h-3.5 w-36 rounded bg-muted animate-pulse"})]})}function U({nameWidth:e,subWidth:a}){return(0,t.jsxs)("div",{className:"flex items-center gap-2 py-1",children:[(0,t.jsx)("div",{className:"h-6 w-6 rounded-full bg-muted animate-pulse shrink-0"}),(0,t.jsxs)("div",{className:"min-w-0 flex-1 space-y-1",children:[(0,t.jsx)("div",{className:`h-2.5 rounded bg-muted animate-pulse ${e}`}),(0,t.jsx)("div",{className:`h-2 rounded bg-muted animate-pulse ${a}`})]}),(0,t.jsx)("div",{className:"h-6 w-14 rounded-3xl bg-muted animate-pulse shrink-0"})]})}function P({member:e,conversationId:s,onLinked:n,onDismiss:i}){let[r,o]=(0,a.useState)("searching"),[l,c]=(0,a.useState)([]),[p,u]=(0,a.useState)(null),[m,h]=(0,a.useState)(null),f=(0,a.useCallback)(async()=>{o("searching"),u(null);try{let t=await fetch("/api/whatsapp/groups/identify",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversationId:s,participantJid:e.participant_jid})}),a=await t.json();if(!t.ok){u(a.error||"Search failed"),o("idle");return}c(a.candidates??[]),o("results")}catch{u("Network error"),o("idle")}},[s,e.participant_jid]),g=(0,a.useRef)(!1);(0,a.useEffect)(()=>{g.current||(g.current=!0,f())},[f]);let x=(0,a.useCallback)(async t=>{h(t.linkedin_url);try{let a=await fetch("/api/contacts/quick-add-linkedin",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({linkedinUrl:t.linkedin_url,name:t.name,headline:t.headline,pictureUrl:t.image_url,profileUrn:t.profile_urn})}),s=await a.json();if(!a.ok||!s.contactId){S.toast.error(s.error||"Failed to create contact"),h(null);return}let i=await fetch("/api/whatsapp/groups/link-member",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({participantJid:e.participant_jid,contactId:s.contactId})}),r=await i.json();if(!i.ok){S.toast.error(r.error||"Contact created but linking failed"),h(null);return}S.toast.success(`${t.name||"Contact"} identified${r.backfilled?` - ${r.backfilled} past messages linked`:""}`,{action:{label:"Open",onClick:()=>window.open(`/people/${s.contactId}`,"_blank")}}),n(s.contactId,t)}catch{S.toast.error("Network error"),h(null)}},[e.participant_jid,n]);return"idle"===r?(0,t.jsxs)("div",{className:"pl-10 pb-1.5 flex items-center gap-2",children:[(0,t.jsxs)("button",{onClick:f,className:"text-[11px] text-muted-foreground hover:text-foreground inline-flex items-center gap-1",children:[(0,t.jsx)(M.Search,{className:"h-3 w-3"})," Try again"]}),p&&(0,t.jsx)("span",{className:"text-[10px] text-destructive",children:p})]}):"searching"===r?(0,t.jsxs)("div",{className:"pl-10 pb-2 space-y-0.5",children:[(0,t.jsx)(U,{nameWidth:"w-24",subWidth:"w-40"}),(0,t.jsx)(U,{nameWidth:"w-32",subWidth:"w-28"})]}):(0,t.jsxs)("div",{className:"pl-10 pb-2 space-y-0.5",children:[0===l.length&&(0,t.jsxs)("p",{className:"text-[11px] text-muted-foreground",children:["No LinkedIn matches for “",e.push_name,"”."]}),l.map(e=>{let a=m===e.linkedin_url;return(0,t.jsxs)("div",{className:`flex items-center gap-2 py-1 ${m&&!a?"opacity-40":""}`,children:[(0,t.jsxs)(W.Avatar,{className:"h-6 w-6",children:[e.image_url?(0,t.jsx)(W.AvatarImage,{src:e.image_url,alt:e.name??""}):null,(0,t.jsx)(W.AvatarFallback,{className:"text-[9px]",children:(e.name||"?").split(/\s+/).slice(0,2).map(e=>e[0]?.toUpperCase()).join("")})]}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"text-[11px] font-medium truncate",children:e.name}),(0,t.jsx)("div",{className:"text-[10px] text-muted-foreground truncate",children:[e.headline,e.location].filter(
1Boolean).join(" · ")})]}),(0,t.jsx)("a",{href:e.linkedin_url,target:"_blank",rel:"noreferrer",className:"shrink-0 text-muted-foreground hover:text-foreground","aria-label":"Open LinkedIn profile",children:(0,t.jsx)(L.ExternalLink,{className:"h-3 w-3"})}),(0,t.jsx)(d.Button,{size:"sm",variant:"outline",className:"rounded-3xl h-6 px-2 text-[10px] shrink-0",onClick:()=>x(e),disabled:null!=m,children:a?"Linking…":"It’s them"})]},e.linkedin_url)}),!m&&(0,t.jsx)("button",{onClick:i,className:"text-[10px] text-muted-foreground hover:text-foreground",children:"Close"})]})}function B({conversationId:e,groupJid:s,groupName:n}){let[i,r]=(0,a.useState)(!1),[o,l]=(0,a.useState)(null),[p,u]=(0,a.useState)(!1),[m,h]=(0,a.useState)(null),[f,g]=(0,a.useState)(""),x=(0,a.useCallback)(async()=>{let t=await fetch("/api/whatsapp/groups/members",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversationId:e})});return t.ok?await t.json():null},[e]);(0,a.useEffect)(()=>{if(!i||o)return;let e=!1;return(async()=>{u(!0);try{let t=await x();(!t?.roster_synced_at||Date.now()-new Date(t.roster_synced_at).getTime()>864e5)&&s&&(await fetch("/api/whatsapp/groups/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({jid:s})})).ok&&(t=await x()),e||l(t)}finally{e||u(!1)}})(),()=>{e=!0}},[i,o,x,s]);let j=(0,a.useCallback)((e,t,a)=>{h(null),l(s=>s&&{...s,members:s.members.map(s=>s.participant_jid===e?{...s,contact_id:t,name:a.name??s.push_name,image_url:a.image_url}:s)})},[]),v=(0,a.useMemo)(()=>o?.members.filter(e=>e.contact_id||e.push_name||e.phone)??[],[o]),w=(0,a.useMemo)(()=>{let e=f.trim().toLowerCase();if(!e)return v;let t=e.replace(/\D/g,"");return v.filter(a=>!![a.name,a.push_name,a.phone].filter(Boolean).join(" ").toLowerCase().includes(e)||t.length>0&&(a.phone?.replace(/\D/g,"").includes(t)??!1))},[v,f]),y=(o?.members.length??0)-v.length,b=o?.participant_count??o?.members.length??null,_=f.trim().length>0;return(0,t.jsxs)(D.Popover,{open:i,onOpenChange:e=>{r(e),e||(g(""),h(null))},children:[(0,t.jsxs)(c.Tooltip,{children:[(0,t.jsx)(c.TooltipTrigger,{asChild:!0,children:(0,t.jsx)(D.PopoverTrigger,{asChild:!0,children:(0,t.jsxs)(d.Button,{variant:"ghost",size:"sm",className:"rounded-3xl h-7 px-2 gap-1","aria-label":"Group members",children:[(0,t.jsx)(A.PeopleGroupIcon,{className:"h-3.5 w-3.5"}),null!=b&&(0,t.jsx)("span",{className:"text-[11px] tabular-nums",children:b})]})})}),(0,t.jsx)(c.TooltipContent,{side:"bottom",children:"Group members"})]}),(0,t.jsxs)(D.PopoverContent,{align:"end",className:"w-[360px] p-0 flex flex-col overflow-hidden",children:[(0,t.jsxs)("div",{className:"px-3 pt-3 pb-2 space-y-2",children:[(0,t.jsxs)("div",{children:[(0,t.jsx)("div",{className:"text-sm font-medium truncate",children:o?.chat_name||n}),null!=b&&(0,t.jsxs)("p",{className:"text-xs text-muted-foreground",children:[b.toLocaleString()," members",y>0&&` \xb7 ${y.toLocaleString()} not yet identified`]}),o?.description&&(0,t.jsx)("p",{className:"text-xs text-muted-foreground line-clamp-2 whitespace-pre-line mt-1",children:o.description})]}),(0,t.jsx)(R.SearchInput,{value:f,onChange:g,size:"sm",placeholder:"Search members…","aria-label":"Search group members"})]}),(0,t.jsxs)("div",{className:"flex-1 overflow-y-auto max-h-[min(60vh,420px)] px-2 pb-2 border-t pt-2",children:[p&&!o&&(0,t.jsxs)(t.Fragment,{children:[(0,t.jsx)($,{}),(0,t.jsx)($,{}),(0,t.jsx)($,{}),(0,t.jsx)($,{}),(0,t.jsx)($,{})]}),!p&&o&&0===v.length&&(0,t.jsx)("p",{className:"text-xs text-muted-foreground px-1 py-3",children:"No members identified yet. Members appear here once they post, or when their number matches a Records contact."}),!p&&v.length>0&&0===w.length&&(0,t.jsxs)("p",{className:"text-xs text-muted-foreground px-1 py-3",children:["No members match “",f.trim(),"”."]}),w.map(a=>{let s,n=a.name||a.push_name||a.phone,i=!a.contact_id&&!!a.push_name,r=(0,t.jsxs)("div",{className:`flex items-center gap-2.5 px-1 py-1.5 rounded-lg ${a.contact_id?"hover:bg-muted/60":""}`,children:[(0,t.jsxs)(W.Avatar,{className:"h-8 w-8",children:[a.image_url?(0,t.jsx)(W.AvatarImage,{src:a.image_url,alt:n??""}):null,(0,t.jsx)(W.AvatarFallback,{className:"text-[10px]",children:(s=a.name||a.push_name)?s.split(/\s+/).slice(0,2).map(e=>e[0]?.toUpperCase()??"").join(""):a.phone?a.phone.slice(-2):"?"})]}),(0,t.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,t.jsx)("div",{className:"text-xs font-medium truncate",children:n}),a.phone&&n!==a.phone&&(0,t.jsx)("div",{className:"text-[10px] text-muted-foreground truncate",children:a.phone})]}),(a.is_admin||a.is_superadmin)&&(0,t.jsx)("span",{className:"text-[10px] text-muted-foreground shrink-0",children:a.is_superadmin?"owner":"admin"})]});return(0,t.jsxs)("div",{children:[(0,t.jsxs)("div",{className:"flex items-center gap-1",children:[(0,t.jsx)("div",{className:"min-w-0 flex-1",children:a.contact_id?(0,t.jsx)("a",{href:`/people/${a.contact_id}`,className:"block",children:r}):r}),i&&(0,t.jsxs)(d.Button,{variant:"outline",size:"sm",className:"rounded-full h-6 px-2 text-[10px] shrink-0 gap-1",onClick:()=>h(e=>e===a.participant_jid?null:a.participant_jid),children:[(0,t.jsx)(M.Search,{className:"h-2.5 w-2.5"}),"Identify"]})]}),i&&m===a.participant_jid&&(0,t.jsx)(P,{member:a,conversationId:e,onDismiss:()=>h(null),onLinked:(e,t)=>j(a.participant_jid,e,t)})]},a.participant_jid)}),!p&&!_&&y>0&&v.length>0&&(0,t.jsxs)("p",{className:"text-[11px] text-muted-foreground px-1 py-2",children:["…and ",y.toLocaleStr
1ing()," more who haven’t posted"]})]})]})]})}var F=e.i(407909),J=e.i(327147),E=e.i(783618);function G(e){if(e.is_outbound)return"failed"===e.delivery_status?"failed":"delivered"}function V({contactId:e,contactName:A,workspaceId:M,hideHeader:L,externalSearchQuery:D,autoFocusComposer:R,directConversationId:W,onBack:$}){let U,P=(0,h.useMergeVars)(e),{status:F,checking:E}=(0,_.useWhatsAppStatus)({workspaceId:M}),z=W?(0,N.getCachedWhatsAppByConversationId)(W):e?(0,N.getCachedWhatsAppConversation)(e):null,q=!!z,[H,K]=(0,a.useState)(z?.conversationId??W??null),[Y,X]=(0,a.useState)(z?.phone??null),[Q,Z]=(0,a.useState)(z?.messages??[]),[ee,et]=(0,a.useState)(!1),[ea,es]=(0,a.useState)(null),[en,ei]=(0,a.useState)(!1),[er,eo]=(0,a.useState)(q),[el,ed]=(0,a.useState)(!1),[ec,ep]=(0,a.useState)(!0),[eu,em]=(0,a.useState)(""),[eh,ef]=(0,a.useState)(!1),[eg,ex]=(0,a.useState)(!1),[ej,ev]=(0,a.useState)([]),[ew,ey]=(0,a.useState)(null),eb=(0,a.useRef)(null),e_=(0,a.useRef)(new Set),[eN,eS]=(0,a.useState)("inline"),[ek,eC]=(0,a.useState)(""),eT=(D??"").trim()||ek,[eI,eO]=(0,a.useState)(null),[eA,eM]=(0,a.useState)(null),[eL,eD]=(0,a.useState)(null);(0,a.useEffect)(()=>{let e=(0,s.createClient)();(async()=>{let{data:{user:t}}=await e.auth.getUser();if(!t)return;eD(t.id);let{data:a}=await e.from("profiles").select("avatar_url, full_name").eq("id",t.id).maybeSingle();a&&(eO(a.avatar_url??null),eM(a.full_name??null))})()},[]);let{peerTyping:eR,notifyTyping:eW,stopTyping:e$}=(0,C.useTypingIndicator)({channel:"whatsapp",conversationId:H,userId:eL});(0,a.useEffect)(()=>{H&&fetch("/api/whatsapp/subscribe-presence",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversationId:H})}).catch(()=>{})},[H]);let eU=(0,a.useMemo)(()=>{if(!eT.trim())return Q;let e=eT.toLowerCase().trim();return Q.filter(t=>!!(t.content?.toLowerCase().includes(e)||t.reply_to?.text?.toLowerCase().includes(e)))},[Q,eT]),eP=(0,a.useCallback)(async()=>{(W?!(0,N.getCachedWhatsAppByConversationId)(W):!e||!(0,N.getCachedWhatsAppConversation)(e))&&ei(!0);try{let t={workspaceId:M};e&&(t.contactId=e),W&&(t.conversationId=W);let a=await fetch("/api/whatsapp/conversation",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),s=await a.json();if(s.conversation){K(s.conversation.id);let t=(s.messages||[]).map(e=>({...e,_status:G(e)}));Z(t),ep(t.length>=50),X(s.phone||null),et(!!s.conversation.is_group),es(s.conversation.is_group?s.conversation.whatsapp_jid??null:null),eF.current=!1;let a={conversationId:s.conversation.id,messages:t,phone:s.phone||null};(W||!e)&&(0,N.setCachedWhatsAppByConversationId)(s.conversation.id,a),e&&!W&&(0,N.setCachedWhatsAppConversation)(e,a)}else"No phone number found for contact"===s.error&&X(null)}catch{S.toast.error("Failed to load WhatsApp conversation")}finally{ei(!1),eo(!0)}},[e,M,W]),eB=(0,a.useCallback)(async()=>{let t=H||W;if(e||t)try{let a=e&&!W?{contactId:e}:{conversationId:t},s=await fetch("/api/whatsapp/messages",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),n=await s.json();if(n.messages){let e=n.messages.map(e=>({...e,_status:G(e)}));Z(t=>(function(e,t,a){let s=new Map(e.map(e=>[e.id,e]));for(let e of t){let t=s.get(e.id);t&&a?.has(e.id)?s.set(e.id,{...e,reactions:t.reactions,is_edited:t.is_edited,is_deleted:t.is_deleted,content:t.is_edited||t.is_deleted?t.content:e.content,_status:G(e)}):s.set(e.id,{...e,_status:G(e)})}let n=new Set;for(let a of e){if(!a.id.startsWith("temp-"))continue;let e=t.filter(e=>!(n.has(e.id)||!e.is_outbound||!a.is_outbound||a.conversation_id&&e.conversation_id&&a.conversation_id!==e.conversation_id||Math.abs(new Date(e.sent_at).getTime()-new Date(a.sent_at).getTime())>=45e3)&&(e.content===a.content||function(e,t){if(!e.is_outbound||!t.is_outbound||!e.media_type||e.media_type!==t.media_type)return!1;let a=(e.content||"").trim(),s=(t.content||"").trim();if(a===s)return!0;switch(e.media_type){case"video":{let e=e=>!e||/^video( message)?$/i.test(e)||/\.(webm|mp4|mov|m4v|mkv)$/i.test(e);return e(a)&&e(s)}case"audio":return(!a||"Voice note"===a)&&(!s||"Voice note"===s);case"image":case"sticker":return!a&&!s;default:return!1}}(a,e)));if(0===e.length)continue;let i=e.reduce((e,t)=>
1Math.abs(new Date(t.sent_at).getTime()-new Date(a.sent_at).getTime())<Math.abs(new Date(e.sent_at).getTime()-new Date(a.sent_at).getTime())?t:e);n.add(i.id),s.delete(a.id),s.set(i.id,{...i,_status:G(i),media_url:i.media_url||a.media_url})}return Array.from(s.values()).sort((e,t)=>new Date(e.sent_at).getTime()-new Date(t.sent_at).getTime())})(t,e,e_.current))}}catch{}},[e,H,W]),eF=(0,a.useRef)(!1),eJ=(0,a.useCallback)(async()=>{if(!H||el||!ec)return;let t=Q.find(e=>!e.id.startsWith("temp-"));if(t){ed(!0);try{let a=e&&!W?{contactId:e,limit:50,before:t.sent_at}:{conversationId:H,limit:50,before:t.sent_at},s=await fetch("/api/whatsapp/messages",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),n=await s.json();if(n.messages){let e=n.messages.map(e=>({...e,_status:G(e)}));if(e.length>=50)eE(e);else if(!eF.current&&Y){eF.current=!0;let s=Math.floor(new Date(t.sent_at).getTime()/1e3),n=function(e){let t=String(e||"").trim();if(!t)throw Error("recipient required");let a=t.toLowerCase(),s=t.lastIndexOf("@");if(s>0){let e=a.slice(s+1);if("s.whatsapp.net"===e||"lid"===e||"g.us"===e){let a=t.slice(0,s);return`${a}@${e}`}throw Error("Invalid WhatsApp peer")}let n=t.replace(/\D/g,"");if(!n)throw Error("Invalid phone");return n.length>15?`${n}@lid`:`${n}@s.whatsapp.net`}(Y),i=await fetch("/api/whatsapp/messages/sync-older",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversationId:H,jid:n,beforeTimestamp:s,limit:50})});if((await i.json()).synced>0){let t=await fetch("/api/whatsapp/messages",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),s=await t.json();if(s.messages){let e=s.messages.map(e=>({...e,_status:G(e)}));e.length<50&&ep(!1),eE(e)}else e.length>0&&eE(e),ep(!1)}else e.length>0&&eE(e),ep(!1)}else e.length>0&&eE(e),ep(!1)}else ep(!1)}catch{}finally{ed(!1)}}},[e,W,H,el,ec,Q,Y]),eE=(0,a.useCallback)(e=>{Z(t=>{let a=new Map(t.map(e=>[e.id,e]));for(let t of e)a.has(t.id)||a.set(t.id,t);return Array.from(a.values()).sort((e,t)=>new Date(e.sent_at).getTime()-new Date(t.sent_at).getTime())})},[]);(0,a.useEffect)(()=>{eP()},[eP]),(0,a.useEffect)(()=>{if(H)return eb.current=setInterval(eB,15e3),()=>{eb.current&&clearInterval(eb.current)}},[H,eB]),(0,f.useOnInboxRefresh)(eB);let eG=(0,a.useRef)(null);(0,a.useEffect)(()=>{let e=[...Q].reverse().find(e=>!e.is_outbound&&!e.id.startsWith("temp-"));if(!e||eG.current===e.id)return;let t=e.conversation_id||H;if(!t)return;let a=()=>{eG.current=e.id,fetch("/api/inbox/mark-read",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({channel:"whatsapp",conversationId:t,is_read:!0})}).then(()=>(0,f.dispatchInboxRefresh)()).catch(()=>{})};if("visible"===document.visibilityState)return void a();let s=()=>{"visible"===document.visibilityState&&a()};return document.addEventListener("visibilitychange",s),()=>document.removeEventListener("visibilitychange",s)},[Q,H]);let eV=(0,a.useRef)(new Set);(0,a.useEffect)(()=>{if(!ee||!H||eV.current.has(H))return;eV.current.add(H);let e=!1;return(async()=>{try{let t=await fetch("/api/whatsapp/group-senders/backfill",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversationId:H})});if(!t.ok)return;let a=await t.json().catch(()=>({}));if(e)return;a?.updated>0&&eB()}catch{}})(),()=>{e=!0}},[ee,H,eB]);let ez=(0,a.useCallback)((e,t,a,s)=>{let n=`temp-${Date.now()}-${Math.random().toString(36).slice(2,6)}`,i={id:n,conversation_id:H||"",whatsapp_message_id:null,content:e,is_outbound:!0,sender_name:null,media_type:t||null,media_url:a||null,reply_to:s||null,reactions:[],is_edited:!1,is_deleted:!1,sent_at:new Date().toISOString(),created_at:new Date().toISOString(),_status:"sending"};return Z(e=>[...e,i]),n},[H]),eq=(0,a.useCallback)(e=>{Z(t=>t.map(t=>t.id===e?{...t,_status:"delivered"}:t)),(0,f.dispatchInboxRefresh)()},[]),eH=(0,a.useCallback)(e=>{Z(t=>t.filter(t=>t.id!==e))},[]),eK=(0,a.useCallback)(async()=>{if(!H)return;if(e$(),ej.length>0){for(let t of(ef(!0),ej)){let a=t.file.type.startsWith("image/"),s=t.file.type.startsWith("video/"),n=a?"":t.file.name,i=a?"image":s?"video":"document",r=s?URL.createObjectURL(t.file):t.preview,o=ez(eu.trim()||n,i,r),l=await (0,y.sendMediaToWhatsApp)({phone:Y||"",conversationId:H,blob:t.file,mimetype:t.file.type,filename:t.file.name,caption:eu.trim()||void 0,contactId:e,workspaceId:M});l.success?eq(o):(S.toast.error(l.error||"Failed to send media"),eH(o))}ev([]),em(""),ef(!1);return}if(!eu.trim())return;let t=(0,g.resolveTemplateVarsLenient)(eu.trim(),P);em(""),ef(!0);let a=ew?{messageId:ew.msg.whatsapp_message_id||ew.msg.id,name:ew.msg.is_outbound?"You":ew.msg.sender_name||A,text:ew.msg.content||function(e){switch(e){case"image":return"Photo";case"video":return"Video";
1case"audio":return"Voice note";case"sticker":return"Sticker";case"document":return"Document";case"gif":return"GIF";default:return""}}(ew.msg.media_type)}:null,s=ez(t,null,null,a);try{let n={conversationId:H,phone:Y||void 0,message:t,contactId:e,workspaceId:M};ew?.msg.whatsapp_message_id&&(n.quotedMessageId=ew.msg.whatsapp_message_id,n.replyTo={...a,fromMe:!!ew.msg.is_outbound,participant:ew.msg.sender_jid||void 0});let i=await fetch("/api/whatsapp/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)}),r=await i.json();r.success?eq(s):(S.toast.error(r.error||"Failed to send"),eH(s),em(t))}catch{S.toast.error("Network error"),eH(s),em(t)}finally{ef(!1),ey(null)}},[eu,Y,H,e,M,ej,ez,eq,eH,ew,A,ee,P,e$]),eY=(0,a.useCallback)(async(t,a)=>{if(!H)return;ef(!0);let s=t.type||"video/webm",n=s.includes("mp4")?"mp4":"webm",i=Math.round(a/1e3),r=Math.floor(i/60),o=(i%60).toString().padStart(2,"0"),l=`video-${r}m${o}s.${n}`;if(t.size<=0xf00000){let a=URL.createObjectURL(t),n=ez("Video","video",a),i=await (0,y.sendMediaToWhatsApp)({phone:Y||"",conversationId:H,blob:t,mimetype:s,filename:l,contactId:e,workspaceId:M});i.success?eq(n):(S.toast.error(i.error||"Failed to send video"),eH(n),URL.revokeObjectURL(a))}else{let n=ez("Uploading video…","text");try{let i=new FormData;i.append("file",new File([t],l,{type:s})),i.append("title",`Video ${new Date().toLocaleDateString("en-GB")}`),i.append("duration_ms",String(a));let r=await fetch("/api/videos/upload",{method:"POST",body:i});if(!r.ok)throw Error("Upload failed");let{video:o}=await r.json(),d=`${await (0,O.resolveShareOrigin)("video")}/watch/${o.share_token}`;eH(n),(0,I.notifyVideoUploaded)({viewUrl:d,shareToken:o.share_token});let c=`🎥 ${d}`,p=ez(c);(await fetch("/api/whatsapp/send",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversationId:H,phone:Y||void 0,message:c,contactId:e,workspaceId:M})})).ok?eq(p):(eH(p),S.toast.error("Failed to send link"))}catch{eH(n),S.toast.error("Failed to upload video")}}ef(!1)},[Y,H,e,M,ez,eq,eH,ee]),eX=(0,a.useCallback)(async t=>{if(!H)return;ef(!0);let a=URL.createObjectURL(t),s=ez("Voice note","audio",a),n=await (0,y.sendMediaToWhatsApp)({phone:Y||"",conversationId:H,blob:t,mimetype:t.type||"audio/webm",ptt:!0,contactId:e,workspaceId:M});n.success?eq(s):(S.toast.error(n.error||"Failed to send voice note"),eH(s),URL.revokeObjectURL(a)),ef(!1)},[Y,H,e,M,ez,eq,eH,ee]),eQ=(0,a.useCallback)(async e=>{let t=[];for(let a of Array.from(e)){let e;if(a.size>0x1000000){S.toast.error(`"${a.name}" is too large (max 4MB). Compress it first.`);continue}if(a.type.startsWith("image/"))e=URL.createObjectURL(a);else if(a.type.startsWith("video/"))try{e=await (0,b.generateVideoThumbnail)(a)}catch{}t.push({id:`${Date.now()}-${Math.random().toString(36).slice(2,8)}`,file:a,preview:e})}t.length>0&&ev(e=>[...e,...t])},[]),eZ=(0,a.useCallback)(e=>{ev(t=>{let a=t.find(t=>t.id===e);return a?.preview&&URL.revokeObjectURL(a.preview),t.filter(t=>t.id!==e)})},[]),e0=(0,a.useCallback)(async()=>{ex(!0);try{await fetch("/api/whatsapp/sync",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({workspaceId:M})}),await eP()}catch{S.toast.error("Sync failed")}finally{ex(!1)}},[M,eP]),e1=(0,a.useCallback)(e=>{ey({msg:e})},[]),e2=(0,a.useCallback)(async e=>{if(!e.whatsapp_message_id)return;let t=Q.find(t=>t.id===e.id);if(t&&e.content!==t.content){e_.current.add(e.id),Z(t=>t.map(t=>t.id===e.id?{...t,content:e.content,is_edited:!0}:t));try{let a=await fetch("/api/whatsapp/edit",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({phone:Y||void 0,whatsappMessageId:e.whatsapp_message_id,newText:e.content,dbMessageId:e.id})}),s=await a.json();s.success||(S.toast.error(s.error||"Failed to edit"),Z(a=>a.map(a=>a.id===e.id?{...a,content:t.content,is_edited:t.is_edited}:a)))}catch{S.toast.error("Network error"),Z(a=>a.map(a=>a.id===e.id?{...a,content:t.content,is_edited:t.is_edited}:a))}finally{setTimeout(()=>e_.current.delete(e.id),6e3)}}},[Y,Q]),e5=(0,a.useCallback)(async e=>{if(e.whatsapp_message_id){e_.current.add(e.id);try{let t=await fetch("/api/whatsapp/delete-message",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({phone:Y||void 0,whatsappMessageId:e.whatsapp_message_id,dbMessageId:e.id})}),a=await t.json();a.success?Z(t=>t.map(t=>
1t.id===e.id?{...t,is_deleted:!0,content:"This message was deleted"}:t)):S.toast.error(a.error||"Failed to delete")}catch{S.toast.error("Network error")}finally{setTimeout(()=>e_.current.delete(e.id),6e3)}}},[Y]),e3=(0,a.useCallback)(async(e,t)=>{if(e.whatsapp_message_id){e_.current.add(e.id),Z(a=>a.map(a=>{if(a.id!==e.id)return a;let s=[...a.reactions||[]].filter(e=>"me"!==e.from);return t&&s.push({emoji:t,from:"me"}),{...a,reactions:s}}));try{await fetch("/api/whatsapp/react",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({phone:Y||void 0,whatsappMessageId:e.whatsapp_message_id,emoji:t,dbMessageId:e.id,fromMe:e.is_outbound})})}catch{S.toast.error("Failed to react")}finally{setTimeout(()=>e_.current.delete(e.id),6e3)}}},[Y]),e4=(0,a.useCallback)(async t=>{if(!H||!eu.trim())return void S.toast.error("Type a message first");try{let a=await fetch("/api/whatsapp/schedule",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({conversationId:H,phone:Y||void 0,content:eu.trim(),scheduledAt:t.toISOString(),contactId:e,workspaceId:M})}),s=await a.json();s.success?(em(""),S.toast.success(`Message scheduled for ${t.toLocaleString("en-GB",{day:"numeric",month:"short",year:"numeric",hour:"numeric",minute:"2-digit",hour12:!0})}`)):S.toast.error(s.error||"Failed to schedule")}catch{S.toast.error("Network error")}},[Y,eu,e,M,H]),e6=(0,a.useMemo)(()=>({onReply:e1,onEdit:e2,onDelete:e5,onReact:e3}),[e1,e2,e5,e3]),e7="image"===(U=ew?.msg.media_type)||"sticker"===U?"image":"gif"===U?"gif":"video"===U?"video":void 0,e8=(0,a.useMemo)(()=>{let e={};for(let t of Q){if(t.is_outbound||!t.sender_jid||!t.sender_name)continue;let a=t.sender_jid.split("@")[0].replace(/\D/g,"");a&&!e[a]&&(e[a]=t.sender_name)}return e},[Q]),e9=ew?{messageId:ew.msg.whatsapp_message_id??ew.msg.id,name:ew.msg.is_outbound?"You":ew.msg.sender_name||A,text:(0,j.substituteMentions)(ew.msg.content,e8),mediaUrl:e7&&"video"!==e7?ew.msg.media_url??void 0:void 0,mediaType:e7}:null,te=Q.length>0;if(!te&&("reconnecting"===F||"restorable"===F||"connecting"===F))return(0,t.jsx)(p.MessageListSkeleton,{});if(!te&&!E&&"connected"!==F)return(0,t.jsxs)("div",{className:"rounded-lg border border-dashed p-8 text-center space-y-3",children:[(0,t.jsx)(n.AlertCircle,{className:"h-8 w-8 mx-auto text-muted-foreground opacity-50"}),(0,t.jsx)("p",{className:"text-sm font-medium text-muted-foreground",children:"WhatsApp not connected"}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Go to Settings → Integrations to connect your WhatsApp."}),(0,t.jsx)(d.Button,{variant:"outline",size:"sm",onClick:()=>window.location.href="/settings",children:"Go to Settings"})]});if(er&&!en&&!Y&&e&&!W&&!ee)return(0,t.jsxs)("div",{className:"rounded-lg border border-dashed p-8 text-center space-y-2",children:[(0,t.jsx)("p",{className:"text-sm text-muted-foreground",children:"No phone number found for this contact."}),(0,t.jsx)("p",{className:"text-xs text-muted-foreground",children:"Add a phone number (ideally with type “WhatsApp”) to start messaging."})]});let tt=en&&!te,ta=(0,t.jsxs)(t.Fragment,{children:[!L&&(0,t.jsxs)("div",{className:"flex items-center justify-between gap-2 px-3 py-2 border-b bg-muted/30 shrink-0",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2 min-w-0 overflow-hidden",children:[$&&(0,t.jsx)(d.Button,{variant:"ghost",size:"sm",className:"rounded-3xl h-7 w-7 p-0 shrink-0",onClick:$,"aria-label":"Back",children:(0,t.jsx)(r.ChevronLeft,{className:"h-4 w-4"})}),(0,t.jsx)(v.WhatsAppSquircle,{}),(0,t.jsx)("span",{className:"text-xs text-muted-foreground truncate",children:"WhatsApp Messages"})]}),(0,t.jsxs)("div",{className:"flex items-center gap-2 shrink-0","data-channel-actions":!0,children:[(0,t.jsx)(o.MessageSearchPill,{value:ek,onChange:eC}),ee&&H&&(0,t.jsx)(B,{conversationId:H,groupJid:ea,groupName:A}),H&&(0,t.jsx)(k.ThreadMetaBar,{conversationId:H,channel:"whatsapp",className:"flex items-center gap-1.5"}),(0,t.jsx)(l.ChatExpandButtons,{expansion:eN,onChange:eS}),(0,t.jsxs)(c.Tooltip,{children:[(0,t.jsx)(c.TooltipTrigger,{asChild:!0,children:(0,t.jsx)(d.Button,{variant:"ghost",size:"sm",className:"rounded-3xl h-7 w-7 p-0",onClick:e0,disabled:eg||tt,children:eg?(0,t.jsx)(J.ButtonSpinner,{}):(0,t.jsx)(i.RefreshCw,{className:"h-3.5 w-3.5"})})}),(0,t.jsx)(c.TooltipContent,{side:"bottom",children:"Sync messages"})]})]})]}),L&&ee&&H&&(0,t.jsx)("div",{className:"flex items-center justify-end gap-1 px-2 py-1 border-b bg-muted/20 shrink-0",children:(0,t.jsx)(B,{conversationId:H,groupJid:ea,groupName:A})}),tt&&0===Q.length?(0,t.jsx)("div",{className:"flex-1 overflow-hidden p-3",children:(0,t.jsx)(p.MessageListSkeleton,{rows:6})}):(0,t.jsx)(x.WhatsAppMessageList,{messages:eU,contactName:A,emptyMessage:tt?"":eT.trim()?"No messages match your search":void 0,hasMore:ec,loadingMore:el,onLoadMore:eJ,conversationKey:H??e,actions:e6,isGroup:ee,meImageUrl:eI,meName:eA}),eR&&(0,t.jsx)("div",{className:`${w.THREAD_GUTTER_X} shrink-0`,children:(0,t.jsx)(T.TypingIndicator,{name:A})}),(0,t.jsx)("div",{className:"border-t py-2 shrink-0 bg-card px-2",children:(0,t.jsx)(m.FollowUpProvider,{channel:"whatsapp",conversationRef:H||W||"",contactId:e||null,children:(0,t.jsx)(u.ChatInputBox,{placeholder:`Message ${A.split(" ")[0]}...`,text:eu,onTextChange:em,onTyping:eW,draftKey:H?`whatsapp:${H}`:void 0,mergeVars:P,onSubmit:eK,sending:eh,disabled:!H||tt,showVoice:!0,onVoiceNote:eX,showVideo:!0,onVideoNote:eY,attachments:ej,onRemoveAttachment:eZ,onReplaceAttachment:async(e,t)=>{let a;if(t.type.startsWith("video/"))try{a=await (0,b.generateVideoThumbnail)(t)}catch{}else t.type.startsWith("image/")&&(a=URL.createObjectURL(t));ev(s=>s.map(s=>s.id===e?{...s,file:t,preview:a}:s))},onDropFiles:eQ,replyTo:e9,onCancelReply:()=>{ey(null),em("")},onScheduleSend:e4,autoFocus:R})})})]});return"inline"!==eN?(0,t.jsx)(l.ChatExpandedSurface,{expansion:eN,title:"WhatsApp Messages",onCollapse:()=>eS("inline"),children:ta}):(0,t.jsx)("div",{className:`flex-1 flex flex-col min-h-0 overflow-hidden ${L?"":"border rounded-2xl bg-card"}`,"data-channel-panel":!0,children:ta})}function z({contactId:e,contactName:s,workspaceId:n,hideHeader:i,onBack:o,preferOpenMostRecentDirectThread:l,autoOpenedDirectDmRef:c,onSelect:p}){let u=(0,a.useCallback)(e=>{let t=[];for(let a of(e.dm&&t.push({conversation_id:e.dm.conversationId,name:s,snippet:e.dm.snippet,date:e.dm.lastMessageAt,is_group:!1,image_url:e.dm.contactImageUrl}),e.groups))t.push({conversation_id:a.conversation_id,name:a.chat_name||"Group",snippet:null,date:a.last_post_at??null,is_group:!0,image_url:a.picture_url??null});return t.sort((e,t)=>
1{let a=e.date?new Date(e.date).getTime():0;return(t.date?new Date(t.date).getTime():0)-a})},[s]),m=(0,N.getCachedWhatsAppList)(e),[h,f]=(0,a.useState)(m?u(m):[]),[g,x]=(0,a.useState)(!m);(0,a.useEffect)(()=>{let e;if(!l||g||c.current)return;let t=0===(e=h.filter(e=>!e.is_group)).length?null:[...e].sort((e,t)=>{let a=e.date?new Date(e.date).getTime():0;return(t.date?new Date(t.date).getTime():0)-a})[0]??null;t&&(c.current=!0,p({conversationId:t.conversation_id,name:t.name,isGroup:!1}))},[l,g,h,p,c]),(0,a.useEffect)(()=>{if(m)return;let t=!1;return(0,N.getInflightWhatsAppList)(e)||(0,N.prefetchWhatsAppList)({contactId:e,workspaceId:n}),(async()=>{let a=(0,N.getInflightWhatsAppList)(e);if(a){let e=await a;if(t)return;e&&f(u(e))}t||x(!1)})(),()=>{t=!0}},[e,n,m,u]);let j=({label:e,dotHex:a})=>(0,t.jsxs)("span",{className:(0,E.pillClass)("default","text-muted-foreground"),children:[(0,t.jsx)("span",{className:"h-1.5 w-1.5 rounded-full",style:{backgroundColor:a}}),e]});return(0,t.jsxs)("div",{className:`flex-1 flex flex-col min-h-0 overflow-hidden ${i?"":"border rounded-2xl bg-card"}`,"data-channel-panel":!0,children:[!i&&(0,t.jsx)("div",{className:"flex items-center justify-between gap-2 px-3 py-2 border-b bg-muted/30 shrink-0",children:(0,t.jsxs)("div",{className:"flex items-center gap-2 shrink-0",children:[o&&(0,t.jsx)(d.Button,{variant:"ghost",size:"sm",className:"rounded-3xl h-7 w-7 p-0 shrink-0",onClick:o,"aria-label":"Back",children:(0,t.jsx)(r.ChevronLeft,{className:"h-4 w-4"})}),(0,t.jsx)(v.WhatsAppSquircle,{}),(0,t.jsx)("span",{className:"text-xs text-muted-foreground",children:"WhatsApp Conversations"})]})}),(0,t.jsx)("div",{className:"flex-1 min-h-0 overflow-y-auto px-1 py-1 space-y-0.5",children:g&&0===h.length?(0,t.jsx)(t.Fragment,{children:Array.from({length:3}).map((e,a)=>(0,t.jsxs)("div",{className:"w-full flex items-start gap-2.5 px-3 py-2.5 rounded-lg","aria-hidden":!0,children:[(0,t.jsx)("div",{className:"h-9 w-9 rounded-full bg-muted/60 animate-pulse shrink-0"}),(0,t.jsxs)("div",{className:"flex-1 min-w-0 space-y-1.5 py-0.5",children:[(0,t.jsx)("div",{className:"h-3 w-24 bg-muted/60 rounded animate-pulse"}),(0,t.jsx)("div",{className:"h-2.5 w-3/4 bg-muted/40 rounded animate-pulse"}),(0,t.jsx)("div",{className:"h-3 w-10 bg-muted/40 rounded-full animate-pulse mt-1"})]})]},a))}):0===h.length?(0,t.jsx)("div",{className:"px-3 py-6 text-center text-[11px] text-muted-foreground/60",children:"No WhatsApp activity for this contact yet."}):h.map(e=>(0,t.jsxs)("button",{type:"button",onClick:()=>p({conversationId:e.conversation_id,name:e.name,isGroup:e.is_group}),className:"w-full text-left flex items-start gap-2.5 px-3 py-2.5 rounded-lg hover:bg-muted/40",children:[(0,t.jsxs)("div",{className:"relative shrink-0",children:[(0,t.jsxs)(W.Avatar,{className:"h-9 w-9",children:[e.image_url&&(0,t.jsx)(W.AvatarImage,{src:e.image_url,alt:e.name}),(0,t.jsx)(W.AvatarFallback,{className:"text-[9px] bg-foreground
1/8 text-foreground/60 font-medium",children:e.is_group?(0,t.jsx)(A.PeopleGroupIcon,{className:"h-4 w-4"}):(e.name[0]||"?").toUpperCase()})]}),e.is_group&&(0,t.jsx)("span",{className:"absolute -bottom-0.5 -right-0.5 flex h-4 w-4 items-center justify-center rounded-full bg-background ring-1 ring-border",children:(0,t.jsx)(A.PeopleGroupIcon,{className:"h-2.5 w-2.5 text-muted-foreground"})})]}),(0,t.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,t.jsxs)("div",{className:"flex items-center gap-2",children:[(0,t.jsx)("span",{className:"text-[13px] truncate font-medium text-foreground/85",children:e.name}),e.date&&(0,t.jsx)("span",{className:"text-[11px] text-muted-foreground tabular-nums ml-auto shrink-0",children:function(e){if(!e)return"";let t=new Date(e),a=Math.floor((new Date().getTime()-t.getTime())/6e4);if(a<1)return"now";if(a<60)return`${a}m`;let s=Math.floor(a/60);if(s<24)return`${s}h`;let n=Math.floor(s/24);return n<7?`${n}d`:t.toLocaleDateString("en-GB",{day:"numeric",month:"short"})}(e.date)})]}),e.snippet&&(0,t.jsx)("p",{className:"text-[11px] text-muted-foreground/70 truncate mt-0.5",children:(0,t.jsx)(F.FormattedText,{text:e.snippet,preview:!0})}),(0,t.jsx)("div",{className:"mt-1 flex items-center gap-1",children:e.is_group?(0,t.jsx)(j,{label:"Group",dotHex:"#9CA3AF"}):(0,t.jsx)(j,{label:"DM",dotHex:"#10B981"})})]})]},e.conversation_id))})]})}e.s(["WhatsAppChatPanel",0,function(e){let{contactId:s,directConversationId:n,workspaceId:i,contactName:r,onBack:o,hideHeader:l,preferOpenMostRecentDirectThread:d}=e,[c,p]=(0,a.useState)(n&&s?{conversationId:n,name:r}:null),u=(0,a.useRef)(!!(n&&s));return((0,a.useEffect)(()=>{u.current=!!(n&&s)},[s,n]),s)?c?(0,t.jsx)(V,{...e,contactName:c.name,directConversationId:c.conversationId,onBack:()=>p(null)}):(0,t.jsx)(z,{contactId:s,contactName:r,workspaceId:i,hideHeader:l,onBack:o,preferOpenMostRecentDirectThread:d,autoOpenedDirectDmRef:u,onSelect:e=>p({conversationId:e.conversationId,name:e.isGroup?e.name:r})}):(0,t.jsx)(V,{...e})}],632036)}]);

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.