OverviewFilesCommitsIssuesDocsReleasesPeers

keet-deobfuscated / @holepunchto / keet-store / store / app / saga / app-call.saga.js

235 lines · javascript ref:
import {
  spawn as l,
  select as e,
  take as a,
  fork as o,
  put as t,
  all as i,
  call as r,
  takeLatest as d,
  takeEvery as n,
  takeLeading as c,
  race as s,
  delay as y,
} from "redux-saga/effects"
import { getCallApi as m, getCoreBackend as p } from "../../../backend"
import { apiCall as f } from "../../../api/core"
import { forkChildren as u } from "../../lib"
import { taskErrorSaga as g } from "../../error"
import {
  callSaga as C,
  callPeersCounterSaga as I,
  getCallStatus as S,
  isCallJoinedMode as h,
  callLeave as R,
  callReset as k,
  callJoinedEvt as x,
  callJoinCmd as v,
  callResume as P,
  getCallPeerSwarmIds as M,
  setCallStatus as w,
  openCallSettings as A,
  isLastInCall as b,
  getCallPeersCount as j,
  getCallId as B,
  setCallPeers as E,
  toggleDmCallsV2 as D,
  setDmCallsV2Enabled as N,
  getDmCallsV2Enabled as O,
  setPendingCall as V,
  getPendingCall as F,
  isSetCallStatusReady as J,
} from "../../call"
import {
  getAppCurrentCallRoomId as q,
  setAppCurrentRoomId as z,
  getAppCurrentRoomId as G,
  setAppCurrentCallRoomId as H,
} from "../app.reducer"
import {
  roomListInViewIdsChangeEvt as K,
  getRoomListInViewIds as L,
  getIsRoomDm as Q,
  setRoomInfo as T,
  switchRoomSubmit as U,
} from "../../room"
import {
  addMemberUnknownSwarmId as W,
  getMemberIdByRoomAndSwarmIds as X,
  unknownSwarmIdsResolveSaga as Y,
} from "../../member"
import { getIsCallsV2Supported as Z } from "../../call/call.reducer"
import { getMyScreenStreamId as $ } from "../../call/call-settings.reducer"
import { callDevicesSaga as _ } from "../../call/call-device.saga"
import { callDMSaga as ll } from "../../call/call-dm.saga"
import { callPreferencesSaga as el, callSettingsSaga as al } from "../../call/call-settings.saga"
import { BOOT_CALL_RESUME_TIMEOUT_MS as ol } from "../app.constants"
import { getMyDeviceId as tl, isDeviceInCall as il } from "../../call/utils"
export function* appBootCallResumeSaga() {
  try {
    yield s({
      scan: r(function* () {
        for (;;) {
          const { payload: l } = yield a(T),
            { roomId: o, activeCallId: i } = l
          if (!i) continue
          if (!(yield e(Z(o)))) continue
          const r = p(),
            d = yield f(r.getActiveCalls, o)
          if (!d.length) continue
          const n = yield f(r.getRoomInfo, o)
          if (il(d[0], tl(n))) return void (yield t(V({ roomId: o, callId: d[0].callId })))
        }
      }),
      joinCall: a(v),
      timeout: y(ol),
    })
  } catch (l) {
    yield g("appBootCallResumeSaga", l)
  }
}
export function* appCallStartMessageSaga({ payload: { roomId: l } }) {
  try {
    const [a, o] = yield i([e(Q(l)), e(Z(l))])
    if (o && a) return
    const t = p()
    if (o) {
      const e = yield f(t.getActiveCalls, l)
      if (0 === e.length) yield f(t.startCall, l, { version: 1 })
      else {
        const a = e[0],
          o = yield f(t.getRoomInfo, l)
        il(a, tl(o)) || (yield f(t.joinCall, l, a.callId, []))
      }
    } else {
      const a = yield e(j, l),
        o = yield e(B)
      a > 0 && o ? yield f(t.joinCall, l, o, []) : yield f(t.startCall, l, { version: 1 })
    }
  } catch (l) {
    yield g("appCallStartMessageSaga", l)
  }
}
export function* appCallEndMessageSaga({ payload: a }) {
  try {
    const { endingCallRing: o, endForAll: r, callId: d, roomId: n } = a || {}
    if (o) return
    const c = n || (yield e(q)),
      [s, y] = yield i([e(Q(c)), e(Z(c))]),
      u = p()
    let g,
      C = s
    if (y) {
      const l = yield f(u.getActiveCalls, c)
      if (!l.length) return
      const e = d ? l.find((l) => l.callId === d) : l[0]
      if (!e || e.endedAt) return
      ;((g = e.callId), C || (C = yield b(e, c)))
    } else {
      if (((g = yield e(B)), !g)) return
      C || (C = 0 === (yield e(j, c)))
    }
    const I = yield e($)
    ;(I && (yield l(() => m().local.closeStream(I))),
      s && y && (yield t(E({ roomId: c, ids: [] }))),
      C || r ? yield f(u.endCall, c, g) : yield f(u.leaveCall, c, g))
  } catch (l) {
    yield g("appCallEndMessageSaga", l)
  }
}
export function* callResumeSaga({ payload: l }) {
  try {
    const { callId: o } = l || {},
      r = yield e(F),
      d = r?.roomId
    if (!d) return
    const n = yield e(G),
      [c, s] = yield i([e(Q(d)), e(O)])
    ;(yield t(V(null)),
      n !== d && (yield t(U({ roomId: d, resumingCall: !0 })), yield a(J)),
      yield t(A()),
      yield t(v(s && c ? { callId: o, resume: !0 } : { resume: !0 })))
  } catch (l) {
    yield g("callResumeSaga", l)
  }
}
export function* toggleDmCallsV2Saga() {
  const l = yield e(O)
  yield t(N(!l))
}
export function* appCallManagerSaga() {
  let l = null
  try {
    for (
      yield d(x, appCallStartMessageSaga),
        yield c(R, appCallEndMessageSaga),
        yield d(P, callResumeSaga),
        yield d(D, toggleDmCallsV2Saga),
        yield o(_),
        yield o(el),
        yield o(ll),
        yield c(A, al),
        yield o(appBootCallResumeSaga);
      ;
    ) {
      const r = yield a([R, z]),
        [d, n, c] = yield i([e(G), e(q), e(S)]),
        s = h(c) || d === n
      if (!z.match(r) || !s) {
        if ((l && (l.cancel(), yield a(k)), d)) {
          const e = R.match(r) && r.payload && r.payload.startNew,
            a = z.match(r) && r.payload.answeringCallRing,
            t = z.match(r) && !r.payload.resumingCall
          l = yield o(C, { roomId: d, startNew: e, skipJoinMsg: a, resume: t })
        } else l = null
        yield t(H(d))
      }
    }
  } catch (l) {
    yield g("call manager", l)
  } finally {
    l?.cancel()
  }
}
export function* appParallelCallPresenceSaga() {
  let l = { roomId: "", task: null }
  try {
    yield n([z, w], function* () {
      const [a, r, d] = yield i([e(G), e(S), e(q)])
      if (!h(r)) return (l.task?.cancel(), void (l = { roomId: "", task: null }))
      if (a === d) return (l.task?.cancel(), void (l = { roomId: "", task: null }))
      if (l.roomId === d) return
      if (yield e(Z(d))) return
      ;(l.task?.cancel(), (l.roomId = a), (l.task = yield o(Y, { roomId: a })))
      const n = yield e(M(a))
      for (const l of n)
        (yield e(X({ roomId: a, swarmId: l }))) || (yield t(W({ roomId: a, swarmId: l })))
    })
  } catch (l) {
    yield g("appParallelCallPresenceSaga", l)
  } finally {
    ;(l.task?.cancel(), (l = { roomId: "", task: null }))
  }
}
export function* appRoomsPresenceCounterSaga() {
  yield u(
    [z, K, H],
    function* () {
      const [l, a, o] = yield i([e(G), e(L), e(q)])
      let t = a
      return (
        l && -1 === t.indexOf(l) && (t = t.concat(l)),
        o && -1 === t.indexOf(o) && (t = t.concat(o)),
        t
      )
    },
    function* ({ taskId: l }) {
      yield I({ roomId: l })
    },
    (l) => g("callPeersCounter", l),
  )
}
export function* appRoomsPresencesSaga() {
  ;(yield o(appParallelCallPresenceSaga), yield o(appRoomsPresenceCounterSaga))
}