@poolse/react 2.26.0 → 2.28.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/dist/index.cjs CHANGED
@@ -69,27 +69,30 @@ function usePoolse() {
69
69
  }
70
70
  function useMe() {
71
71
  const chat = usePoolse();
72
- const [state, setState] = react.useState({
73
- me: null,
74
- loading: true,
75
- error: null
72
+ const [state, setState] = react.useState(() => {
73
+ const known = chat.me.peek();
74
+ return { me: known, loading: known === null, error: null };
76
75
  });
77
76
  react.useEffect(() => {
78
77
  let cancelled = false;
79
78
  const controller = new AbortController();
79
+ const off = chat.me.onChange((me) => {
80
+ if (!cancelled) setState({ me, loading: false, error: null });
81
+ });
80
82
  chat.me.show(controller.signal).then((me) => {
81
83
  if (!cancelled) setState({ me, loading: false, error: null });
82
84
  }).catch((err) => {
83
85
  if (!cancelled) {
84
- setState({
85
- me: null,
86
+ setState((prev) => ({
87
+ me: prev.me,
86
88
  loading: false,
87
89
  error: err instanceof Error ? err : new Error(String(err))
88
- });
90
+ }));
89
91
  }
90
92
  });
91
93
  return () => {
92
94
  cancelled = true;
95
+ off();
93
96
  controller.abort();
94
97
  };
95
98
  }, [chat]);
@@ -1664,6 +1667,83 @@ function useLiveCall(conversationId) {
1664
1667
  }, [chat, conversationId, apply, refresh]);
1665
1668
  return { call, participantIds, refresh };
1666
1669
  }
1670
+ function useRoom(conversationId, opts) {
1671
+ const poolse = usePoolse();
1672
+ const { call: live, participantIds } = useLiveCall(conversationId);
1673
+ const media = useCallRoom(conversationId, { livekit: opts.livekit, aloneGraceMs: 0 });
1674
+ const session = react.useRef(null);
1675
+ const [joining, setJoining] = react.useState(false);
1676
+ const [error, setError] = react.useState(null);
1677
+ react.useEffect(() => {
1678
+ session.current = null;
1679
+ setError(null);
1680
+ }, [conversationId]);
1681
+ const join = react.useCallback(
1682
+ async (kind = "audio", joinOpts = {}) => {
1683
+ if (!conversationId) return;
1684
+ setJoining(true);
1685
+ setError(null);
1686
+ try {
1687
+ session.current = joinOpts.ring ? await poolse.rooms.ring(conversationId, kind) : await poolse.rooms.start(conversationId, kind);
1688
+ const connected = await media.join();
1689
+ if (!connected) throw new Error("Rooms need the SFU, which this deployment does not have.");
1690
+ if (kind === "video") await media.setCameraEnabled(true);
1691
+ } catch (err) {
1692
+ setError(err instanceof Error ? err : new Error(String(err)));
1693
+ media.leave();
1694
+ } finally {
1695
+ setJoining(false);
1696
+ }
1697
+ },
1698
+ [poolse, conversationId, media]
1699
+ );
1700
+ const leave = react.useCallback(() => {
1701
+ media.leave();
1702
+ const s = session.current;
1703
+ session.current = null;
1704
+ if (s) void poolse.rooms.leave(s).catch(() => {
1705
+ });
1706
+ }, [poolse, media]);
1707
+ const joined = media.status === "connected" || media.status === "connecting" || joining;
1708
+ return {
1709
+ live,
1710
+ presentIds: participantIds,
1711
+ joined,
1712
+ joining,
1713
+ join,
1714
+ leave,
1715
+ media,
1716
+ error: error ?? media.error
1717
+ };
1718
+ }
1719
+ function useReadReceipts() {
1720
+ const chat = usePoolse();
1721
+ const { me } = useMe();
1722
+ const state = receiptsOf(me);
1723
+ const setShared = react.useCallback(
1724
+ async (share) => {
1725
+ await chat.me.update({ read_receipts: share });
1726
+ },
1727
+ [chat]
1728
+ );
1729
+ return { ...state, setShared };
1730
+ }
1731
+ function receiptsOf(me) {
1732
+ const r = me?.read_receipts;
1733
+ return {
1734
+ visible: r?.visible ?? true,
1735
+ mode: r?.mode ?? "on",
1736
+ shared: r?.shared ?? true,
1737
+ canChange: r?.can_change ?? false
1738
+ };
1739
+ }
1740
+ var EDIT_WINDOW_MS = 15 * 60 * 1e3;
1741
+ function canEditOwnMessage(args) {
1742
+ if (!args.isSelf || args.deleted) return false;
1743
+ if (args.receiptsVisible) return (args.readState ?? "sent") === "sent";
1744
+ const sent = Date.parse(args.insertedAt);
1745
+ return Number.isFinite(sent) && (args.now ?? Date.now()) - sent < EDIT_WINDOW_MS;
1746
+ }
1667
1747
 
1668
1748
  Object.defineProperty(exports, "ApiError", {
1669
1749
  enumerable: true,
@@ -1717,9 +1797,12 @@ Object.defineProperty(exports, "parseCallLogBody", {
1717
1797
  enumerable: true,
1718
1798
  get: function () { return sdk.parseCallLogBody; }
1719
1799
  });
1800
+ exports.EDIT_WINDOW_MS = EDIT_WINDOW_MS;
1720
1801
  exports.PoolseProvider = PoolseProvider;
1802
+ exports.canEditOwnMessage = canEditOwnMessage;
1721
1803
  exports.computeGroupPosition = computeGroupPosition;
1722
1804
  exports.formatDayLabel = formatDayLabel;
1805
+ exports.receiptsOf = receiptsOf;
1723
1806
  exports.sameDay = sameDay;
1724
1807
  exports.sameGroup = sameGroup;
1725
1808
  exports.useAttachmentUpload = useAttachmentUpload;
@@ -1735,7 +1818,9 @@ exports.useMessages = useMessages;
1735
1818
  exports.usePoolse = usePoolse;
1736
1819
  exports.usePresence = usePresence;
1737
1820
  exports.useReactions = useReactions;
1821
+ exports.useReadReceipts = useReadReceipts;
1738
1822
  exports.useRealtimeStatus = useRealtimeStatus;
1823
+ exports.useRoom = useRoom;
1739
1824
  exports.useThread = useThread;
1740
1825
  exports.useTyping = useTyping;
1741
1826
  exports.useUser = useUser;