OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-store / store / app / saga / desktop-room-notifications.saga.js

204 lines · javascript ref:
import { select as e, call as t, put as o, all as i, fork as r } from "redux-saga/effects"
import { apiTakeEvery as n } from "../../lib"
import { frequencyCalculator as a } from "../../lib/frequency-calculator"
import { getCoreBackend as s } from "../../../backend"
import { apiCall as l } from "../../../api/core"
import { taskErrorSaga as m } from "../../error"
import { UI_PANEL as d, getUIAppActive as c, getUIPanelState as y } from "../../ui-desktop"
import {
  DM_CALL_NOTIFICATION_THRESHOLD as f,
  getNotificationFrequenceResetInterval as u,
  NOTIFICATION_CODE as p,
  NOTIFICATION_MAX_FREQUENCY as N,
  userCustomNotification as b,
} from "../../notification"
import {
  getAppCurrentCallRoomId as I,
  getAppCurrentRoomId as g,
  getRoomBlurred as B,
} from "../app.reducer"
import {
  CHAT_MESSAGE_TYPE as h,
  chatGetMessageRender as A,
  getChatListViewLatest as S,
  parseMessage as v,
} from "../../chat"
import {
  ROOM_TYPE as T,
  parseRoomConfigResponse as M,
  getRoomNotificationById as H,
  setNotifications as O,
} from "../../room"
import {
  NOTIFICATIONS_ALERT_TYPES as R,
  NOTIFICATIONS_TYPES as C,
  getPreferencesNotificationsAlerts as D,
  getPreferencesNotificationsType as E,
} from "../../preferences"
import { getMyMemberId as x } from "../../identity"
import { callNotificationReceived as U } from "../../call"
import { burstController as k } from "../../lib/burst-controller"
export const NOTIFICATION_THRESHOLD = 6048e5
export const isFreshNotification = (e) => Math.abs(Date.now() - e) <= 6048e5
function* F({
  roomId: t,
  message: r,
  appActive: n,
  notifyByPush: a,
  notifyBySound: d,
  notifyByBanner: c,
}) {
  try {
    const m = s(),
      [y, f, u] = yield i([
        l(m.getRoomInfo, t),
        l(m.getMember, t, r.memberId),
        l(m.getBlockedMembers),
      ])
    if (y?.preferences?.status) {
      const i = !y.preferences.status.isFullyMuted
      if (
        (i !== (yield e(H(t))) && (yield o(O({ [t]: { notifications: i } }))),
        y.preferences.status.isFullyMuted)
      )
        return
    }
    const { title: N, roomType: I, avatarUrl: g } = M(y.config, t),
      B = I === T.DM,
      {
        member: h,
        messageText: S,
        isBlocked: v,
        messageDisplay: R,
      } = yield A({
        roomId: t,
        message: r,
        memberData: f,
        blockedMembers: u,
        disabledCapabilities: B,
      })
    if (v) return
    const { displayName: C, capabilities: D } = h,
      E = I === T.BROADCAST ? "" : C
    yield o(
      b({
        appActive: n,
        avatarUrl: g,
        code: p.ROOM_ACTIVITY,
        roomType: I,
        notifyByPush: a,
        notifyBySound: d,
        notifyByBanner: c,
        profileName: E,
        capabilities: D,
        roomMessage: { ...r, display: R, chat: S ? { ...r.chat, text: S } : r.chat, blocked: v },
        roomId: t,
        roomTitle: B ? h.displayName : N,
      }),
    )
  } catch (e) {
    yield m("putRoomActivityNotification", e)
  }
}
function* P({ roomId: t, seq: o }) {
  const [r, n, a, m, f, u, p, N, b] = yield i([
    e(x),
    e(y),
    e(c),
    e(g),
    e(H(t)),
    e(E),
    e(D),
    e(S),
    e(B, t),
  ])
  if (b) return null
  if (!f || u === C.NONE) return null
  if (a && m === t && n[d.CHAT] && N) return null
  try {
    const e = s(),
      i = yield l(e.getChatMessage, t, o),
      { message: n } = v(i)
    if (n.memberId === r || !isFreshNotification(n.timestamp)) return null
    const m = p.includes(R.PUSH),
      d = p.includes(R.BANNER),
      c = p.includes(R.SOUND),
      y = !!n.chat?.mentions?.find((e) => e.memberId === r)
    return u !== C.MENTIONS || y
      ? {
          roomId: t,
          message: n,
          appActive: a,
          notifyByPush: m,
          notifyBySound: c,
          notifyByBanner: d,
        }
      : null
  } catch (e) {
    return { error: e, errorHandlerName: "activeRoomsActivityHandler" }
  }
}
function* q({ roomId: t, seq: o }) {
  try {
    const [r, n, a, m] = yield i([e(x), e(H(t)), e(E), e(B, t)])
    if (m) return null
    if (!n || a === C.NONE) return null
    const d = yield e(D),
      y = !!d.includes(R.PUSH),
      f = !!d.includes(R.BANNER),
      u = !!d.includes(R.SOUND),
      p = s(),
      N = yield e(c),
      b = yield l(p.getChatMessage, t, o),
      { message: I } = v(b)
    if (I.memberId === r || !isFreshNotification(I.timestamp)) return null
    const g = !!I.chat?.mentions?.find((e) => e.memberId === r)
    return a !== C.MENTIONS || g
      ? {
          roomId: t,
          message: I,
          appActive: N,
          notifyByPush: y,
          notifyBySound: u,
          notifyByBanner: f,
        }
      : null
  } catch (e) {
    return { error: e, errorHandlerName: "inactiveRoomsActivityHandler" }
  }
}
export function* notifyCallStartEndSaga(e, t) {
  ;[h.CALL_STARTED, h.CALL_HANGUP].includes(e?.event?.type) &&
    Math.abs(Date.now() - e.timestamp) <= f &&
    (yield o(U({ message: e, roomId: t })))
}
function* L(o, r, { roomId: n, index: a }) {
  try {
    if (!n || !Number.isInteger(a)) return
    let s
    if (
      ((s = (yield i([e(g), e(I)])).includes(n)
        ? yield P({ roomId: n, seq: a })
        : yield q({ roomId: n, seq: a })),
      s?.error)
    )
      return void (yield m(s.errorHandlerName, s.error))
    if (s) {
      if (o.updateFrequency() <= N) {
        const e = s.notifyBySound && r.allow()
        yield t(F, { ...s, notifyBySound: e })
      }
      yield t(notifyCallStartEndSaga, s.message, n)
    }
  } catch (e) {
    yield m("allRoomsActivityHandler", e)
  }
}
const _ = 2e3
export function* desktopRoomNotificationsSaga() {
  const t = yield e(u),
    o = a(t),
    i = k(_)
  yield n([s().subscribeUnreadActivity, { all: !0, includeIndex: !0 }], (e) => r(L, o, i, e))
}