OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-store / store / chat / search / chat-search.model.js

119 lines · javascript ref:
import { DISPLAY_TYPES as t } from "@holepunchto/keet-core/legacy-constants"
import {
  CHAT_SEARCH_LIMIT as e,
  ELLIPSIS as r,
  SEARCH_DATA_STATUS as n,
  SEARCH_MODE as h,
} from "./chat-search.constant"
import { isEmpty as s, last as i } from "../../lib/array"
export const isChatSearching = (t) => t !== h.NONE
export const isChatSearchLoading = (t) => t === n.ASKED || t === n.LOADING_MORE
export const isEmptySearchTerms = (t) =>
  !Array.isArray(t) || 0 === t.length || !t.reduce((t, e) => t || !!e, !1)
export const isSearchTermsLimited = (t) => 1 === t.length && t[0].length <= e.CHARS
export const createHighlightSegments = (t, r) => {
  if (s(t) || !r) return []
  if (isSearchTermsLimited(t)) return []
  const n = new Set(),
    h = r.toLowerCase()
  return t
    .reduce((t, s, i) => {
      if (i >= e.TERMS) return t
      const a = s.toLowerCase()
      if (n.has(a)) return t
      n.add(a)
      let g = h.indexOf(a)
      for (; g >= 0 && g < h.length; ) {
        const e = g + a.length
        ;(t.push({ start: g, end: e, highlightStr: r.slice(g, e) }),
          (g = h.indexOf(a, g + a.length)))
      }
      return t
    }, [])
    .sort((t, e) => t.start - e.start)
    .reduce((t, e) => {
      const r = i(t)
      if (!r) return (t.push(e), t)
      if (e.start <= r.end) {
        if (e.end <= r.end) return t
        const n = r.highlightStr.concat(e.highlightStr.slice(r.end - e.end)),
          h = { start: r.start, end: e.end, highlightStr: n }
        return ((t[t.length - 1] = h), t)
      }
      return (t.push(e), t)
    }, [])
}
const a = [
  t.BOLD,
  t.ITALIC,
  t.CODE,
  t.CODE_BLOCK,
  t.STRIKE_THROUGH,
  t.HTTP_LINK,
  t.MENTION,
  t.PEAR_LINK,
]
export const notTextSegment = (t) => t.reduce((t, e) => t || (e.type && !a.includes(e.type)), !1)
export const addSegmentHighlight = (t, e) =>
  s(t) || s(e)
    ? t
    : t.map((t) => {
        if (notTextSegment(t.styles)) return t
        const r = { ...t, highlight: [] }
        let n = !1
        return (
          e.forEach((t) => {
            const { start: e, end: h, highlightStr: s } = t
            if (r.end <= e || r.start >= h) return
            const i = Math.max(r.start, e) - r.start,
              a = Math.min(r.end, h) - r.start,
              g = e < r.start ? r.start - e : 0 - i
            ;(r.highlight.push({
              start: i,
              end: a,
              highlightStr: s.slice(i + g, a + g),
              key: `${i}-${a}`,
            }),
              (n = !0))
          }),
          n ? r : t
        )
      })
export const trimTextAndSegment = (t, e, n) => {
  if (!t) return
  let h
  t.includes("\n") && (h = t.replaceAll("\n", " "))
  const i = e?.find((t) => !s(t.highlight))
  if (!e || !i || s(i.highlight)) return { trimmedText: h, trimmedSegments: void 0 }
  const a = i.start + i.highlight[0].start,
    { HIGHLIGHT_START_LIMIT: g, HIGHLIGHT_START_OFFSET: o, HIGHLIGHT_LENGTH_LIMIT: c } = n
  if (a <= g) return { trimmedText: h, trimmedSegments: void 0 }
  const l = a - o
  h = `${r}${(h || t).slice(l)}`
  const d = e.reduce(
    (t, e) => (
      e.end <= l ||
        Math.max(e.start - l, 0) + r.length > c ||
        t.push({
          ...e,
          start: Math.max(e.start - l, 0) + r.length,
          end: Math.max(e.end - l, 0) + r.length,
          highlight:
            e.start >= l
              ? e?.highlight
              : e?.highlight?.map((t) => ({
                  ...t,
                  start: Math.max(t.start - l + e.start, 0),
                  end: Math.max(t.end - l + e.start, 0),
                })),
        }),
      t
    ),
    [],
  )
  return (
    d.unshift({ start: 0, end: r.length, styles: [], highlight: [] }),
    { trimmedText: h, trimmedSegments: d }
  )
}