@poolse/react 2.1.6 → 2.2.0
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/CHANGELOG.md +149 -149
- package/LICENSE +21 -21
- package/README.md +335 -335
- package/dist/index.cjs +181 -0
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +100 -2
- package/dist/index.d.ts +100 -2
- package/dist/index.js +180 -1
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { PoolseConfig, Poolse, Me, Uuid, Conversation, ConversationCreateRequest, Membership, MemberRole, Message, MessageCreateRequest, RealtimeStatus, Attachment, AttachmentUploadInput, PoolseUserProfile } from '@poolse/sdk';
|
|
2
|
+
import { PoolseConfig, Poolse, Me, Uuid, Conversation, ConversationCreateRequest, Membership, MemberRole, Message, MessageCreateRequest, RealtimeStatus, Attachment, AttachmentUploadInput, PoolseUserProfile, VoiceStatus, VoiceParticipant, VoiceRoomOptions, IncomingCall, OutgoingCall } from '@poolse/sdk';
|
|
3
3
|
export { ApiError, Attachment, AttachmentStatus, AttachmentUploadInput, AttachmentUploadRequest, AttachmentUploadResponse, AuthError, Conversation, ConversationCreateRequest, Me, MemberRole, Membership, Message, MessageCreateRequest, MessageType, NetworkError, PoolseConfig, PoolseError, PoolseUserProfile, RateLimitedError, RealtimeStatus, Uuid } from '@poolse/sdk';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
|
@@ -485,4 +485,102 @@ declare function sameDay(a: string, b: string): boolean;
|
|
|
485
485
|
*/
|
|
486
486
|
declare function formatDayLabel(iso: string, now?: Date): string;
|
|
487
487
|
|
|
488
|
-
|
|
488
|
+
interface UseVoiceRoom {
|
|
489
|
+
status: VoiceStatus;
|
|
490
|
+
/** Everyone currently in the room, oldest join first. */
|
|
491
|
+
participants: VoiceParticipant[];
|
|
492
|
+
muted: boolean;
|
|
493
|
+
error: Error | null;
|
|
494
|
+
/** Acquire the mic and connect. Safe to call twice. */
|
|
495
|
+
join: () => Promise<void>;
|
|
496
|
+
leave: () => void;
|
|
497
|
+
toggleMute: () => void;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Discord-style voice room for a conversation: join, see who else is
|
|
501
|
+
* in, watch who's talking, mute yourself.
|
|
502
|
+
*
|
|
503
|
+
* The room is torn down when the conversation changes or the component
|
|
504
|
+
* unmounts, so a navigation away hangs up rather than leaving a phantom
|
|
505
|
+
* participant behind.
|
|
506
|
+
*
|
|
507
|
+
* const voice = useVoiceRoom(conversationId);
|
|
508
|
+
* <Button onPress={voice.join} title="Join Voice" />
|
|
509
|
+
*
|
|
510
|
+
* For ringing someone who hasn't joined yet, see `useCalls`.
|
|
511
|
+
*/
|
|
512
|
+
declare function useVoiceRoom(conversationId: string | null, opts?: VoiceRoomOptions): UseVoiceRoom;
|
|
513
|
+
|
|
514
|
+
/** Where a call is in its lifecycle, from this device's point of view. */
|
|
515
|
+
type CallPhase = 'idle'
|
|
516
|
+
/** We placed a call and are waiting for an answer. */
|
|
517
|
+
| 'ringing-out'
|
|
518
|
+
/** Someone is ringing us. */
|
|
519
|
+
| 'ringing-in'
|
|
520
|
+
/** Both sides agreed; the voice room should be joined now. */
|
|
521
|
+
| 'active'
|
|
522
|
+
/** The far side said no. */
|
|
523
|
+
| 'declined'
|
|
524
|
+
/** The person we called is already on another call. */
|
|
525
|
+
| 'busy'
|
|
526
|
+
/** Nobody picked up before the ring timeout elapsed. */
|
|
527
|
+
| 'timed-out';
|
|
528
|
+
interface UseCallsOptions {
|
|
529
|
+
/**
|
|
530
|
+
* How long a ring may go unanswered, in milliseconds, before it is
|
|
531
|
+
* given up on. Defaults to 45s, roughly what the mainstream call apps
|
|
532
|
+
* use. Pass `0` to ring indefinitely.
|
|
533
|
+
*
|
|
534
|
+
* The server deliberately holds no timer — only the UI knows when it
|
|
535
|
+
* stopped waiting — so this is what actually ends an unanswered call.
|
|
536
|
+
* Both directions are covered: an outbound ring cancels itself, and an
|
|
537
|
+
* inbound one gives up too, otherwise a caller that crashed mid-ring
|
|
538
|
+
* would leave the callee's phone ringing forever.
|
|
539
|
+
*/
|
|
540
|
+
ringTimeoutMs?: number;
|
|
541
|
+
}
|
|
542
|
+
interface UseCalls {
|
|
543
|
+
phase: CallPhase;
|
|
544
|
+
/** Set while `phase` is `ringing-in`. */
|
|
545
|
+
incoming: IncomingCall | null;
|
|
546
|
+
/** Set while `phase` is `ringing-out` or `active`. */
|
|
547
|
+
outgoing: OutgoingCall | null;
|
|
548
|
+
/**
|
|
549
|
+
* Conversation whose voice room should be joined once `phase` turns
|
|
550
|
+
* `active` — the same id for both caller and callee.
|
|
551
|
+
*/
|
|
552
|
+
activeConversationId: string | null;
|
|
553
|
+
error: Error | null;
|
|
554
|
+
/** Ring every other member of a conversation. */
|
|
555
|
+
call: (conversationId: string) => Promise<void>;
|
|
556
|
+
/** Answer the inbound ring. */
|
|
557
|
+
accept: () => Promise<void>;
|
|
558
|
+
/** Reject the inbound ring. */
|
|
559
|
+
decline: () => Promise<void>;
|
|
560
|
+
/** Hang up an outbound ring before it's answered. */
|
|
561
|
+
cancel: () => Promise<void>;
|
|
562
|
+
/** Drop back to idle — call after leaving the room, or to clear a
|
|
563
|
+
* `declined` / `busy` / `timed-out` state the UI has finished
|
|
564
|
+
* showing. */
|
|
565
|
+
reset: () => void;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* WhatsApp-style calling: ring a conversation, show an incoming-call
|
|
569
|
+
* screen, accept or decline.
|
|
570
|
+
*
|
|
571
|
+
* This hook is only the *invitation* half. Audio starts when you join
|
|
572
|
+
* the voice room, which the host app does once `phase` is `active`:
|
|
573
|
+
*
|
|
574
|
+
* const calls = useCalls(myUserId);
|
|
575
|
+
* const voice = useVoiceRoom(calls.activeConversationId);
|
|
576
|
+
*
|
|
577
|
+
* useEffect(() => {
|
|
578
|
+
* if (calls.phase === 'active') void voice.join();
|
|
579
|
+
* }, [calls.phase]);
|
|
580
|
+
*
|
|
581
|
+
* Keeping them separate means a "join voice" button and a ringing call
|
|
582
|
+
* share exactly one implementation of the media path.
|
|
583
|
+
*/
|
|
584
|
+
declare function useCalls(userId: string | null, opts?: UseCallsOptions): UseCalls;
|
|
585
|
+
|
|
586
|
+
export { type CallPhase, type GroupPosition, PoolseProvider, type PoolseProviderProps, type ReactionMap, type UploadItem, type UploadItemStatus, type UseCalls, type UseUserState, type UseVoiceRoom, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { PoolseConfig, Poolse, Me, Uuid, Conversation, ConversationCreateRequest, Membership, MemberRole, Message, MessageCreateRequest, RealtimeStatus, Attachment, AttachmentUploadInput, PoolseUserProfile } from '@poolse/sdk';
|
|
2
|
+
import { PoolseConfig, Poolse, Me, Uuid, Conversation, ConversationCreateRequest, Membership, MemberRole, Message, MessageCreateRequest, RealtimeStatus, Attachment, AttachmentUploadInput, PoolseUserProfile, VoiceStatus, VoiceParticipant, VoiceRoomOptions, IncomingCall, OutgoingCall } from '@poolse/sdk';
|
|
3
3
|
export { ApiError, Attachment, AttachmentStatus, AttachmentUploadInput, AttachmentUploadRequest, AttachmentUploadResponse, AuthError, Conversation, ConversationCreateRequest, Me, MemberRole, Membership, Message, MessageCreateRequest, MessageType, NetworkError, PoolseConfig, PoolseError, PoolseUserProfile, RateLimitedError, RealtimeStatus, Uuid } from '@poolse/sdk';
|
|
4
4
|
import { ReactNode } from 'react';
|
|
5
5
|
|
|
@@ -485,4 +485,102 @@ declare function sameDay(a: string, b: string): boolean;
|
|
|
485
485
|
*/
|
|
486
486
|
declare function formatDayLabel(iso: string, now?: Date): string;
|
|
487
487
|
|
|
488
|
-
|
|
488
|
+
interface UseVoiceRoom {
|
|
489
|
+
status: VoiceStatus;
|
|
490
|
+
/** Everyone currently in the room, oldest join first. */
|
|
491
|
+
participants: VoiceParticipant[];
|
|
492
|
+
muted: boolean;
|
|
493
|
+
error: Error | null;
|
|
494
|
+
/** Acquire the mic and connect. Safe to call twice. */
|
|
495
|
+
join: () => Promise<void>;
|
|
496
|
+
leave: () => void;
|
|
497
|
+
toggleMute: () => void;
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Discord-style voice room for a conversation: join, see who else is
|
|
501
|
+
* in, watch who's talking, mute yourself.
|
|
502
|
+
*
|
|
503
|
+
* The room is torn down when the conversation changes or the component
|
|
504
|
+
* unmounts, so a navigation away hangs up rather than leaving a phantom
|
|
505
|
+
* participant behind.
|
|
506
|
+
*
|
|
507
|
+
* const voice = useVoiceRoom(conversationId);
|
|
508
|
+
* <Button onPress={voice.join} title="Join Voice" />
|
|
509
|
+
*
|
|
510
|
+
* For ringing someone who hasn't joined yet, see `useCalls`.
|
|
511
|
+
*/
|
|
512
|
+
declare function useVoiceRoom(conversationId: string | null, opts?: VoiceRoomOptions): UseVoiceRoom;
|
|
513
|
+
|
|
514
|
+
/** Where a call is in its lifecycle, from this device's point of view. */
|
|
515
|
+
type CallPhase = 'idle'
|
|
516
|
+
/** We placed a call and are waiting for an answer. */
|
|
517
|
+
| 'ringing-out'
|
|
518
|
+
/** Someone is ringing us. */
|
|
519
|
+
| 'ringing-in'
|
|
520
|
+
/** Both sides agreed; the voice room should be joined now. */
|
|
521
|
+
| 'active'
|
|
522
|
+
/** The far side said no. */
|
|
523
|
+
| 'declined'
|
|
524
|
+
/** The person we called is already on another call. */
|
|
525
|
+
| 'busy'
|
|
526
|
+
/** Nobody picked up before the ring timeout elapsed. */
|
|
527
|
+
| 'timed-out';
|
|
528
|
+
interface UseCallsOptions {
|
|
529
|
+
/**
|
|
530
|
+
* How long a ring may go unanswered, in milliseconds, before it is
|
|
531
|
+
* given up on. Defaults to 45s, roughly what the mainstream call apps
|
|
532
|
+
* use. Pass `0` to ring indefinitely.
|
|
533
|
+
*
|
|
534
|
+
* The server deliberately holds no timer — only the UI knows when it
|
|
535
|
+
* stopped waiting — so this is what actually ends an unanswered call.
|
|
536
|
+
* Both directions are covered: an outbound ring cancels itself, and an
|
|
537
|
+
* inbound one gives up too, otherwise a caller that crashed mid-ring
|
|
538
|
+
* would leave the callee's phone ringing forever.
|
|
539
|
+
*/
|
|
540
|
+
ringTimeoutMs?: number;
|
|
541
|
+
}
|
|
542
|
+
interface UseCalls {
|
|
543
|
+
phase: CallPhase;
|
|
544
|
+
/** Set while `phase` is `ringing-in`. */
|
|
545
|
+
incoming: IncomingCall | null;
|
|
546
|
+
/** Set while `phase` is `ringing-out` or `active`. */
|
|
547
|
+
outgoing: OutgoingCall | null;
|
|
548
|
+
/**
|
|
549
|
+
* Conversation whose voice room should be joined once `phase` turns
|
|
550
|
+
* `active` — the same id for both caller and callee.
|
|
551
|
+
*/
|
|
552
|
+
activeConversationId: string | null;
|
|
553
|
+
error: Error | null;
|
|
554
|
+
/** Ring every other member of a conversation. */
|
|
555
|
+
call: (conversationId: string) => Promise<void>;
|
|
556
|
+
/** Answer the inbound ring. */
|
|
557
|
+
accept: () => Promise<void>;
|
|
558
|
+
/** Reject the inbound ring. */
|
|
559
|
+
decline: () => Promise<void>;
|
|
560
|
+
/** Hang up an outbound ring before it's answered. */
|
|
561
|
+
cancel: () => Promise<void>;
|
|
562
|
+
/** Drop back to idle — call after leaving the room, or to clear a
|
|
563
|
+
* `declined` / `busy` / `timed-out` state the UI has finished
|
|
564
|
+
* showing. */
|
|
565
|
+
reset: () => void;
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* WhatsApp-style calling: ring a conversation, show an incoming-call
|
|
569
|
+
* screen, accept or decline.
|
|
570
|
+
*
|
|
571
|
+
* This hook is only the *invitation* half. Audio starts when you join
|
|
572
|
+
* the voice room, which the host app does once `phase` is `active`:
|
|
573
|
+
*
|
|
574
|
+
* const calls = useCalls(myUserId);
|
|
575
|
+
* const voice = useVoiceRoom(calls.activeConversationId);
|
|
576
|
+
*
|
|
577
|
+
* useEffect(() => {
|
|
578
|
+
* if (calls.phase === 'active') void voice.join();
|
|
579
|
+
* }, [calls.phase]);
|
|
580
|
+
*
|
|
581
|
+
* Keeping them separate means a "join voice" button and a ringing call
|
|
582
|
+
* share exactly one implementation of the media path.
|
|
583
|
+
*/
|
|
584
|
+
declare function useCalls(userId: string | null, opts?: UseCallsOptions): UseCalls;
|
|
585
|
+
|
|
586
|
+
export { type CallPhase, type GroupPosition, PoolseProvider, type PoolseProviderProps, type ReactionMap, type UploadItem, type UploadItemStatus, type UseCalls, type UseUserState, type UseVoiceRoom, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
package/dist/index.js
CHANGED
|
@@ -1062,7 +1062,186 @@ function formatDayLabel(iso, now = /* @__PURE__ */ new Date()) {
|
|
|
1062
1062
|
}
|
|
1063
1063
|
return d.toLocaleDateString(void 0, { day: "numeric", month: "short", year: "numeric" });
|
|
1064
1064
|
}
|
|
1065
|
+
function useVoiceRoom(conversationId, opts = {}) {
|
|
1066
|
+
const poolse = usePoolse();
|
|
1067
|
+
const [status, setStatus] = useState("idle");
|
|
1068
|
+
const [participants, setParticipants] = useState([]);
|
|
1069
|
+
const [muted, setMuted] = useState(false);
|
|
1070
|
+
const [error, setError] = useState(null);
|
|
1071
|
+
const optsRef = useRef(opts);
|
|
1072
|
+
const room = useMemo(
|
|
1073
|
+
() => conversationId ? poolse.realtime.voice(conversationId, optsRef.current) : null,
|
|
1074
|
+
[poolse, conversationId]
|
|
1075
|
+
);
|
|
1076
|
+
useEffect(() => {
|
|
1077
|
+
if (!room) return;
|
|
1078
|
+
setStatus(room.getStatus());
|
|
1079
|
+
setParticipants(room.getParticipants());
|
|
1080
|
+
setMuted(room.isMuted());
|
|
1081
|
+
const offStatus = room.onStatus(setStatus);
|
|
1082
|
+
const offRoster = room.onParticipants(setParticipants);
|
|
1083
|
+
const offError = room.onError(setError);
|
|
1084
|
+
return () => {
|
|
1085
|
+
offStatus();
|
|
1086
|
+
offRoster();
|
|
1087
|
+
offError();
|
|
1088
|
+
room.leave();
|
|
1089
|
+
};
|
|
1090
|
+
}, [room]);
|
|
1091
|
+
const join = useCallback(async () => {
|
|
1092
|
+
if (!room) return;
|
|
1093
|
+
setError(null);
|
|
1094
|
+
try {
|
|
1095
|
+
await room.join();
|
|
1096
|
+
} catch (err) {
|
|
1097
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1098
|
+
}
|
|
1099
|
+
}, [room]);
|
|
1100
|
+
const leave = useCallback(() => {
|
|
1101
|
+
room?.leave();
|
|
1102
|
+
}, [room]);
|
|
1103
|
+
const toggleMute = useCallback(() => {
|
|
1104
|
+
if (!room) return;
|
|
1105
|
+
setMuted(room.toggleMute());
|
|
1106
|
+
}, [room]);
|
|
1107
|
+
return { status, participants, muted, error, join, leave, toggleMute };
|
|
1108
|
+
}
|
|
1109
|
+
function useCalls(userId, opts = {}) {
|
|
1110
|
+
const ringTimeoutMs = opts.ringTimeoutMs ?? 45e3;
|
|
1111
|
+
const poolse = usePoolse();
|
|
1112
|
+
const [phase, setPhase] = useState("idle");
|
|
1113
|
+
const [incoming, setIncoming] = useState(null);
|
|
1114
|
+
const [outgoing, setOutgoing] = useState(null);
|
|
1115
|
+
const [activeConversationId, setActiveConversationId] = useState(null);
|
|
1116
|
+
const [error, setError] = useState(null);
|
|
1117
|
+
const actionsRef = useRef({
|
|
1118
|
+
cancel: async () => {
|
|
1119
|
+
},
|
|
1120
|
+
decline: async () => {
|
|
1121
|
+
}
|
|
1122
|
+
});
|
|
1123
|
+
const calls = useMemo(() => userId ? poolse.realtime.calls(userId) : null, [poolse, userId]);
|
|
1124
|
+
useEffect(() => {
|
|
1125
|
+
if (!calls) return;
|
|
1126
|
+
const offIncoming = calls.onIncoming((call2) => {
|
|
1127
|
+
setPhase((current) => {
|
|
1128
|
+
if (current !== "idle") {
|
|
1129
|
+
void calls.markBusy(call2).catch(() => {
|
|
1130
|
+
});
|
|
1131
|
+
return current;
|
|
1132
|
+
}
|
|
1133
|
+
setIncoming(call2);
|
|
1134
|
+
return "ringing-in";
|
|
1135
|
+
});
|
|
1136
|
+
});
|
|
1137
|
+
const offAccepted = calls.onAccepted((call2) => {
|
|
1138
|
+
setPhase("active");
|
|
1139
|
+
setActiveConversationId(call2.conversationId);
|
|
1140
|
+
});
|
|
1141
|
+
const offDeclined = calls.onDeclined(() => {
|
|
1142
|
+
setPhase("declined");
|
|
1143
|
+
setOutgoing(null);
|
|
1144
|
+
});
|
|
1145
|
+
const offBusy = calls.onBusy(() => {
|
|
1146
|
+
setPhase("busy");
|
|
1147
|
+
setOutgoing(null);
|
|
1148
|
+
});
|
|
1149
|
+
const offCancelled = calls.onCancelled((call2) => {
|
|
1150
|
+
setIncoming((current) => {
|
|
1151
|
+
if (current && current.callId !== call2.callId) return current;
|
|
1152
|
+
setPhase("idle");
|
|
1153
|
+
return null;
|
|
1154
|
+
});
|
|
1155
|
+
});
|
|
1156
|
+
return () => {
|
|
1157
|
+
offIncoming();
|
|
1158
|
+
offAccepted();
|
|
1159
|
+
offDeclined();
|
|
1160
|
+
offBusy();
|
|
1161
|
+
offCancelled();
|
|
1162
|
+
};
|
|
1163
|
+
}, [calls]);
|
|
1164
|
+
const call = useCallback(
|
|
1165
|
+
async (conversationId) => {
|
|
1166
|
+
if (!calls) return;
|
|
1167
|
+
setError(null);
|
|
1168
|
+
try {
|
|
1169
|
+
const placed = await calls.invite(conversationId);
|
|
1170
|
+
setOutgoing(placed);
|
|
1171
|
+
setPhase("ringing-out");
|
|
1172
|
+
} catch (err) {
|
|
1173
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1174
|
+
setPhase("idle");
|
|
1175
|
+
}
|
|
1176
|
+
},
|
|
1177
|
+
[calls]
|
|
1178
|
+
);
|
|
1179
|
+
const accept = useCallback(async () => {
|
|
1180
|
+
if (!calls || !incoming) return;
|
|
1181
|
+
try {
|
|
1182
|
+
await calls.accept(incoming);
|
|
1183
|
+
setActiveConversationId(incoming.conversationId);
|
|
1184
|
+
setPhase("active");
|
|
1185
|
+
setIncoming(null);
|
|
1186
|
+
} catch (err) {
|
|
1187
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1188
|
+
}
|
|
1189
|
+
}, [calls, incoming]);
|
|
1190
|
+
const decline = useCallback(async () => {
|
|
1191
|
+
if (!calls || !incoming) return;
|
|
1192
|
+
try {
|
|
1193
|
+
await calls.decline(incoming);
|
|
1194
|
+
} catch (err) {
|
|
1195
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1196
|
+
} finally {
|
|
1197
|
+
setIncoming(null);
|
|
1198
|
+
setPhase("idle");
|
|
1199
|
+
}
|
|
1200
|
+
}, [calls, incoming]);
|
|
1201
|
+
const cancel = useCallback(async () => {
|
|
1202
|
+
if (!calls || !outgoing) return;
|
|
1203
|
+
try {
|
|
1204
|
+
await calls.cancel(outgoing);
|
|
1205
|
+
} catch (err) {
|
|
1206
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
1207
|
+
} finally {
|
|
1208
|
+
setOutgoing(null);
|
|
1209
|
+
setPhase("idle");
|
|
1210
|
+
}
|
|
1211
|
+
}, [calls, outgoing]);
|
|
1212
|
+
actionsRef.current = { cancel, decline };
|
|
1213
|
+
useEffect(() => {
|
|
1214
|
+
if (ringTimeoutMs <= 0) return;
|
|
1215
|
+
if (phase !== "ringing-out" && phase !== "ringing-in") return;
|
|
1216
|
+
const outbound = phase === "ringing-out";
|
|
1217
|
+
const timer = setTimeout(() => {
|
|
1218
|
+
void (outbound ? actionsRef.current.cancel() : actionsRef.current.decline()).finally(() => {
|
|
1219
|
+
if (outbound) setPhase("timed-out");
|
|
1220
|
+
});
|
|
1221
|
+
}, ringTimeoutMs);
|
|
1222
|
+
return () => clearTimeout(timer);
|
|
1223
|
+
}, [phase, ringTimeoutMs]);
|
|
1224
|
+
const reset = useCallback(() => {
|
|
1225
|
+
setPhase("idle");
|
|
1226
|
+
setIncoming(null);
|
|
1227
|
+
setOutgoing(null);
|
|
1228
|
+
setActiveConversationId(null);
|
|
1229
|
+
setError(null);
|
|
1230
|
+
}, []);
|
|
1231
|
+
return {
|
|
1232
|
+
phase,
|
|
1233
|
+
incoming,
|
|
1234
|
+
outgoing,
|
|
1235
|
+
activeConversationId,
|
|
1236
|
+
error,
|
|
1237
|
+
call,
|
|
1238
|
+
accept,
|
|
1239
|
+
decline,
|
|
1240
|
+
cancel,
|
|
1241
|
+
reset
|
|
1242
|
+
};
|
|
1243
|
+
}
|
|
1065
1244
|
|
|
1066
|
-
export { PoolseProvider, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser };
|
|
1245
|
+
export { PoolseProvider, computeGroupPosition, formatDayLabel, sameDay, sameGroup, useAttachmentUpload, useAttachmentUrl, useCalls, useConversation, useConversations, useMe, useMembers, useMessages, usePoolse, usePresence, useReactions, useRealtimeStatus, useThread, useTyping, useUser, useVoiceRoom };
|
|
1067
1246
|
//# sourceMappingURL=index.js.map
|
|
1068
1247
|
//# sourceMappingURL=index.js.map
|