OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-store / store / chat / list-view / list-view-jump.saga.js

124 lines · javascript ref:
import { select as e, put as t, take as o } from "redux-saga/effects"
import { getCoreBackend as i } from "../../../backend"
import { apiCall as s } from "../../../api/core"
import { logWarning as a, taskErrorSaga as r } from "../../error"
import { QUERY_FIRST_LOAD_COUNT as d } from "../chat.constant"
import { isSeqInRange as n, isUnsetRange as m } from "../chat.model"
import {
  getCoreId as c,
  sendChatMessageSuccess as l,
  createFirstQuery as p,
  createFirstMiddleQuery as h,
} from "../message"
import { ANCHOR_STATUS as y } from "./list-view.constant"
import { getChatMessageState as u, getChatMessageSeqLoaded as f } from "./list-view-data.selector"
import { getChatListViewState as g, getChatMessagesInView as w } from "./list-view.selector"
import { fetchMessagesCmd as q } from "./list-view-data.action"
import {
  chatMessageJumpToBottomCmd as E,
  chatMessageJumpToCmd as I,
  chatMessageJumpToSeqCmd as b,
  setChatMessageAnchor as L,
} from "./list-view.action"
import {
  createAnchorToBottom as v,
  createAnchorToMessage as J,
  isChatListLive as D,
} from "./list-view.model"
import { sharedCoreMessagesUpdate as T } from "../../api/data.action"
export function* chatListViewJumpToSeqHandler(o) {
  try {
    const { count: i, byId: s, seqLoaded: a } = yield e(u),
      { mode: r } = yield e(g)
    if (!D(r)) throw new Error(`chat is not running yet, mode=${r}`)
    const { seq: m, pos: c, highlight: l } = o.payload
    if (!Number.isInteger(m)) throw new Error("neither messageId nor seq provided")
    let p
    const f = n(a, m)
    if (f) {
      if (((p = Object.values(s).find((e) => e.seq === m)), !p))
        throw new Error(`unable to get message data for seq=${m}`)
    } else p = { seq: m }
    const w = J({
      highlight: l,
      pos: c,
      messageId: p.id || "",
      seq: p.seq,
      status: f ? y.LOADED : y.ASKED,
    })
    if ((yield t(L(w)), !f)) {
      const e = p.seq < d ? d : p.seq,
        o = h({ count: i, bottomSeq: e })
      yield t(q(o))
    }
  } catch (e) {
    yield r("chatMessageJumpToSeqHandler", e)
  }
}
export function* chatListViewJumpToHandler(o, a) {
  try {
    const { count: r, byId: l } = yield e(u),
      { mode: p } = yield e(g)
    if (!D(p)) throw new Error(`chat is not running yet, mode=${p}`)
    const { messageId: E, pos: I, highlight: b } = a.payload
    if (!E) throw new Error("no messageId provided")
    let v = l[E]
    if (!v) {
      const { deviceId: e, seq: t } = c(E),
        a = i()
      if (
        ((v = yield s(a.getChatMessageById, o, { deviceId: e, seq: t })),
        !v && !Number.isInteger(v.seq))
      )
        throw new Error(`unable to get message data for id=${E}`)
    }
    const T = yield e(f),
      V = yield e(w)
    let H = y.ASKED
    const S = n(T, v.seq)
    ;(S && (H = y.LOADED), m(V) || V.bottom !== v.seq || (H = y.RENDERED))
    const A = J({ highlight: b, pos: I, messageId: E, seq: v.seq, status: H })
    if ((yield t(L(A)), !S)) {
      const e = v.seq < d ? d : v.seq,
        o = h({ count: r, bottomSeq: e })
      yield t(q(o))
    }
  } catch (e) {
    yield r("chatMessageJumpToHandler", e)
  }
}
export function* chatListViewJumpToBottomHandler(o) {
  try {
    const { count: i, seqLoaded: s, ids: a } = yield e(u),
      { inView: r } = yield e(g)
    if (m(r)) throw new Error(`Invalid inView range top=${r?.top} bottom=${r?.bottom}`)
    const d = p({ count: i }),
      n = o,
      c = s.bottom === i - 1 ? a[0] : "",
      l = c ? y.LOADED : y.ASKED,
      h = v({ pos: n, status: l, messageId: c })
    ;(yield t(L(h)), i && !c && (yield t(q(d))))
  } catch (e) {
    yield r("chatMessageJumpToBottomHandler", e)
  }
}
export function* chatListViewJump(i, s) {
  const { mode: r, paused: d } = yield e(g)
  d
    ? yield t(a({ message: "Attempt to add an anchor while the chat is paused." }))
    : (D(r) || (yield o(T)),
      E.match(s)
        ? yield chatListViewJumpToBottomHandler(s.payload?.pos)
        : l.match(s)
          ? yield chatListViewJumpToBottomHandler()
          : I.match(s)
            ? yield chatListViewJumpToHandler(i, s)
            : b.match(s) && (yield chatListViewJumpToSeqHandler(s)))
}
export function* chatListViewJumpToEditingMessage({ payload: o }) {
  const { messageId: i } = o,
    s = yield e(w),
    { seq: a } = c(i)
  n(s, a) || (yield t(I({ messageId: i })))
}