OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-store / store / chat / list-view / list-view-data.reducer.js

220 lines · javascript ref:
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
  }
}