import { sharedCoreMessagesUpdate as e } from "../../api/data.action"
import { arrayEqual as s, first as t, last as a } from "../../lib/array"
import { removeFileEntries as r } from "../../media/file"
import { myMemberMuted as o } from "../../member"
import { CHAT_WORKER as n } from "../chat.constant"
import {
setChatMessageCount as d,
updateMessage as i,
groupMessages as c,
isMessageChanged as g,
isMessageChangedExcludeGrouping as m,
} from "../message"
import {
setChatMessagesFetching as u,
setEditingMessage as p,
clearEditingMessage as l,
setChatMessageSendLimited as M,
setPendingNavigationLink as y,
updateChatMessageMentions as f,
askMentionMemberCmd as h,
clearMentionMemberCmd as b,
} from "./list-view-data.action"
import {
CHAT_LIST_DATA_INITIAL_STATE as I,
CHAT_LIST_VIEW_INITIAL_STATE as R,
} from "./list-view.constant"
const C = (e, s) => ({
...e,
groupCount: s.groupCount,
groupSeq: s.groupSeq,
isHead: s.isHead,
datetime: s.datetime,
parentId: s.parentId,
groupMemberIds: s.groupMemberIds,
isOutOfOrder: s.isOutOfOrder,
})
export const updateMessagesMap = (e, s) => {
const t = {}
let a = !1
const { length: r } = s
for (let o = 0; o < r; o += 1) {
const r = s[o],
{ id: n } = r,
d = e[n]
d
? m(d, r)
? ((t[n] = r), (a = !0))
: g(d, r)
? ((t[n] = C(d, r)), (a = !0))
: (t[n] = d)
: ((t[n] = r), (a = !0))
}
return a ? t : e
}
export const updateMessagesIds = (e, t) => {
const a = t.map((e) => e.id)
return s(e, a) ? e : a
}
export const updateMessageStateReducer = (e, s) => {
const { byId: r, ids: o, seqLoaded: n } = e,
d = t(s)?.seq || 0,
i = a(s)?.seq || 0
return {
...e,
groupedMessages: s,
byId: updateMessagesMap(r, s),
ids: updateMessagesIds(o, s),
seqLoaded: n.top === i && n.bottom === d ? n : { top: i, bottom: d },
}
}
export const setChatMessagesFetchingReducer = (e, { payload: s }) => {
const { name: t, status: a, timestamp: r, callCount: o } = s
let n = e.message.fetch.timeCompleteStats
if (!1 === a && o) {
const s = e.message.fetch.byName[t]?.timestamp
if (Number.isInteger(r) && Number.isInteger(s)) {
const e = Math.max(r - s, 0)
e > 0 && ((n = n.slice(-9)), n.push(Math.floor(e / o)))
}
}
return {
...e,
message: {
...e.message,
fetch: {
...e.message.fetch,
all: a ? e.message.fetch.all + 1 : Math.max(e.message.fetch.all - 1, 0),
byName: { ...e.message.fetch.byName, [t]: { status: a, timestamp: r } },
timeCompleteStats: n,
},
},
}
}
export const setChatMessageCountReducer = (e, { payload: s }) => {
const { seqLoaded: t, count: a } = e.message
let r = e
if (s < a && t.bottom >= s)
if (t.top >= s)
r = {
...r,
message: { ...I, count: s },
listView: { ...R, lastSeenSeq: r.listView.lastSeenSeq },
}
else {
const t = e.message.groupedMessages.filter((e) => e.seq < s)
r = {
...r,
message: { ...updateMessageStateReducer({ ...r.message, byId: {}, ids: [] }, t), count: s },
}
}
else r = { ...r, message: { ...r.message, count: s } }
return r
}
export const canConcatMessages = ({ worker: e, newMessages: s, groupedMessages: r }) =>
!s.length ||
!r.length ||
(e === n.BOTTOM ? a(s).seq - 1 === t(r).seq : e === n.TOP && a(r).seq === t(s).seq + 1)
export const concatMessages = ({ worker: e, newMessages: s, groupedMessages: t }) =>
e === n.BOTTOM ? [...s, ...t] : e === n.TOP ? [...t, ...s] : t
export const updateChatMessagesReducer = (e, { payload: s }) => {
const { worker: t } = s,
a = s.chatMessages
if (!Array.isArray(a) || !a.length) return e
const { groupedMessages: r, byId: o } = e.message
let d = e,
i = null
if (t === n.INITIAL) i = a
else if (t === n.BOTTOM || t === n.TOP)
canConcatMessages({ worker: t, newMessages: a, groupedMessages: r }) &&
(i = concatMessages({ worker: t, newMessages: a, groupedMessages: r }))
else if (t === n.SUB) {
const e = new Map()
;(a.forEach((s) => {
const { id: t } = s,
a = o[t]
a && m(a, s) && e.set(t, s)
}),
e.size && (i = r.map((s) => e.get(s.id) || s)))
}
if (i) {
const e = c(i),
s = updateMessageStateReducer(d.message, e)
d = { ...d, message: s }
}
return d
}
export const updateDeletedChatMessagesReducer = (e, { payload: { messageIds: s } }) => {
if (!Array.isArray(s) || !s.length) return e
const { groupedMessages: t, byId: a } = e.message
let r = a,
o = t
return (
s.forEach((e) => {
const s = a[e]
;(s && !s.deleted && (r = { ...r, [e]: { ...s, deleted: !0, fileId: "", fileIds: [] } }),
-1 !== o.findIndex((s) => s.id === e && !s.deleted) &&
(o = o.map((s) => (s.id === e ? { ...s, deleted: !0, fileId: "", fileIds: [] } : s))))
}),
r === a && o === t ? e : { ...e, message: { ...e.message, byId: r, groupedMessages: o } }
)
}
export const setEditingMessageReducer = (e, s) => {
const { messageId: t } = s.payload || {}
return { ...e, editingMessageId: t }
}
export const setChatMessageSendLimitedReducer = (e, s) => ({ ...e, sendLimited: s.payload })
export const clearEditingMessageReducer = (e) =>
e.editingMessageId ? { ...e, editingMessageId: "" } : e
export const setPendingNavigationLinkReducer = (e, { payload: s }) => ({
...e,
pendingNavigationLink: s,
})
export const askMentionMemberCmdReducer = (e, { payload: s }) => ({
...e,
mentionMemberRequest: s || null,
})
export const clearMentionMemberCmdReducer = (e) =>
e.mentionMemberRequest ? { ...e, mentionMemberRequest: null } : e
export const updateChatMessageMentionsReducer = (e, { payload: s }) => {
const {
member: { memberId: t, displayName: a, capabilities: r },
} = s,
o = {}
for (const s of Object.values(e.message.byId))
(s.chat?.mentions || []).some((e) => e.memberId === t) &&
(o[s.id] = i(s, { memberById: { [t]: { memberId: t, displayName: a, capabilities: r } } }))
if (0 === Object.keys(o).length) return e
const n = e.message.groupedMessages.map((e) => (o[e.id] ? o[e.id] : e))
return { ...e, message: { ...e.message, byId: { ...e.message.byId, ...o }, groupedMessages: n } }
}
export const chatListViewMessageReducer = (s, t) => {
switch (t.type) {
case d.type:
return setChatMessageCountReducer(s, t)
case u.type:
return setChatMessagesFetchingReducer(s, t)
case e.type:
return updateChatMessagesReducer(s, t)
case r.type:
return updateDeletedChatMessagesReducer(s, t)
case p.type:
return setEditingMessageReducer(s, t)
case l.type:
case o.type:
return clearEditingMessageReducer(s)
case M.type:
return setChatMessageSendLimitedReducer(s, t)
case y.type:
return setPendingNavigationLinkReducer(s, t)
case h.type:
return askMentionMemberCmdReducer(s, t)
case b.type:
return clearMentionMemberCmdReducer(s)
case f.type:
return updateChatMessageMentionsReducer(s, t)
default:
return s
}
}