@poolse/react 2.8.0 → 2.8.1

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.
package/dist/index.cjs CHANGED
@@ -1070,6 +1070,7 @@ function useVoiceRoom(conversationId, opts = {}) {
1070
1070
  const [muted, setMuted] = react.useState(false);
1071
1071
  const [error, setError] = react.useState(null);
1072
1072
  const optsRef = react.useRef(opts);
1073
+ const joined = react.useRef(false);
1073
1074
  const room = react.useMemo(
1074
1075
  () => conversationId ? poolse.realtime.voice(conversationId, optsRef.current) : null,
1075
1076
  [poolse, conversationId]
@@ -1086,7 +1087,10 @@ function useVoiceRoom(conversationId, opts = {}) {
1086
1087
  offStatus();
1087
1088
  offRoster();
1088
1089
  offError();
1089
- room.leave();
1090
+ if (joined.current) {
1091
+ joined.current = false;
1092
+ room.leave();
1093
+ }
1090
1094
  };
1091
1095
  }, [room]);
1092
1096
  const join = react.useCallback(async () => {
@@ -1094,11 +1098,14 @@ function useVoiceRoom(conversationId, opts = {}) {
1094
1098
  setError(null);
1095
1099
  try {
1096
1100
  await room.join();
1101
+ joined.current = true;
1097
1102
  } catch (err) {
1098
1103
  setError(err instanceof Error ? err : new Error(String(err)));
1099
1104
  }
1100
1105
  }, [room]);
1101
1106
  const leave = react.useCallback(() => {
1107
+ if (!joined.current) return;
1108
+ joined.current = false;
1102
1109
  room?.leave();
1103
1110
  }, [room]);
1104
1111
  const toggleMute = react.useCallback(() => {
@@ -1147,6 +1154,12 @@ function useCalls(userId, opts = {}) {
1147
1154
  setPhase("busy");
1148
1155
  setOutgoing(null);
1149
1156
  });
1157
+ const offEnded = calls.onEnded(() => {
1158
+ setPhase("idle");
1159
+ setIncoming(null);
1160
+ setOutgoing(null);
1161
+ setActiveConversationId(null);
1162
+ });
1150
1163
  const offCancelled = calls.onCancelled((call2) => {
1151
1164
  setIncoming((current) => {
1152
1165
  if (current && current.callId !== call2.callId) return current;
@@ -1159,6 +1172,7 @@ function useCalls(userId, opts = {}) {
1159
1172
  offAccepted();
1160
1173
  offDeclined();
1161
1174
  offBusy();
1175
+ offEnded();
1162
1176
  offCancelled();
1163
1177
  };
1164
1178
  }, [calls]);
@@ -1230,6 +1244,27 @@ function useCalls(userId, opts = {}) {
1230
1244
  }, ringTimeoutMs);
1231
1245
  return () => clearTimeout(timer);
1232
1246
  }, [phase, ringTimeoutMs]);
1247
+ const hangUp = react.useCallback(async () => {
1248
+ const conversationId = activeConversationId ?? incoming?.conversationId ?? outgoing?.conversationId;
1249
+ const callId = incoming?.callId ?? outgoing?.callId;
1250
+ try {
1251
+ if (!calls || !callId || !conversationId) return;
1252
+ if (phase === "ringing-out" && outgoing) {
1253
+ await calls.cancel(outgoing);
1254
+ } else if (phase === "ringing-in" && incoming) {
1255
+ await calls.decline(incoming);
1256
+ } else if (phase === "active") {
1257
+ await calls.hangUp({ callId, conversationId });
1258
+ }
1259
+ } catch (err) {
1260
+ setError(err instanceof Error ? err : new Error(String(err)));
1261
+ } finally {
1262
+ setPhase("idle");
1263
+ setIncoming(null);
1264
+ setOutgoing(null);
1265
+ setActiveConversationId(null);
1266
+ }
1267
+ }, [calls, phase, incoming, outgoing, activeConversationId]);
1233
1268
  const reset = react.useCallback(() => {
1234
1269
  setPhase("idle");
1235
1270
  setIncoming(null);
@@ -1247,6 +1282,7 @@ function useCalls(userId, opts = {}) {
1247
1282
  accept,
1248
1283
  decline,
1249
1284
  cancel,
1285
+ hangUp,
1250
1286
  reset
1251
1287
  };
1252
1288
  }