OverviewFilesCommitsIssuesDocsReleasesPeers

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

178 lines · javascript ref:
import {
  put as e,
  select as r,
  take as o,
  takeEvery as d,
  fork as m,
  call as a,
  race as l,
} from "redux-saga/effects"
import { apiSubscribeSaga as s, apiTakeEvery as t } from "../lib"
import { getChanged as i } from "../lib/array"
import { getCallApi as c, getCoreBackend as n } from "../../backend"
import { apiCall as I } from "../../api/core"
import { taskError as y, taskErrorSaga as p } from "../error"
import {
  getMemberIdByRoomAndSwarmIds as u,
  unknownSwarmIdsResolveSaga as b,
  isSetMembersBySwarmId as f,
  addMemberUnknownSwarmId as E,
} from "../member"
import { getMyMemberId as w } from "../identity"
import {
  increaseCallPeersCount as M,
  decreaseCallPeersCount as P,
  removeCallPeersCount as v,
  setCallPeers as g,
  setRoomActiveCall as C,
  updateCallRemoteMedia as R,
} from "./call.action"
import {
  getCallPeersCount as S,
  getCallPresenceStreamName as A,
  getCallUnknownPresenceState as H,
  getIsCallsV2Supported as k,
} from "./call.reducer"
import { PRESENCE_EVT as h } from "./call.constants"
import {
  addCallMemberId as _,
  removeCallMemberId as x,
  addCallMemberStream as D,
  removeCallMemberStream as V,
  addCallUnknownPresenceEvt as N,
} from "./call-presence.action"
import { getRoomDiscoveryKeyById as T, getRoomVersion as B } from "../room/room.selector"
import {
  setRoomDiscoveryKey as O,
  setRoomVersion as K,
  setRoomInfo as G,
} from "../room/room.action"
import { getAppCurrentRoomId as U, setAppCurrentRoomId as j } from "../app/app.reducer"
export function* callPresenceEvtHandler({ memberId: o, swarmId: d, peerEvt: m }) {
  switch (m.type) {
    case h.ADD_MEMBER:
      yield e(_({ memberId: o, swarmId: d }))
      break
    case h.REMOVE_MEMBER:
      yield e(x({ memberId: o, swarmId: d }))
      break
    case h.ADD_STREAM: {
      const { streamId: r, streamName: a } = m
      yield e(D({ memberId: o, swarmId: d, streamId: r, streamName: a }))
      break
    }
    case h.REMOVE_STREAM: {
      const { streamId: r, streamName: o } = m
      yield e(V({ swarmId: d, streamId: r, streamName: o }))
      break
    }
    case h.STREAM_STATUS_CHANGED: {
      const { audioMuted: a, videoMuted: l, streamId: s } = m,
        t = yield r(A(d, s))
      t
        ? yield e(
            R({
              memberId: o,
              swarmId: d,
              audioMuted: a,
              videoMuted: l,
              streamName: t,
              streamId: s,
            }),
          )
        : yield p("callPresenceEvtHandler: unknown stream changed")
      break
    }
  }
}
export function* callPresenceMemberResolvedHandler({ payload: e }) {
  try {
    const { swarmId: o, roomId: d } = e,
      m = (yield r(H))[o]
    if (!Array.isArray(m) || 0 === m.length) return
    const a = yield r(u({ roomId: d, swarmId: o }))
    if (!a) return
    for (const e of m) yield callPresenceEvtHandler({ memberId: a, swarmId: o, peerEvt: e })
  } catch (e) {
    yield p("callPresenceMemberResolvedHandler", e)
  }
}
export function* callPresenceHandler({ roomId: o }, d) {
  try {
    if (!d?.type || !d?.swarmId) return
    const { swarmId: m } = d,
      a = yield r(u({ roomId: o, swarmId: m }))
    if (!a) return (yield e(N(d)), void (yield e(E({ roomId: o, swarmId: m }))))
    yield callPresenceEvtHandler({ memberId: a, swarmId: m, peerEvt: d })
  } catch (e) {
    yield p("callPresenceHandler", e)
  }
}
export function* callPeersCounterV2Saga({ roomId: o }) {
  const d = n(),
    m = yield r(w)
  let a = null
  yield s(
    [d.subscribeActiveCalls, o],
    function* (r) {
      const d = r.find((e) => !e.endedAt),
        l = d ? d.members.reduce((e, r) => (r.memberId !== m && e.push(r.memberId), e), []) : [],
        s = i(a, l)
      s && ((a = s), yield e(g({ roomId: o, ids: s })))
      const t = {
        roomId: o,
        callId: d?.callId || null,
        memberId: d?.members?.[0]?.memberId || null,
        isMyCall: d?.members?.some((e) => e.memberId === m) || !1,
      }
      yield e(C(t))
    },
    { onError: (r) => e(y("callPeersCounterV2Saga", r)), onCleanup: () => e(v({ roomId: o })) },
  )
}
function* q({ roomId: o }) {
  const d = n()
  let a = yield r(T(o))
  if (!a) {
    const { discoveryKey: r } = yield I(d.getRoomKeys, o)
    ;((a = r), yield e(O({ roomId: o, key: r })))
  }
  a
    ? (yield m(b, { roomId: o }),
      yield s(
        [() => c().presence.subscribePresence(a)],
        function* (d) {
          const { swarmId: m, type: a } = d
          switch (a) {
            case h.ADD_MEMBER:
              ;(yield e(M({ roomId: o, swarmId: m })),
                (yield r(u({ roomId: o, swarmId: m }))) || (yield e(E({ roomId: o, swarmId: m }))))
              break
            case h.REMOVE_MEMBER:
              ;(yield r(S, o)) > 0 && (yield e(P({ roomId: o, swarmId: m })))
          }
        },
        {
          onError: (r) => e(y("appCallPeersCounterSaga", r)),
          onCleanup: () => e(v({ roomId: o })),
        },
      ))
    : yield e(y("appCallPeersCounterSaga", { message: "unable to get room discovery key" }))
}
export function* callPeersCounterSaga({ roomId: e }) {
  for (; 0 === (yield r(B(e))); ) yield o([K, G])
  ;(yield r(k(e)))
    ? (yield r(U)) !== e
      ? (yield l([a(q, { roomId: e }), o((r) => j.match(r) && r.payload.roomId === e)]),
        yield callPeersCounterV2Saga({ roomId: e }))
      : yield callPeersCounterV2Saga({ roomId: e })
    : yield q({ roomId: e })
}
export function* callPresenceSaga({ roomId: e, callId: r }) {
  ;(yield d(f({ roomId: e }), callPresenceMemberResolvedHandler),
    yield m(b, { roomId: e }),
    yield t([() => c().presence.subscribePresence(r)], callPresenceHandler, {
      params: [{ roomId: e }],
    }))
}