UNPKG

@connectycube/use-chat

Version:

A React hook for state management in ConnectyCube-powered chat solutions

3 lines (2 loc) 22.9 kB
import{jsx as t}from"react/jsx-runtime";import e,{useState as a,useRef as n,useEffect as r,useCallback as i,createContext as s,useContext as o}from"react";import{PrivacyListAction as c,ChatEvent as d,ChatType as u,DialogType as l}from"connectycube/types";import h from"connectycube";var m,f,g;function _(t){return t&&t.__esModule&&Object.prototype.hasOwnProperty.call(t,"default")?t.default:t}!function(t){t.ADDED_TO_DIALOG="dialog/ADDED_TO_DIALOG",t.REMOVED_FROM_DIALOG="dialog/REMOVED_FROM_DIALOG",t.ADD_PARTICIPANTS="dialog/ADD_PARTICIPANTS",t.REMOVE_PARTICIPANTS="dialog/REMOVE_PARTICIPANTS",t.NEW_DIALOG="dialog/NEW_DIALOG"}(m||(m={}));var p=_(function(){if(g)return f;g=1;var t=e;return f=function(e){var a=t.useState(e),n=a[0],r=a[1],i=t.useRef(n);return[n,t.useCallback((function(t){i.current=function(t){return"function"==typeof t}(t)?t(i.current):t,r(i.current)}),[]),i]}}());const y=43200,w=Symbol.for("constructDateFrom");function v(t,e){return"function"==typeof t?t(e):t&&"object"==typeof t&&w in t?t[w](e):t instanceof Date?new t.constructor(e):new Date(e)}function b(t,e){return v(t,t)}let D={};function M(){return D}function A(t){const e=b(t),a=new Date(Date.UTC(e.getFullYear(),e.getMonth(),e.getDate(),e.getHours(),e.getMinutes(),e.getSeconds(),e.getMilliseconds()));return a.setUTCFullYear(e.getFullYear()),+t-+a}function S(t,...e){const a=v.bind(null,t||e.find((t=>"object"==typeof t)));return e.map(a)}function E(t,e){const a=+b(t)-+b(e);return a<0?-1:a>0?1:a}function T(t,e){const a=b(t);return+function(t){const e=b(t);return e.setHours(23,59,59,999),e}(a)==+function(t){const e=b(t),a=e.getMonth();return e.setFullYear(e.getFullYear(),a+1,0),e.setHours(23,59,59,999),e}(a)}function P(t,e,a){const[n,r,i]=S(a?.in,t,t,e),s=E(r,i),o=Math.abs(function(t,e,a){const[n,r]=S(a?.in,t,e);return 12*(n.getFullYear()-r.getFullYear())+(n.getMonth()-r.getMonth())}(r,i));if(o<1)return 0;1===r.getMonth()&&r.getDate()>27&&r.setDate(30),r.setMonth(r.getMonth()-s*o);let c=E(r,i)===-s;T(n)&&1===o&&1===E(n,i)&&(c=!1);const d=s*(o-+c);return 0===d?0:d}function O(t,e,a){const n=function(t,e){return+b(t)-+b(e)}(t,e)/1e3;return(r=a?.roundingMethod,t=>{const e=(r?Math[r]:Math.trunc)(t);return 0===e?0:e})(n);var r}const C={lessThanXSeconds:{one:"less than a second",other:"less than {{count}} seconds"},xSeconds:{one:"1 second",other:"{{count}} seconds"},halfAMinute:"half a minute",lessThanXMinutes:{one:"less than a minute",other:"less than {{count}} minutes"},xMinutes:{one:"1 minute",other:"{{count}} minutes"},aboutXHours:{one:"about 1 hour",other:"about {{count}} hours"},xHours:{one:"1 hour",other:"{{count}} hours"},xDays:{one:"1 day",other:"{{count}} days"},aboutXWeeks:{one:"about 1 week",other:"about {{count}} weeks"},xWeeks:{one:"1 week",other:"{{count}} weeks"},aboutXMonths:{one:"about 1 month",other:"about {{count}} months"},xMonths:{one:"1 month",other:"{{count}} months"},aboutXYears:{one:"about 1 year",other:"about {{count}} years"},xYears:{one:"1 year",other:"{{count}} years"},overXYears:{one:"over 1 year",other:"over {{count}} years"},almostXYears:{one:"almost 1 year",other:"almost {{count}} years"}};function I(t){return(e={})=>{const a=e.width?String(e.width):t.defaultWidth;return t.formats[a]||t.formats[t.defaultWidth]}}const L={date:I({formats:{full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},defaultWidth:"full"}),time:I({formats:{full:"h:mm:ss a zzzz",long:"h:mm:ss a z",medium:"h:mm:ss a",short:"h:mm a"},defaultWidth:"full"}),dateTime:I({formats:{full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},defaultWidth:"full"})},R={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"};function W(t){return(e,a)=>{let n;if("formatting"===(a?.context?String(a.context):"standalone")&&t.formattingValues){const e=t.defaultFormattingWidth||t.defaultWidth,r=a?.width?String(a.width):e;n=t.formattingValues[r]||t.formattingValues[e]}else{const e=t.defaultWidth,r=a?.width?String(a.width):t.defaultWidth;n=t.values[r]||t.values[e]}return n[t.argumentCallback?t.argumentCallback(e):e]}}function N(t){return(e,a={})=>{const n=a.width,r=n&&t.matchPatterns[n]||t.matchPatterns[t.defaultMatchWidth],i=e.match(r);if(!i)return null;const s=i[0],o=n&&t.parsePatterns[n]||t.parsePatterns[t.defaultParseWidth],c=Array.isArray(o)?function(t,e){for(let a=0;a<t.length;a++)if(e(t[a]))return a;return}(o,(t=>t.test(s))):function(t,e){for(const a in t)if(Object.prototype.hasOwnProperty.call(t,a)&&e(t[a]))return a;return}(o,(t=>t.test(s)));let d;d=t.valueCallback?t.valueCallback(c):c,d=a.valueCallback?a.valueCallback(d):d;return{value:d,rest:e.slice(s.length)}}}var k;const x={code:"en-US",formatDistance:(t,e,a)=>{let n;const r=C[t];return n="string"==typeof r?r:1===e?r.one:r.other.replace("{{count}}",e.toString()),a?.addSuffix?a.comparison&&a.comparison>0?"in "+n:n+" ago":n},formatLong:L,formatRelative:(t,e,a,n)=>R[t],localize:{ordinalNumber:(t,e)=>{const a=Number(t),n=a%100;if(n>20||n<10)switch(n%10){case 1:return a+"st";case 2:return a+"nd";case 3:return a+"rd"}return a+"th"},era:W({values:{narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},defaultWidth:"wide"}),quarter:W({values:{narrow:["1","2","3","4"],abbreviated:["Q1","Q2","Q3","Q4"],wide:["1st quarter","2nd quarter","3rd quarter","4th quarter"]},defaultWidth:"wide",argumentCallback:t=>t-1}),month:W({values:{narrow:["J","F","M","A","M","J","J","A","S","O","N","D"],abbreviated:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],wide:["January","February","March","April","May","June","July","August","September","October","November","December"]},defaultWidth:"wide"}),day:W({values:{narrow:["S","M","T","W","T","F","S"],short:["Su","Mo","Tu","We","Th","Fr","Sa"],abbreviated:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],wide:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"]},defaultWidth:"wide"}),dayPeriod:W({values:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"morning",afternoon:"afternoon",evening:"evening",night:"night"}},defaultWidth:"wide",formattingValues:{narrow:{am:"a",pm:"p",midnight:"mi",noon:"n",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},abbreviated:{am:"AM",pm:"PM",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"},wide:{am:"a.m.",pm:"p.m.",midnight:"midnight",noon:"noon",morning:"in the morning",afternoon:"in the afternoon",evening:"in the evening",night:"at night"}},defaultFormattingWidth:"wide"})},match:{ordinalNumber:(k={matchPattern:/^(\d+)(th|st|nd|rd)?/i,parsePattern:/\d+/i,valueCallback:t=>parseInt(t,10)},(t,e={})=>{const a=t.match(k.matchPattern);if(!a)return null;const n=a[0],r=t.match(k.parsePattern);if(!r)return null;let i=k.valueCallback?k.valueCallback(r[0]):r[0];return i=e.valueCallback?e.valueCallback(i):i,{value:i,rest:t.slice(n.length)}}),era:N({matchPatterns:{narrow:/^(b|a)/i,abbreviated:/^(b\.?\s?c\.?|b\.?\s?c\.?\s?e\.?|a\.?\s?d\.?|c\.?\s?e\.?)/i,wide:/^(before christ|before common era|anno domini|common era)/i},defaultMatchWidth:"wide",parsePatterns:{any:[/^b/i,/^(a|c)/i]},defaultParseWidth:"any"}),quarter:N({matchPatterns:{narrow:/^[1234]/i,abbreviated:/^q[1234]/i,wide:/^[1234](th|st|nd|rd)? quarter/i},defaultMatchWidth:"wide",parsePatterns:{any:[/1/i,/2/i,/3/i,/4/i]},defaultParseWidth:"any",valueCallback:t=>t+1}),month:N({matchPatterns:{narrow:/^[jfmasond]/i,abbreviated:/^(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i,wide:/^(january|february|march|april|may|june|july|august|september|october|november|december)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^j/i,/^f/i,/^m/i,/^a/i,/^m/i,/^j/i,/^j/i,/^a/i,/^s/i,/^o/i,/^n/i,/^d/i],any:[/^ja/i,/^f/i,/^mar/i,/^ap/i,/^may/i,/^jun/i,/^jul/i,/^au/i,/^s/i,/^o/i,/^n/i,/^d/i]},defaultParseWidth:"any"}),day:N({matchPatterns:{narrow:/^[smtwf]/i,short:/^(su|mo|tu|we|th|fr|sa)/i,abbreviated:/^(sun|mon|tue|wed|thu|fri|sat)/i,wide:/^(sunday|monday|tuesday|wednesday|thursday|friday|saturday)/i},defaultMatchWidth:"wide",parsePatterns:{narrow:[/^s/i,/^m/i,/^t/i,/^w/i,/^t/i,/^f/i,/^s/i],any:[/^su/i,/^m/i,/^tu/i,/^w/i,/^th/i,/^f/i,/^sa/i]},defaultParseWidth:"any"}),dayPeriod:N({matchPatterns:{narrow:/^(a|p|mi|n|(in the|at) (morning|afternoon|evening|night))/i,any:/^([ap]\.?\s?m\.?|midnight|noon|(in the|at) (morning|afternoon|evening|night))/i},defaultMatchWidth:"any",parsePatterns:{any:{am:/^a/i,pm:/^p/i,midnight:/^mi/i,noon:/^no/i,morning:/morning/i,afternoon:/afternoon/i,evening:/evening/i,night:/night/i}},defaultParseWidth:"any"})},options:{weekStartsOn:0,firstWeekContainsDate:1}};function U(t,e){return function(t,e,a){const n=M(),r=a?.locale??n.locale??x,i=E(t,e);if(isNaN(i))throw new RangeError("Invalid time value");const s=Object.assign({},a,{addSuffix:a?.addSuffix,comparison:i}),[o,c]=S(a?.in,...i>0?[e,t]:[t,e]),d=O(c,o),u=(A(c)-A(o))/1e3,l=Math.round((d-u)/60);let h;if(l<2)return a?.includeSeconds?d<5?r.formatDistance("lessThanXSeconds",5,s):d<10?r.formatDistance("lessThanXSeconds",10,s):d<20?r.formatDistance("lessThanXSeconds",20,s):d<40?r.formatDistance("halfAMinute",0,s):d<60?r.formatDistance("lessThanXMinutes",1,s):r.formatDistance("xMinutes",1,s):0===l?r.formatDistance("lessThanXMinutes",1,s):r.formatDistance("xMinutes",l,s);if(l<45)return r.formatDistance("xMinutes",l,s);if(l<90)return r.formatDistance("aboutXHours",1,s);if(l<1440){const t=Math.round(l/60);return r.formatDistance("aboutXHours",t,s)}if(l<2520)return r.formatDistance("xDays",1,s);if(l<y){const t=Math.round(l/1440);return r.formatDistance("xDays",t,s)}if(l<86400)return h=Math.round(l/y),r.formatDistance("aboutXMonths",h,s);if(h=P(c,o),h<12){const t=Math.round(l/y);return r.formatDistance("xMonths",t,s)}{const t=h%12,e=Math.trunc(h/12);return t<3?r.formatDistance("aboutXYears",e,s):t<9?r.formatDistance("overXYears",e,s):r.formatDistance("almostXYears",e+1,s)}}(t,function(t){return v(t,Date.now())}(t),e)}const F="[useChat][useBlockList]",G="ConnectyCubeBlockList";function Y(t){const[e,i]=a(new Set),s=n(!1),o=t=>e.has(t),d=async(a,n)=>{if(!t)return void console.warn(`${F}[upsert]: ${n} user ${a} failed, chat is not connected`);const r=new Set(e),o={name:G,items:[{user_id:a,action:n,mutualBlock:!0}]};try{n===c.DENY?r.add(a):n===c.ALLOW&&r.delete(a),s.current?(await h.chat.privacylist.setAsDefault(null),await h.chat.privacylist.update(o),r.size>0&&await h.chat.privacylist.setAsDefault(G)):(await h.chat.privacylist.create(o),await h.chat.privacylist.setAsDefault(G))}catch(t){return}finally{i(r)}};return r((()=>{t&&(async()=>{if(!t)return void console.warn(`${F}[fetch]: chat is not connected`);if((await h.chat.privacylist.getNames()).default===G){const t=(await h.chat.privacylist.getList(G)).items.reduce(((t,e)=>(e.action===c.DENY&&t.add(+e.user_id),t)),new Set);s.current=!0,i(t)}})()}),[t]),{blockedUsers:Array.from(e),isBlockedUser:o,unblockUser:async t=>{o(t)?await d(t,c.ALLOW):console.warn(`${F}[unblock]: user ${t} is not blocked`)},blockUser:async t=>{o(t)?console.warn(`${F}[block]: user ${t} is already blocked`):await d(t,c.DENY)}}}const j=t=>{let e;if("string"==typeof t){const a=new Date(t).getTime();e=isNaN(a)?void 0:a}else"number"==typeof t&&(e=1e3*t);return e},V=t=>{let e;if(t<=30)e="Online";else if(t<3600)e=`Last seen ${Math.ceil(t/60)} minutes ago`;else if(t<86400)e=`Last seen ${Math.ceil(t/3600)} hours ago`;else{const a=new Date(Date.now()-1e3*t);e=`Last seen ${a.getUTCDate()}/${(a.getMonth()+1).toString().padStart(2,"0")}/${a.getFullYear()}`}return e},$="[useChat][useUsers]",X=100;function H(t){const[e,s,o]=p({}),[c,u]=a({}),[l,m]=a(0),[f,g]=a({}),_=n(0),y=i((async e=>{const{items:a}=await h.users.getV2({full_name:{start_with:e},limit:X}),{items:n}=await h.users.getV2({login:{start_with:e},limit:X}),r=new Map;return[...a,...n].forEach((t=>{r.set(t.id,t)})),Array.from(r.values()).filter((e=>e.id!==t))}),[t]),w=async()=>{let t=l;try{const{count:e}=await h.users.getOnlineCount();t=e,m(t)}catch(t){console.error(`${$}[getOnlineCount][Error]:`,t)}return t};return r((()=>(h.chat.addListener(d.USER_LAST_ACTIVITY,((t,e)=>{if("number"==typeof t&&e>=0){const a=V(e);g((e=>({...e,[t]:a})))}})),()=>{h.chat.removeListener(d.USER_LAST_ACTIVITY)})),[]),{_retrieveAndStoreUsers:async t=>{const a=t.filter((t=>!e[t]));if(a.length>0){const t={limit:X,id:{in:a}},{items:e}=await h.users.getV2(t),n=e.reduce(((t,e)=>(t[e.id]=e,t)),{...o.current});s(n)}},exports:{users:e,searchUsers:y,listOnlineUsers:async(t=!1)=>{const e=_.current,a=Date.now();let n=c;return(a-e>6e4||t)&&(n=await(async()=>{const t=await w(),e=[];let a={};try{let n=X,r=0;for(;r<t;)e.push(h.users.listOnline({limit:n,offset:r}).then((({users:t})=>t))),r+=n;a=(await Promise.all(e)).flat().reduce(((t,e)=>(t[e.id]=e,t)),{}),s({...o.current,...a}),u(a)}catch(t){console.error(`${$}[listOnline][Error]:`,t)}return a})(),_.current=Date.now()),Object.values(n)},listOnlineUsersWithParams:async t=>{let e={};try{const{users:a}=await h.users.listOnline(t);e=a.reduce(((t,e)=>(t[e.id]=e,t)),{}),s({...o.current,...e}),u(e)}catch(t){console.error(`${$}[listOnlineWithParams][Error]:`,t)}return Object.values(e)},onlineUsers:Object.values(c),getOnlineUsersCount:w,onlineUsersCount:l,lastActivity:f,getLastActivity:async t=>{let e="Last seen recently";try{const{seconds:a}=await h.chat.getLastUserActivity(t);e=V(a)}catch(t){console.error(`${$}[getLastActivity][Error]:`,t)}finally{return g((a=>({...a,[t]:e}))),e}},subscribeToUserLastActivityStatus:t=>{h.chat.subscribeToUserLastActivityStatus(t)},unsubscribeFromUserLastActivityStatus:t=>{h.chat.unsubscribeFromUserLastActivityStatus(t)}}}}const z=s(void 0);z.displayName="ChatContext";const J=()=>{const t=o(z);if(!t)throw new Error("useChat must be within ChatProvider");return t},q=({children:e})=>{const[i,s]=a(navigator.onLine),[o,c]=a(!1),[f,g]=a({total:0}),[_,y]=a({}),[w,v]=a({}),[b,D]=a({}),M=n({}),A=n(null),S=n(null),E=n({}),[T,P,O]=p([]),[C,I,L]=p(),[R,W,N]=p(),k=Y(o),x=H(C),{_retrieveAndStoreUsers:F}=x,G=async t=>{const e={chat_dialog_id:t,sort_desc:"date_sent",limit:100,skip:0};try{const a=(await h.chat.message.list(e)).items.sort(((t,e)=>t._id.toString().localeCompare(e._id.toString()))).map((t=>{const e=t.attachments?.map((t=>({...t,url:h.storage.privateUrl(t.uid)})));return{...t,attachments:e}}));return y((e=>({...e,[t]:a}))),a}catch(e){if(404===e.code)return y((e=>({...e,[t]:[]}))),[];throw e}},V=t=>{if(t??=R,!t)throw"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.";if(t.type!==l.PRIVATE)return;const e=t.occupants_ids.filter((t=>t!==C))[0];return E.current[e]=t._id,e},$=async t=>{const e={read:1,chat_dialog_id:t._id};await h.chat.message.update("",e),P((e=>e.map((e=>e._id===t._id?{...e,unread_messages_count:0}:e))))},X=(t,e,a,n)=>{const r={type:a.type===l.PRIVATE?u.CHAT:u.GROUPCHAT,body:t,extension:{save_to_history:1,dialog_id:a._id}};e&&(r.extension.attachments=e);return h.chat.send(a.type===l.PRIVATE?n:a._id,r)},J=(t,e,a,n,r,i,s)=>{const o=Math.round((new Date).getTime()/1e3);P((t=>t.map((t=>t._id===a?{...t,last_message:e,last_message_user_id:n,last_message_date_sent:o}:t)).sort(((t,e)=>{const a=j(t.last_message_date_sent)||j(t.created_at);return(j(e.last_message_date_sent)||j(e.created_at))-a})))),y((c=>({...c,[a]:[...c[a]||[],{_id:t,created_at:o,updated_at:o,chat_dialog_id:a,message:e,sender_id:n,recipient_id:r,date_sent:o,read:0,read_ids:[n],delivered_ids:[n],views_count:0,attachments:i||[],reactions:{},isLoading:s}]})))},q=(t,e,a,n={})=>{const r={body:t,extension:{dialogId:e,...n}};h.chat.sendSystemMessage(a,r)},B=(t,e,a)=>{v((n=>{const r=n[t],i=r?new Set(r):new Set;return a?i.add(e):i.delete(e),{...n,[t]:[...i]}}))},Q=(t,e)=>{B(t,e,!1),clearTimeout(M.current[t][e]),delete M.current[t][e]};r((()=>{const t=new AbortController,e=new AbortController;return window.addEventListener("online",(()=>{s(!0)}),{signal:t.signal}),window.addEventListener("offline",(()=>{s(!1),D({})}),{signal:e.signal}),()=>{t.abort(),e.abort()}}),[]);const K=()=>{D({})},Z=()=>{console.log("[useChat] Reconnected")},tt=(t,e)=>{if(t===L.current)return;const a=N.current,n=e.dialog_id,r=e.id,i=e.body||"",s=e.type===u.CHAT?L.current:void 0,o=e.extension.attachments?.length>0?e.extension.attachments.map((t=>({...t,url:h.storage.privateUrl(t.uid)}))):void 0;J(r,i,n,t,s,o),Q(n,t),P((t=>t.map((t=>t._id===n?{...t,unread_messages_count:a&&a._id===e.dialog_id?t.unread_messages_count:(t.unread_messages_count||0)+1,last_message:e.body,last_message_date_sent:parseInt(e.extension.date_sent)}:t)))),A.current&&A.current(t,e)},et=(t,e)=>{S.current&&S.current(t,e)},at=async t=>{const e=t.extension.dialogId,a=t.userId;if(a!==L.current)switch(t.body){case m.NEW_DIALOG:case m.ADDED_TO_DIALOG:{const t=(await h.chat.dialog.list({_id:e})).items[0];F(t.occupants_ids),P((e=>[t,...e.filter((e=>e._id!==t._id))]));break}case m.ADD_PARTICIPANTS:{const a=t.extension.addedParticipantsIds.split(",").map(Number);F(a),P((t=>t.map((t=>(t._id===e&&(t.occupants_ids=Array.from(new Set([...t.occupants_ids,...a]))),t)))));break}case m.REMOVE_PARTICIPANTS:{const a=t.extension.removedParticipantsIds.split(",").map(Number);P((t=>t.map((t=>(t._id===e&&(t.occupants_ids=t.occupants_ids.filter((t=>!a.includes(t)))),t)))));break}case m.REMOVED_FROM_DIALOG:P((t=>t.map((t=>(t._id===e&&t.type!==l.PRIVATE&&(t.occupants_ids=t.occupants_ids.filter((t=>t!==a))),t)))))}},nt=(t,e,a)=>{a!==L.current&&y((n=>((n[e]||[]).forEach((e=>{e._id===t&&0===e.read&&(e.read=1,e.read_ids?.push(a))})),n)))},rt=(t,e,a)=>{const n=a||(t=>{let e=E.current[t];if(!e){const a=O.current.find((e=>e.type===l.PRIVATE&&V(e)===t));a&&(e=a._id,E.current[t]=e)}return e})(e);n&&e&&e!==L.current&&(B(n,e,t),M.current[n]||(M.current[n]={}),t?(M.current[n]?.[e]&&(clearTimeout(M.current[n][e]),delete M.current[n][e]),M.current[n][e]=setTimeout((()=>{Q(n,e)}),6e3)):Q(n,e))};return r((()=>(h.chat.addListener(d.DISCONNECTED,K),h.chat.addListener(d.RECONNECTED,Z),h.chat.addListener(d.MESSAGE,tt),h.chat.addListener(d.ERROR_MESSAGE,et),h.chat.addListener(d.SYSTEM_MESSAGE,at),h.chat.addListener(d.READ_MESSAGE,nt),h.chat.addListener(d.TYPING_MESSAGE,rt),()=>{h.chat.removeAllListeners()})),[]),r((()=>{(()=>{const t={total:0};T.forEach((({_id:e,unread_messages_count:a=0})=>{e!==R?._id&&(t[e]=a,t.total+=a)})),g(t)})()}),[T]),t(z.Provider,{value:{isOnline:i,connect:async t=>{try{const e=await h.chat.connect(t);e&&(c(e),I(t.userId))}catch(t){console.error(`Failed to connect due to ${t}`)}},isConnected:o,disconnect:()=>{h.chat.isConnected&&(h.chat.disconnect(),I(void 0),c(!1))},currentUserId:C,selectDialog:async t=>{W(t),t&&(b[t._id]||(await G(t._id),D({...b,[t._id]:!0})),t.unread_messages_count>0&&await $(t).catch((t=>{})))},selectedDialog:R,getDialogOpponentId:V,unreadMessagesCount:f,getMessages:G,messages:_,sendMessage:(t,e)=>{if(e??=R,!e)throw"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.";const a=V(e),n=X(t,null,e,a);J(n,t,e._id,C,a)},dialogs:T,getDialogs:async t=>{const{items:e}=await h.chat.dialog.list(t);P((t=>{const a=[...t,...e],n=new Map;a.forEach((t=>n.set(t._id,t)));return Array.from(n.values()).sort(((t,e)=>{const a=j(t.last_message_date_sent)||j(t.created_at)||0;return(j(e.last_message_date_sent)||j(e.created_at)||0)-a}))}));const a=Array.from(new Set(e.flatMap((t=>t.occupants_ids))));return F(a),e},createChat:async(t,e)=>{const a={type:l.PRIVATE,occupants_ids:[t],extensions:e},n=await h.chat.dialog.create(a);return P((t=>[n,...t.filter((t=>t._id!==n._id))])),E.current[t]=n._id,q(m.NEW_DIALOG,n._id,t),F([t,C]),n},createGroupChat:async(t,e,a,n)=>{const r={type:l.GROUP,name:e,photo:a,occupants_ids:t,extensions:n},i=await h.chat.dialog.create(r);return P((t=>[i,...t.filter((t=>t._id!==i._id))])),t.forEach((t=>{q(m.NEW_DIALOG,i._id,t)})),F([...t,C]),i},sendTypingStatus:t=>{if(t??=R,!t)throw"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.";h.chat.sendIsTypingStatus(t.type===l.PRIVATE?V(t):t._id)},typingStatus:w,sendMessageWithAttachment:async(t,e)=>{if(e??=R,!e)throw"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.";const a=V(e),n=Date.now()+"",r=t.map(((t,e)=>({uid:`local-${n}-${e}`,type:t.type,url:URL.createObjectURL(t)})));J(n,"Attachment",e._id,C,a,r,!0);const i=t.map((t=>{const e={file:t,name:t.name,type:t.type,size:t.size,public:!1};return h.storage.createAndUpload(e)})),s=(await Promise.all(i)).map((({uid:t,content_type:e})=>({uid:t,type:e??"",url:h.storage.privateUrl(t)}))),o=X("Attachment",s,e,a);y((t=>({...t,[e._id]:t[e._id].map((t=>t._id===n?{...t,_id:o,attachments:r,isLoading:!1}:t))})))},markDialogAsRead:$,removeUsersFromGroupChat:async t=>{if(!R)throw new Error("No dialog selected");const e=R._id,a={pull_all:{occupants_ids:t}};await h.chat.dialog.update(e,a),t.forEach((t=>{q(m.REMOVED_FROM_DIALOG,e,t)})),R.occupants_ids.filter((e=>!t.includes(e)&&e!==C)).forEach((a=>{q(m.REMOVE_PARTICIPANTS,e,a,{removedParticipantsIds:t.join()})}));const n={...R,occupants_ids:R.occupants_ids.filter((e=>!t.includes(e)))};P((t=>t.map((t=>t._id===e?n:t)))),W(n)},addUsersToGroupChat:async t=>{if(!R)throw new Error("No dialog selected");const e=R._id,a={push_all:{occupants_ids:t}};await h.chat.dialog.update(e,a),R.occupants_ids.filter((t=>t!==C)).forEach((a=>{q(m.ADD_PARTICIPANTS,e,a,{addedParticipantsIds:t.join()})})),t.forEach((t=>{q(m.ADDED_TO_DIALOG,e,t)})),F(t);const n={...R,occupants_ids:Array.from(new Set([...R.occupants_ids,...t]))};P((t=>t.map((t=>t._id===e?n:t)))),W(n)},leaveGroupChat:async()=>{if(!R)throw new Error("No dialog selected");await h.chat.dialog.delete(R._id),R.occupants_ids.filter((t=>t!==C)).forEach((t=>{q(m.REMOVED_FROM_DIALOG,R._id,t)})),P(T.filter((t=>t._id!==R._id))),W(void 0)},readMessage:(t,e,a)=>{h.chat.sendReadStatus({messageId:t,userId:e,dialogId:a}),y((e=>({...e,[a]:e[a].map((e=>e._id===t?{...e,read:1}:e))}))),P((t=>t.map((t=>t._id===a?{...t,unread_messages_count:Math.max(0,t.unread_messages_count-1)}:t))))},lastMessageSentTimeString:t=>U(t.last_message_date_sent?1e3*t.last_message_date_sent:t.created_at,{addSuffix:!0}),messageSentTimeString:t=>U(1e3*t.date_sent,{addSuffix:!0}),processOnMessage:t=>{A.current=t},processOnMessageError:t=>{S.current=t},...k,...x.exports},children:e})};export{q as ChatProvider,J as useChat}; //# sourceMappingURL=index.js.map