@decentnetwork/beagle 0.1.35 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- window.__DK_UI_VERSION="0.1.34";
1
+ window.__DK_UI_VERSION="0.1.35";
2
2
  const ICON_PATHS = {
3
3
  // ---- tab bar (the four must feel like one set) ----
4
4
  users: '<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/>',
@@ -3795,6 +3795,14 @@ function useCallController(selfId, onCallLog) {
3795
3795
  return;
3796
3796
  }
3797
3797
  engine.on("incomingCall", (info) => {
3798
+ const claimedAt = claimedCalls.current.get(String(info.callId).toLowerCase());
3799
+ if (claimedAt && Date.now() - claimedAt < 5 * 6e4) {
3800
+ try {
3801
+ engine.discard && engine.discard(info.callId);
3802
+ } catch (e) {
3803
+ }
3804
+ return;
3805
+ }
3798
3806
  setIncoming(info);
3799
3807
  if (onCallLogRef.current)
3800
3808
  onCallLogRef.current(info.peerId, !!info.video, "incoming");
@@ -3860,6 +3868,7 @@ function useCallController(selfId, onCallLog) {
3860
3868
  }, [active]);
3861
3869
  const claimTabId = React.useRef(Math.random().toString(36).slice(2));
3862
3870
  const claimBus = React.useRef(null);
3871
+ const claimedCalls = React.useRef(/* @__PURE__ */ new Map());
3863
3872
  React.useEffect(() => {
3864
3873
  let ch = null;
3865
3874
  try {
@@ -3872,9 +3881,16 @@ function useCallController(selfId, onCallLog) {
3872
3881
  const m = ev.data || {};
3873
3882
  if (!m || m.tabId === claimTabId.current || m.type !== "claimed")
3874
3883
  return;
3884
+ if (m.callId)
3885
+ claimedCalls.current.set(String(m.callId).toLowerCase(), Date.now());
3875
3886
  const inc = incomingRef.current;
3876
- if (inc && (inc.callId === m.callId || inc.peerId === m.peerId))
3887
+ if (inc && (inc.callId === m.callId || inc.peerId === m.peerId)) {
3877
3888
  setIncoming(null);
3889
+ try {
3890
+ engineRef.current && engineRef.current.discard && engineRef.current.discard(inc.callId);
3891
+ } catch (e) {
3892
+ }
3893
+ }
3878
3894
  };
3879
3895
  return () => {
3880
3896
  try {
@@ -4664,7 +4680,7 @@ function DkApp() {
4664
4680
  }, [refreshBackend]);
4665
4681
  React.useEffect(() => {
4666
4682
  const mine = window.__DK_UI_VERSION;
4667
- const served = me && me.lanVer;
4683
+ const served = me && me.beagleVer;
4668
4684
  if (!mine || !served || mine === served)
4669
4685
  return;
4670
4686
  const key = "dk-reloaded-for-" + served;
@@ -4672,7 +4688,7 @@ function DkApp() {
4672
4688
  return;
4673
4689
  sessionStorage.setItem(key, "1");
4674
4690
  window.location.reload();
4675
- }, [me && me.lanVer]);
4691
+ }, [me && me.beagleVer]);
4676
4692
  const peers = data.peers;
4677
4693
  const [pendingAddr, setPendingAddr] = React.useState(() => dkParseDeepLinkAddress());
4678
4694
  React.useEffect(() => {
@@ -402,6 +402,16 @@ var PeerWebRTC = (() => {
402
402
  var _a;
403
403
  return !!((_a = __privateGet(this, _sessions).get(__privateMethod(this, _normId, normId_fn).call(this, callId))) == null ? void 0 : _a.screenStream);
404
404
  }
405
+ /** Silently drop a call WITHOUT signaling the peer — for a tab that lost
406
+ * the cross-tab answer race: another tab owns the call now, so sending
407
+ * reject/bye from this one would kill the live call. Local cleanup only. */
408
+ discard(callId) {
409
+ const session = __privateGet(this, _sessions).get(__privateMethod(this, _normId, normId_fn).call(this, callId));
410
+ if (!session)
411
+ return;
412
+ __privateMethod(this, _log, log_fn).call(this, `discarding call ${callId} (claimed elsewhere)`);
413
+ __privateMethod(this, _cleanup, cleanup_fn).call(this, session, "close");
414
+ }
405
415
  /** Tear down every call (e.g. on app shutdown). */
406
416
  dispose() {
407
417
  for (const session of [...__privateGet(this, _sessions).values()]) {
package/dist/server.js CHANGED
@@ -1406,6 +1406,11 @@ export function startBeagleServer(opts) {
1406
1406
  autoAccept: typeof node.autoAccept === "boolean" ? node.autoAccept : null,
1407
1407
  avatarUrl: ensPub.get(identity.userid ?? "")?.avatarUrl ?? null,
1408
1408
  punkId: ensPub.get(identity.userid ?? "")?.punkId ?? null,
1409
+ // The UI compares this against its baked-in __DK_UI_VERSION and
1410
+ // reloads itself when they differ — an open tab otherwise runs a
1411
+ // stale bundle forever after a beagle update (multi-tab call fixes
1412
+ // "didn't work" purely because old tabs never picked them up).
1413
+ beagleVer: beagleVersion(),
1409
1414
  };
1410
1415
  const fl = (flist.ok ? (flist.data?.friends ?? []) : []);
1411
1416
  const peers = fl.map((f) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@decentnetwork/beagle",
3
- "version": "0.1.35",
3
+ "version": "0.1.36",
4
4
  "description": "Beagle — P2P chat, file transfer and calls for regular users, on the Decent Network. No admin privilege required.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -28,7 +28,7 @@
28
28
  "@decentnetwork/chat-components": "^0.1.3",
29
29
  "@decentnetwork/lan": "^0.1.256",
30
30
  "@decentnetwork/peer": "^0.1.138",
31
- "@decentnetwork/peer-webrtc": "^0.2.13",
31
+ "@decentnetwork/peer-webrtc": "^0.2.14",
32
32
  "js-yaml": "^4.1.0",
33
33
  "yargs": "^17.7.2"
34
34
  },