@usechat/react-native 1.0.16 → 1.0.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +16 -6
- package/dist/index.d.ts +16 -6
- package/dist/index.js +259 -256
- package/dist/index.mjs +310 -307
- package/package.json +11 -11
package/dist/index.mjs
CHANGED
|
@@ -1,463 +1,466 @@
|
|
|
1
1
|
'use client'
|
|
2
|
-
var
|
|
2
|
+
var Ae={status:"idle",projectId:null,error:null},Ks=()=>{Ae={status:"pending",projectId:null,error:null}},$s=C=>{Ae={status:"success",projectId:C,error:null}},Ro=C=>{Ae={status:"error",projectId:null,error:C}};var $n=()=>({...Ae}),Rt=()=>{if(Ae.status==="error")throw new Error(`UseChat SDK: Invalid Project ID
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
${Ae.error}
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
import { initChat } from '@usechat/react-native';
|
|
8
|
-
await initChat({ projectId: 'your-project-id' });`);if(!ke.isInitialized)throw new Error(`UseChat SDK is not initialized.
|
|
6
|
+
Please check your project ID in the UseChat dashboard: https://app.usechat.dev`);if(Ae.status==="idle")throw new Error(`UseChat SDK is not initialized.
|
|
9
7
|
|
|
10
|
-
Please call initChat() with
|
|
8
|
+
Please call initChat() with your project ID before using any UseChat components.
|
|
11
9
|
|
|
12
10
|
Example:
|
|
13
11
|
import { initChat } from '@usechat/react-native';
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
12
|
+
|
|
13
|
+
// In your app entry point (_layout.tsx or App.tsx):
|
|
14
|
+
await initChat({ projectId: 'your-project-id' });`);return Ae.status==="pending"?"pending":"ready"},qn=()=>{if(Rt()==="pending")throw new Error("SDK is still initializing");return Ae.projectId},Jo=()=>Ae.status==="success",Xo=()=>Ae.status==="pending",Zo=()=>Ae.status;var Yn="https://usechat.dev/api/validate-project",Ot=null,_n=async C=>{let{projectId:S,apiUrl:T=Yn,debug:M=!1}=C;if(Jo())return M&&console.log(`[UseChat SDK] Already initialized with projectId: ${S}`),{success:!0,message:"Chat SDK already initialized",projectId:S,activatedAt:new Date().toISOString()};if(Xo()&&Ot)return M&&console.log("[UseChat SDK] Initialization already in progress..."),Ot;if(!S||typeof S!="string"||S.trim()===""){let R="Project ID is required";throw Ro(R),new Error(`[UseChat SDK] ${R}`)}return Ks(),M&&console.log(`[UseChat SDK] Initializing with projectId: ${S}`),Ot=(async()=>{try{let R=await fetch(`${T}?projectId=${S}`,{method:"GET",headers:{"Content-Type":"application/json"}}),A=await R.json();if(!R.ok){let I=A.error||`Project ID "${S}" not found. Please check your project ID.`;throw Ro(I),new Error(`[UseChat SDK] ${I}`)}return $s(S),M&&console.log(`[UseChat SDK] Successfully initialized with project: ${A.name}`),{success:!0,message:`Chat SDK initialized with project: ${A.name}`,projectId:S,projectName:A.name,activatedAt:new Date().toISOString()}}catch(R){if(R instanceof Error&&R.message.startsWith("[UseChat SDK]"))throw R;let A="Failed to initialize SDK. Please check your network connection.";throw Ro(A),new Error(`[UseChat SDK] ${A}`)}finally{Ot=null}})(),Ot};import Xs,{useState as ss,useRef as Zs,useCallback as wt}from"react";import{View as Qe,StyleSheet as Ra}from"react-native";import{createContext as Qn,useContext as ea}from"react";import{StyleSheet as ta}from"react-native";import{KeyboardProvider as Ca,KeyboardAvoidingView as Ma}from"react-native-keyboard-controller";import{createContext as Xn,useContext as Ys,useState as Zn,useCallback as qs}from"react";var Gn={"input.placeholder":"Type a message...","search.placeholder":"Search chats...","status.online":"Online","status.offline":"Offline","status.typing":"typing...","message.deleted":"This message was deleted","message.sending":"Sending...","message.sent":"Sent","message.delivered":"Delivered","message.read":"Read","message.failed":"Failed to send","action.reply":"Reply","action.copy":"Copy","action.delete":"Delete","action.cancel":"Cancel","action.send":"Send","action.clear":"Clear","action.clearAll":"Clear All","attachment.add":"Add attachment","attachment.remove":"Remove","attachment.clear":"Clear","attachment.attachments":"Attachments:","accessibility.back":"Go back","accessibility.send":"Send message","accessibility.attach":"Add attachment","accessibility.emoji":"Add emoji","accessibility.videoCall":"Start video call","accessibility.voiceCall":"Start voice call","accessibility.info":"Chat info","accessibility.search":"Search chats","accessibility.typing":"Someone is typing","error.fileTooLarge":"File is too large","error.invalidFileType":"Invalid file type","error.maxAttachments":"Maximum attachments reached","error.networkError":"Network error occurred","time.justNow":"Just now","time.minutesAgo":"{{count}} min ago","time.hoursAgo":"{{count}}h ago","time.daysAgo":"{{count}}d ago","time.weeksAgo":"{{count}}w ago","time.monthsAgo":"{{count}}mo ago","time.yearsAgo":"{{count}}y ago","date.today":"Today","date.yesterday":"Yesterday","date.todayWithTime":"Today {{time}}","date.yesterdayWithTime":"Yesterday {{time}}"},Jn={"input.placeholder":"Napisz wiadomo\u015B\u0107...","search.placeholder":"Szukaj czat\xF3w...","status.online":"Online","status.offline":"Offline","status.typing":"pisze...","message.deleted":"Ta wiadomo\u015B\u0107 zosta\u0142a usuni\u0119ta","message.sending":"Wysy\u0142anie...","message.sent":"Wys\u0142ano","message.delivered":"Dostarczono","message.read":"Przeczytano","message.failed":"Nie uda\u0142o si\u0119 wys\u0142a\u0107","action.reply":"Odpowiedz","action.copy":"Kopiuj","action.delete":"Usu\u0144","action.cancel":"Anuluj","action.send":"Wy\u015Blij","action.clear":"Wyczy\u015B\u0107","action.clearAll":"Wyczy\u015B\u0107 wszystko","attachment.add":"Dodaj za\u0142\u0105cznik","attachment.remove":"Usu\u0144","attachment.clear":"Wyczy\u015B\u0107","attachment.attachments":"Za\u0142\u0105czniki:","accessibility.back":"Wr\xF3\u0107","accessibility.send":"Wy\u015Blij wiadomo\u015B\u0107","accessibility.attach":"Dodaj za\u0142\u0105cznik","accessibility.emoji":"Dodaj emoji","accessibility.videoCall":"Rozpocznij wideorozmow\u0119","accessibility.voiceCall":"Rozpocznij rozmow\u0119 g\u0142osow\u0105","accessibility.info":"Informacje o czacie","accessibility.search":"Szukaj czat\xF3w","accessibility.typing":"Kto\u015B pisze","error.fileTooLarge":"Plik jest za du\u017Cy","error.invalidFileType":"Nieprawid\u0142owy typ pliku","error.maxAttachments":"Osi\u0105gni\u0119to maksymaln\u0105 liczb\u0119 za\u0142\u0105cznik\xF3w","error.networkError":"Wyst\u0105pi\u0142 b\u0142\u0105d sieci","time.justNow":"W\u0142a\u015Bnie teraz","time.minutesAgo":"{{count}} min temu","time.hoursAgo":"{{count}}h temu","time.daysAgo":"{{count}}d temu","time.weeksAgo":"{{count}}t temu","time.monthsAgo":"{{count}}mies temu","time.yearsAgo":"{{count}}l temu","date.today":"Dzisiaj","date.yesterday":"Wczoraj","date.todayWithTime":"Dzisiaj {{time}}","date.yesterdayWithTime":"Wczoraj {{time}}"},wo={en:Gn,pl:Jn},Ht=C=>wo[C]||wo.en,Io=C=>C==="en"||C==="pl";var Qo=Xn(void 0),Po=({children:C,locale:S="en",fallbackLocale:T="en"})=>{let[M,R]=Zn(S),A=qs((V,E={})=>{let B=Ht(M)[V];return!B&&M!==T&&(B=Ht(T)[V]),B?B.replace(/\{\{(\w+)\}\}/g,(k,z)=>E[z]?.toString()||k):(console.warn(`Translation missing for key: ${V} in locale: ${M}`),V)},[M,T]),I=qs(V=>{Io(V)?R(V):(console.warn(`Unsupported locale: ${V}. Falling back to 'en'`),R("en"))},[]),P={t:A,locale:M,setLocale:I};return<Qo.Provider value={P}>
|
|
15
|
+
{C}
|
|
16
|
+
</Qo.Provider>},_s=()=>{let C=Ys(Qo);if(!C)throw new Error("useTranslation must be used within an I18nProvider");return C},Te=()=>{let C=Ys(Qo);return C?C.t:S=>S};var Gs=Qn(null),Ta=({children:C,config:S={},locale:T="en"})=>{let M={keyboardBehavior:"padding",keyboardVerticalOffset:60,enableReactionDetails:!0,enableMessageActions:!0,enableScrollToBottom:!0,enableTypingIndicator:!0,...S};return<Po locale={T}>
|
|
17
|
+
<Gs.Provider value={{config:M}}>
|
|
18
|
+
<Ca>
|
|
19
|
+
<Ma behavior={M.keyboardBehavior}style={[Sa.keyboardContainer]}keyboardVerticalOffset={M.keyboardVerticalOffset}>
|
|
20
20
|
{}
|
|
21
|
-
{
|
|
22
|
-
</
|
|
23
|
-
</
|
|
24
|
-
</
|
|
25
|
-
</
|
|
26
|
-
{N||<
|
|
21
|
+
{C}
|
|
22
|
+
</Ma>
|
|
23
|
+
</Ca>
|
|
24
|
+
</Gs.Provider>
|
|
25
|
+
</Po>},es=Ta,Nt=()=>{let C=ea(Gs);if(!C)throw new Error("useChatConfig must be used within a ChatProvider");return C.config},Sa=ta.create({container:{flex:1},keyboardContainer:{flex:1,overflow:"hidden"}});import{useState as ts,useCallback as Wt}from"react";var Ut=(C={})=>{let{uploader:S,maxAttachments:T=10,maxFileSize:M=10*1024*1024,allowedTypes:R=["image/*","application/pdf","text/*"],onAttachmentAdd:A,onAttachmentRemove:I,onAttachmentUpload:P}=C,[V,E]=ts([]),[v,B]=ts(!1),[k,z]=ts(0),D=Wt(N=>{if(V.length>=T){console.warn(`Maximum ${T} attachments allowed`);return}if(N.data?.size&&N.data.size>M){console.warn(`File size exceeds ${M/(1024*1024)}MB limit`);return}if(N.data?.type&&!R.some(re=>re.endsWith("/*")?N.data.type.startsWith(re.slice(0,-1)):N.data.type===re)){console.warn(`File type ${N.data.type} not allowed`);return}let F={...N,id:N.id||`att_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,uploadStatus:"pending",uploadProgress:0};E(G=>[...G,F]),A&&A(F)},[V.length,T,M,R,A]),L=Wt(N=>{E(F=>F.filter(G=>G.id!==N)),I&&I(N)},[I]),O=Wt(()=>{E([])},[]),j=Wt(async N=>{try{let F;switch(N){case"image":F={type:"image",data:{uri:"mock-image-uri",width:800,height:600,fileName:"image.jpg",fileSize:1024*1024}};break;case"document":F={type:"document",data:{uri:"mock-document-uri",name:"document.pdf",size:2048*1024,mimeType:"application/pdf"}};break;case"location":F={type:"location",data:{coordinates:{latitude:0,longitude:0},address:"Mock Address",timestamp:Date.now()}};break;case"contact":F={type:"contact",data:{id:"contact-1",name:"John Doe",phoneNumbers:["+1234567890"],emails:["john@example.com"]}};break;default:throw new Error(`Unsupported attachment type: ${N}`)}let G={id:`att_${Date.now()}_${Math.random().toString(36).substr(2,9)}`,type:N,data:F.data,fileName:F.data.fileName||F.data.name,fileSize:F.data.fileSize||F.data.size,mimeType:F.data.mimeType,uploadStatus:"pending",uploadProgress:0};D(G)}catch(F){console.error("Error opening picker:",F)}},[D]),H=Wt(async()=>{if(!S)return console.warn("No uploader provided, skipping upload"),V;if(V.length===0)return[];B(!0),z(0);try{let N=V.map(async(J,Ce)=>{try{E(Ie=>Ie.map(W=>W.id===J.id?{...W,uploadStatus:"uploading",uploadProgress:0}:W));let Z=setInterval(()=>{E(Ie=>Ie.map(W=>W.id===J.id?{...W,uploadProgress:Math.min((W.uploadProgress??0)+10,90)}:W))},100),ae=await S.upload(J.data);clearInterval(Z);let oe={...J,uploadStatus:"completed",uploadProgress:100,data:{...J.data,url:ae.url,metadata:ae.metadata}};return E(Ie=>Ie.map(W=>W.id===J.id?oe:W)),oe}catch(Z){return console.error(`Error uploading attachment ${J.id}:`,Z),E(ae=>ae.map(oe=>oe.id===J.id?{...oe,uploadStatus:"failed",uploadProgress:0}:oe)),{...J,uploadStatus:"failed",uploadProgress:0}}}),F=await Promise.all(N),re=F.filter(J=>J.uploadStatus==="completed").length/F.length*100;return z(re),P&&P(F),F}catch(N){return console.error("Error uploading attachments:",N),V}finally{B(!1)}},[V,S,P]);return{attachments:V,openPicker:j,addAttachment:D,removeAttachment:L,clearAttachments:O,uploadAttachments:H,isUploading:v,uploadProgress:k}};import{useState as os,useCallback as Ze}from"react";var Js=(C={})=>{let{onSend:S,onFocus:T,initialValue:M="",maxLength:R=1e3}=C,[A,I]=os(M),[P,V]=os(40),[E,v]=os(!1),B=Ze(H=>{H.length<=R&&I(H)},[R]),k=Ze(H=>{if(!A.trim()&&(!H||H.length===0))return;let N=A.trim();S&&S(N,H),I(""),V(40)},[A,S]),z=Ze(()=>{v(!0),T&&T()},[T]),D=Ze(()=>{v(!1)},[]),L=Ze(H=>{V(Math.max(40,Math.min(H,120)))},[]),O=Ze(()=>{I(""),V(40)},[]),j=Ze(H=>{I(H)},[]);return{message:A,composerHeight:P,isFocused:E,handleTextChange:B,handleSend:k,handleFocus:z,handleBlur:D,handleContentSizeChange:L,clearMessage:O,setMessage:j}};var wa=({messages:C,components:S={},renderProps:T={},onMessageSend:M,onReactionAdd:R,onReactionRemove:A,onMessageDelete:I,onActionPress:P,attachmentUploader:V,maxAttachments:E=10,maxFileSize:v=10*1024*1024,allowedFileTypes:B=["image/*","application/pdf","text/*"],enableReactionDetails:k,enableMessageActions:z=!0,enableScrollToBottom:D,enableTypingIndicator:L,isTyping:O=!1,typingUserName:j,isLoading:H=!1,loadingComponent:N})=>{let F=Nt(),[G,re]=ss(!1),J=S.MessageList||He,Ce=S.MessageInput||Oe,Z=k??F.enableReactionDetails??!0,ae=z??F.enableMessageActions??!0,oe=D??F.enableScrollToBottom??!0,Ie=L??F.enableTypingIndicator??!0,[W,ve]=ss(null),Me=Zs(null),[Je,Q]=ss(C||[]),Pe=Zs((C||[]).length+1);Xs.useEffect(()=>{C&&(Q(C),Pe.current=C.length+1)},[C]),Xs.useEffect(()=>{if(W&&Me.current){let U=setTimeout(()=>{Me.current?.focus()},150);return()=>clearTimeout(U)}},[W]);let De=Ut({uploader:V,maxAttachments:E,maxFileSize:v,allowedTypes:B}),ee=Js({onSend:(U,q)=>{if(W){let Y={id:W.id,text:W.text,senderName:W.senderName,senderId:W.senderId,isMe:W.isMe,timestamp:W.timestamp,type:W.type==="image"?"image":"text",imageData:W.imageData};if(q&&q.length>0){let K=q[0],te={id:Pe.current++,text:U.trim(),isMe:!0,timestamp:new Date().toISOString(),status:"sent",replyTo:Y,attachments:q,type:K.type==="image"?"image":"text",...K.type==="image"&&K.data&&{imageData:{uri:K.data.uri||"",width:K.data.width||300,height:K.data.height||200,fileName:K.fileName||"image.jpg",fileSize:K.fileSize||0}}};Q(Ve=>[...Ve,te]),M&&M(te)}else{let K={id:Pe.current++,text:U.trim(),isMe:!0,timestamp:new Date().toISOString(),status:"sent",replyTo:Y};Q(te=>[...te,K]),M&&M(K)}ve(null)}else if(q&&q.length>0){let Y=q[0],K={id:Pe.current++,text:U.trim(),isMe:!0,timestamp:new Date().toISOString(),status:"sent",attachments:q,type:Y.type==="image"?"image":"text",...Y.type==="image"&&Y.data&&{imageData:{uri:Y.data.uri||"",width:Y.data.width||300,height:Y.data.height||200,fileName:Y.fileName||"image.jpg",fileSize:Y.fileSize||0}}};Q(te=>[...te,K]),M&&M(K)}else{let Y={id:Pe.current++,text:U.trim(),isMe:!0,timestamp:new Date().toISOString(),status:"sent"};Q(K=>[...K,Y]),M&&M(Y)}De.clearAttachments()},onFocus:()=>{}}),St=wt((U,q)=>{console.log("\u{1F525} Chat - addReaction called with messageId:",U,"and emoji:",q),Q(Y=>Y.map(K=>K.id===U?K.reactions?.find(Ve=>Ve.emoji===q)?{...K,reactions:K.reactions?.map(Ve=>Ve.emoji===q?{...Ve,count:Ve.count+1,users:[...Ve.users,"currentUser"]}:Ve)}:{...K,reactions:[...K.reactions||[],{emoji:q,count:1,users:["currentUser"]}]}:K)),R&&R(U,q)},[R]),Xe=wt((U,q)=>{Q(Y=>Y.map(K=>K.id===U?{...K,reactions:K.reactions?.map(te=>te.emoji===q?{...te,count:Math.max(0,te.count-1),users:te.users.filter(Ve=>Ve!=="currentUser")}:te).filter(te=>te.count>0)}:K)),A&&A(U,q)},[A]),Go=wt(U=>{Q(q=>q.map(Y=>Y.id===U?{...Y,deleted:!0,text:"",reactions:void 0}:Y)),I&&I(U)},[I]),se=wt(()=>{ve(null)},[]),Re=wt(U=>{ve(U),setTimeout(()=>{Me.current?.focus()},100)},[]),Ft=wt(U=>{if(G)return;let{layout:q}=U.nativeEvent;q.height<=0||re(!0)},[G]);if(H)return<Qe style={et.container}>
|
|
26
|
+
{N||<Qe style={et.loadingContainer}>
|
|
27
27
|
{}
|
|
28
|
-
</
|
|
29
|
-
</
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
</
|
|
33
|
-
</
|
|
34
|
-
<
|
|
35
|
-
<J messages={
|
|
28
|
+
</Qe>}
|
|
29
|
+
</Qe>;if(!G)return<Qe style={et.container}>
|
|
30
|
+
<Qe style={et.chatContainer}onLayout={Ft}>
|
|
31
|
+
<Qe style={et.loadingContainer}>{N}</Qe>
|
|
32
|
+
</Qe>
|
|
33
|
+
</Qe>;let Us=T.renderInput;return<Qe style={et.container}>
|
|
34
|
+
<Qe style={et.fill}>
|
|
35
|
+
<J messages={Je}isTyping={Ie?O:!1}typingUserName={j}showScrollToBottom={oe}isReplyActive={!!W}enableMessageActions={ae}enableReactionDetails={Z}onReactionAdd={St}onReactionRemove={Xe}onMessageDelete={Go}onReplyMessage={Re}onActionPress={(U,q)=>{U==="reply"?Re(q):P?.(U,q)}}/>
|
|
36
36
|
|
|
37
|
-
{Us?Us({value:ee.message,onChangeText:ee.handleTextChange,onSend:ee.handleSend,onFocus:ee.handleFocus,height:ee.composerHeight,onContentSizeChange:ee.handleContentSizeChange,replyToMessage:W,onCancelReply:se,attachments:
|
|
37
|
+
{Us?Us({value:ee.message,onChangeText:ee.handleTextChange,onSend:ee.handleSend,onFocus:ee.handleFocus,height:ee.composerHeight,onContentSizeChange:ee.handleContentSizeChange,replyToMessage:W,onCancelReply:se,attachments:De.attachments,onAttachmentAdd:De.addAttachment,onAttachmentRemove:De.removeAttachment,onAttachmentUpload:De.uploadAttachments}):<Ce ref={Me}value={ee.message}onChangeText={ee.handleTextChange}onSend={ee.handleSend}onFocus={ee.handleFocus}height={ee.composerHeight}onContentSizeChange={ee.handleContentSizeChange}replyToMessage={W}onCancelReply={se}onAttachmentSend={(U,q)=>{let Y=U.type==="image",K={id:Pe.current++,text:q?.trim()||"",isMe:!0,timestamp:new Date().toISOString(),status:"sent",type:Y?"image":"text",...Y&&U.data&&{imageData:{uri:U.data.uri||"",width:U.data.width||300,height:U.data.height||200,fileName:U.data.fileName||U.data.name||"image.jpg",fileSize:U.data.fileSize||U.data.size||0}}};Q(te=>[...te,K]),M&&M(K),ee.handleTextChange("")}}/>}
|
|
38
38
|
|
|
39
39
|
{}
|
|
40
|
-
</
|
|
40
|
+
</Qe>
|
|
41
41
|
|
|
42
42
|
{}
|
|
43
|
-
</
|
|
43
|
+
</Qe>},et=Ra.create({container:{flex:1},chatContainer:{flex:1,overflow:"hidden"},fill:{flex:1},loadingContainer:{flex:1,justifyContent:"center",alignItems:"center"}}),ns=wa;import{View as Ne,Text as Cs,TouchableOpacity as Ao}from"react-native";import{ArrowLeft as Da,Info as Va,Phone as Ba,Video as La}from"lucide-react-native";import{useContext as Aa}from"react";import{createContext as Ia,useMemo as va}from"react";var Kt={colors:{primary:"#3B82F6",secondary:"#34B7F1",background:"#FFFFFF",surface:"#F7F8FA",surfaceSecondary:"#F3F4F6",text:"#111827",textSecondary:"#6B7280",textMuted:"#9CA3AF",border:"#E5E7EB",borderLight:"#F3F4F6",success:"#10B981",error:"#EF4444",warning:"#F59E0B",unread:"#EBF8FF",online:"#10B981",messageBubble:{sent:"#3B82F6",received:"#E5E7EB",sentText:"#FFFFFF",receivedText:"#111827"},gray:{50:"#F9FAFB",100:"#F3F4F6",200:"#E5E7EB",300:"#D1D5DB",400:"#9CA3AF",500:"#6B7280",600:"#4B5563",700:"#374151",800:"#1F2937",900:"#111827"},blue:{50:"#EBF8FF",500:"#3B82F6",600:"#2563EB"},green:{500:"#10B981"}},spacing:{xs:4,sm:8,md:12,lg:16,xl:24,xxl:32},borderRadius:{sm:4,md:8,lg:12,xl:16,full:9999},typography:{fontFamily:"System",fontSize:{xs:12,sm:14,base:16,lg:18,xl:20,xxl:24},fontWeight:{normal:"400",medium:"500",semibold:"600",bold:"700"},lineHeight:{tight:16,normal:20,relaxed:24}}};var as=Ia(Kt),Pa=(C,S)=>({colors:{...C.colors,...S.colors},spacing:{...C.spacing,...S.spacing},borderRadius:{...C.borderRadius,...S.borderRadius},typography:{...C.typography,...S.typography}}),Qs=({children:C,theme:S})=>{let T=va(()=>S?Pa(Kt,S):Kt,[S]);return<as.Provider value={T}>{C}</as.Provider>};var $=()=>{let C=Aa(as);if(!C)throw new Error("useTheme must be used within a ThemeProvider");return C};var ja=({name:C="George Alan",isOnline:S=!0,onBack:T=()=>{},onVideoCall:M,onVoiceCall:R,onInfo:A})=>{let I=$(),P=Te();return<Ne style={{flexDirection:"row",alignItems:"center",justifyContent:"space-between",borderBottomWidth:1,borderBottomColor:I.colors.borderLight,backgroundColor:I.colors.background,paddingHorizontal:I.spacing.lg,paddingVertical:I.spacing.md,zIndex:50}}>
|
|
44
44
|
<Ne style={{flex:1,flexDirection:"row",alignItems:"center"}}>
|
|
45
|
-
<
|
|
46
|
-
<
|
|
47
|
-
</
|
|
45
|
+
<Ao onPress={T}style={{marginRight:I.spacing.md}}>
|
|
46
|
+
<Da size={24}color={I.colors.gray[700]}/>
|
|
47
|
+
</Ao>
|
|
48
48
|
|
|
49
49
|
<Ne style={{flex:1,flexDirection:"row",alignItems:"center"}}>
|
|
50
50
|
{}
|
|
51
51
|
<Ne style={{position:"relative",marginRight:I.spacing.md}}>
|
|
52
52
|
<Ne style={{height:40,width:40,alignItems:"center",justifyContent:"center",borderRadius:I.borderRadius.full,backgroundColor:I.colors.gray[200]}}>
|
|
53
|
-
<
|
|
53
|
+
<Cs style={{fontSize:I.typography.fontSize.base,color:I.colors.text}}>
|
|
54
54
|
👤
|
|
55
|
-
</
|
|
55
|
+
</Cs>
|
|
56
56
|
</Ne>
|
|
57
|
-
{
|
|
57
|
+
{S&&<Ne style={{position:"absolute",bottom:-2,right:-2,height:12,width:12,borderRadius:I.borderRadius.full,borderWidth:1,borderColor:I.colors.background,backgroundColor:I.colors.online}}/>}
|
|
58
58
|
</Ne>
|
|
59
59
|
|
|
60
60
|
<Ne style={{flex:1}}>
|
|
61
|
-
<
|
|
62
|
-
{
|
|
63
|
-
</
|
|
64
|
-
<
|
|
65
|
-
{P(
|
|
66
|
-
</
|
|
61
|
+
<Cs style={{fontSize:I.typography.fontSize.lg,fontWeight:I.typography.fontWeight.semibold,color:I.colors.text}}>
|
|
62
|
+
{C}
|
|
63
|
+
</Cs>
|
|
64
|
+
<Cs style={{fontSize:I.typography.fontSize.sm,color:I.colors.textSecondary}}>
|
|
65
|
+
{P(S?"status.online":"status.offline")}
|
|
66
|
+
</Cs>
|
|
67
67
|
</Ne>
|
|
68
68
|
</Ne>
|
|
69
69
|
</Ne>
|
|
70
70
|
|
|
71
71
|
<Ne style={{flexDirection:"row",alignItems:"center",gap:I.spacing.lg}}>
|
|
72
72
|
{}
|
|
73
|
-
{
|
|
74
|
-
<
|
|
75
|
-
</
|
|
76
|
-
{
|
|
77
|
-
<
|
|
78
|
-
</
|
|
79
|
-
{
|
|
80
|
-
<
|
|
81
|
-
</
|
|
73
|
+
{M&&<Ao onPress={M}>
|
|
74
|
+
<La size={24}color={I.colors.gray[700]}/>
|
|
75
|
+
</Ao>}
|
|
76
|
+
{R&&<Ao onPress={R}>
|
|
77
|
+
<Ba size={24}color={I.colors.gray[700]}/>
|
|
78
|
+
</Ao>}
|
|
79
|
+
{A&&<Ao onPress={A}>
|
|
80
|
+
<Va size={24}color={I.colors.gray[700]}/>
|
|
81
|
+
</Ao>}
|
|
82
82
|
</Ne>
|
|
83
|
-
</Ne>},
|
|
84
|
-
<Vo style={{fontSize:T.typography.fontSize.xs,fontWeight:T.typography.fontWeight.medium,color:
|
|
85
|
-
{
|
|
83
|
+
</Ne>},zo=ja;import{useRef as Qa}from"react";import{View as Yt,Text as Ue,Pressable as Cr,TouchableOpacity as Mr}from"react-native";import ke from"dayjs";import Ea from"dayjs/plugin/isToday";import Fa from"dayjs/plugin/isYesterday";import Oa from"dayjs/plugin/relativeTime";import Ha from"dayjs/plugin/localizedFormat";import"dayjs/locale/pl";import"dayjs/locale/en";ke.extend(Ea);ke.extend(Fa);ke.extend(Oa);ke.extend(Ha);var Na=(C,S="en")=>{let T=ke(C).locale(S);return T.isToday()?S==="pl"?"Dzisiaj":"Today":T.isYesterday()?S==="pl"?"Wczoraj":"Yesterday":T.format("ddd D MMMM")},en=(C,S,T="en")=>{let M=ke(C).locale(T);return M.isToday()?S("date.today"):M.isYesterday()?S("date.yesterday"):M.format("ddd D MMMM")},Wa=C=>ke(C).format("YYYY-MM-DD"),Do=(C,S="en")=>{if(C.length===0)return[];let T=[],M=null;return C.forEach((R,A)=>{let I=Wa(R.timestamp);if(M!==I){let V=Na(R.timestamp,S),E={id:`date-${I}`,listItemType:"date-separator",date:I,displayDate:V};T.push(E),M=I}let P={...R,listItemType:"message"};T.push(P)}),T},$t=(C,S="en")=>ke(C).locale(S).format("HH:mm"),tn=(C,S="en")=>ke(C).locale(S).fromNow();var on=(C,S,T="en")=>{let M=ke(C).locale(T);return M.isToday()?S("date.todayWithTime",{time:M.format("HH:mm")}):M.isYesterday()?S("date.yesterdayWithTime",{time:M.format("HH:mm")}):M.format("DD MMM YYYY HH:mm")};import{View as Ms,Text as Vo,Image as Ua}from"react-native";var Ka=({replyTo:C,isMyMessage:S})=>{let T=$(),M=(E,v=50)=>E.length<=v?E:E.substring(0,v)+"...",R=S?"rgba(255, 255, 255, 0.3)":T.colors.primary,A=S?"rgba(255, 255, 255, 0.8)":T.colors.primary,I=S?"rgba(255, 255, 255, 0.7)":T.colors.textSecondary,P=S?"rgba(255, 255, 255, 0.1)":T.colors.surfaceSecondary,V=C.type==="image"&&C.imageData;return<Ms style={{marginBottom:T.spacing.sm,borderRadius:T.borderRadius.md,padding:T.spacing.sm,backgroundColor:P,borderLeftWidth:4,borderLeftColor:R}}>
|
|
84
|
+
<Vo style={{fontSize:T.typography.fontSize.xs,fontWeight:T.typography.fontWeight.medium,color:A,marginBottom:T.spacing.xs}}>
|
|
85
|
+
{C.isMe?"You":C.senderName||"Sender"}
|
|
86
86
|
</Vo>
|
|
87
87
|
|
|
88
|
-
{
|
|
89
|
-
<
|
|
90
|
-
<
|
|
88
|
+
{V?<Ms style={{flexDirection:"row",alignItems:"center"}}>
|
|
89
|
+
<Ua source={{uri:C.imageData.uri}}style={{width:40,height:40,borderRadius:T.borderRadius.sm,marginRight:T.spacing.sm}}resizeMode="cover"/>
|
|
90
|
+
<Ms style={{flex:1}}>
|
|
91
91
|
<Vo style={{fontSize:T.typography.fontSize.xs,color:I,fontStyle:"italic",marginBottom:T.spacing.xs}}>
|
|
92
92
|
📷 Image
|
|
93
93
|
</Vo>
|
|
94
|
-
{
|
|
95
|
-
{C
|
|
94
|
+
{C.text&&C.text.trim()&&<Vo style={{fontSize:T.typography.fontSize.sm,color:I,lineHeight:T.typography.lineHeight.tight}}>
|
|
95
|
+
{M(C.text,30)}
|
|
96
96
|
</Vo>}
|
|
97
|
-
</
|
|
98
|
-
</
|
|
99
|
-
{C
|
|
97
|
+
</Ms>
|
|
98
|
+
</Ms>:<Vo style={{fontSize:T.typography.fontSize.sm,color:I,lineHeight:T.typography.lineHeight.tight}}>
|
|
99
|
+
{M(C.text)}
|
|
100
100
|
</Vo>}
|
|
101
|
-
</
|
|
102
|
-
<
|
|
101
|
+
</Ms>},It=Ka;import{useState as sn,useCallback as qt}from"react";import{View as Bo,Image as Cn,Pressable as Mn,Modal as $a,Dimensions as qa,StyleSheet as Ya,Text as _a}from"react-native";var{width:Ts,height:Tn}=qa.get("window"),Ga=({imageData:C,isMe:S,onImagePress:T,onLongPress:M})=>{let R=$(),[A,I]=sn(!1),[P,V]=sn(!1),v=qt(()=>{let O=Ts*.6,j=300;if(!C.width||!C.height)return{width:O,height:j};let H=C.width/C.height,N=O,F=N/H;return F>j&&(F=j,N=F*H),{width:Math.round(N),height:Math.round(F)}},[C.width,C.height])(),B=qt(()=>{T?T():I(!0)},[T]),k=qt(()=>{console.error("Failed to load image:",C.uri),V(!0)},[C.uri]),z=qt(()=>{I(!1)},[]),L=qt(()=>{if(!C.width||!C.height)return{width:Ts,height:Tn*.8};let O=C.width/C.height,j=Ts*.9,H=Tn*.8,N=j,F=N/O;return F>H&&(F=H,N=F*O),{width:Math.round(N),height:Math.round(F)}},[C.width,C.height])();return P?<Bo style={[We.errorContainer,{width:v.width,height:v.height,backgroundColor:S?R.colors.messageBubble.sent:R.colors.messageBubble.received,borderRadius:R.borderRadius.lg}]}>
|
|
102
|
+
<_a style={[We.errorText,{color:S?R.colors.messageBubble.sentText:R.colors.messageBubble.receivedText,fontSize:R.typography.fontSize.sm}]}>
|
|
103
103
|
Failed to load image
|
|
104
|
-
</
|
|
104
|
+
</_a>
|
|
105
105
|
</Bo>:<>
|
|
106
|
-
<
|
|
107
|
-
<Bo style={[We.imageContainer,{borderRadius:
|
|
108
|
-
<
|
|
106
|
+
<Mn onPress={B}onLongPress={M}delayLongPress={500}>
|
|
107
|
+
<Bo style={[We.imageContainer,{borderRadius:R.borderRadius.lg,overflow:"hidden"}]}>
|
|
108
|
+
<Cn source={{uri:C.uri}}style={[We.image,{width:v.width,height:v.height}]}resizeMode='cover'onError={k}/>
|
|
109
109
|
|
|
110
110
|
{}
|
|
111
111
|
<Bo style={We.imageOverlay}/>
|
|
112
112
|
</Bo>
|
|
113
|
-
</
|
|
113
|
+
</Mn>
|
|
114
114
|
|
|
115
115
|
{}
|
|
116
|
-
|
|
117
|
-
<
|
|
116
|
+
<$a visible={A}transparent animationType='fade'onRequestClose={z}>
|
|
117
|
+
<Mn style={We.modalContainer}onPress={z}>
|
|
118
118
|
<Bo style={We.modalContent}>
|
|
119
|
-
<
|
|
119
|
+
<Cn source={{uri:C.uri}}style={[We.modalImage,{width:L.width,height:L.height,borderRadius:R.borderRadius.lg}]}resizeMode='contain'/>
|
|
120
120
|
</Bo>
|
|
121
|
-
</
|
|
122
|
-
|
|
123
|
-
</>},We=
|
|
124
|
-
<
|
|
125
|
-
<
|
|
126
|
-
<
|
|
127
|
-
<
|
|
128
|
-
{
|
|
129
|
-
</
|
|
130
|
-
</
|
|
131
|
-
</
|
|
132
|
-
<
|
|
133
|
-
<
|
|
134
|
-
{
|
|
135
|
-
</
|
|
136
|
-
</
|
|
137
|
-
</
|
|
138
|
-
<
|
|
139
|
-
{
|
|
121
|
+
</Mn>
|
|
122
|
+
</$a>
|
|
123
|
+
</>},We=Ya.create({imageContainer:{position:"relative"},image:{backgroundColor:"#f0f0f0"},imageOverlay:{position:"absolute",top:0,left:0,right:0,bottom:0,backgroundColor:"transparent"},errorContainer:{justifyContent:"center",alignItems:"center",borderWidth:1,borderColor:"#e0e0e0"},errorText:{textAlign:"center",fontWeight:"500"},modalContainer:{flex:1,backgroundColor:"rgba(0, 0, 0, 0.9)",justifyContent:"center",alignItems:"center"},modalContent:{justifyContent:"center",alignItems:"center"},modalImage:{backgroundColor:"transparent"}}),Lo=Ga;import{View as Eo,Text as Sn,StyleSheet as Ja}from"react-native";import{Trash2 as Xa}from"lucide-react-native";var Za=({isMe:C,timestamp:S,senderName:T})=>{let M=$(),R=Te();return<Eo style={[vt.container,{alignSelf:C?"flex-end":"flex-start",maxWidth:"80%"}]}>
|
|
124
|
+
<Eo style={[vt.messageBubble,{backgroundColor:M.colors.gray[100],borderColor:M.colors.gray[200]}]}>
|
|
125
|
+
<Eo style={vt.content}>
|
|
126
|
+
<Xa size={16}color={M.colors.gray[500]}/>
|
|
127
|
+
<Sn style={[vt.deletedText,{color:M.colors.gray[500]}]}>
|
|
128
|
+
{R("message.deleted")}
|
|
129
|
+
</Sn>
|
|
130
|
+
</Eo>
|
|
131
|
+
</Eo>
|
|
132
|
+
<Eo style={[vt.metadata,{alignSelf:C?"flex-end":"flex-start"}]}>
|
|
133
|
+
<Sn style={[vt.timestamp,{color:M.colors.gray[400]}]}>
|
|
134
|
+
{S}
|
|
135
|
+
</Sn>
|
|
136
|
+
</Eo>
|
|
137
|
+
</Eo>},vt=Ja.create({container:{marginVertical:4,marginHorizontal:15},messageBubble:{borderRadius:18,paddingHorizontal:16,paddingVertical:12,borderWidth:1,borderStyle:"dashed"},content:{flexDirection:"row",alignItems:"center",justifyContent:"center"},deletedText:{fontSize:14,fontStyle:"italic",marginLeft:8},metadata:{marginTop:4,paddingHorizontal:4},timestamp:{fontSize:11}}),Fo=Za;var Tr=({message:C,onLongPress:S,onReactionPress:T})=>{let M=$(),R=Qa(null),A=()=>{R.current?R.current.measureInWindow((V,E,v,B)=>{let k={x:Math.round(V),y:Math.round(E),width:Math.round(v),height:Math.round(B)};S?.(C,k)}):S?.(C)},I=()=>{C.reactions&&C.reactions.length>0&&T?.(C)},P=C.type==="image"&&C.imageData;return C.deleted?<Fo isMe={C.isMe}timestamp={$t(C.timestamp)}senderName={C.senderName}/>:<Yt style={{marginBottom:M.spacing.md,alignItems:C.isMe?"flex-end":"flex-start",marginHorizontal:M.spacing.sm}}>
|
|
138
|
+
<Cr ref={R}onLongPress={A}delayLongPress={500}style={{maxWidth:P?"75%":"80%",borderRadius:P?M.borderRadius.lg:M.borderRadius.xl,borderBottomRightRadius:C.isMe?4:P?M.borderRadius.lg:M.borderRadius.xl,borderBottomLeftRadius:C.isMe?P?M.borderRadius.lg:M.borderRadius.xl:4,paddingHorizontal:P?0:M.spacing.lg,paddingVertical:P?0:M.spacing.md,backgroundColor:P?"transparent":C.isMe?M.colors.messageBubble.sent:M.colors.messageBubble.received,overflow:"hidden"}}>
|
|
139
|
+
{C.replyTo&&<It replyTo={C.replyTo}isMyMessage={C.isMe}/>}
|
|
140
140
|
|
|
141
|
-
{P?<
|
|
142
|
-
{
|
|
141
|
+
{P?<Lo imageData={C.imageData}isMe={C.isMe}onLongPress={A}/>:<Ue style={{fontSize:M.typography.fontSize.base,color:C.isMe?M.colors.messageBubble.sentText:M.colors.messageBubble.receivedText}}>
|
|
142
|
+
{C.text}
|
|
143
143
|
</Ue>}
|
|
144
144
|
|
|
145
145
|
{}
|
|
146
|
-
{P&&
|
|
147
|
-
<Ue style={{fontSize:
|
|
148
|
-
{
|
|
146
|
+
{P&&C.text&&C.text.trim()&&<Yt style={{paddingHorizontal:M.spacing.lg,paddingVertical:M.spacing.md,backgroundColor:C.isMe?M.colors.messageBubble.sent:M.colors.messageBubble.received,borderRadius:M.borderRadius.lg,marginTop:M.spacing.xs}}>
|
|
147
|
+
<Ue style={{fontSize:M.typography.fontSize.base,color:C.isMe?M.colors.messageBubble.sentText:M.colors.messageBubble.receivedText}}>
|
|
148
|
+
{C.text}
|
|
149
149
|
</Ue>
|
|
150
|
-
</
|
|
151
|
-
</
|
|
150
|
+
</Yt>}
|
|
151
|
+
</Cr>
|
|
152
152
|
|
|
153
153
|
{}
|
|
154
|
-
{
|
|
155
|
-
{
|
|
156
|
-
<Ue style={{fontSize:
|
|
157
|
-
{
|
|
154
|
+
{C.reactions&&C.reactions.length>0&&<Mr onPress={I}style={{marginTop:M.spacing.xs,flexDirection:"row",alignItems:"center",backgroundColor:M.colors.background,borderRadius:M.borderRadius.full,justifyContent:C.isMe?"flex-end":"flex-start"}}>
|
|
155
|
+
{C.reactions.map((V,E)=><Yt key={`${V.emoji}-${E}`}style={{flexDirection:"row",alignItems:"center",padding:M.spacing.xs}}>
|
|
156
|
+
<Ue style={{fontSize:M.typography.fontSize.sm}}>
|
|
157
|
+
{V.emoji}
|
|
158
158
|
</Ue>
|
|
159
|
-
{
|
|
160
|
-
{
|
|
159
|
+
{V.count>1&&<Ue style={{fontSize:M.typography.fontSize.xs,color:M.colors.textSecondary,marginLeft:M.spacing.xs,fontWeight:M.typography.fontWeight.medium}}>
|
|
160
|
+
{V.count}
|
|
161
161
|
</Ue>}
|
|
162
|
-
</
|
|
163
|
-
</
|
|
162
|
+
</Yt>)}
|
|
163
|
+
</Mr>}
|
|
164
164
|
|
|
165
|
-
<
|
|
166
|
-
<Ue style={{fontSize:
|
|
167
|
-
{
|
|
165
|
+
<Yt style={{marginHorizontal:M.spacing.sm,marginTop:M.spacing.xs,flexDirection:"row",alignItems:"center",justifyContent:C.isMe?"flex-end":"flex-start"}}>
|
|
166
|
+
<Ue style={{fontSize:M.typography.fontSize.xs,color:M.colors.textSecondary}}>
|
|
167
|
+
{$t(C.timestamp)}
|
|
168
168
|
</Ue>
|
|
169
|
-
{
|
|
170
|
-
{
|
|
169
|
+
{C.isMe&&C.status&&<Yt style={{marginLeft:M.spacing.xs}}>
|
|
170
|
+
{C.status==="sent"&&<Ue style={{fontSize:M.typography.fontSize.xs,color:M.colors.gray[400]}}>
|
|
171
171
|
✓
|
|
172
172
|
</Ue>}
|
|
173
|
-
{
|
|
173
|
+
{C.status==="delivered"&&<Ue style={{fontSize:M.typography.fontSize.xs,color:M.colors.gray[400]}}>
|
|
174
174
|
✓✓
|
|
175
175
|
</Ue>}
|
|
176
|
-
{
|
|
176
|
+
{C.status==="read"&&<Ue style={{fontSize:M.typography.fontSize.xs,color:M.colors.primary}}>
|
|
177
177
|
✓✓
|
|
178
178
|
</Ue>}
|
|
179
|
-
</
|
|
180
|
-
</
|
|
181
|
-
</
|
|
179
|
+
</Yt>}
|
|
180
|
+
</Yt>
|
|
181
|
+
</Yt>},Oo=Tr;import{View as Le,Text as Pt,TouchableOpacity as Sr,Image as Rr}from"react-native";import{X as Ir}from"lucide-react-native";var vr=({replyToMessage:C,onCancel:S})=>{let T=$(),M=(I,P=50)=>I.length<=P?I:I.substring(0,P)+"...",R=!!C.replyTo,A=C.type==="image"&&C.imageData;return<Le style={{borderBottomWidth:1,borderBottomColor:T.colors.border,backgroundColor:T.colors.surface,paddingHorizontal:T.spacing.lg,paddingVertical:T.spacing.md}}>
|
|
182
182
|
<Le style={{flexDirection:"row",alignItems:"center",justifyContent:"space-between"}}>
|
|
183
183
|
<Le style={{flex:1,marginRight:T.spacing.md}}>
|
|
184
184
|
<Le style={{flexDirection:"row",alignItems:"center",marginBottom:T.spacing.xs}}>
|
|
185
|
-
<Le style={{width:4,backgroundColor:T.colors.primary,borderRadius:T.borderRadius.full,marginRight:T.spacing.md,height:
|
|
185
|
+
<Le style={{width:4,backgroundColor:T.colors.primary,borderRadius:T.borderRadius.full,marginRight:T.spacing.md,height:R?48:32}}/>
|
|
186
186
|
<Le style={{flex:1}}>
|
|
187
|
-
<
|
|
188
|
-
Replying to {
|
|
189
|
-
{
|
|
190
|
-
</
|
|
187
|
+
<Pt style={{fontSize:T.typography.fontSize.xs,fontWeight:T.typography.fontWeight.medium,color:T.colors.primary,marginBottom:T.spacing.xs}}>
|
|
188
|
+
Replying to {C.isMe?"yourself":C.senderName||"sender"}
|
|
189
|
+
{R&&" (reply thread)"}
|
|
190
|
+
</Pt>
|
|
191
191
|
|
|
192
192
|
{}
|
|
193
|
-
{
|
|
194
|
-
<
|
|
195
|
-
Originally replying to: {
|
|
196
|
-
</
|
|
197
|
-
<
|
|
198
|
-
{C
|
|
199
|
-
</
|
|
193
|
+
{R&&<Le style={{marginBottom:T.spacing.sm,padding:T.spacing.sm,backgroundColor:T.colors.surfaceSecondary,borderRadius:T.borderRadius.md,borderLeftWidth:2,borderLeftColor:T.colors.gray[300]}}>
|
|
194
|
+
<Pt style={{fontSize:T.typography.fontSize.xs,color:T.colors.textSecondary,marginBottom:T.spacing.xs}}>
|
|
195
|
+
Originally replying to: {C.replyTo.isMe?"yourself":C.replyTo.senderName||"sender"}
|
|
196
|
+
</Pt>
|
|
197
|
+
<Pt style={{fontSize:T.typography.fontSize.xs,color:T.colors.textSecondary,lineHeight:T.typography.lineHeight.tight}}>
|
|
198
|
+
{M(C.replyTo.text,40)}
|
|
199
|
+
</Pt>
|
|
200
200
|
</Le>}
|
|
201
201
|
|
|
202
|
-
{
|
|
203
|
-
<
|
|
202
|
+
{A?<Le style={{flexDirection:"row",alignItems:"center"}}>
|
|
203
|
+
<Rr source={{uri:C.imageData.uri}}style={{width:32,height:32,borderRadius:T.borderRadius.sm,marginRight:T.spacing.sm}}resizeMode="cover"/>
|
|
204
204
|
<Le style={{flex:1}}>
|
|
205
|
-
<
|
|
205
|
+
<Pt style={{fontSize:T.typography.fontSize.xs,color:T.colors.gray[600],fontStyle:"italic",marginBottom:T.spacing.xs}}>
|
|
206
206
|
📷 Image
|
|
207
|
-
</
|
|
208
|
-
{
|
|
209
|
-
{C
|
|
210
|
-
</
|
|
207
|
+
</Pt>
|
|
208
|
+
{C.text&&C.text.trim()&&<Pt style={{fontSize:T.typography.fontSize.sm,color:T.colors.gray[700],lineHeight:T.typography.lineHeight.tight}}>
|
|
209
|
+
{M(C.text,40)}
|
|
210
|
+
</Pt>}
|
|
211
211
|
</Le>
|
|
212
|
-
</Le>:<
|
|
213
|
-
{C
|
|
214
|
-
</
|
|
212
|
+
</Le>:<Pt style={{fontSize:T.typography.fontSize.sm,color:T.colors.gray[700],lineHeight:T.typography.lineHeight.tight}}>
|
|
213
|
+
{M(C.text)}
|
|
214
|
+
</Pt>}
|
|
215
215
|
</Le>
|
|
216
216
|
</Le>
|
|
217
217
|
</Le>
|
|
218
218
|
|
|
219
|
-
<
|
|
219
|
+
<Sr onPress={S}style={{height:32,width:32,alignItems:"center",justifyContent:"center",borderRadius:T.borderRadius.full,backgroundColor:T.colors.gray[200]}}hitSlop={{top:8,bottom:8,left:8,right:8}}>
|
|
220
220
|
<Ir size={16}color={T.colors.textSecondary}/>
|
|
221
|
-
</
|
|
221
|
+
</Sr>
|
|
222
222
|
</Le>
|
|
223
|
-
</Le>},
|
|
224
|
-
<
|
|
223
|
+
</Le>},_t=vr;import{useRef as Ke,useState as Rn,useEffect as ws}from"react";import{View as Gt,Text as Vt,TouchableOpacity as Dt,StyleSheet as Ss,Pressable as Br,ScrollView as Lr,Dimensions as jr,Animated as we,Image as Er}from"react-native";import{Reply as Fr,Copy as Or,Plus as Hr,Trash2 as Nr}from"lucide-react-native";import{useState as Pr,useEffect as Ar}from"react";import Dr from"rn-emoji-keyboard";var Vr=({visible:C,onClose:S,onEmojiSelected:T})=>{let[M,R]=Pr(!1);Ar(()=>{R(!!C)},[C]);let A=P=>{console.log("Selected emoji:",P),T(P.emoji),R(!1),S()},I=()=>{R(!1),S()};return C?<Dr onEmojiSelected={A}open={M}onClose={I}enableSearchBar/>:null},At=Vr;var Wr=({visible:C,onPress:S,children:T})=>C?<Gt style={ne.overlay}>
|
|
224
|
+
<Dt style={ne.backdrop}onPress={S}activeOpacity={1}/>
|
|
225
225
|
{T}
|
|
226
|
-
</
|
|
227
|
-
{
|
|
226
|
+
</Gt>:null,{width:zt,height:Rs}=jr.get("window"),Ur=({message:C,positions:S,messagePosition:T,containerRef:M,containerOffset:R,setContainerOffset:A})=>{let I=$(),P=Ke(new we.Value(T.y)).current,V=Ke(new we.Value(0)).current,E=Ke(!1),v=C.type==="image"&&C.imageData;return ws(()=>{E.current=!1,M.current&&M.current.measureInWindow((B,k,z,D)=>{A({x:B,y:k});let L=T.y-k,O=S.messagePreviewTop-k;P.setValue(L),V.setValue(0),requestAnimationFrame(()=>{we.parallel([we.timing(P,{toValue:O,duration:250,useNativeDriver:!1}),we.timing(V,{toValue:1,duration:250,useNativeDriver:!1})]).start(()=>{E.current=!0})})})},[S.messagePreviewTop,T.y,M]),<we.View style={{position:"absolute",top:P,left:T.x,width:T.width,height:C.replyTo?T.height+10:T.height,zIndex:1e3,opacity:V,maxWidth:v?"75%":"80%",borderRadius:v?I.borderRadius.lg:I.borderRadius.xl,paddingHorizontal:v?0:I.spacing.lg,paddingVertical:v?0:I.spacing.md,backgroundColor:v?"transparent":C.isMe?I.colors.messageBubble.sent:I.colors.messageBubble.received,overflow:"hidden"}}>
|
|
227
|
+
{C.replyTo&&<It replyTo={C.replyTo}isMyMessage={C.isMe}/>}
|
|
228
228
|
|
|
229
|
-
{v?<
|
|
230
|
-
<Er source={{uri:
|
|
229
|
+
{v?<Gt>
|
|
230
|
+
<Er source={{uri:C.imageData.uri}}style={{width:T.width,height:T.height,borderRadius:I.borderRadius.lg}}resizeMode='cover'/>
|
|
231
231
|
{}
|
|
232
|
-
{
|
|
233
|
-
<
|
|
234
|
-
{
|
|
235
|
-
</
|
|
236
|
-
</
|
|
237
|
-
</
|
|
238
|
-
{
|
|
239
|
-
</
|
|
240
|
-
</we.View>},Kr=({visible:
|
|
232
|
+
{C.text&&C.text.trim()&&<Gt style={{paddingHorizontal:I.spacing.lg,paddingVertical:I.spacing.md,backgroundColor:C.isMe?I.colors.messageBubble.sent:I.colors.messageBubble.received,borderRadius:I.borderRadius.lg,marginTop:I.spacing.xs}}>
|
|
233
|
+
<Vt style={{fontSize:I.typography.fontSize.base,color:C.isMe?I.colors.messageBubble.sentText:I.colors.messageBubble.receivedText}}>
|
|
234
|
+
{C.text}
|
|
235
|
+
</Vt>
|
|
236
|
+
</Gt>}
|
|
237
|
+
</Gt>:<Vt style={{fontSize:I.typography.fontSize.base,color:C.isMe?I.colors.messageBubble.sentText:I.colors.messageBubble.receivedText}}>
|
|
238
|
+
{C.text}
|
|
239
|
+
</Vt>}
|
|
240
|
+
</we.View>},Kr=({visible:C,onClose:S,isMyMessage:T,selectedMessage:M,messagePosition:R,onActionPress:A,onEmojiReact:I})=>{let P=Te(),[V,E]=Rn(!1),v=Ke(null),[B,k]=Rn({x:0,y:0}),z=Ke(new we.Value(0)).current,D=Ke(new we.Value(0)).current,L=Ke(!1),O=Ke(!1),j=Z=>{A(Z),S()},H=Z=>{I?.(Z),S()},N=()=>{E(!0)},F=()=>{E(!1)},G=Z=>{I?.(Z),E(!1),S()},re=["\u2764\uFE0F","\u{1F602}","\u{1F62E}","\u{1F622}","\u{1F621}","\u{1F44D}"],Ce=(()=>{if(!R)return{emojiBar:{top:Rs/2-200,left:zt/2-160},actionMenu:{top:Rs/2+50,left:zt/2-100}};let Z=320,ae=60,oe=200,Ie=160,W=20,ve=8,Me,Je,Q,Pe,De,ee=Rs/2,St=ae+ve+R.height+ve+Ie,Xe=ee-St/2;return Je=Xe,De=Xe+ae+ve,Pe=Xe+ae+ve+R.height+ve,Me=R.x,Q=R.x,Me+Z>zt-W&&(Me=zt-Z-W),Me<W&&(Me=W),Q+oe>zt-W&&(Q=zt-oe-W),Q<W&&(Q=W),{emojiBar:{top:Je,left:Me},actionMenu:{top:Pe,left:Q},messagePreviewTop:De,isNearAverageHeight:!0,isNearTop:!0,isEdgeCase:!0}})();return ws(()=>{C&&R&&!O.current&&(z.setValue(0),D.setValue(0),setTimeout(()=>{we.sequence([we.timing(z,{toValue:1,duration:200,useNativeDriver:!1}),we.timing(D,{toValue:1,duration:200,useNativeDriver:!1})]).start(()=>{O.current=!0})},50))},[C,R,z,D]),ws(()=>{C||(L.current=!1,O.current=!1,z.setValue(0),D.setValue(0))},[C,z,D]),C?<>
|
|
241
241
|
{}
|
|
242
|
-
<Wr visible={!0}onPress={
|
|
243
|
-
<
|
|
242
|
+
<Wr visible={!0}onPress={S}>
|
|
243
|
+
<Br style={ne.overlayPressable}onPress={S}/>
|
|
244
244
|
</Wr>
|
|
245
245
|
|
|
246
|
-
<
|
|
246
|
+
<Gt ref={v}style={{position:"absolute",top:0,left:0,right:0,bottom:0,pointerEvents:"none"}}>
|
|
247
247
|
{}
|
|
248
|
-
</
|
|
248
|
+
</Gt>
|
|
249
249
|
|
|
250
250
|
{}
|
|
251
|
-
{
|
|
251
|
+
{R&&M&&<Ur message={M}positions={Ce}messagePosition={R}containerRef={v}containerOffset={B}setContainerOffset={k}/>}
|
|
252
252
|
|
|
253
253
|
{}
|
|
254
|
-
<we.View style={[
|
|
255
|
-
<Lr horizontal showsHorizontalScrollIndicator={!1}contentContainerStyle={
|
|
256
|
-
{re.map((Z,
|
|
257
|
-
<
|
|
258
|
-
</
|
|
259
|
-
<
|
|
254
|
+
<we.View style={[ne.emojiBar,{position:"absolute",top:Ce.emojiBar.top-(B.y||0),left:Ce.emojiBar.left,opacity:z,pointerEvents:"auto"}]}>
|
|
255
|
+
<Lr horizontal showsHorizontalScrollIndicator={!1}contentContainerStyle={ne.emojiContainer}>
|
|
256
|
+
{re.map((Z,ae)=><Dt key={ae}style={ne.emojiButton}onPress={()=>H(Z)}>
|
|
257
|
+
<Vt style={ne.emojiText}>{Z}</Vt>
|
|
258
|
+
</Dt>)}
|
|
259
|
+
<Dt style={ne.addEmojiButton}onPress={N}>
|
|
260
260
|
<Hr size={20}color='#666'/>
|
|
261
|
-
</
|
|
261
|
+
</Dt>
|
|
262
262
|
</Lr>
|
|
263
263
|
</we.View>
|
|
264
264
|
|
|
265
265
|
{}
|
|
266
|
-
<we.View style={[
|
|
267
|
-
<
|
|
266
|
+
<we.View style={[ne.actionMenu,{position:"absolute",top:Ce.actionMenu.top-(B.y||0)+(M?.replyTo?10:0),left:Ce.actionMenu.left,opacity:D,pointerEvents:"auto"}]}>
|
|
267
|
+
<Gt style={ne.actionItems}>
|
|
268
268
|
{}
|
|
269
|
-
<
|
|
269
|
+
<Dt style={ne.actionRow}onPress={()=>j("reply")}>
|
|
270
270
|
<Fr size={18}color='#333'/>
|
|
271
|
-
<
|
|
272
|
-
</
|
|
271
|
+
<Vt style={ne.actionLabel}>{P("action.reply")}</Vt>
|
|
272
|
+
</Dt>
|
|
273
273
|
|
|
274
274
|
{}
|
|
275
|
-
<
|
|
275
|
+
<Dt style={ne.actionRow}onPress={()=>j("copy")}>
|
|
276
276
|
<Or size={18}color='#333'/>
|
|
277
|
-
<
|
|
278
|
-
</
|
|
277
|
+
<Vt style={ne.actionLabel}>{P("action.copy")}</Vt>
|
|
278
|
+
</Dt>
|
|
279
279
|
|
|
280
280
|
{}
|
|
281
|
-
{T&&<
|
|
281
|
+
{T&&<Dt style={ne.actionRow}onPress={()=>j("delete")}>
|
|
282
282
|
<Nr size={18}color='#ff4444'/>
|
|
283
|
-
<
|
|
283
|
+
<Vt style={[ne.actionLabel,{color:"#ff4444"}]}>
|
|
284
284
|
{P("action.delete")}
|
|
285
|
-
</
|
|
286
|
-
</
|
|
287
|
-
</
|
|
285
|
+
</Vt>
|
|
286
|
+
</Dt>}
|
|
287
|
+
</Gt>
|
|
288
288
|
</we.View>
|
|
289
289
|
|
|
290
290
|
{}
|
|
291
|
-
<
|
|
292
|
-
</>:null},
|
|
293
|
-
<Jr ref={I}onClose={O}containerStyle={
|
|
291
|
+
<At visible={V}onClose={F}onEmojiSelected={G}/>
|
|
292
|
+
</>:null},ne=Ss.create({spotlightOverlay:{position:"absolute",top:0,left:0,right:0,bottom:0},overlayPressable:{flex:1,backgroundColor:"transparent"},emojiBar:{backgroundColor:"white",borderRadius:25,paddingHorizontal:12,paddingVertical:8,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.25,shadowRadius:12,elevation:12,zIndex:1001,maxWidth:320},emojiContainer:{flexDirection:"row",alignItems:"center",paddingHorizontal:4},emojiButton:{width:36,height:36,borderRadius:18,backgroundColor:"#f8f9fa",justifyContent:"center",alignItems:"center",marginHorizontal:3},emojiText:{fontSize:18},addEmojiButton:{width:36,height:36,borderRadius:18,backgroundColor:"#f8f9fa",justifyContent:"center",alignItems:"center",marginHorizontal:3},actionMenu:{backgroundColor:"white",borderRadius:12,shadowColor:"#000",shadowOffset:{width:0,height:4},shadowOpacity:.25,shadowRadius:12,elevation:12,zIndex:1001,minWidth:160,maxWidth:200},actionItems:{paddingVertical:4},actionRow:{flexDirection:"row",alignItems:"center",paddingVertical:12,paddingHorizontal:16,minHeight:44},actionLabel:{fontSize:15,color:"#333",marginLeft:12,fontWeight:"500"},hiddenEmojiInput:{position:"absolute",left:-9999,opacity:0,height:0,width:0},overlay:{...Ss.absoluteFillObject,zIndex:1e3},backdrop:{...Ss.absoluteFillObject,backgroundColor:"rgba(0, 0, 0, 0.8)"}}),Ho=Kr;import{useRef as $r,useEffect as qr,useState as Yr}from"react";import{View as $e,Text as Ee,TouchableOpacity as In,ScrollView as _r,StyleSheet as Gr}from"react-native";import Jr from"react-native-actions-sheet";var Xr=({visible:C,onClose:S,reactions:T,messageText:M,onAddReaction:R,onRemoveReaction:A})=>{let I=$r(null),[P,V]=Yr(!1);qr(()=>{C?I.current?.show():I.current?.hide()},[C]);let v=(()=>{let j=[];return T.forEach(H=>{let N=[{id:"1",name:"You",avatar:"\u{1F464}"},{id:"2",name:"Anna",avatar:"\u{1F469}"},{id:"3",name:"Young Beetle",avatar:"\u{1F697}"},{id:"4",name:"Lele",avatar:"\u{1F3AD}"},{id:"5",name:"Needle",avatar:"\u{1F3E0}"}];for(let F=0;F<Math.min(H.count,N.length);F++)j.push({id:`${H.emoji}-${F}`,name:N[F].name,avatar:N[F].avatar,emoji:H.emoji,timestamp:new Date().toISOString()})}),j})(),B=T.reduce((j,H)=>j+H.count,0),k=j=>{console.log("Remove reaction called with:",j),console.log("onRemoveReaction prop exists:",!!A),console.log("User is current user:",j.name==="You"),j.name==="You"&&A?(console.log("Calling onRemoveReaction with emoji:",j.emoji),A(j.emoji)):console.log("Not calling onRemoveReaction because:",{isCurrentUser:j.name==="You",hasCallback:!!A})},z=()=>{I.current?.hide(),S(),setTimeout(()=>{V(!0)},300)},D=()=>{V(!1)},L=j=>{console.log("Selected emoji from picker:",j),R?.(j),V(!1),S()},O=()=>{I.current?.hide(),S()};return<>
|
|
293
|
+
<Jr ref={I}onClose={O}containerStyle={_.container}headerAlwaysVisible={!0}gestureEnabled={!0}closeOnTouchBackdrop={!0}>
|
|
294
294
|
{}
|
|
295
|
-
|
|
296
|
-
<Ee style={
|
|
297
|
-
<
|
|
298
|
-
<Ee style={
|
|
299
|
-
</
|
|
300
|
-
|
|
295
|
+
<$e style={_.header}>
|
|
296
|
+
<Ee style={_.title}>{B} reactions</Ee>
|
|
297
|
+
<In onPress={O}style={_.closeButton}>
|
|
298
|
+
<Ee style={_.closeText}>✕</Ee>
|
|
299
|
+
</In>
|
|
300
|
+
</$e>
|
|
301
301
|
|
|
302
302
|
{}
|
|
303
|
-
|
|
304
|
-
<Ee style={
|
|
305
|
-
{
|
|
303
|
+
<$e style={_.messagePreview}>
|
|
304
|
+
<Ee style={_.messageText}numberOfLines={2}>
|
|
305
|
+
{M}
|
|
306
306
|
</Ee>
|
|
307
|
-
|
|
307
|
+
</$e>
|
|
308
308
|
|
|
309
309
|
{}
|
|
310
|
-
|
|
310
|
+
<$e style={_.reactionButtons}>
|
|
311
311
|
{}
|
|
312
312
|
|
|
313
|
-
{T.map((j,H)
|
|
314
|
-
<Ee style={
|
|
315
|
-
<Ee style={
|
|
316
|
-
|
|
317
|
-
|
|
313
|
+
{T.map((j,H)=><$e key={H}style={_.reactionButton}>
|
|
314
|
+
<Ee style={_.reactionEmoji}>{j.emoji}</Ee>
|
|
315
|
+
<Ee style={_.reactionCount}>{j.count}</Ee>
|
|
316
|
+
</$e>)}
|
|
317
|
+
</$e>
|
|
318
318
|
|
|
319
319
|
{}
|
|
320
|
-
<
|
|
321
|
-
{v.map(j=>{let H=j.name==="You",N=H?
|
|
322
|
-
|
|
323
|
-
<Ee style={
|
|
324
|
-
|
|
325
|
-
<Ee style={
|
|
326
|
-
{H&&<Ee style={
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
<Ee style={
|
|
331
|
-
|
|
320
|
+
<_r style={_.userReactionsList}showsVerticalScrollIndicator={!1}>
|
|
321
|
+
{v.map(j=>{let H=j.name==="You",N=H?In:$e;return<N key={j.id}style={[_.userReactionItem,H&&_.tappableUserReactionItem]}onPress={H?()=>k(j):void 0}activeOpacity={H?.7:1}>
|
|
322
|
+
<$e style={_.userInfo}>
|
|
323
|
+
<Ee style={_.userAvatar}>{j.avatar}</Ee>
|
|
324
|
+
<$e style={_.userDetails}>
|
|
325
|
+
<Ee style={_.userName}>{j.name}</Ee>
|
|
326
|
+
{H&&<Ee style={_.removeText}>Tap to remove</Ee>}
|
|
327
|
+
</$e>
|
|
328
|
+
</$e>
|
|
329
|
+
<$e style={_.userReactionEmoji}>
|
|
330
|
+
<Ee style={_.emojiText}>{j.emoji}</Ee>
|
|
331
|
+
</$e>
|
|
332
332
|
</N>})}
|
|
333
|
-
</
|
|
333
|
+
</_r>
|
|
334
334
|
</Jr>
|
|
335
335
|
|
|
336
336
|
{}
|
|
337
|
-
<
|
|
338
|
-
</>},
|
|
339
|
-
<
|
|
337
|
+
<At visible={P}onClose={D}onEmojiSelected={L}/>
|
|
338
|
+
</>},_=Gr.create({container:{backgroundColor:"white",borderTopLeftRadius:20,borderTopRightRadius:20,paddingTop:20,paddingBottom:40,maxHeight:"70%"},header:{flexDirection:"row",justifyContent:"space-between",alignItems:"center",paddingHorizontal:20,paddingBottom:15,borderBottomWidth:1,borderBottomColor:"#f0f0f0"},title:{fontSize:18,fontWeight:"600",color:"#333"},closeButton:{padding:5},closeText:{fontSize:18,color:"#666",fontWeight:"500"},messagePreview:{paddingHorizontal:20,paddingVertical:15,borderBottomWidth:1,borderBottomColor:"#f0f0f0"},messageText:{fontSize:14,color:"#666",lineHeight:20},reactionButtons:{flexDirection:"row",paddingHorizontal:20,paddingVertical:15,gap:10},addReactionButton:{flexDirection:"row",alignItems:"center",backgroundColor:"#f8f9fa",borderWidth:1,borderColor:"#e9ecef",borderRadius:20,paddingHorizontal:12,paddingVertical:8},addReactionIcon:{fontSize:16,marginRight:4},addReactionText:{fontSize:14,color:"#666",fontWeight:"500"},reactionButton:{flexDirection:"row",alignItems:"center",backgroundColor:"#28a745",borderRadius:20,paddingHorizontal:12,paddingVertical:8},reactionEmoji:{fontSize:16,marginRight:4},reactionCount:{fontSize:14,color:"white",fontWeight:"600"},userReactionsList:{paddingHorizontal:20,paddingTop:10},userReactionItem:{flexDirection:"row",justifyContent:"space-between",alignItems:"center",paddingVertical:12,borderBottomWidth:1,borderBottomColor:"#f8f9fa"},tappableUserReactionItem:{backgroundColor:"#f8f9fa",borderRadius:8,paddingHorizontal:8,marginVertical:2},userInfo:{flexDirection:"row",alignItems:"center",flex:1},userAvatar:{fontSize:24,marginRight:12},userDetails:{flex:1},userName:{fontSize:16,fontWeight:"500",color:"#333"},removeText:{fontSize:12,color:"#dc3545",marginTop:2,fontWeight:"500"},userReactionEmoji:{backgroundColor:"#f8f9fa",borderRadius:16,paddingHorizontal:8,paddingVertical:4},emojiText:{fontSize:16}}),No=Xr;import Zr,{forwardRef as Qr,useImperativeHandle as ei}from"react";import{View as Wo,Text as Pn,TouchableOpacity as An}from"react-native";import Ci from"react-native-actions-sheet";import{X as Mi}from"lucide-react-native";var Ct=Qr(({onOptionSelect:C,options:S},T)=>{let M=Zr.useRef(null);ei(T,()=>({show:()=>M.current?.show(),hide:()=>M.current?.hide()}));let R=A=>{C(A),M.current?.hide()};return<Ci ref={M}headerAlwaysVisible gestureEnabled={!0}statusBarTranslucent drawUnderStatusBar={!1}containerStyle={{borderTopLeftRadius:20,borderTopRightRadius:20}}>
|
|
339
|
+
<Wo style={{padding:20,width:"100%"}}>
|
|
340
340
|
|
|
341
341
|
{}
|
|
342
|
-
<
|
|
343
|
-
<
|
|
342
|
+
<Wo style={{flexDirection:"row",justifyContent:"space-between",alignItems:"center",marginBottom:20}}>
|
|
343
|
+
<Pn style={{fontSize:18,fontWeight:"600",color:"#1F2937"}}>
|
|
344
344
|
Share Content
|
|
345
|
-
</
|
|
346
|
-
<
|
|
347
|
-
<
|
|
348
|
-
</
|
|
349
|
-
</
|
|
345
|
+
</Pn>
|
|
346
|
+
<An onPress={()=>M.current?.hide()}>
|
|
347
|
+
<Mi size={24}color="#6B7280"/>
|
|
348
|
+
</An>
|
|
349
|
+
</Wo>
|
|
350
350
|
|
|
351
351
|
{}
|
|
352
|
-
<
|
|
353
|
-
{
|
|
354
|
-
<
|
|
355
|
-
<I size={24}color={
|
|
356
|
-
</
|
|
357
|
-
<
|
|
358
|
-
{
|
|
359
|
-
</
|
|
360
|
-
</
|
|
361
|
-
</
|
|
362
|
-
</
|
|
363
|
-
</
|
|
364
|
-
<Is style={
|
|
365
|
-
<Is style={
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
352
|
+
<Wo style={{flexDirection:"row",flexWrap:"wrap",justifyContent:"space-between",paddingBottom:20}}>
|
|
353
|
+
{S.map(A=>{let I=A.icon;return<An key={A.id}style={{width:"30%",aspectRatio:1,marginBottom:20,alignItems:"center",justifyContent:"center"}}onPress={()=>R(A.id)}>
|
|
354
|
+
<Wo style={{width:60,height:60,borderRadius:30,backgroundColor:"#F3F4F6",alignItems:"center",justifyContent:"center",marginBottom:8}}>
|
|
355
|
+
<I size={24}color={A.color}/>
|
|
356
|
+
</Wo>
|
|
357
|
+
<Pn style={{fontSize:12,color:"#6B7280",textAlign:"center",fontWeight:"500"}}>
|
|
358
|
+
{A.label}
|
|
359
|
+
</Pn>
|
|
360
|
+
</An>})}
|
|
361
|
+
</Wo>
|
|
362
|
+
</Wo>
|
|
363
|
+
</Ci>});Ct.displayName="AttachmentMenu";import{useEffect as Ti,useRef as Si}from"react";import{View as Is,StyleSheet as Ri,Animated as qe}from"react-native";var wi=({isVisible:C})=>{let S=Si(new qe.Value(0)).current;return Ti(()=>{if(!C){S.setValue(0);return}let T=qe.loop(qe.sequence([qe.timing(S,{toValue:1,duration:1200,useNativeDriver:!0}),qe.timing(S,{toValue:0,duration:1200,useNativeDriver:!0})]));return T.start(),()=>{T.stop()}},[C,S]),C?<Is style={Bt.container}>
|
|
364
|
+
<Is style={Bt.bubble}>
|
|
365
|
+
<Is style={Bt.dotsContainer}>
|
|
366
|
+
<qe.View style={[Bt.dot,{opacity:S.interpolate({inputRange:[0,.5,1],outputRange:[.3,1,.3]}),transform:[{translateY:S.interpolate({inputRange:[0,.5,1],outputRange:[0,-4,0]})}]}]}/>
|
|
367
|
+
<qe.View style={[Bt.dot,{opacity:S.interpolate({inputRange:[.33,.83,1.33],outputRange:[.3,1,.3]}),transform:[{translateY:S.interpolate({inputRange:[.33,.83,1.33],outputRange:[0,-4,0]})}]}]}/>
|
|
368
|
+
<qe.View style={[Bt.dot,{opacity:S.interpolate({inputRange:[.66,1.16,1.66],outputRange:[.3,1,.3]}),transform:[{translateY:S.interpolate({inputRange:[.66,1.16,1.66],outputRange:[0,-4,0]})}]}]}/>
|
|
369
369
|
</Is>
|
|
370
370
|
</Is>
|
|
371
|
-
</Is>:null},
|
|
372
|
-
{({pressed:P})=><Ps.View style={[{position:"absolute",bottom:40,right:
|
|
373
|
-
<Pi size={20}color={
|
|
371
|
+
</Is>:null},Bt=Ri.create({container:{paddingHorizontal:15,paddingVertical:5},bubble:{backgroundColor:"#fff",borderRadius:18,paddingHorizontal:12,paddingVertical:8,alignSelf:"flex-start",maxWidth:"80%"},senderNameContainer:{marginBottom:4},senderName:{fontSize:12,color:"#666",fontWeight:"500"},dotsContainer:{flexDirection:"row",alignItems:"center",justifyContent:"center"},dot:{width:6,height:6,borderRadius:3,backgroundColor:"#999",marginHorizontal:3}}),Lt=wi;import vs from"react";import{Pressable as Ii,Animated as Ps}from"react-native";import{ChevronDown as Pi}from"lucide-react-native";var Ai=({visible:C,onPress:S,isReplyActive:T=!1})=>{let M=$(),R=vs.useRef(new Ps.Value(0)).current,[A,I]=vs.useState(!1);return vs.useEffect(()=>{Ps.timing(R,{toValue:C?1:0,duration:200,useNativeDriver:!0}).start(()=>{I(C)})},[C,R]),!C&&!A?null:<Ii onPress={S}hitSlop={{top:10,bottom:10,left:10,right:10}}>
|
|
372
|
+
{({pressed:P})=><Ps.View style={[{position:"absolute",bottom:40,right:M.spacing.lg,zIndex:9999,width:32,height:32,backgroundColor:M.colors.background,borderRadius:M.borderRadius.xl,justifyContent:"center",alignItems:"center",shadowColor:"#000",shadowOffset:{width:0,height:2},shadowOpacity:.25,shadowRadius:3.84,elevation:5,opacity:R,transform:P?[{scale:.95}]:[]}]}>
|
|
373
|
+
<Pi size={20}color={M.colors.text}/>
|
|
374
374
|
</Ps.View>}
|
|
375
|
-
</Ii>},
|
|
376
|
-
<
|
|
377
|
-
<
|
|
378
|
-
{
|
|
379
|
-
</
|
|
380
|
-
</
|
|
381
|
-
</Va>},Uo=Bi;import qo,{forwardRef as qi,useRef as Yi,useImperativeHandle as $i,useCallback as Gi}from"react";import{View as Vs,TextInput as _i,TouchableOpacity as Ba,Platform as Da}from"react-native";import{Plus as Ji,Send as Xi,Mic as Zi}from"lucide-react-native";import{useRef as ki,useCallback as Ge}from"react";import{Alert as X}from"react-native";import{Camera as Li,Image as ji,MapPin as Ei,User as Fi,FileText as Oi,BarChart3 as Hi,Calendar as Ni}from"lucide-react-native";var Di={maxWidth:1920,maxHeight:1920,quality:.8,format:"jpeg"},As=async(M,R={})=>{try{let T;try{T=await import("expo-image-manipulator")}catch(B){console.log("expo-image-manipulator not available, returning original image info:",B);let A=`image_${Date.now()}.jpg`;return{uri:M,width:1920,height:1920,fileName:A}}let C={...Di,...R};console.log("Starting image compression...",{uri:M,options:C});let S=await T.manipulateAsync(M,[],{});console.log("Original image info:",{width:S.width,height:S.height,uri:S.uri});let V=[];if(C.maxWidth||C.maxHeight){let{width:B,height:k}=S,A=B,z=k;if(C.maxWidth&&B>C.maxWidth){let L=C.maxWidth/B;A=C.maxWidth,z=k*L}if(C.maxHeight&&z>C.maxHeight){let L=C.maxHeight/z;z=C.maxHeight,A=A*L}(A!==B||z!==k)&&(V.push({resize:{width:Math.round(A),height:Math.round(z)}}),console.log("Resizing image:",{from:{width:B,height:k},to:{width:Math.round(A),height:Math.round(z)}}))}let I={compress:C.quality,format:C.format==="png"?T.SaveFormat?.PNG:T.SaveFormat?.JPEG};console.log("Applying compression with options:",I);let P=await T.manipulateAsync(M,V,I);console.log("Image compression completed:",{originalUri:M,compressedUri:P.uri,finalDimensions:{width:P.width,height:P.height}});let D=Date.now(),E=C.format==="png"?"png":"jpg",v=`compressed_image_${D}.${E}`;return{uri:P.uri,width:P.width,height:P.height,fileName:v}}catch(T){console.error("Error compressing image:",T);let C=T instanceof Error?T.message:"Unknown error";throw new Error(`Failed to compress image: ${C}`)}},zs=(M,R)=>M>3e3||R>3e3?{maxWidth:1920,maxHeight:1920,quality:.7,format:"jpeg"}:M>1920||R>1920?{maxWidth:1920,maxHeight:1920,quality:.8,format:"jpeg"}:{quality:.9,format:"jpeg"};var Wi=[{id:"photo",label:"Photo",icon:ji,color:"#3B82F6"},{id:"camera",label:"Camera",icon:Li,color:"#6B7280"},{id:"location",label:"Location",icon:Ei,color:"#10B981"},{id:"contact",label:"Contact",icon:Fi,color:"#6B7280"},{id:"document",label:"Document",icon:Oi,color:"#3B82F6"},{id:"poll",label:"Poll",icon:Hi,color:"#F59E0B"},{id:"event",label:"Event",icon:Ni,color:"#EF4444"}],Ko=M=>{let R=ki(null),T=Ge(async()=>{console.log("Photo selection initiated");try{let v;try{v=await import("expo-image-picker")}catch(A){console.log("expo-image-picker not available:",A),X.alert("Feature Not Available","Photo selection requires expo-image-picker to be installed. Please install expo-image-picker to use this feature.",[{text:"OK"}]);return}console.log("Requesting photo library permissions...");let{status:B}=await v.requestMediaLibraryPermissionsAsync();if(console.log("Photo library permission status:",B),B!=="granted"){X.alert("Permission needed","Please grant photo library access to select images.");return}console.log("Waiting for UI to stabilize..."),await new Promise(A=>setTimeout(()=>A(void 0),300)),console.log("Launching image picker...");let k=await v.launchImageLibraryAsync({mediaTypes:"images",allowsEditing:!0,aspect:[4,3],quality:.8,allowsMultipleSelection:!1});if(console.log("Image picker result:",k),!k.canceled&&k.assets&&k.assets.length>0){let A=k.assets[0];console.log("Photo selected successfully:",A.uri);try{console.log("Starting image compression...");let z=zs(A.width||1920,A.height||1920),L=await As(A.uri,z);console.log("Image compression completed:",L),M?.({type:"image",data:{...L,originalFileSize:A.fileSize}})}catch(z){console.error("Image compression failed:",z),X.alert("Compression Error","Failed to compress image. Sending original image.",[{text:"OK"}]),M?.({type:"image",data:{uri:A.uri,width:A.width,height:A.height,fileSize:A.fileSize,fileName:A.fileName||"image.jpg"}})}}else console.log("Photo selection was canceled by user")}catch(v){console.error("Error in photo selection process:",v),X.alert("Photo Selection Error","Failed to open photo library. Please try again or check your device permissions.",[{text:"OK"}])}},[M]),C=Ge(async()=>{console.log("Camera capture initiated");try{let v;try{v=await import("expo-image-picker")}catch(A){console.log("expo-image-picker not available:",A),X.alert("Feature Not Available","Camera capture requires expo-image-picker to be installed. Please install expo-image-picker to use this feature.",[{text:"OK"}]);return}console.log("Requesting camera permissions...");let{status:B}=await v.requestCameraPermissionsAsync();if(console.log("Camera permission status:",B),B!=="granted"){X.alert("Permission needed","Please grant camera access to take photos.");return}console.log("Waiting for UI to stabilize..."),await new Promise(A=>setTimeout(()=>A(void 0),300)),console.log("Launching camera...");let k=await v.launchCameraAsync({allowsEditing:!0,aspect:[4,3],quality:.8,mediaTypes:"images"});if(console.log("Camera result:",k),!k.canceled&&k.assets&&k.assets.length>0){let A=k.assets[0];console.log("Photo captured successfully:",A.uri);try{console.log("Starting camera image compression...");let z=zs(A.width||1920,A.height||1920),L=await As(A.uri,z);console.log("Camera image compression completed:",L),M?.({type:"image",data:{...L,originalFileSize:A.fileSize}})}catch(z){console.error("Camera image compression failed:",z),X.alert("Compression Error","Failed to compress captured image. Sending original image.",[{text:"OK"}]),M?.({type:"image",data:{uri:A.uri,width:A.width,height:A.height,fileSize:A.fileSize,fileName:A.fileName||"camera_photo.jpg"}})}}else console.log("Camera capture was canceled by user")}catch(v){console.error("Error in camera capture process:",v),X.alert("Camera Error","Failed to open camera. Please try again or check your device permissions.",[{text:"OK"}])}},[M]),S=Ge(async()=>{console.log("Location sharing initiated");try{let v;try{v=await import("expo-location")}catch(L){console.log("expo-location not available:",L),X.alert("Feature Not Available","Location sharing requires expo-location to be installed. Please install expo-location to use this feature.",[{text:"OK"}]);return}console.log("Requesting location permissions...");let{status:B}=await v.requestForegroundPermissionsAsync();if(console.log("Location permission status:",B),B!=="granted"){X.alert("Permission needed","Please grant location access to share your location.");return}console.log("Getting current location...");let k=await v.getCurrentPositionAsync({accuracy:v.Accuracy.High});console.log("Getting address from coordinates...");let A=await v.reverseGeocodeAsync({latitude:k.coords.latitude,longitude:k.coords.longitude}),z={coordinates:{latitude:k.coords.latitude,longitude:k.coords.longitude},address:A[0]||null,timestamp:k.timestamp};console.log("Location shared successfully:",z.coordinates),M?.({type:"location",data:z})}catch(v){console.error("Error in location sharing process:",v),X.alert("Location Error","Failed to get your location. Please try again or check your device permissions.",[{text:"OK"}])}},[M]),V=Ge(async()=>{try{let v;try{v=await import("expo-contacts")}catch(k){console.log("expo-contacts not available:",k),X.alert("Feature Not Available","Contact sharing requires expo-contacts to be installed. Please install expo-contacts to use this feature.",[{text:"OK"}]);return}let{status:B}=await v.requestPermissionsAsync();if(B!=="granted"){X.alert("Permission needed","Please grant contacts access to share contacts.");return}X.alert("Contact Sharing","Contact selection feature is coming soon! This would open a contact picker.",[{text:"OK",onPress:()=>console.log("Contact sharing acknowledged")}])}catch(v){console.error("Error accessing contacts:",v),X.alert("Error","Failed to access contacts. Please try again.")}finally{R.current?.hide()}},[]),I=Ge(async()=>{console.log("Document selection initiated");try{let v;try{v=await import("expo-document-picker")}catch(k){console.log("expo-document-picker not available:",k),X.alert("Feature Not Available","Document selection requires expo-document-picker to be installed. Please install expo-document-picker to use this feature.",[{text:"OK"}]);return}console.log("Waiting for UI to stabilize..."),await new Promise(k=>setTimeout(()=>k(void 0),300)),console.log("Launching document picker...");let B=await v.getDocumentAsync({type:"*/*",copyToCacheDirectory:!0,multiple:!1});if(console.log("Document picker result:",B),!B.canceled&&B.assets&&B.assets.length>0){let k=B.assets[0];console.log("Document selected successfully:",k.name),M?.({type:"document",data:{uri:k.uri,name:k.name,size:k.size,mimeType:k.mimeType}})}else console.log("Document selection was canceled by user")}catch(v){console.error("Error in document selection process:",v),X.alert("Document Selection Error","Failed to open document picker. Please try again.",[{text:"OK"}])}},[M]),P=Ge(()=>{X.alert("Create Poll","Poll creation feature is coming soon! This would open a poll creation interface.",[{text:"OK",onPress:()=>console.log("Poll creation acknowledged")}])},[]),D=Ge(()=>{X.alert("Create Event","Event creation feature is coming soon! This would open an event creation interface.",[{text:"OK",onPress:()=>console.log("Event creation acknowledged")}])},[]),E=Ge(async v=>{console.log(`Selected attachment option: ${v}`);try{switch(v){case"photo":await T();break;case"camera":await C();break;case"location":await S();break;case"contact":await V();break;case"document":await I();break;case"poll":P();break;case"event":D();break;default:console.warn(`Unknown attachment option: ${v}`)}}catch(B){console.error(`Error handling ${v}:`,B),X.alert("Error",`Failed to handle ${v}. Please try again.`)}},[T,C,S,V,I,P,D]);return{menuRef:R,handleOptionSelect:E,options:Wi}};import _e,{useRef as Ui,useCallback as Ae,createContext as Ki,useContext as Bm}from"react";var Qt=(M={})=>{let{initialValue:R="",initialHeight:T=50,onValueChange:C,onHeightChange:S,onSend:V,onAttachmentSend:I,onReplyCancel:P,onFocus:D,onBlur:E,maxHeight:v=100,minHeight:B=50,maxLength:k=1e3,placeholder:A="Type a message..."}=M,z=Ui(null),[L,O]=_e.useState(R),[j,H]=_e.useState(T),[N,F]=_e.useState(!1),[_,re]=_e.useState(null),[J,Me]=_e.useState([]),Z=_e.useMemo(()=>({value:L,height:j,isFocused:N,replyToMessage:_,attachments:J}),[L,j,N,_,J]),ne=Ae(se=>{O(se),C?.(se)},[C]),oe=Ae(se=>{let Se=Math.max(B,Math.min(v,se));H(Se),S?.(Se)},[B,v,S]),Ie=Ae(()=>{F(!0),D?.()},[D]),W=Ae(()=>{F(!1),E?.()},[E]),ve=Ae(se=>{let{height:Se}=se.nativeEvent.contentSize,Wt=Math.max(B,Math.min(v,Se+16));oe(Wt)},[B,v,oe]),Ce=Ae(()=>{V&&(L||J.length>0)&&(V(L,J,_),O(R),Me([]),re(null),H(T))},[V,L,J,_,R,T]),Xe=Ae(se=>{I?(I(se,L),L&&O(R)):Me(Se=>[...Se,{...se,id:Date.now().toString()}])},[I,L,R]),Q=Ae(se=>{Me(Se=>[...Se,se])},[]),Pe=Ae(se=>{Me(Se=>Se.filter(Wt=>Wt.id!==se))},[]),ze=Ae(()=>{Me([])},[]),ee=Ae(()=>{re(null),P?.()},[P]),wt=Ae(()=>{z.current?.focus()},[]),Ze=_e.useMemo(()=>({setValue:ne,setHeight:oe,setFocus:F,setReplyToMessage:re,addAttachment:Q,removeAttachment:Pe,clearAttachments:ze,sendMessage:Ce,cancelReply:ee,focusInput:wt,handleAttachmentSelected:Xe,handleContentSizeChange:ve,handleFocus:Ie,handleBlur:W}),[ne,oe,F,re,Q,Pe,ze,Ce,ee,wt,Xe,ve,Ie,W]),Go=_e.useMemo(()=>({textInputRef:z}),[]);return{state:Z,actions:Ze,refs:Go}},km=Ki(null);var Oe=qi(({value:M,onChangeText:R,onSend:T,onFocus:C,height:S,onContentSizeChange:V,replyToMessage:I,onCancelReply:P,onAttachmentSend:D},E)=>{let v=q(),B=Te(),k=Yi(null);$i(E,()=>({focus:()=>{k.current?.focus()}}));let{state:A,actions:z}=Qt({initialValue:M,initialHeight:S,onValueChange:R,onHeightChange:V,onSend:T,onAttachmentSend:D,onReplyCancel:P,onFocus:C});qo.useEffect(()=>{M!==A.value&&z.setValue(M)},[M,A.value,z]),qo.useEffect(()=>{S!==A.height&&z.setHeight(S)},[S,A.height,z]),qo.useEffect(()=>{I!==A.replyToMessage&&z.setReplyToMessage(I||null)},[I,A.replyToMessage,z]),qo.useEffect(()=>{if(I&&k.current){let j=setTimeout(()=>{k.current?.focus()},100);return()=>clearTimeout(j)}},[I]);let L=Gi(j=>{if(console.log("Attachment selected:",j),D)D(j,M.trim()||void 0),M.trim()&&R("");else switch(j.type){case"image":console.log("Image attachment ready to send:",{uri:j.data.uri,dimensions:{width:j.data.width,height:j.data.height},fileName:j.data.fileName});break;case"document":console.log("Document attachment ready to send:",{name:j.data.name,size:j.data.size});break;case"location":console.log("Location attachment ready to send:",j.data.coordinates);break;case"contact":console.log("Contact attachment ready to send:",j.data);break;default:console.log("Other attachment ready to send:",j)}},[D,M,R]),O=Ko(L);return<>
|
|
382
|
-
{I&&P&&<
|
|
383
|
-
<
|
|
384
|
-
<
|
|
385
|
-
<
|
|
375
|
+
</Ii>},Uo=Ai;import{View as Dn,Text as Di}from"react-native";var Vi=({displayDate:C})=>{let S=$();return<Dn style={{marginVertical:S.spacing.lg,alignItems:"center"}}>
|
|
376
|
+
<Dn style={{borderRadius:S.borderRadius.full,backgroundColor:S.colors.surfaceSecondary,paddingHorizontal:S.spacing.md,paddingVertical:S.spacing.xs}}>
|
|
377
|
+
<Di style={{fontSize:S.typography.fontSize.xs,color:S.colors.textSecondary,fontWeight:S.typography.fontWeight.medium}}>
|
|
378
|
+
{C}
|
|
379
|
+
</Di>
|
|
380
|
+
</Dn>
|
|
381
|
+
</Dn>},Ko=Vi;import qo,{forwardRef as $i,useRef as qi,useImperativeHandle as Yi,useCallback as _i}from"react";import{View as Ds,TextInput as Gi,TouchableOpacity as Vn,Platform as Bn}from"react-native";import{Plus as Ji,Send as Xi,Mic as Zi}from"lucide-react-native";import{useRef as ki,useCallback as Ye}from"react";import{Alert as X}from"react-native";import{Camera as Li,Image as ji,MapPin as Ei,User as Fi,FileText as Oi,BarChart3 as Hi,Calendar as Ni}from"lucide-react-native";var Bi={maxWidth:1920,maxHeight:1920,quality:.8,format:"jpeg"},As=async(C,S={})=>{try{let T;try{T=await import("expo-image-manipulator")}catch(B){console.log("expo-image-manipulator not available, returning original image info:",B);let z=`image_${Date.now()}.jpg`;return{uri:C,width:1920,height:1920,fileName:z}}let M={...Bi,...S};console.log("Starting image compression...",{uri:C,options:M});let R=await T.manipulateAsync(C,[],{});console.log("Original image info:",{width:R.width,height:R.height,uri:R.uri});let A=[];if(M.maxWidth||M.maxHeight){let{width:B,height:k}=R,z=B,D=k;if(M.maxWidth&&B>M.maxWidth){let L=M.maxWidth/B;z=M.maxWidth,D=k*L}if(M.maxHeight&&D>M.maxHeight){let L=M.maxHeight/D;D=M.maxHeight,z=z*L}(z!==B||D!==k)&&(A.push({resize:{width:Math.round(z),height:Math.round(D)}}),console.log("Resizing image:",{from:{width:B,height:k},to:{width:Math.round(z),height:Math.round(D)}}))}let I={compress:M.quality,format:M.format==="png"?T.SaveFormat?.PNG:T.SaveFormat?.JPEG};console.log("Applying compression with options:",I);let P=await T.manipulateAsync(C,A,I);console.log("Image compression completed:",{originalUri:C,compressedUri:P.uri,finalDimensions:{width:P.width,height:P.height}});let V=Date.now(),E=M.format==="png"?"png":"jpg",v=`compressed_image_${V}.${E}`;return{uri:P.uri,width:P.width,height:P.height,fileName:v}}catch(T){console.error("Error compressing image:",T);let M=T instanceof Error?T.message:"Unknown error";throw new Error(`Failed to compress image: ${M}`)}},zs=(C,S)=>C>3e3||S>3e3?{maxWidth:1920,maxHeight:1920,quality:.7,format:"jpeg"}:C>1920||S>1920?{maxWidth:1920,maxHeight:1920,quality:.8,format:"jpeg"}:{quality:.9,format:"jpeg"};var Wi=[{id:"photo",label:"Photo",icon:ji,color:"#3B82F6"},{id:"camera",label:"Camera",icon:Li,color:"#6B7280"},{id:"location",label:"Location",icon:Ei,color:"#10B981"},{id:"contact",label:"Contact",icon:Fi,color:"#6B7280"},{id:"document",label:"Document",icon:Oi,color:"#3B82F6"},{id:"poll",label:"Poll",icon:Hi,color:"#F59E0B"},{id:"event",label:"Event",icon:Ni,color:"#EF4444"}],$o=C=>{let S=ki(null),T=Ye(async()=>{console.log("Photo selection initiated");try{let v;try{v=await import("expo-image-picker")}catch(z){console.log("expo-image-picker not available:",z),X.alert("Feature Not Available","Photo selection requires expo-image-picker to be installed. Please install expo-image-picker to use this feature.",[{text:"OK"}]);return}console.log("Requesting photo library permissions...");let{status:B}=await v.requestMediaLibraryPermissionsAsync();if(console.log("Photo library permission status:",B),B!=="granted"){X.alert("Permission needed","Please grant photo library access to select images.");return}console.log("Waiting for UI to stabilize..."),await new Promise(z=>setTimeout(()=>z(void 0),300)),console.log("Launching image picker...");let k=await v.launchImageLibraryAsync({mediaTypes:"images",allowsEditing:!0,aspect:[4,3],quality:.8,allowsMultipleSelection:!1});if(console.log("Image picker result:",k),!k.canceled&&k.assets&&k.assets.length>0){let z=k.assets[0];console.log("Photo selected successfully:",z.uri);try{console.log("Starting image compression...");let D=zs(z.width||1920,z.height||1920),L=await As(z.uri,D);console.log("Image compression completed:",L),C?.({type:"image",data:{...L,originalFileSize:z.fileSize}})}catch(D){console.error("Image compression failed:",D),X.alert("Compression Error","Failed to compress image. Sending original image.",[{text:"OK"}]),C?.({type:"image",data:{uri:z.uri,width:z.width,height:z.height,fileSize:z.fileSize,fileName:z.fileName||"image.jpg"}})}}else console.log("Photo selection was canceled by user")}catch(v){console.error("Error in photo selection process:",v),X.alert("Photo Selection Error","Failed to open photo library. Please try again or check your device permissions.",[{text:"OK"}])}},[C]),M=Ye(async()=>{console.log("Camera capture initiated");try{let v;try{v=await import("expo-image-picker")}catch(z){console.log("expo-image-picker not available:",z),X.alert("Feature Not Available","Camera capture requires expo-image-picker to be installed. Please install expo-image-picker to use this feature.",[{text:"OK"}]);return}console.log("Requesting camera permissions...");let{status:B}=await v.requestCameraPermissionsAsync();if(console.log("Camera permission status:",B),B!=="granted"){X.alert("Permission needed","Please grant camera access to take photos.");return}console.log("Waiting for UI to stabilize..."),await new Promise(z=>setTimeout(()=>z(void 0),300)),console.log("Launching camera...");let k=await v.launchCameraAsync({allowsEditing:!0,aspect:[4,3],quality:.8,mediaTypes:"images"});if(console.log("Camera result:",k),!k.canceled&&k.assets&&k.assets.length>0){let z=k.assets[0];console.log("Photo captured successfully:",z.uri);try{console.log("Starting camera image compression...");let D=zs(z.width||1920,z.height||1920),L=await As(z.uri,D);console.log("Camera image compression completed:",L),C?.({type:"image",data:{...L,originalFileSize:z.fileSize}})}catch(D){console.error("Camera image compression failed:",D),X.alert("Compression Error","Failed to compress captured image. Sending original image.",[{text:"OK"}]),C?.({type:"image",data:{uri:z.uri,width:z.width,height:z.height,fileSize:z.fileSize,fileName:z.fileName||"camera_photo.jpg"}})}}else console.log("Camera capture was canceled by user")}catch(v){console.error("Error in camera capture process:",v),X.alert("Camera Error","Failed to open camera. Please try again or check your device permissions.",[{text:"OK"}])}},[C]),R=Ye(async()=>{console.log("Location sharing initiated");try{let v;try{v=await import("expo-location")}catch(L){console.log("expo-location not available:",L),X.alert("Feature Not Available","Location sharing requires expo-location to be installed. Please install expo-location to use this feature.",[{text:"OK"}]);return}console.log("Requesting location permissions...");let{status:B}=await v.requestForegroundPermissionsAsync();if(console.log("Location permission status:",B),B!=="granted"){X.alert("Permission needed","Please grant location access to share your location.");return}console.log("Getting current location...");let k=await v.getCurrentPositionAsync({accuracy:v.Accuracy.High});console.log("Getting address from coordinates...");let z=await v.reverseGeocodeAsync({latitude:k.coords.latitude,longitude:k.coords.longitude}),D={coordinates:{latitude:k.coords.latitude,longitude:k.coords.longitude},address:z[0]||null,timestamp:k.timestamp};console.log("Location shared successfully:",D.coordinates),C?.({type:"location",data:D})}catch(v){console.error("Error in location sharing process:",v),X.alert("Location Error","Failed to get your location. Please try again or check your device permissions.",[{text:"OK"}])}},[C]),A=Ye(async()=>{try{let v;try{v=await import("expo-contacts")}catch(k){console.log("expo-contacts not available:",k),X.alert("Feature Not Available","Contact sharing requires expo-contacts to be installed. Please install expo-contacts to use this feature.",[{text:"OK"}]);return}let{status:B}=await v.requestPermissionsAsync();if(B!=="granted"){X.alert("Permission needed","Please grant contacts access to share contacts.");return}X.alert("Contact Sharing","Contact selection feature is coming soon! This would open a contact picker.",[{text:"OK",onPress:()=>console.log("Contact sharing acknowledged")}])}catch(v){console.error("Error accessing contacts:",v),X.alert("Error","Failed to access contacts. Please try again.")}finally{S.current?.hide()}},[]),I=Ye(async()=>{console.log("Document selection initiated");try{let v;try{v=await import("expo-document-picker")}catch(k){console.log("expo-document-picker not available:",k),X.alert("Feature Not Available","Document selection requires expo-document-picker to be installed. Please install expo-document-picker to use this feature.",[{text:"OK"}]);return}console.log("Waiting for UI to stabilize..."),await new Promise(k=>setTimeout(()=>k(void 0),300)),console.log("Launching document picker...");let B=await v.getDocumentAsync({type:"*/*",copyToCacheDirectory:!0,multiple:!1});if(console.log("Document picker result:",B),!B.canceled&&B.assets&&B.assets.length>0){let k=B.assets[0];console.log("Document selected successfully:",k.name),C?.({type:"document",data:{uri:k.uri,name:k.name,size:k.size,mimeType:k.mimeType}})}else console.log("Document selection was canceled by user")}catch(v){console.error("Error in document selection process:",v),X.alert("Document Selection Error","Failed to open document picker. Please try again.",[{text:"OK"}])}},[C]),P=Ye(()=>{X.alert("Create Poll","Poll creation feature is coming soon! This would open a poll creation interface.",[{text:"OK",onPress:()=>console.log("Poll creation acknowledged")}])},[]),V=Ye(()=>{X.alert("Create Event","Event creation feature is coming soon! This would open an event creation interface.",[{text:"OK",onPress:()=>console.log("Event creation acknowledged")}])},[]),E=Ye(async v=>{console.log(`Selected attachment option: ${v}`);try{switch(v){case"photo":await T();break;case"camera":await M();break;case"location":await R();break;case"contact":await A();break;case"document":await I();break;case"poll":P();break;case"event":V();break;default:console.warn(`Unknown attachment option: ${v}`)}}catch(B){console.error(`Error handling ${v}:`,B),X.alert("Error",`Failed to handle ${v}. Please try again.`)}},[T,M,R,A,I,P,V]);return{menuRef:S,handleOptionSelect:E,options:Wi}};import _e,{useRef as Ui,useCallback as ze,createContext as Ki,useContext as Ou}from"react";var Jt=(C={})=>{let{initialValue:S="",initialHeight:T=50,onValueChange:M,onHeightChange:R,onSend:A,onAttachmentSend:I,onReplyCancel:P,onFocus:V,onBlur:E,maxHeight:v=100,minHeight:B=50,maxLength:k=1e3,placeholder:z="Type a message..."}=C,D=Ui(null),[L,O]=_e.useState(S),[j,H]=_e.useState(T),[N,F]=_e.useState(!1),[G,re]=_e.useState(null),[J,Ce]=_e.useState([]),Z=_e.useMemo(()=>({value:L,height:j,isFocused:N,replyToMessage:G,attachments:J}),[L,j,N,G,J]),ae=ze(se=>{O(se),M?.(se)},[M]),oe=ze(se=>{let Re=Math.max(B,Math.min(v,se));H(Re),R?.(Re)},[B,v,R]),Ie=ze(()=>{F(!0),V?.()},[V]),W=ze(()=>{F(!1),E?.()},[E]),ve=ze(se=>{let{height:Re}=se.nativeEvent.contentSize,Ft=Math.max(B,Math.min(v,Re+16));oe(Ft)},[B,v,oe]),Me=ze(()=>{A&&(L||J.length>0)&&(A(L,J,G),O(S),Ce([]),re(null),H(T))},[A,L,J,G,S,T]),Je=ze(se=>{I?(I(se,L),L&&O(S)):Ce(Re=>[...Re,{...se,id:Date.now().toString()}])},[I,L,S]),Q=ze(se=>{Ce(Re=>[...Re,se])},[]),Pe=ze(se=>{Ce(Re=>Re.filter(Ft=>Ft.id!==se))},[]),De=ze(()=>{Ce([])},[]),ee=ze(()=>{re(null),P?.()},[P]),St=ze(()=>{D.current?.focus()},[]),Xe=_e.useMemo(()=>({setValue:ae,setHeight:oe,setFocus:F,setReplyToMessage:re,addAttachment:Q,removeAttachment:Pe,clearAttachments:De,sendMessage:Me,cancelReply:ee,focusInput:St,handleAttachmentSelected:Je,handleContentSizeChange:ve,handleFocus:Ie,handleBlur:W}),[ae,oe,F,re,Q,Pe,De,Me,ee,St,Je,ve,Ie,W]),Go=_e.useMemo(()=>({textInputRef:D}),[]);return{state:Z,actions:Xe,refs:Go}},Nu=Ki(null);var Oe=$i(({value:C,onChangeText:S,onSend:T,onFocus:M,height:R,onContentSizeChange:A,replyToMessage:I,onCancelReply:P,onAttachmentSend:V},E)=>{let v=$(),B=Te(),k=qi(null);Yi(E,()=>({focus:()=>{k.current?.focus()}}));let{state:z,actions:D}=Jt({initialValue:C,initialHeight:R,onValueChange:S,onHeightChange:A,onSend:T,onAttachmentSend:V,onReplyCancel:P,onFocus:M});qo.useEffect(()=>{C!==z.value&&D.setValue(C)},[C,z.value,D]),qo.useEffect(()=>{R!==z.height&&D.setHeight(R)},[R,z.height,D]),qo.useEffect(()=>{I!==z.replyToMessage&&D.setReplyToMessage(I||null)},[I,z.replyToMessage,D]),qo.useEffect(()=>{if(I&&k.current){let j=setTimeout(()=>{k.current?.focus()},100);return()=>clearTimeout(j)}},[I]);let L=_i(j=>{if(console.log("Attachment selected:",j),V)V(j,C.trim()||void 0),C.trim()&&S("");else switch(j.type){case"image":console.log("Image attachment ready to send:",{uri:j.data.uri,dimensions:{width:j.data.width,height:j.data.height},fileName:j.data.fileName});break;case"document":console.log("Document attachment ready to send:",{name:j.data.name,size:j.data.size});break;case"location":console.log("Location attachment ready to send:",j.data.coordinates);break;case"contact":console.log("Contact attachment ready to send:",j.data);break;default:console.log("Other attachment ready to send:",j)}},[V,C,S]),O=$o(L);return<>
|
|
382
|
+
{I&&P&&<_t replyToMessage={I}onCancel={P}/>}
|
|
383
|
+
<Ds style={{borderTopWidth:1,borderTopColor:v.colors.borderLight,backgroundColor:v.colors.background}}>
|
|
384
|
+
<Ds style={{flexDirection:"row",alignItems:"center",backgroundColor:v.colors.background,paddingHorizontal:v.spacing.lg,paddingVertical:v.spacing.sm,minHeight:R}}>
|
|
385
|
+
<Vn style={{marginRight:v.spacing.md}}onPress={()=>O.menuRef.current?.show()}>
|
|
386
386
|
<Ji size={24}color={v.colors.textSecondary}/>
|
|
387
|
-
</
|
|
388
|
-
|
|
389
|
-
<
|
|
390
|
-
<
|
|
391
|
-
</
|
|
392
|
-
|
|
393
|
-
<
|
|
394
|
-
{
|
|
395
|
-
</
|
|
396
|
-
</
|
|
397
|
-
</
|
|
398
|
-
|
|
399
|
-
<
|
|
400
|
-
</>});Oe.displayName="MessageInput";import{View as
|
|
401
|
-
{
|
|
402
|
-
</
|
|
403
|
-
<
|
|
404
|
-
<
|
|
405
|
-
<
|
|
406
|
-
<
|
|
407
|
-
<
|
|
408
|
-
<
|
|
409
|
-
</
|
|
410
|
-
</
|
|
411
|
-
|
|
412
|
-
|
|
387
|
+
</Vn>
|
|
388
|
+
|
|
389
|
+
<Ds style={{flex:1,flexDirection:"row",alignItems:"center",borderRadius:v.borderRadius.full,backgroundColor:v.colors.surfaceSecondary,paddingHorizontal:v.spacing.lg,paddingVertical:6}}>
|
|
390
|
+
<Gi ref={k}style={{flex:1,fontSize:v.typography.fontSize.base,maxHeight:70,minHeight:18,paddingTop:Bn.OS==="ios"?6:3,paddingBottom:Bn.OS==="ios"?6:3,color:v.colors.text}}value={C}onChangeText={S}placeholder={B("input.placeholder")}placeholderTextColor={v.colors.textMuted}multiline maxLength={1e3}onFocus={M}onContentSizeChange={D.handleContentSizeChange}returnKeyType='default'textAlignVertical='center'/>
|
|
391
|
+
</Ds>
|
|
392
|
+
|
|
393
|
+
<Vn onPress={T}style={{marginLeft:v.spacing.md,height:40,width:40,alignItems:"center",justifyContent:"center",borderRadius:v.borderRadius.full,backgroundColor:C.trim()?v.colors.primary:v.colors.gray[300]}}disabled={!C.trim()}>
|
|
394
|
+
{C.trim()?<Xi size={18}color='white'/>:<Zi size={18}color='white'/>}
|
|
395
|
+
</Vn>
|
|
396
|
+
</Ds>
|
|
397
|
+
</Ds>
|
|
398
|
+
|
|
399
|
+
<Ct ref={O.menuRef}onOptionSelect={O.handleOptionSelect}options={O.options}/>
|
|
400
|
+
</>});Oe.displayName="MessageInput";import{View as Cm,TextInput as Mm,TouchableOpacity as Tm,Platform as Sm}from"react-native";import{Plus as Im,Send as Pm,Mic as Am}from"lucide-react-native";import Sl,{forwardRef as Rl}from"react";import al,{createContext as rl,useContext as il,useMemo as ll}from"react";import{useMemo as el,useCallback as tl}from"react";function Xt(C,S={}){let{initialNumToRender:T=20,maxToRenderPerBatch:M=10,windowSize:R=10}=S,A=el(()=>Do(C).reverse(),[C]),I=tl(P=>P.listItemType==="date-separator"?P.id:P.id.toString(),[]);return{messageItems:A,keyExtractor:I,flatListProps:{initialNumToRender:T,maxToRenderPerBatch:M,windowSize:R,inverted:!0,showsVerticalScrollIndicator:!1,keyboardShouldPersistTaps:"handled",removeClippedSubviews:!1,scrollEventThrottle:16}}}import{useState as ol,useCallback as Mt,useRef as kn}from"react";function Vs(C={}){let{scrollThreshold:S=50,autoScrollToBottom:T=!0}=C,M=kn(null),[R,A]=ol({isNearBottom:!0,isNearTop:!1,showScrollToBottomButton:!1}),I=kn(0),P=Mt(D=>{let{contentOffset:L,contentSize:O,layoutMeasurement:j}=D.nativeEvent,H=L.y,N=Math.abs(H)<S,F=Math.abs(H)>O.height-j.height-S;A({isNearBottom:N,isNearTop:F,showScrollToBottomButton:!N})},[S]),V=Mt(D=>{let L=D>I.current;return I.current=D,L},[]),E=Mt(()=>{},[]),v=Mt((D=!0)=>{M.current&&M.current.scrollToOffset({offset:0,animated:D})},[]),B=Mt((D,L=!0)=>{M.current&&M.current.scrollToOffset({offset:D,animated:L})},[]),k=Mt((D,L=!0)=>{M.current&&M.current.scrollToIndex({index:D,animated:L})},[]),z=Mt(D=>{V(D)&&T&&M.current&&setTimeout(()=>{v()},100)},[V,T,v]);return{flatListRef:M,scrollState:R,handleScroll:P,handleContentSizeChange:E,handleNewMessages:z,scrollToEnd:v,scrollToOffset:B,scrollToIndex:k}}import{useState as sl,useCallback as Bs}from"react";function Zt(C={}){let{enableMessageActions:S=!0}=C,[T,M]=sl({actionSheetVisible:!1,selectedMessage:null,messagePosition:void 0}),R=Bs((P,V)=>{S&&M({actionSheetVisible:!0,selectedMessage:P,messagePosition:V})},[S]),A=Bs(()=>{M({actionSheetVisible:!1,selectedMessage:null,messagePosition:void 0})},[]),I=Bs((P,V)=>{if(!T.selectedMessage)return;let{selectedMessage:E}=T;switch(P){case"reply":V?.onReply?.(E);break;case"copy":if(V?.onCopy)V.onCopy(E);else{let v=E.type==="image"&&E.imageData?E.text||"Image message":E.text;import("./clipboard-O4FPD4J6.mjs").then(({copyToClipboard:B})=>{B(v)}).catch(()=>{console.log("Clipboard functionality not available")})}break;case"delete":V?.onDelete?.(E.id);break;default:V?.onCustomAction?.(P,E);break}A()},[T.selectedMessage,A]);return{actionState:T,handleMessageLongPress:R,handleActionSheetClose:A,handleActionPress:I}}import{useState as Ln,useCallback as Qt}from"react";function eo(C={}){let{enableReactionDetails:S=!0}=C,[T,M]=Ln({isReactionDetailsVisible:!1,selectedReactions:[],selectedMessageText:""}),[R,A]=Ln(null),I=Qt(B=>{S&&B.reactions&&B.reactions.length>0&&(A(B),M({isReactionDetailsVisible:!0,selectedReactions:B.reactions,selectedMessageText:B.text}))},[S]),P=Qt(()=>{M({isReactionDetailsVisible:!1,selectedReactions:[],selectedMessageText:""}),A(null)},[]),V=Qt((B,k)=>{R&&k?.(R.id,B),P()},[R,P]),E=Qt((B,k)=>{R&&k?.(R.id,B),P()},[R,P]),v=Qt((B,k)=>{R&&k?.(R.id,B)},[R]);return{reactionState:T,selectedMessage:R,handleReactionPress:I,handleReactionDetailsClose:P,handleAddReaction:V,handleRemoveReaction:E,handleEmojiReact:v}}import{useState as nl,useCallback as jn}from"react";function ks(){let[C,S]=nl({replyToMessage:null}),T=jn(R=>{S({replyToMessage:R})},[]),M=jn(()=>{S({replyToMessage:null})},[]);return{replyState:C,setReplyToMessage:T,clearReply:M}}var En=rl(null);function jt(){let C=il(En);if(!C)throw new Error("useMessageListContext must be used within MessageListProvider");return C}function Co({children:C,messages:S,config:T={},...M}){let R=Xt(S,T),A=Vs(T),I=Zt(T),P=eo(T),V=ks();al.useEffect(()=>{A.handleNewMessages(S.length)},[S.length,A.handleNewMessages]);let E=ll(()=>({messageList:R,scroll:A,actions:I,reactions:P,reply:V,config:T,callbacks:M}),[R,A,I,P,V,T,M]);return<En.Provider value={E}>
|
|
401
|
+
{C}
|
|
402
|
+
</En.Provider>}import{useCallback as Yo}from"react";import{View as Cl,StyleSheet as Ml,FlatList as Tl}from"react-native";var Ge={Provider:Co,Container:({children:C,style:S})=><Cl style={[Fn.container,S]}>{C}</Cl>,Messages:({renderMessage:C,style:S})=>{let{messageList:T,scroll:M,actions:R,reactions:A,callbacks:I}=jt(),P=Yo(({item:E,index:v})=>C&&E.listItemType!=="date-separator"?C({message:E,index:v})||null:E.listItemType==="date-separator"?<Ko date={E.date}displayDate={E.displayDate}/>:<Oo message={E}onLongPress={R.handleMessageLongPress}onReactionPress={A.handleReactionPress}onReactionRemove={I.onReactionRemove}/>,[R.handleMessageLongPress,A.handleReactionPress,I.onReactionRemove,C]),V=Yo(E=>{M.handleScroll(E);let{isNearBottom:v,isNearTop:B}=M.scrollState;I.onScrollPositionChange?.(v,B),v&&I.onScrollToBottom?.(),B&&I.onScrollToTop?.()},[M.handleScroll,M.scrollState,I]);return<Tl ref={M.flatListRef}data={T.messageItems}renderItem={P}keyExtractor={T.keyExtractor}contentContainerStyle={[Fn.contentContainer,S]}onContentSizeChange={M.handleContentSizeChange}onScroll={V}{...T.flatListProps}/>},TypingIndicator:({isVisible:C})=>C?<Lt isVisible={C}/>:null,ScrollButton:({visible:C,isReplyActive:S,onPress:T})=>{let{scroll:M}=jt();return<Uo visible={C??M.scrollState.showScrollToBottomButton}onPress={T??M.scrollToEnd}isReplyActive={S}/>},ActionSheet:()=>{let{actions:C,reactions:S,reply:T,callbacks:M,config:R}=jt(),A=Yo(P=>{C.handleActionPress(P,{onReply:V=>{T.setReplyToMessage(V),M.onReplyMessage?.(V)},onDelete:M.onMessageDelete,onCustomAction:M.onActionPress})},[C.handleActionPress,T.setReplyToMessage,M]),I=Yo(P=>{console.log("\u{1F525} MessageListCompound - handleEmojiReact called with emoji:",P);let V=C.actionState.selectedMessage;console.log("\u{1F525} MessageListCompound - selectedMessage:",V?.id,"callbacks.onReactionAdd exists:",!!M.onReactionAdd),V&&M.onReactionAdd?(console.log("\u{1F525} MessageListCompound - Calling onReactionAdd for message:",V.id,"emoji:",P),M.onReactionAdd(V.id,P)):console.log("\u{1F525} MessageListCompound - NOT calling onReactionAdd. selectedMessage:",!!V,"callback exists:",!!M.onReactionAdd)},[C.actionState.selectedMessage,M.onReactionAdd]);return R.enableMessageActions?<Ho visible={C.actionState.actionSheetVisible}onClose={C.handleActionSheetClose}isMyMessage={C.actionState.selectedMessage?.isMe||!1}selectedMessage={C.actionState.selectedMessage||void 0}messagePosition={C.actionState.messagePosition}onActionPress={A}onEmojiReact={I}/>:null},ReactionDetails:()=>{let{reactions:C,callbacks:S,config:T}=jt();return T.enableReactionDetails?<No visible={C.reactionState.isReactionDetailsVisible}onClose={C.handleReactionDetailsClose}reactions={C.reactionState.selectedReactions}messageText={C.reactionState.selectedMessageText}onRemoveReaction={M=>C.handleRemoveReaction(M,S.onReactionRemove)}/>:null}},Fn=Ml.create({container:{flex:1},contentContainer:{paddingVertical:16}});var He=Rl(({messages:C,isTyping:S,showScrollToBottom:T=!1,isReplyActive:M=!1,...R},A)=>{let I={scrollThreshold:R.scrollThreshold,autoScrollToBottom:R.autoScrollToBottom,enableMessageActions:R.enableMessageActions,enableReactionDetails:R.enableReactionDetails},P={onScrollToBottom:R.onScrollToBottom,onScrollToTop:R.onScrollToTop,onScrollPositionChange:R.onScrollPositionChange,onReactionAdd:R.onReactionAdd,onReactionRemove:R.onReactionRemove,onMessageDelete:R.onMessageDelete,onReplyMessage:R.onReplyMessage,onActionPress:R.onActionPress};return Sl.useImperativeHandle(A,()=>({scrollToEnd:(V=!0)=>{},scrollToOffset:(V,E=!0)=>{},scrollToIndex:(V,E=!0)=>{}}),[]),<Co messages={C}config={I}{...P}>
|
|
403
|
+
<Ge.Container>
|
|
404
|
+
<Ge.Messages/>
|
|
405
|
+
<Ge.TypingIndicator isVisible={S}/>
|
|
406
|
+
<Ge.ScrollButton visible={T?void 0:!1}isReplyActive={M}/>
|
|
407
|
+
<Ge.ActionSheet/>
|
|
408
|
+
<Ge.ReactionDetails/>
|
|
409
|
+
</Ge.Container>
|
|
410
|
+
</Co>});He.displayName="MessageList";import wl,{useState as Il,useEffect as vl}from"react";import{View as Pl,Text as Al,ActivityIndicator as Dl,StyleSheet as Vl}from"react-native";var Bl=()=><Pl style={On.container}>
|
|
411
|
+
<Dl size="small"color="#007AFF"/>
|
|
412
|
+
<Al style={On.text}>Initializing...</Al>
|
|
413
|
+
</Pl>,On=Vl.create({container:{flex:1,justifyContent:"center",alignItems:"center",padding:20},text:{marginTop:8,fontSize:14,color:"#666"}});function Se(C){let S=wl.forwardRef((M,R)=>{let[,A]=Il(0),I=Rt();return vl(()=>{if(I==="pending"){let P=setInterval(()=>{Zo()!=="pending"&&(clearInterval(P),A(E=>E+1))},100);return()=>clearInterval(P)}},[I]),I==="pending"?<Bl/>:<C{...M}ref={R}/>}),T=C.displayName||C.name||"Component";return S.displayName=`RequireAuth(${T})`,S}function Be(C){return(...S)=>{if(Rt()==="pending")throw new Error("[UseChat SDK] SDK is still initializing. Make sure to await initChat() before rendering components that use this hook.");return C(...S)}}import{FlatList as Nl,RefreshControl as Wl}from"react-native";import{View as To,Text as _o,TouchableOpacity as Ol}from"react-native";import{View as Ls,Image as Ll,Text as El}from"react-native";var Fl=({avatar:C,isOnline:S=!1,size:T="medium"})=>{let M=$(),R=()=>{switch(T){case"small":return{width:32,height:32};case"large":return{width:64,height:64};default:return{width:48,height:48}}},A=()=>{switch(T){case"small":return{width:12,height:12};case"large":return{width:24,height:24};default:return{width:16,height:16}}},I=R(),P=A(),E=(()=>{switch(T){case"small":return 14;case"large":return 28;default:return 20}})();return<Ls style={{position:"relative"}}>
|
|
414
|
+
{C&&C.trim()!==""?<Ll source={{uri:C}}style={[I,{borderRadius:M.borderRadius.full}]}resizeMode="cover"/>:<Ls style={[I,{borderRadius:M.borderRadius.full,backgroundColor:M.colors.primary,justifyContent:"center",alignItems:"center"}]}>
|
|
415
|
+
<El style={{color:M.colors.background,fontSize:E,fontWeight:"600"}}>
|
|
413
416
|
👤
|
|
414
|
-
</
|
|
417
|
+
</El>
|
|
415
418
|
</Ls>}
|
|
416
419
|
|
|
417
420
|
{}
|
|
418
|
-
{
|
|
419
|
-
</Ls>},
|
|
421
|
+
{S&&<Ls style={[P,{position:"absolute",bottom:-2,right:-2,backgroundColor:M.colors.online,borderRadius:M.borderRadius.full,borderWidth:2,borderColor:M.colors.background}]}/>}
|
|
422
|
+
</Ls>},Mo=Fl;var Hl=({item:C,onPress:S})=>{let T=$(),M=C.unreadCount&&C.unreadCount>0;return<Ol style={{flexDirection:"row",alignItems:"center",paddingHorizontal:T.spacing.lg,paddingVertical:T.spacing.md,borderBottomWidth:1,borderBottomColor:T.colors.borderLight,backgroundColor:M?T.colors.unread:T.colors.background}}onPress={()=>S(C)}>
|
|
420
423
|
<To style={{marginRight:T.spacing.md}}>
|
|
421
|
-
<
|
|
424
|
+
<Mo avatar={C.avatar}isOnline={C.isOnline}size="medium"/>
|
|
422
425
|
</To>
|
|
423
426
|
|
|
424
427
|
<To style={{flex:1,marginRight:T.spacing.md}}>
|
|
425
428
|
{}
|
|
426
429
|
<To style={{flexDirection:"row",justifyContent:"space-between",alignItems:"center",marginBottom:T.spacing.xs}}>
|
|
427
|
-
|
|
428
|
-
{
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
{
|
|
432
|
-
|
|
430
|
+
<_o style={{fontSize:T.typography.fontSize.base,flex:1,fontWeight:M?T.typography.fontWeight.bold:T.typography.fontWeight.semibold,color:T.colors.text}}>
|
|
431
|
+
{C.name}
|
|
432
|
+
</_o>
|
|
433
|
+
<_o style={{fontSize:T.typography.fontSize.sm,marginLeft:T.spacing.sm,color:M?T.colors.gray[700]:T.colors.textSecondary,fontWeight:M?T.typography.fontWeight.medium:T.typography.fontWeight.normal}}>
|
|
434
|
+
{C.time}
|
|
435
|
+
</_o>
|
|
433
436
|
</To>
|
|
434
437
|
|
|
435
438
|
{}
|
|
436
439
|
<To style={{flexDirection:"row",alignItems:"center"}}>
|
|
437
|
-
|
|
438
|
-
{
|
|
439
|
-
|
|
440
|
-
{
|
|
441
|
-
|
|
442
|
-
{
|
|
443
|
-
|
|
440
|
+
<_o style={{fontSize:T.typography.fontSize.sm,flex:1,color:M?T.colors.gray[800]:T.colors.textSecondary,fontWeight:M?T.typography.fontWeight.medium:T.typography.fontWeight.normal}}numberOfLines={1}>
|
|
441
|
+
{C.message}
|
|
442
|
+
</_o>
|
|
443
|
+
{C.unreadCount&&<To style={{width:20,height:20,backgroundColor:T.colors.primary,borderRadius:T.borderRadius.full,alignItems:"center",justifyContent:"center",marginLeft:T.spacing.sm}}>
|
|
444
|
+
<_o style={{fontSize:T.typography.fontSize.xs,color:"white",fontWeight:T.typography.fontWeight.bold}}>
|
|
445
|
+
{C.unreadCount}
|
|
446
|
+
</_o>
|
|
444
447
|
</To>}
|
|
445
448
|
</To>
|
|
446
449
|
</To>
|
|
447
|
-
</
|
|
448
|
-
|
|
449
|
-
{
|
|
450
|
-
|
|
451
|
-
</
|
|
450
|
+
</Ol>},So=Hl;var Ul=({chats:C,onChatPress:S,onRefresh:T,refreshing:M=!1})=>{let R=({item:A})=><So item={A}onPress={S}/>;return<Nl data={C}renderItem={R}keyExtractor={A=>A.id}showsVerticalScrollIndicator={!1}style={{flex:1}}refreshControl={T?<Wl refreshing={M}onRefresh={T}tintColor="#007AFF"colors={["#007AFF"]}/>:void 0}/>},js=Ul;import{View as Kl,Text as $l}from"react-native";var ql=({title:C})=>{let S=$();return<Kl style={{backgroundColor:S.colors.background,paddingHorizontal:S.spacing.lg,paddingVertical:S.spacing.lg,borderBottomWidth:1,borderBottomColor:S.colors.borderLight}}>
|
|
451
|
+
<$l style={{fontSize:S.typography.fontSize.xxl,fontWeight:S.typography.fontWeight.bold,color:S.colors.text}}>
|
|
452
|
+
{C}
|
|
453
|
+
</$l>
|
|
454
|
+
</Kl>},Es=ql;import{View as Fs,TextInput as Yl,TouchableOpacity as _l}from"react-native";import{Search as Gl,X as Jl}from"lucide-react-native";var Xl=({value:C,onChangeText:S,onClear:T,placeholder:M})=>{let R=$(),I=Te()("search.placeholder");return<Fs style={{backgroundColor:R.colors.background,paddingHorizontal:R.spacing.lg,paddingVertical:R.spacing.md,borderBottomWidth:1,borderBottomColor:R.colors.borderLight}}>
|
|
452
455
|
<Fs style={{position:"relative"}}>
|
|
453
|
-
<Fs style={{position:"absolute",left:
|
|
454
|
-
<
|
|
456
|
+
<Fs style={{position:"absolute",left:R.spacing.md,top:"50%",transform:[{translateY:-10}],zIndex:10}}>
|
|
457
|
+
<Gl size={20}color={R.colors.textMuted}/>
|
|
455
458
|
</Fs>
|
|
456
459
|
|
|
457
|
-
<
|
|
460
|
+
<Yl value={C}onChangeText={S}placeholder={M||I}placeholderTextColor={R.colors.textMuted}style={{backgroundColor:R.colors.surfaceSecondary,borderRadius:R.borderRadius.full,paddingLeft:48,paddingRight:40,paddingVertical:R.spacing.md,color:R.colors.text,fontSize:R.typography.fontSize.base}}autoCapitalize="none"autoCorrect={!1}clearButtonMode="never"/>
|
|
458
461
|
|
|
459
|
-
{
|
|
460
|
-
<
|
|
461
|
-
</
|
|
462
|
+
{C.length>0&&<_l onPress={T}style={{position:"absolute",right:R.spacing.md,top:"50%",transform:[{translateY:-10}]}}hitSlop={{top:10,bottom:10,left:10,right:10}}>
|
|
463
|
+
<Jl size={20}color={R.colors.textMuted}/>
|
|
464
|
+
</_l>}
|
|
462
465
|
</Fs>
|
|
463
|
-
</Fs>},Os=
|
|
466
|
+
</Fs>},Os=Xl;import{useState as Zl,useCallback as Et}from"react";import Hs from"dayjs";var Tt=Hs(),Hn=Tt.subtract(1,"day"),Nn=Tt.subtract(2,"day"),Wn=Tt.subtract(3,"day"),Ql=[{id:1,text:"Hi! How are you?",isMe:!1,timestamp:Wn.hour(10).minute(30).toISOString(),senderName:"Anna"},{id:2,text:"Hey! Great, thanks! And you?",isMe:!0,timestamp:Wn.hour(10).minute(31).toISOString(),reactions:[{emoji:"\u2764\uFE0F",count:1,users:["anna"]}]},{id:3,text:"Good too! What are we doing tonight?",isMe:!1,timestamp:Nn.hour(14).minute(20).toISOString(),senderName:"Anna"},{id:4,text:"Maybe we could go to the movies?",isMe:!0,timestamp:Nn.hour(14).minute(25).toISOString(),reactions:[{emoji:"\u{1F44D}",count:2,users:["anna","me"]},{emoji:"\u{1F3AC}",count:1,users:["anna"]}]},{id:5,text:"Good idea! I'll check the showtimes",isMe:!1,timestamp:Hn.hour(9).minute(15).toISOString(),senderName:"Anna"},{id:6,text:"Great! What movies are you interested in?",isMe:!0,timestamp:Hn.hour(9).minute(20).toISOString()},{id:7,text:"Maybe something action or comedy?",isMe:!1,timestamp:Tt.hour(8).minute(30).toISOString(),senderName:"Anna",reactions:[{emoji:"\u{1F602}",count:1,users:["me"]},{emoji:"\u{1F3AD}",count:1,users:["anna"]}]},{id:8,text:"Sounds great! I'll check what's playing",isMe:!0,timestamp:Tt.hour(8).minute(35).toISOString()},{id:9,text:"Perfect! What time should we meet?",isMe:!1,timestamp:Tt.hour(9).minute(10).toISOString(),senderName:"Anna",replyTo:{id:8,text:"Sounds great! I'll check what's playing",senderName:void 0,isMe:!0,type:"text"}},{id:10,text:"How about 7:00 PM? The show is at 8:00 PM",isMe:!0,timestamp:Tt.hour(9).minute(15).toISOString(),reactions:[{emoji:"\u{1F44D}",count:1,users:["anna"]},{emoji:"\u23F0",count:1,users:["me"]}]}],Ns=C=>{let S=Ql.map(v=>v.isMe?v:{...v,senderName:C||v.senderName}),[T,M]=Zl(S),R=Et((v,B)=>{if(console.log("sendMessage called with text:",v,"and replyTo:",B),!v.trim())return;let k={id:Date.now(),text:v.trim(),isMe:!0,timestamp:Hs().toISOString(),status:"sent",replyTo:B};M(z=>[...z,k]),setTimeout(()=>{M(z=>z.map(D=>D.id===k.id?{...D,status:"delivered"}:D))},1e3),setTimeout(()=>{M(z=>z.map(D=>D.id===k.id?{...D,status:"read"}:D))},3e3)},[]),A=Et((v,B,k)=>{let z={id:Date.now(),text:B||"",isMe:!0,timestamp:Hs().toISOString(),status:"sent",type:"image",imageData:v,replyTo:k};M(D=>[...D,z]),setTimeout(()=>{M(D=>D.map(L=>L.id===z.id?{...L,status:"delivered"}:L))},1e3),setTimeout(()=>{M(D=>D.map(L=>L.id===z.id?{...L,status:"read"}:L))},3e3)},[]),I=Et((v,B)=>{M(k=>k.map(z=>z.id===v?{...z,status:B}:z))},[]),P=Et((v,B)=>{M(k=>k.map(z=>{if(z.id===v){let D=z.reactions||[],L=D.findIndex(O=>O.emoji===B);if(L>=0){let O=[...D];return O[L]={...O[L],count:O[L].count+1,users:[...O[L].users,"me"]},{...z,reactions:O}}else{let O={emoji:B,count:1,users:["me"]};return{...z,reactions:[...D,O]}}}return z}))},[]),V=Et((v,B)=>{console.log("removeReaction 1212121 called with messageId:",v,"and emoji:",B),M(k=>k.map(z=>{if(z.id===v){let D=z.reactions||[],L=D.findIndex(O=>O.emoji===B);if(L>=0){let O=D[L];if(O.count>1){let j=[...D];return j[L]={...O,count:O.count-1,users:O.users.filter(H=>H!=="me")},{...z,reactions:j}}else return{...z,reactions:D.filter(j=>j.emoji!==B)}}}return z}))},[]),E=Et(v=>{console.log("deleteMessage called with messageId:",v),M(B=>{let k=B.map(z=>z.id===v?{...z,deleted:!0}:z);return console.log("Message marked as deleted:",v),k})},[]);return{messages:T,sendMessage:R,sendImageMessage:A,updateMessageStatus:I,addReaction:P,deleteMessage:E,removeReaction:V}};import{useState as Un,useCallback as Fe}from"react";var Ws=(C={})=>{Rt();let[S,T]=Un(C.initialMessages||[]),[M,R]=Un(!1),A=Fe((D,L)=>{let O={id:Date.now(),text:D,isMe:!0,timestamp:new Date().toISOString(),status:"sent",replyTo:L?{id:L.id,text:L.text,senderName:L.senderName,isMe:L.isMe}:void 0};T(j=>[O,...j])},[]),I=Fe(D=>{T(L=>[D,...L])},[]),P=Fe((D,L)=>{T(O=>O.map(j=>j.id===D?{...j,...L}:j))},[]),V=Fe(D=>{T(L=>L.filter(O=>O.id!==D))},[]),E=Fe((D,L)=>{T(O=>O.map(j=>{if(j.id!==D)return j;let H=j.reactions||[];if(H.find(F=>F.emoji===L))return{...j,reactions:H.map(F=>F.emoji===L?{...F,count:F.count+1,users:[...F.users,"current-user"]}:F)};{let F={emoji:L,count:1,users:["current-user"]};return{...j,reactions:[...H,F]}}}))},[]),v=Fe((D,L)=>{T(O=>O.map(j=>{if(j.id!==D)return j;let H=j.reactions||[],N=H.find(F=>F.emoji===L);return N?N.count<=1?{...j,reactions:H.filter(F=>F.emoji!==L)}:{...j,reactions:H.map(F=>F.emoji===L?{...F,count:F.count-1,users:F.users.filter(G=>G!=="current-user")}:F)}:j}))},[]),B=Fe(D=>{R(D)},[]),k=Fe(()=>{T(C.initialMessages||[]),R(!1)},[C.initialMessages]),z=Fe(D=>S.find(L=>L.id===D),[S]);return{messages:S,isTyping:M,sendMessage:A,addReaction:E,removeReaction:v,setMessages:T,addMessage:I,updateMessage:P,deleteMessage:V,setTyping:B,resetChat:k,getMessageById:z}};import{useState as Mp,useCallback as Tp,useRef as Sp,useEffect as Rp}from"react";var Kn=()=>{let C=Te(),S=()=>"en";return{formatDate:P=>en(P,C,S()),formatTime:P=>$t(P,S()),formatRelative:P=>tn(P,S()),formatDateTimeWithTime:P=>on(P,C,S()),groupMessages:P=>Do(P,S())}};var Zp=Se(ns),Qp=Se(es),eh=Be(Nt),oh=Se(He),sh=Se(Oe),ah=Se(zo),ih=Se(Lt),ch=Se(js),dh=Se(So),uh=Se(Es),mh=Se(Os),hh=Se(Mo),fh=Se(Ct),bh=Se(Qs),Ch=Be($),wh=Be(Ws),Ih=Be(Ns),vh=Be(Xt),Ph=Be(Zt),Ah=Be(eo),zh=Be(Ut),Vh=Be(Jt),kh=Be(Kn);export{fh as AttachmentMenu,Zp as Chat,hh as ChatAvatar,uh as ChatHeader,dh as ChatItem,ch as ChatList,mh as ChatListSearchBar,Qp as ChatProvider,ah as ChatScreenHeader,Po as I18nProvider,sh as MessageInput,oh as MessageList,bh as ThemeProvider,ih as TypingIndicator,Kt as defaultTheme,wo as defaultTranslations,$n as getAuthState,Zo as getInitStatus,qn as getProjectId,Ht as getTranslation,_n as initChat,Jo as isInitialized,Xo as isInitializing,Io as isSupportedLocale,zh as useAttachments,eh as useChatConfig,Ih as useChatMessages,wh as useChatSDK,kh as useDateFormatter,Ph as useMessageActions,Vh as useMessageInput,vh as useMessageList,Ah as useMessageReactions,Ch as useTheme,_s as useTranslation,Te as useTranslationFunction};
|