@aperture-browser/session-react 0.0.0-nightly.83.67c1220a0cc0 → 0.0.0-nightly.84.0c72bc0d2eaf

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.
@@ -95,7 +95,7 @@ const pointerButtonCode = {
95
95
  right: 273,
96
96
  middle: 274
97
97
  };
98
- function useLiveSession({ sessionId, displayName = null, credentials, sessionToken, role, enabled, webrtcSupported, iceServers }) {
98
+ function useLiveSession({ sessionId, displayName = null, credentials, sessionToken, role, enabled, webrtcSupported, iceServers, autoSize }) {
99
99
  const identity = useMemo(() => collaborationIdentity(role, displayName), [displayName, role]);
100
100
  const runtime = useRuntime();
101
101
  const baseUrl = useBaseUrl();
@@ -128,6 +128,7 @@ function useLiveSession({ sessionId, displayName = null, credentials, sessionTok
128
128
  const [presentationSwitching, setPresentationSwitching] = useState(false);
129
129
  const [presentation, setPresentation] = useState(null);
130
130
  const [recordings, setRecordings] = useState([]);
131
+ const [viewportOwnership, setViewportOwnership] = useState(null);
131
132
  const [clientId, setClientId] = useState("");
132
133
  const [holderClientId, setHolderClientId] = useState(null);
133
134
  const [leaseMode, setLeaseMode] = useState(null);
@@ -153,6 +154,10 @@ function useLiveSession({ sessionId, displayName = null, credentials, sessionTok
153
154
  setMediaSize(resolveMediaSize(message.targets, message.activeTargetId));
154
155
  setRecordings(message.recordings);
155
156
  setPresentation(message.presentation ?? null);
157
+ setViewportOwnership(message.autoSize === void 0 ? null : {
158
+ ownerClientId: message.viewportOwnerClientId ?? null,
159
+ autoSize: message.autoSize
160
+ });
156
161
  setLastError(null);
157
162
  return;
158
163
  case "targets.state":
@@ -180,6 +185,12 @@ function useLiveSession({ sessionId, displayName = null, credentials, sessionTok
180
185
  releasePendingRef.current = false;
181
186
  setLastError((current) => current?.code === "input_busy" || current?.code === "input_not_owned" ? null : current);
182
187
  return;
188
+ case "viewport.state":
189
+ setViewportOwnership({
190
+ ownerClientId: message.viewportOwnerClientId ?? null,
191
+ autoSize: message.autoSize
192
+ });
193
+ return;
183
194
  case "presence.cursor":
184
195
  if (message.clientId !== followingClientIdRef.current) return;
185
196
  setCursors((current) => new Map(current).set(message.clientId, message));
@@ -235,6 +246,7 @@ function useLiveSession({ sessionId, displayName = null, credentials, sessionTok
235
246
  setParticipants([]);
236
247
  setCursors(/* @__PURE__ */ new Map());
237
248
  setRecordings([]);
249
+ setViewportOwnership(null);
238
250
  publishFrame(null);
239
251
  publishPaint({ type: "clear" });
240
252
  return;
@@ -246,6 +258,7 @@ function useLiveSession({ sessionId, displayName = null, credentials, sessionTok
246
258
  credentials,
247
259
  sessionToken,
248
260
  identity,
261
+ autoSize,
249
262
  iceServers,
250
263
  webrtcSupported,
251
264
  callbacks: {
@@ -270,6 +283,7 @@ function useLiveSession({ sessionId, displayName = null, credentials, sessionTok
270
283
  publishPaint({ type: "clear" });
271
284
  })));
272
285
  }, [
286
+ autoSize,
273
287
  baseUrl,
274
288
  credentials,
275
289
  enabled,
@@ -526,6 +540,7 @@ function useLiveSession({ sessionId, displayName = null, credentials, sessionTok
526
540
  presentation,
527
541
  mediaSwitching: targetSwitching || presentationSwitching,
528
542
  recordings,
543
+ viewportOwnership,
529
544
  sendBrowserInput,
530
545
  selectTarget,
531
546
  requestSelectTarget,
@@ -1750,6 +1765,7 @@ function focusedElement(node) {
1750
1765
  //#endregion
1751
1766
  //#region src/hooks/use-browser-control.ts
1752
1767
  const emptyIceServers$1 = [];
1768
+ const AUTO_SIZE_DEFAULT_STORAGE_KEY = "aperture.viewport.auto-size-default";
1753
1769
  function useBrowserControl({ sessionId, credentials, displayName, sessionToken, collaborationRole = "owner", enabled = true, webrtcProducerSupported = false, webrtcIceServers = emptyIceServers$1, onNotice }) {
1754
1770
  const runtime = useRuntime();
1755
1771
  const onNoticeRef = useRef(onNotice);
@@ -1758,6 +1774,11 @@ function useBrowserControl({ sessionId, credentials, displayName, sessionToken,
1758
1774
  level,
1759
1775
  message
1760
1776
  }));
1777
+ const [viewportAutoSizeDefault, setViewportAutoSizeDefaultState] = useState(loadAutoSizeDefault);
1778
+ const [viewportAutoSync, setViewportAutoSyncState] = useState(() => collaborationRole !== "viewer" && viewportAutoSizeDefault);
1779
+ const viewportAutoSyncRef = useRef(viewportAutoSync);
1780
+ viewportAutoSyncRef.current = viewportAutoSync;
1781
+ const autoSizePreference = useCallback(() => viewportAutoSyncRef.current, []);
1761
1782
  const live = useLiveSession({
1762
1783
  sessionId,
1763
1784
  displayName,
@@ -1766,7 +1787,8 @@ function useBrowserControl({ sessionId, credentials, displayName, sessionToken,
1766
1787
  role: collaborationRole,
1767
1788
  enabled: Boolean(enabled && sessionId && credentials),
1768
1789
  webrtcSupported: webrtcProducerSupported,
1769
- iceServers: webrtcIceServers
1790
+ iceServers: webrtcIceServers,
1791
+ autoSize: autoSizePreference
1770
1792
  });
1771
1793
  const [targetOrder, setTargetOrder] = useState([]);
1772
1794
  const targets = useMemo(() => mergeTargetsInCurrentOrder(targetOrder, live.targets), [live.targets, targetOrder]);
@@ -1776,18 +1798,15 @@ function useBrowserControl({ sessionId, credentials, displayName, sessionToken,
1776
1798
  phaseRef.current = live.phase;
1777
1799
  const [viewport, setViewportState] = useState(DEFAULT_VIEWPORT);
1778
1800
  const [browserViewportSize, setBrowserViewportSizeState] = useState(null);
1779
- const [viewportAutoSync, setViewportAutoSyncState] = useState(false);
1780
1801
  const [captured, setCaptured] = useState(false);
1781
1802
  const [recordingBusy, setRecordingBusy] = useState(false);
1782
1803
  const activeTargetIdRef = useRef(null);
1783
1804
  const viewportRef = useRef(viewport);
1784
1805
  const inputDimensionsRef = useRef(DEFAULT_VIEWPORT);
1785
1806
  const browserViewportSizeRef = useRef(null);
1786
- const viewportAutoSyncRef = useRef(false);
1787
1807
  activeTargetIdRef.current = live.activeTargetId;
1788
1808
  viewportRef.current = viewport;
1789
1809
  browserViewportSizeRef.current = browserViewportSize;
1790
- viewportAutoSyncRef.current = viewportAutoSync;
1791
1810
  useEffect(() => {
1792
1811
  if (live.phase !== "connected") setCaptured(false);
1793
1812
  }, [live.phase]);
@@ -1860,21 +1879,54 @@ function useBrowserControl({ sessionId, credentials, displayName, sessionToken,
1860
1879
  const targetId = activeTargetIdRef.current;
1861
1880
  if (targetId) live.command("page.history-forward", { targetId });
1862
1881
  }, [live]);
1863
- const commitViewport = useCallback((preset) => {
1882
+ const viewportOwnership = live.viewportOwnership;
1883
+ const viewportOwnershipRef = useRef(viewportOwnership);
1884
+ viewportOwnershipRef.current = viewportOwnership;
1885
+ const viewportAutoSizeActive = viewportAutoSync && (viewportOwnership === null || viewportOwnership.ownerClientId === live.collaboration.clientId);
1886
+ const viewportAutoSizeActiveRef = useRef(viewportAutoSizeActive);
1887
+ viewportAutoSizeActiveRef.current = viewportAutoSizeActive;
1888
+ useEffect(() => {
1889
+ if (viewportOwnership !== null) {
1890
+ viewportAutoSyncRef.current = viewportOwnership.autoSize;
1891
+ setViewportAutoSyncState(viewportOwnership.autoSize);
1892
+ }
1893
+ }, [viewportOwnership]);
1894
+ const runAutoSizeViewport = useEffectCallback((payload) => live.request("viewport.set", payload).pipe(Effect.ignore), [live.request]);
1895
+ const commitViewport = useCallback((preset, autoSize) => {
1864
1896
  setViewportState(preset);
1865
1897
  const targetId = activeTargetIdRef.current;
1866
- if (targetId) live.command("viewport.set", {
1898
+ if (targetId === null) return;
1899
+ const payload = {
1867
1900
  targetId,
1868
1901
  width: preset.width,
1869
1902
  height: preset.height,
1870
1903
  deviceScaleFactor: preset.deviceScaleFactor
1904
+ };
1905
+ if (autoSize && viewportOwnershipRef.current !== null) runAutoSizeViewport({
1906
+ ...payload,
1907
+ autoSize: true
1871
1908
  });
1872
- }, [live]);
1909
+ else live.command("viewport.set", payload);
1910
+ }, [live.command, runAutoSizeViewport]);
1911
+ const setViewportAutoSync = useCallback((nextEnabled) => {
1912
+ if (viewportAutoSyncRef.current === nextEnabled) return;
1913
+ viewportAutoSyncRef.current = nextEnabled;
1914
+ setViewportAutoSyncState(nextEnabled);
1915
+ if (viewportOwnershipRef.current !== null) live.command("viewport.auto-size.set", { enabled: nextEnabled });
1916
+ }, [live.command]);
1917
+ useEffect(() => {
1918
+ const size = browserViewportSizeRef.current;
1919
+ if (viewportAutoSizeActive && live.phase === "connected" && live.activeTargetId !== null && size !== null) commitViewport(createBrowserViewport(size, viewportRef.current.deviceScaleFactor), true);
1920
+ }, [
1921
+ commitViewport,
1922
+ live.activeTargetId,
1923
+ live.phase,
1924
+ viewportAutoSizeActive
1925
+ ]);
1873
1926
  const setViewport = useCallback((preset) => {
1874
- viewportAutoSyncRef.current = false;
1875
- setViewportAutoSyncState(false);
1876
- commitViewport(preset);
1877
- }, [commitViewport]);
1927
+ setViewportAutoSync(false);
1928
+ commitViewport(preset, false);
1929
+ }, [commitViewport, setViewportAutoSync]);
1878
1930
  const setBrowserViewportSize = useCallback((size) => {
1879
1931
  const next = {
1880
1932
  width: Math.round(size.width),
@@ -1885,21 +1937,25 @@ function useBrowserControl({ sessionId, credentials, displayName, sessionToken,
1885
1937
  if (current?.width === next.width && current.height === next.height) return;
1886
1938
  browserViewportSizeRef.current = next;
1887
1939
  setBrowserViewportSizeState(next);
1888
- if (viewportAutoSyncRef.current) commitViewport(createBrowserViewport(next, viewportRef.current.deviceScaleFactor));
1889
- }, [commitViewport]);
1890
- const setViewportAutoSync = useCallback((nextEnabled) => {
1891
- viewportAutoSyncRef.current = nextEnabled;
1892
- setViewportAutoSyncState(nextEnabled);
1893
- const size = browserViewportSizeRef.current;
1894
- if (nextEnabled && size) commitViewport(createBrowserViewport(size, viewportRef.current.deviceScaleFactor));
1940
+ if (viewportAutoSizeActiveRef.current) commitViewport(createBrowserViewport(next, viewportRef.current.deviceScaleFactor), true);
1895
1941
  }, [commitViewport]);
1896
1942
  const setViewportToBrowserSize = useCallback(() => {
1897
1943
  const size = browserViewportSizeRef.current;
1898
1944
  if (!size) return;
1899
- viewportAutoSyncRef.current = false;
1900
- setViewportAutoSyncState(false);
1901
- commitViewport(createBrowserViewport(size, viewportRef.current.deviceScaleFactor));
1902
- }, [commitViewport]);
1945
+ setViewportAutoSync(false);
1946
+ commitViewport(createBrowserViewport(size, viewportRef.current.deviceScaleFactor), false);
1947
+ }, [commitViewport, setViewportAutoSync]);
1948
+ const takeOverViewport = useCallback(() => {
1949
+ viewportAutoSyncRef.current = true;
1950
+ setViewportAutoSyncState(true);
1951
+ live.command("viewport.owner.claim");
1952
+ }, [live.command]);
1953
+ const setViewportAutoSizeDefault = useCallback((nextEnabled) => {
1954
+ setViewportAutoSizeDefaultState(nextEnabled);
1955
+ try {
1956
+ window.localStorage.setItem(AUTO_SIZE_DEFAULT_STORAGE_KEY, String(nextEnabled));
1957
+ } catch {}
1958
+ }, []);
1903
1959
  const settleRecording = (effect, failure) => effect.pipe(Effect.catch((error) => notify("error", errorMessage(error, failure))), Effect.ensuring(Effect.sync(() => setRecordingBusy(false))));
1904
1960
  const runStartRecording = useEffectCallback((mode, targetId) => settleRecording(live.request("recording.start", {
1905
1961
  mode,
@@ -2000,6 +2056,9 @@ function useBrowserControl({ sessionId, credentials, displayName, sessionToken,
2000
2056
  viewport,
2001
2057
  browserViewportSize,
2002
2058
  viewportAutoSync,
2059
+ viewportAutoSizeActive,
2060
+ viewportOwnership,
2061
+ viewportAutoSizeDefault,
2003
2062
  captured,
2004
2063
  recordings: live.recordings,
2005
2064
  recordingBusy,
@@ -2014,6 +2073,8 @@ function useBrowserControl({ sessionId, credentials, displayName, sessionToken,
2014
2073
  setBrowserViewportSize,
2015
2074
  setViewportAutoSync,
2016
2075
  setViewportToBrowserSize,
2076
+ setViewportAutoSizeDefault,
2077
+ takeOverViewport,
2017
2078
  setWebRTCStreamSettings,
2018
2079
  selectMediaStream,
2019
2080
  sendInput,
@@ -2048,6 +2109,13 @@ function mergeTargetsInCurrentOrder(order, nextTargets) {
2048
2109
  for (const nextTarget of nextTargets) if (!seen.has(nextTarget.id)) ordered.push(nextTarget);
2049
2110
  return ordered;
2050
2111
  }
2112
+ function loadAutoSizeDefault() {
2113
+ try {
2114
+ return window.localStorage.getItem(AUTO_SIZE_DEFAULT_STORAGE_KEY) === "true";
2115
+ } catch {
2116
+ return false;
2117
+ }
2118
+ }
2051
2119
  function createBrowserViewport(size, deviceScaleFactor) {
2052
2120
  return createViewportPreset(size.width, size.height, deviceScaleFactor);
2053
2121
  }
@@ -2133,4 +2201,4 @@ function useSharedSession({ token, displayName, onNotice }) {
2133
2201
  //#endregion
2134
2202
  export { makeApertureRuntime as a, collaborationPaintLifetimeMs as c, RuntimeProviderMissingError as d, useBaseUrl as f, useRuntime as g, useRunApi as h, ApertureProvider as i, useLiveSession as l, useFork as m, parseShareToken as n, useBrowserControl as o, useEffectCallback as p, useSharedSession as r, SessionViewport as s, LiveSessionError$1 as t, RuntimeProvider as u };
2135
2203
 
2136
- //# sourceMappingURL=headless-Mx2uuxft.js.map
2204
+ //# sourceMappingURL=headless-CJ5KaGbF.js.map