UNPKG

@connectycube/use-chat

Version:

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

3 lines (2 loc) 23.2 kB
"use strict";var t,e,a,n=require("react/jsx-runtime"),r=require("react"),i=require("connectycube/types"),s=require("connectycube");function o(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"}(t||(t={}));var c=o(function(){if(a)return e;a=1;var t=r;return e=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 u=43200,d=Symbol.for("constructDateFrom");function l(t,e){return"function"==typeof t?t(e):t&&"object"==typeof t&&d in t?t[d](e):t instanceof Date?new t.constructor(e):new Date(e)}function h(t,e){return l(t,t)}let m={};function f(){return m}function g(t){const e=h(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 _(t,...e){const a=l.bind(null,t||e.find((t=>"object"==typeof t)));return e.map(a)}function p(t,e){const a=+h(t)-+h(e);return a<0?-1:a>0?1:a}function y(t,e){const a=h(t);return+function(t){const e=h(t);return e.setHours(23,59,59,999),e}(a)==+function(t){const e=h(t),a=e.getMonth();return e.setFullYear(e.getFullYear(),a+1,0),e.setHours(23,59,59,999),e}(a)}function v(t,e,a){const[n,r,i]=_(a?.in,t,t,e),s=p(r,i),o=Math.abs(function(t,e,a){const[n,r]=_(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=p(r,i)===-s;y(n)&&1===o&&1===p(n,i)&&(c=!1);const u=s*(o-+c);return 0===u?0:u}function w(t,e,a){const n=function(t,e){return+h(t)-+h(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 b={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 D(t){return(e={})=>{const a=e.width?String(e.width):t.defaultWidth;return t.formats[a]||t.formats[t.defaultWidth]}}const A={date:D({formats:{full:"EEEE, MMMM do, y",long:"MMMM do, y",medium:"MMM d, y",short:"MM/dd/yyyy"},defaultWidth:"full"}),time:D({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:D({formats:{full:"{{date}} 'at' {{time}}",long:"{{date}} 'at' {{time}}",medium:"{{date}}, {{time}}",short:"{{date}}, {{time}}"},defaultWidth:"full"})},M={lastWeek:"'last' eeee 'at' p",yesterday:"'yesterday at' p",today:"'today at' p",tomorrow:"'tomorrow at' p",nextWeek:"eeee 'at' p",other:"P"};function E(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 S(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 u;u=t.valueCallback?t.valueCallback(c):c,u=a.valueCallback?a.valueCallback(u):u;return{value:u,rest:e.slice(s.length)}}}var T;const C={code:"en-US",formatDistance:(t,e,a)=>{let n;const r=b[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:A,formatRelative:(t,e,a,n)=>M[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:E({values:{narrow:["B","A"],abbreviated:["BC","AD"],wide:["Before Christ","Anno Domini"]},defaultWidth:"wide"}),quarter:E({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:E({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:E({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:E({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:(T={matchPattern:/^(\d+)(th|st|nd|rd)?/i,parsePattern:/\d+/i,valueCallback:t=>parseInt(t,10)},(t,e={})=>{const a=t.match(T.matchPattern);if(!a)return null;const n=a[0],r=t.match(T.parsePattern);if(!r)return null;let i=T.valueCallback?T.valueCallback(r[0]):r[0];return i=e.valueCallback?e.valueCallback(i):i,{value:i,rest:t.slice(n.length)}}),era:S({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:S({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:S({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:S({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:S({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 P(t,e){return function(t,e,a){const n=f(),r=a?.locale??n.locale??C,i=p(t,e);if(isNaN(i))throw new RangeError("Invalid time value");const s=Object.assign({},a,{addSuffix:a?.addSuffix,comparison:i}),[o,c]=_(a?.in,...i>0?[e,t]:[t,e]),d=w(c,o),l=(g(c)-g(o))/1e3,h=Math.round((d-l)/60);let m;if(h<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===h?r.formatDistance("lessThanXMinutes",1,s):r.formatDistance("xMinutes",h,s);if(h<45)return r.formatDistance("xMinutes",h,s);if(h<90)return r.formatDistance("aboutXHours",1,s);if(h<1440){const t=Math.round(h/60);return r.formatDistance("aboutXHours",t,s)}if(h<2520)return r.formatDistance("xDays",1,s);if(h<u){const t=Math.round(h/1440);return r.formatDistance("xDays",t,s)}if(h<86400)return m=Math.round(h/u),r.formatDistance("aboutXMonths",m,s);if(m=v(c,o),m<12){const t=Math.round(h/u);return r.formatDistance("xMonths",t,s)}{const t=m%12,e=Math.trunc(m/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 l(t,Date.now())}(t),e)}const O="[useChat][useBlockList]",I="ConnectyCubeBlockList";function L(t){const[e,a]=r.useState(new Set),n=r.useRef(!1),o=t=>e.has(t),c=async(r,o)=>{if(!t)return void console.warn(`${O}[upsert]: ${o} user ${r} failed, chat is not connected`);const c=new Set(e),u={name:I,items:[{user_id:r,action:o,mutualBlock:!0}]};try{o===i.PrivacyListAction.DENY?c.add(r):o===i.PrivacyListAction.ALLOW&&c.delete(r),n.current?(await s.chat.privacylist.setAsDefault(null),await s.chat.privacylist.update(u),c.size>0&&await s.chat.privacylist.setAsDefault(I)):(await s.chat.privacylist.create(u),await s.chat.privacylist.setAsDefault(I))}catch(t){return}finally{a(c)}};return r.useEffect((()=>{t&&(async()=>{if(!t)return void console.warn(`${O}[fetch]: chat is not connected`);if((await s.chat.privacylist.getNames()).default===I){const t=(await s.chat.privacylist.getList(I)).items.reduce(((t,e)=>(e.action===i.PrivacyListAction.DENY&&t.add(+e.user_id),t)),new Set);n.current=!0,a(t)}})()}),[t]),{blockedUsers:Array.from(e),isBlockedUser:o,unblockUser:async t=>{o(t)?await c(t,i.PrivacyListAction.ALLOW):console.warn(`${O}[unblock]: user ${t} is not blocked`)},blockUser:async t=>{o(t)?console.warn(`${O}[block]: user ${t} is already blocked`):await c(t,i.PrivacyListAction.DENY)}}}const R=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},W=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},x="[useChat][useUsers]",N=100;function k(t){const[e,a,n]=c({}),[o,u]=r.useState({}),[d,l]=r.useState(0),[h,m]=r.useState({}),f=r.useRef(0),g=r.useCallback((async e=>{const{items:a}=await s.users.getV2({full_name:{start_with:e},limit:N}),{items:n}=await s.users.getV2({login:{start_with:e},limit:N}),r=new Map;return[...a,...n].forEach((t=>{r.set(t.id,t)})),Array.from(r.values()).filter((e=>e.id!==t))}),[t]),_=async()=>{let t=d;try{const{count:e}=await s.users.getOnlineCount();t=e,l(t)}catch(t){console.error(`${x}[getOnlineCount][Error]:`,t)}return t};return r.useEffect((()=>(s.chat.addListener(i.ChatEvent.USER_LAST_ACTIVITY,((t,e)=>{if("number"==typeof t&&e>=0){const a=W(e);m((e=>({...e,[t]:a})))}})),()=>{s.chat.removeListener(i.ChatEvent.USER_LAST_ACTIVITY)})),[]),{_retrieveAndStoreUsers:async t=>{const r=t.filter((t=>!e[t]));if(r.length>0){const t={limit:N,id:{in:r}},{items:e}=await s.users.getV2(t),i=e.reduce(((t,e)=>(t[e.id]=e,t)),{...n.current});a(i)}},exports:{users:e,searchUsers:g,listOnlineUsers:async(t=!1)=>{const e=f.current,r=Date.now();let i=o;return(r-e>6e4||t)&&(i=await(async()=>{const t=await _(),e=[];let r={};try{let i=N,o=0;for(;o<t;)e.push(s.users.listOnline({limit:i,offset:o}).then((({users:t})=>t))),o+=i;r=(await Promise.all(e)).flat().reduce(((t,e)=>(t[e.id]=e,t)),{}),a({...n.current,...r}),u(r)}catch(t){console.error(`${x}[listOnline][Error]:`,t)}return r})(),f.current=Date.now()),Object.values(i)},listOnlineUsersWithParams:async t=>{let e={};try{const{users:r}=await s.users.listOnline(t);e=r.reduce(((t,e)=>(t[e.id]=e,t)),{}),a({...n.current,...e}),u(e)}catch(t){console.error(`${x}[listOnlineWithParams][Error]:`,t)}return Object.values(e)},onlineUsers:Object.values(o),getOnlineUsersCount:_,onlineUsersCount:d,lastActivity:h,getLastActivity:async t=>{let e="Last seen recently";try{const{seconds:a}=await s.chat.getLastUserActivity(t);e=W(a)}catch(t){console.error(`${x}[getLastActivity][Error]:`,t)}finally{return m((a=>({...a,[t]:e}))),e}},subscribeToUserLastActivityStatus:t=>{s.chat.subscribeToUserLastActivityStatus(t)},unsubscribeFromUserLastActivityStatus:t=>{s.chat.unsubscribeFromUserLastActivityStatus(t)}}}}const U=r.createContext(void 0);U.displayName="ChatContext";exports.ChatProvider=({children:e})=>{const[a,o]=r.useState(navigator.onLine),[u,d]=r.useState(!1),[l,h]=r.useState({total:0}),[m,f]=r.useState({}),[g,_]=r.useState({}),[p,y]=r.useState({}),v=r.useRef({}),w=r.useRef(null),b=r.useRef(null),D=r.useRef({}),[A,M,E]=c([]),[S,T,C]=c(),[O,I,W]=c(),x=L(u),N=k(S),{_retrieveAndStoreUsers:F}=N,j=async t=>{const e={chat_dialog_id:t,sort_desc:"date_sent",limit:100,skip:0};try{const a=(await s.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:s.storage.privateUrl(t.uid)})));return{...t,attachments:e}}));return f((e=>({...e,[t]:a}))),a}catch(e){if(404===e.code)return f((e=>({...e,[t]:[]}))),[];throw e}},G=t=>{if(t??=O,!t)throw"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.";if(t.type!==i.DialogType.PRIVATE)return;const e=t.occupants_ids.filter((t=>t!==S))[0];return D.current[e]=t._id,e},Y=async t=>{const e={read:1,chat_dialog_id:t._id};await s.chat.message.update("",e),M((e=>e.map((e=>e._id===t._id?{...e,unread_messages_count:0}:e))))},V=(t,e,a,n)=>{const r={type:a.type===i.DialogType.PRIVATE?i.ChatType.CHAT:i.ChatType.GROUPCHAT,body:t,extension:{save_to_history:1,dialog_id:a._id}};e&&(r.extension.attachments=e);return s.chat.send(a.type===i.DialogType.PRIVATE?n:a._id,r)},$=(t,e,a,n,r,i,s)=>{const o=Math.round((new Date).getTime()/1e3);M((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=R(t.last_message_date_sent)||R(t.created_at);return(R(e.last_message_date_sent)||R(e.created_at))-a})))),f((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}]})))},X=(t,e,a,n={})=>{const r={body:t,extension:{dialogId:e,...n}};s.chat.sendSystemMessage(a,r)},q=(t,e,a)=>{_((n=>{const r=n[t],i=r?new Set(r):new Set;return a?i.add(e):i.delete(e),{...n,[t]:[...i]}}))},H=(t,e)=>{q(t,e,!1),clearTimeout(v.current[t][e]),delete v.current[t][e]};r.useEffect((()=>{const t=new AbortController,e=new AbortController;return window.addEventListener("online",(()=>{o(!0)}),{signal:t.signal}),window.addEventListener("offline",(()=>{o(!1),y({})}),{signal:e.signal}),()=>{t.abort(),e.abort()}}),[]);const z=()=>{y({})},J=()=>{console.log("[useChat] Reconnected")},B=(t,e)=>{if(t===C.current)return;const a=W.current,n=e.dialog_id,r=e.id,o=e.body||"",c=e.type===i.ChatType.CHAT?C.current:void 0,u=e.extension.attachments?.length>0?e.extension.attachments.map((t=>({...t,url:s.storage.privateUrl(t.uid)}))):void 0;$(r,o,n,t,c,u),H(n,t),M((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)))),w.current&&w.current(t,e)},Q=(t,e)=>{b.current&&b.current(t,e)},K=async e=>{const a=e.extension.dialogId,n=e.userId;if(n!==C.current)switch(e.body){case t.NEW_DIALOG:case t.ADDED_TO_DIALOG:{const t=(await s.chat.dialog.list({_id:a})).items[0];F(t.occupants_ids),M((e=>[t,...e.filter((e=>e._id!==t._id))]));break}case t.ADD_PARTICIPANTS:{const t=e.extension.addedParticipantsIds.split(",").map(Number);F(t),M((e=>e.map((e=>(e._id===a&&(e.occupants_ids=Array.from(new Set([...e.occupants_ids,...t]))),e)))));break}case t.REMOVE_PARTICIPANTS:{const t=e.extension.removedParticipantsIds.split(",").map(Number);M((e=>e.map((e=>(e._id===a&&(e.occupants_ids=e.occupants_ids.filter((e=>!t.includes(e)))),e)))));break}case t.REMOVED_FROM_DIALOG:M((t=>t.map((t=>(t._id===a&&t.type!==i.DialogType.PRIVATE&&(t.occupants_ids=t.occupants_ids.filter((t=>t!==n))),t)))))}},Z=(t,e,a)=>{a!==C.current&&f((n=>((n[e]||[]).forEach((e=>{e._id===t&&0===e.read&&(e.read=1,e.read_ids?.push(a))})),n)))},tt=(t,e,a)=>{const n=a||(t=>{let e=D.current[t];if(!e){const a=E.current.find((e=>e.type===i.DialogType.PRIVATE&&G(e)===t));a&&(e=a._id,D.current[t]=e)}return e})(e);n&&e&&e!==C.current&&(q(n,e,t),v.current[n]||(v.current[n]={}),t?(v.current[n]?.[e]&&(clearTimeout(v.current[n][e]),delete v.current[n][e]),v.current[n][e]=setTimeout((()=>{H(n,e)}),6e3)):H(n,e))};return r.useEffect((()=>(s.chat.addListener(i.ChatEvent.DISCONNECTED,z),s.chat.addListener(i.ChatEvent.RECONNECTED,J),s.chat.addListener(i.ChatEvent.MESSAGE,B),s.chat.addListener(i.ChatEvent.ERROR_MESSAGE,Q),s.chat.addListener(i.ChatEvent.SYSTEM_MESSAGE,K),s.chat.addListener(i.ChatEvent.READ_MESSAGE,Z),s.chat.addListener(i.ChatEvent.TYPING_MESSAGE,tt),()=>{s.chat.removeAllListeners()})),[]),r.useEffect((()=>{(()=>{const t={total:0};A.forEach((({_id:e,unread_messages_count:a=0})=>{e!==O?._id&&(t[e]=a,t.total+=a)})),h(t)})()}),[A]),n.jsx(U.Provider,{value:{isOnline:a,connect:async t=>{try{const e=await s.chat.connect(t);e&&(d(e),T(t.userId))}catch(t){console.error(`Failed to connect due to ${t}`)}},isConnected:u,disconnect:()=>{s.chat.isConnected&&(s.chat.disconnect(),T(void 0),d(!1))},currentUserId:S,selectDialog:async t=>{I(t),t&&(p[t._id]||(await j(t._id),y({...p,[t._id]:!0})),t.unread_messages_count>0&&await Y(t).catch((t=>{})))},selectedDialog:O,getDialogOpponentId:G,unreadMessagesCount:l,getMessages:j,messages:m,sendMessage:(t,e)=>{if(e??=O,!e)throw"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.";const a=G(e),n=V(t,null,e,a);$(n,t,e._id,S,a)},dialogs:A,getDialogs:async t=>{const{items:e}=await s.chat.dialog.list(t);M((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=R(t.last_message_date_sent)||R(t.created_at)||0;return(R(e.last_message_date_sent)||R(e.created_at)||0)-a}))}));const a=Array.from(new Set(e.flatMap((t=>t.occupants_ids))));return F(a),e},createChat:async(e,a)=>{const n={type:i.DialogType.PRIVATE,occupants_ids:[e],extensions:a},r=await s.chat.dialog.create(n);return M((t=>[r,...t.filter((t=>t._id!==r._id))])),D.current[e]=r._id,X(t.NEW_DIALOG,r._id,e),F([e,S]),r},createGroupChat:async(e,a,n,r)=>{const o={type:i.DialogType.GROUP,name:a,photo:n,occupants_ids:e,extensions:r},c=await s.chat.dialog.create(o);return M((t=>[c,...t.filter((t=>t._id!==c._id))])),e.forEach((e=>{X(t.NEW_DIALOG,c._id,e)})),F([...e,S]),c},sendTypingStatus:t=>{if(t??=O,!t)throw"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.";s.chat.sendIsTypingStatus(t.type===i.DialogType.PRIVATE?G(t):t._id)},typingStatus:g,sendMessageWithAttachment:async(t,e)=>{if(e??=O,!e)throw"No dialog provided. You need to provide a dialog via function argument or select a dialog via 'selectDialog'.";const a=G(e),n=Date.now()+"",r=t.map(((t,e)=>({uid:`local-${n}-${e}`,type:t.type,url:URL.createObjectURL(t)})));$(n,"Attachment",e._id,S,a,r,!0);const i=t.map((t=>{const e={file:t,name:t.name,type:t.type,size:t.size,public:!1};return s.storage.createAndUpload(e)})),o=(await Promise.all(i)).map((({uid:t,content_type:e})=>({uid:t,type:e??"",url:s.storage.privateUrl(t)}))),c=V("Attachment",o,e,a);f((t=>({...t,[e._id]:t[e._id].map((t=>t._id===n?{...t,_id:c,attachments:r,isLoading:!1}:t))})))},markDialogAsRead:Y,removeUsersFromGroupChat:async e=>{if(!O)throw new Error("No dialog selected");const a=O._id,n={pull_all:{occupants_ids:e}};await s.chat.dialog.update(a,n),e.forEach((e=>{X(t.REMOVED_FROM_DIALOG,a,e)})),O.occupants_ids.filter((t=>!e.includes(t)&&t!==S)).forEach((n=>{X(t.REMOVE_PARTICIPANTS,a,n,{removedParticipantsIds:e.join()})}));const r={...O,occupants_ids:O.occupants_ids.filter((t=>!e.includes(t)))};M((t=>t.map((t=>t._id===a?r:t)))),I(r)},addUsersToGroupChat:async e=>{if(!O)throw new Error("No dialog selected");const a=O._id,n={push_all:{occupants_ids:e}};await s.chat.dialog.update(a,n),O.occupants_ids.filter((t=>t!==S)).forEach((n=>{X(t.ADD_PARTICIPANTS,a,n,{addedParticipantsIds:e.join()})})),e.forEach((e=>{X(t.ADDED_TO_DIALOG,a,e)})),F(e);const r={...O,occupants_ids:Array.from(new Set([...O.occupants_ids,...e]))};M((t=>t.map((t=>t._id===a?r:t)))),I(r)},leaveGroupChat:async()=>{if(!O)throw new Error("No dialog selected");await s.chat.dialog.delete(O._id),O.occupants_ids.filter((t=>t!==S)).forEach((e=>{X(t.REMOVED_FROM_DIALOG,O._id,e)})),M(A.filter((t=>t._id!==O._id))),I(void 0)},readMessage:(t,e,a)=>{s.chat.sendReadStatus({messageId:t,userId:e,dialogId:a}),f((e=>({...e,[a]:e[a].map((e=>e._id===t?{...e,read:1}:e))}))),M((t=>t.map((t=>t._id===a?{...t,unread_messages_count:Math.max(0,t.unread_messages_count-1)}:t))))},lastMessageSentTimeString:t=>P(t.last_message_date_sent?1e3*t.last_message_date_sent:t.created_at,{addSuffix:!0}),messageSentTimeString:t=>P(1e3*t.date_sent,{addSuffix:!0}),processOnMessage:t=>{w.current=t},processOnMessageError:t=>{b.current=t},...x,...N.exports},children:e})},exports.useChat=()=>{const t=r.useContext(U);if(!t)throw new Error("useChat must be within ChatProvider");return t}; //# sourceMappingURL=index.cjs.map