@microsoft/live-share-react 1.0.0-preview.11 → 1.0.0-preview.13
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/README.md +3 -3
- package/bin/index.d.ts +7 -0
- package/bin/index.d.ts.map +1 -0
- package/bin/index.js +7 -0
- package/bin/index.js.map +1 -0
- package/bin/interfaces/LiveInterfaceExtensions.d.ts +9 -0
- package/bin/interfaces/LiveInterfaceExtensions.d.ts.map +1 -0
- package/bin/interfaces/LiveInterfaceExtensions.js +6 -0
- package/bin/interfaces/LiveInterfaceExtensions.js.map +1 -0
- package/bin/interfaces/index.d.ts +2 -0
- package/bin/interfaces/index.d.ts.map +1 -0
- package/bin/interfaces/index.js +2 -0
- package/bin/interfaces/index.js.map +1 -0
- package/bin/internal-hooks/index.d.ts +2 -0
- package/bin/internal-hooks/index.d.ts.map +1 -0
- package/bin/internal-hooks/index.js +2 -0
- package/bin/internal-hooks/index.js.map +1 -0
- package/bin/internal-hooks/useDynamicDDSRegistry.d.ts +14 -0
- package/bin/internal-hooks/useDynamicDDSRegistry.d.ts.map +1 -0
- package/bin/internal-hooks/useDynamicDDSRegistry.js +142 -0
- package/bin/internal-hooks/useDynamicDDSRegistry.js.map +1 -0
- package/bin/internal-hooks/useSharedStateRegistry.d.ts +31 -0
- package/bin/internal-hooks/useSharedStateRegistry.d.ts.map +1 -0
- package/bin/internal-hooks/useSharedStateRegistry.js +102 -0
- package/bin/internal-hooks/useSharedStateRegistry.js.map +1 -0
- package/bin/internal-hooks/useStateRef.d.ts +7 -0
- package/bin/internal-hooks/useStateRef.d.ts.map +1 -0
- package/bin/internal-hooks/useStateRef.js +15 -0
- package/bin/internal-hooks/useStateRef.js.map +1 -0
- package/bin/live-hooks/index.d.ts +7 -0
- package/bin/live-hooks/index.d.ts.map +1 -0
- package/bin/live-hooks/index.js +7 -0
- package/bin/live-hooks/index.js.map +1 -0
- package/bin/live-hooks/useLiveAICompletion.d.ts +29 -0
- package/bin/live-hooks/useLiveAICompletion.d.ts.map +1 -0
- package/bin/live-hooks/useLiveAICompletion.js +186 -0
- package/bin/live-hooks/useLiveAICompletion.js.map +1 -0
- package/bin/live-hooks/useLiveCanvas.d.ts +28 -0
- package/bin/live-hooks/useLiveCanvas.d.ts.map +1 -0
- package/bin/live-hooks/useLiveCanvas.js +159 -0
- package/bin/live-hooks/useLiveCanvas.js.map +1 -0
- package/bin/live-hooks/useLiveCoPilot.d.ts +28 -0
- package/bin/live-hooks/useLiveCoPilot.d.ts.map +1 -0
- package/bin/live-hooks/useLiveCoPilot.js +178 -0
- package/bin/live-hooks/useLiveCoPilot.js.map +1 -0
- package/bin/live-hooks/useLiveEvent.d.ts +22 -0
- package/bin/live-hooks/useLiveEvent.d.ts.map +1 -0
- package/bin/live-hooks/useLiveEvent.js +93 -0
- package/bin/live-hooks/useLiveEvent.js.map +1 -0
- package/bin/live-hooks/useLivePresence.d.ts +26 -0
- package/bin/live-hooks/useLivePresence.d.ts.map +1 -0
- package/bin/live-hooks/useLivePresence.js +102 -0
- package/bin/live-hooks/useLivePresence.js.map +1 -0
- package/bin/live-hooks/useLiveState.d.ts +20 -0
- package/bin/live-hooks/useLiveState.d.ts.map +1 -0
- package/bin/live-hooks/useLiveState.js +73 -0
- package/bin/live-hooks/useLiveState.js.map +1 -0
- package/bin/live-hooks/useLiveTimer.d.ts +8 -0
- package/bin/live-hooks/useLiveTimer.d.ts.map +1 -0
- package/bin/live-hooks/useLiveTimer.js +145 -0
- package/bin/live-hooks/useLiveTimer.js.map +1 -0
- package/bin/live-hooks/useMediaSynchronizer.d.ts +23 -0
- package/bin/live-hooks/useMediaSynchronizer.d.ts.map +1 -0
- package/bin/live-hooks/useMediaSynchronizer.js +185 -0
- package/bin/live-hooks/useMediaSynchronizer.js.map +1 -0
- package/bin/live-share-turbo/AzureTurboClient.d.ts +39 -0
- package/bin/live-share-turbo/AzureTurboClient.d.ts.map +1 -0
- package/bin/live-share-turbo/AzureTurboClient.js +56 -0
- package/bin/live-share-turbo/AzureTurboClient.js.map +1 -0
- package/bin/live-share-turbo/LiveShareTurboClient.d.ts +53 -0
- package/bin/live-share-turbo/LiveShareTurboClient.d.ts.map +1 -0
- package/bin/live-share-turbo/LiveShareTurboClient.js +69 -0
- package/bin/live-share-turbo/LiveShareTurboClient.js.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboDataObject.d.ts +31 -0
- package/bin/live-share-turbo/dds-objects/TurboDataObject.d.ts.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboDataObject.js +75 -0
- package/bin/live-share-turbo/dds-objects/TurboDataObject.js.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveCanvas.d.ts +48 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveCanvas.d.ts.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveCanvas.js +104 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveCanvas.js.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveEvent.d.ts +28 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveEvent.d.ts.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveEvent.js +68 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveEvent.js.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveMediaSession.d.ts +60 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveMediaSession.d.ts.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveMediaSession.js +111 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveMediaSession.js.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLivePresence.d.ts +77 -0
- package/bin/live-share-turbo/dds-objects/TurboLivePresence.d.ts.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLivePresence.js +137 -0
- package/bin/live-share-turbo/dds-objects/TurboLivePresence.js.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveState.d.ts +30 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveState.d.ts.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveState.js +74 -0
- package/bin/live-share-turbo/dds-objects/TurboLiveState.js.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboSharedMap.d.ts +61 -0
- package/bin/live-share-turbo/dds-objects/TurboSharedMap.d.ts.map +1 -0
- package/bin/live-share-turbo/dds-objects/TurboSharedMap.js +108 -0
- package/bin/live-share-turbo/dds-objects/TurboSharedMap.js.map +1 -0
- package/bin/live-share-turbo/dds-objects/index.d.ts +8 -0
- package/bin/live-share-turbo/dds-objects/index.d.ts.map +1 -0
- package/bin/live-share-turbo/dds-objects/index.js +8 -0
- package/bin/live-share-turbo/dds-objects/index.js.map +1 -0
- package/bin/live-share-turbo/index.d.ts +5 -0
- package/bin/live-share-turbo/index.d.ts.map +1 -0
- package/bin/live-share-turbo/index.js +5 -0
- package/bin/live-share-turbo/index.js.map +1 -0
- package/bin/live-share-turbo/interfaces/IFluidTurboClient.d.ts +15 -0
- package/bin/live-share-turbo/interfaces/IFluidTurboClient.d.ts.map +1 -0
- package/bin/live-share-turbo/interfaces/IFluidTurboClient.js +2 -0
- package/bin/live-share-turbo/interfaces/IFluidTurboClient.js.map +1 -0
- package/bin/live-share-turbo/interfaces/index.d.ts +3 -0
- package/bin/live-share-turbo/interfaces/index.d.ts.map +1 -0
- package/bin/live-share-turbo/interfaces/index.js +3 -0
- package/bin/live-share-turbo/interfaces/index.js.map +1 -0
- package/bin/live-share-turbo/internals/FluidTurboClient.d.ts +39 -0
- package/bin/live-share-turbo/internals/FluidTurboClient.d.ts.map +1 -0
- package/bin/live-share-turbo/internals/FluidTurboClient.js +121 -0
- package/bin/live-share-turbo/internals/FluidTurboClient.js.map +1 -0
- package/bin/live-share-turbo/internals/index.d.ts +2 -0
- package/bin/live-share-turbo/internals/index.d.ts.map +1 -0
- package/bin/live-share-turbo/internals/index.js +2 -0
- package/bin/live-share-turbo/internals/index.js.map +1 -0
- package/bin/live-share-turbo/internals/types.d.ts +4 -0
- package/bin/live-share-turbo/internals/types.d.ts.map +1 -0
- package/bin/live-share-turbo/internals/types.js +2 -0
- package/bin/live-share-turbo/internals/types.js.map +1 -0
- package/bin/providers/AzureProvider.d.ts +34 -0
- package/bin/providers/AzureProvider.d.ts.map +1 -0
- package/bin/providers/AzureProvider.js +102 -0
- package/bin/providers/AzureProvider.js.map +1 -0
- package/bin/providers/FluidContextProvider.d.ts +34 -0
- package/bin/providers/FluidContextProvider.d.ts.map +1 -0
- package/bin/providers/FluidContextProvider.js +99 -0
- package/bin/providers/FluidContextProvider.js.map +1 -0
- package/bin/providers/LiveShareContextProvider.d.ts +42 -0
- package/bin/providers/LiveShareContextProvider.d.ts.map +1 -0
- package/bin/providers/LiveShareContextProvider.js +63 -0
- package/bin/providers/LiveShareContextProvider.js.map +1 -0
- package/bin/providers/LiveShareProvider.d.ts +63 -0
- package/bin/providers/LiveShareProvider.d.ts.map +1 -0
- package/bin/providers/LiveShareProvider.js +69 -0
- package/bin/providers/LiveShareProvider.js.map +1 -0
- package/bin/providers/index.d.ts +3 -0
- package/bin/providers/index.d.ts.map +1 -0
- package/bin/providers/index.js +3 -0
- package/bin/providers/index.js.map +1 -0
- package/bin/shared-hooks/index.d.ts +4 -0
- package/bin/shared-hooks/index.d.ts.map +1 -0
- package/bin/shared-hooks/index.js +4 -0
- package/bin/shared-hooks/index.js.map +1 -0
- package/bin/shared-hooks/useDynamicDDS.d.ts +19 -0
- package/bin/shared-hooks/useDynamicDDS.d.ts.map +1 -0
- package/bin/shared-hooks/useDynamicDDS.js +68 -0
- package/bin/shared-hooks/useDynamicDDS.js.map +1 -0
- package/bin/shared-hooks/useLockedTask.d.ts +11 -0
- package/bin/shared-hooks/useLockedTask.d.ts.map +1 -0
- package/bin/shared-hooks/useLockedTask.js +82 -0
- package/bin/shared-hooks/useLockedTask.js.map +1 -0
- package/bin/shared-hooks/useSharedMap.d.ts +22 -0
- package/bin/shared-hooks/useSharedMap.d.ts.map +1 -0
- package/bin/shared-hooks/useSharedMap.js +106 -0
- package/bin/shared-hooks/useSharedMap.js.map +1 -0
- package/bin/shared-hooks/useSharedState.d.ts +21 -0
- package/bin/shared-hooks/useSharedState.d.ts.map +1 -0
- package/bin/shared-hooks/useSharedState.js +67 -0
- package/bin/shared-hooks/useSharedState.js.map +1 -0
- package/bin/shared-hooks/useTaskManager.d.ts +13 -0
- package/bin/shared-hooks/useTaskManager.d.ts.map +1 -0
- package/bin/shared-hooks/useTaskManager.js +86 -0
- package/bin/shared-hooks/useTaskManager.js.map +1 -0
- package/bin/types/ActionTypes.d.ts +106 -0
- package/bin/types/ActionTypes.d.ts.map +1 -0
- package/bin/types/ActionTypes.js +6 -0
- package/bin/types/ActionTypes.js.map +1 -0
- package/bin/types/PropTypes.d.ts +8 -0
- package/bin/types/PropTypes.d.ts.map +1 -0
- package/bin/types/PropTypes.js +6 -0
- package/bin/types/PropTypes.js.map +1 -0
- package/bin/types/ResultTypes.d.ts +175 -0
- package/bin/types/ResultTypes.d.ts.map +1 -0
- package/bin/types/ResultTypes.js +6 -0
- package/bin/types/ResultTypes.js.map +1 -0
- package/bin/types/index.d.ts +4 -0
- package/bin/types/index.d.ts.map +1 -0
- package/bin/types/index.js +4 -0
- package/bin/types/index.js.map +1 -0
- package/bin/utils/getContainerSchema.d.ts +8 -0
- package/bin/utils/getContainerSchema.d.ts.map +1 -0
- package/bin/utils/getContainerSchema.js +41 -0
- package/bin/utils/getContainerSchema.js.map +1 -0
- package/bin/utils/index.d.ts +2 -0
- package/bin/utils/index.d.ts.map +1 -0
- package/bin/utils/index.js +2 -0
- package/bin/utils/index.js.map +1 -0
- package/bin/utils/type-check.d.ts +15 -0
- package/bin/utils/type-check.d.ts.map +1 -0
- package/bin/utils/type-check.js +54 -0
- package/bin/utils/type-check.js.map +1 -0
- package/package.json +13 -13
- package/src/internal-hooks/useSharedStateRegistry.ts +6 -5
- package/src/live-hooks/useLiveEvent.ts +14 -18
- package/src/live-hooks/useLivePresence.ts +13 -7
- package/src/live-hooks/useLiveState.ts +8 -6
- package/src/live-hooks/useLiveTimer.ts +21 -18
- package/src/live-hooks/useMediaSynchronizer.ts +37 -27
- package/src/providers/AzureProvider.tsx +2 -7
- package/src/providers/LiveShareProvider.tsx +45 -15
- package/src/shared-hooks/useDynamicDDS.ts +15 -8
- package/src/shared-hooks/useSharedMap.ts +17 -10
- package/src/shared-hooks/useSharedState.ts +5 -1
- package/src/types/ActionTypes.ts +89 -11
- package/src/types/ResultTypes.ts +22 -8
|
@@ -18,15 +18,15 @@ import { useDynamicDDS } from "../shared-hooks";
|
|
|
18
18
|
* @param initialState Optional. the initial state value of type TState
|
|
19
19
|
* @param allowedRoles Optional. the user roles that are allowed to mutate the synchronized state
|
|
20
20
|
* @returns ordered values: first value is the synchronized state value and the second is a setter to change the state value.
|
|
21
|
+
* The setter returns a void promise, which will throw if the user does not have the required roles to set.
|
|
21
22
|
*/
|
|
22
|
-
export function useLiveState<
|
|
23
|
-
TState = any,
|
|
24
|
-
>(
|
|
23
|
+
export function useLiveState<TState = any>(
|
|
25
24
|
uniqueKey: string,
|
|
26
25
|
initialState: TState,
|
|
27
26
|
allowedRoles?: UserMeetingRole[]
|
|
28
27
|
): [TState, SetLiveStateAction<TState>] {
|
|
29
|
-
const [currentState, setCurrentState] =
|
|
28
|
+
const [currentState, setCurrentState] =
|
|
29
|
+
React.useState<TState>(initialState);
|
|
30
30
|
/**
|
|
31
31
|
* User facing: dynamically load the DDS for the given unique key.
|
|
32
32
|
*/
|
|
@@ -37,9 +37,11 @@ export function useLiveState<
|
|
|
37
37
|
|
|
38
38
|
/**
|
|
39
39
|
* Change state callback that is user facing
|
|
40
|
+
* @param state TState to set
|
|
41
|
+
* @returns void promise, which will throw if the user does not have the required roles
|
|
40
42
|
*/
|
|
41
43
|
const setState = React.useCallback(
|
|
42
|
-
(state: TState) => {
|
|
44
|
+
async (state: TState) => {
|
|
43
45
|
if (!liveState) {
|
|
44
46
|
console.error(
|
|
45
47
|
new Error(
|
|
@@ -56,7 +58,7 @@ export function useLiveState<
|
|
|
56
58
|
);
|
|
57
59
|
return;
|
|
58
60
|
}
|
|
59
|
-
liveState.set(state);
|
|
61
|
+
return await liveState.set(state);
|
|
60
62
|
},
|
|
61
63
|
[liveState]
|
|
62
64
|
);
|
|
@@ -31,7 +31,7 @@ export function useLiveTimer(
|
|
|
31
31
|
onStart?: OnTimerDidStartAction,
|
|
32
32
|
onPause?: OnTimerDidPauseAction,
|
|
33
33
|
onPlay?: OnTimerDidPlayAction,
|
|
34
|
-
onFinish?: OnTimerDidFinishAction
|
|
34
|
+
onFinish?: OnTimerDidFinishAction
|
|
35
35
|
): IUseLiveTimerResults {
|
|
36
36
|
/**
|
|
37
37
|
* User facing: Stateful timer config.
|
|
@@ -47,11 +47,13 @@ export function useLiveTimer(
|
|
|
47
47
|
const { dds: liveTimer } = useDynamicDDS<LiveTimer>(uniqueKey, LiveTimer);
|
|
48
48
|
|
|
49
49
|
/**
|
|
50
|
-
*
|
|
50
|
+
* Callback to send event through `LiveTimer`
|
|
51
|
+
* @param duration the duration for the timer in milliseconds
|
|
52
|
+
* @returns void promise that will throw when user does not have required roles
|
|
51
53
|
*/
|
|
52
54
|
const start: OnStartTimerAction = React.useCallback(
|
|
53
|
-
(duration: number)
|
|
54
|
-
if (liveTimer
|
|
55
|
+
async (duration: number) => {
|
|
56
|
+
if (liveTimer === undefined) {
|
|
55
57
|
console.error(
|
|
56
58
|
new Error("Cannot call start when liveTimer is undefined")
|
|
57
59
|
);
|
|
@@ -65,16 +67,17 @@ export function useLiveTimer(
|
|
|
65
67
|
);
|
|
66
68
|
return;
|
|
67
69
|
}
|
|
68
|
-
liveTimer
|
|
70
|
+
return await liveTimer.start(duration);
|
|
69
71
|
},
|
|
70
|
-
[liveTimer
|
|
72
|
+
[liveTimer]
|
|
71
73
|
);
|
|
72
74
|
|
|
73
75
|
/**
|
|
74
|
-
*
|
|
76
|
+
* Callback to send event through `LiveTimer`
|
|
77
|
+
* @returns void promise that will throw when user does not have required roles
|
|
75
78
|
*/
|
|
76
|
-
const play: OnPlayTimerAction = React.useCallback(()
|
|
77
|
-
if (liveTimer
|
|
79
|
+
const play: OnPlayTimerAction = React.useCallback(async () => {
|
|
80
|
+
if (liveTimer === undefined) {
|
|
78
81
|
console.error(
|
|
79
82
|
new Error("Cannot call play when liveTimer is undefined")
|
|
80
83
|
);
|
|
@@ -86,14 +89,15 @@ export function useLiveTimer(
|
|
|
86
89
|
);
|
|
87
90
|
return;
|
|
88
91
|
}
|
|
89
|
-
liveTimer
|
|
90
|
-
}, [liveTimer
|
|
92
|
+
return await liveTimer.play();
|
|
93
|
+
}, [liveTimer]);
|
|
91
94
|
|
|
92
95
|
/**
|
|
93
|
-
*
|
|
96
|
+
* Callback to send event through `LiveTimer`
|
|
97
|
+
* @returns void promise that will throw when user does not have required roles
|
|
94
98
|
*/
|
|
95
|
-
const pause: OnPauseTimerAction = React.useCallback(()
|
|
96
|
-
if (liveTimer
|
|
99
|
+
const pause: OnPauseTimerAction = React.useCallback(async () => {
|
|
100
|
+
if (liveTimer === undefined) {
|
|
97
101
|
console.error(
|
|
98
102
|
new Error("Cannot call pause when liveTimer is undefined")
|
|
99
103
|
);
|
|
@@ -105,15 +109,14 @@ export function useLiveTimer(
|
|
|
105
109
|
);
|
|
106
110
|
return;
|
|
107
111
|
}
|
|
108
|
-
liveTimer
|
|
109
|
-
}, [liveTimer
|
|
112
|
+
return await liveTimer.pause();
|
|
113
|
+
}, [liveTimer]);
|
|
110
114
|
|
|
111
115
|
/**
|
|
112
116
|
* Setup change listeners and start `LiveTimer` if needed
|
|
113
117
|
*/
|
|
114
118
|
React.useEffect(() => {
|
|
115
|
-
if (liveTimer === undefined)
|
|
116
|
-
return;
|
|
119
|
+
if (liveTimer === undefined) return;
|
|
117
120
|
// Register event listeners
|
|
118
121
|
const onTimerConfigChange = (config: ITimerConfig) => {
|
|
119
122
|
setTimerConfig(config);
|
|
@@ -52,28 +52,34 @@ export function useMediaSynchronizer(
|
|
|
52
52
|
/**
|
|
53
53
|
* User facing: dynamically load the LiveMediaSession DDS for the given unique key.
|
|
54
54
|
*/
|
|
55
|
-
const { dds: mediaSession } = useDynamicDDS<LiveMediaSession>(
|
|
55
|
+
const { dds: mediaSession } = useDynamicDDS<LiveMediaSession>(
|
|
56
|
+
uniqueKey,
|
|
57
|
+
LiveMediaSession
|
|
58
|
+
);
|
|
56
59
|
|
|
57
60
|
/**
|
|
58
|
-
*
|
|
61
|
+
* Play callback
|
|
59
62
|
*/
|
|
60
|
-
const play = React.useCallback(()
|
|
61
|
-
mediaSynchronizer
|
|
63
|
+
const play = React.useCallback(async () => {
|
|
64
|
+
if (!mediaSynchronizer) return;
|
|
65
|
+
return await mediaSynchronizer.play();
|
|
62
66
|
}, [mediaSynchronizer]);
|
|
63
67
|
|
|
64
68
|
/**
|
|
65
|
-
*
|
|
69
|
+
* Pause callback
|
|
66
70
|
*/
|
|
67
|
-
const pause = React.useCallback(()
|
|
68
|
-
mediaSynchronizer
|
|
71
|
+
const pause = React.useCallback(async () => {
|
|
72
|
+
if (!mediaSynchronizer) return;
|
|
73
|
+
return await mediaSynchronizer.pause();
|
|
69
74
|
}, [mediaSynchronizer]);
|
|
70
75
|
|
|
71
76
|
/**
|
|
72
77
|
* User facing: seek callback
|
|
73
78
|
*/
|
|
74
79
|
const seekTo = React.useCallback(
|
|
75
|
-
(time: number)
|
|
76
|
-
mediaSynchronizer
|
|
80
|
+
async (time: number) => {
|
|
81
|
+
if (!mediaSynchronizer) return;
|
|
82
|
+
return await mediaSynchronizer.seekTo(time);
|
|
77
83
|
},
|
|
78
84
|
[mediaSynchronizer]
|
|
79
85
|
);
|
|
@@ -82,12 +88,12 @@ export function useMediaSynchronizer(
|
|
|
82
88
|
* User facing: set track callback
|
|
83
89
|
*/
|
|
84
90
|
const setTrack = React.useCallback(
|
|
85
|
-
(track: Partial<ExtendedMediaMetadata> | string | null)
|
|
86
|
-
|
|
91
|
+
async (track: Partial<ExtendedMediaMetadata> | string | null) => {
|
|
92
|
+
if (!mediaSynchronizer) return;
|
|
87
93
|
if (isExtendedMediaMetadata(track)) {
|
|
88
|
-
mediaSynchronizer
|
|
94
|
+
return await mediaSynchronizer.setTrack(track);
|
|
89
95
|
} else if (typeof track === "string") {
|
|
90
|
-
mediaSynchronizer
|
|
96
|
+
return await mediaSynchronizer.setTrack({
|
|
91
97
|
trackIdentifier: track,
|
|
92
98
|
} as ExtendedMediaMetadata);
|
|
93
99
|
}
|
|
@@ -119,8 +125,8 @@ export function useMediaSynchronizer(
|
|
|
119
125
|
* Setup change listeners and start `LiveMediaSession` if needed
|
|
120
126
|
*/
|
|
121
127
|
React.useEffect(() => {
|
|
122
|
-
if (mediaSession === undefined || !mediaPlayerElementRef)
|
|
123
|
-
|
|
128
|
+
if (mediaSession === undefined || !mediaPlayerElementRef) return;
|
|
129
|
+
let mounted = true;
|
|
124
130
|
// Query the HTML5 media element from the document and set reference
|
|
125
131
|
let mediaPlayer: IMediaPlayer | undefined;
|
|
126
132
|
if (isRefObject<IMediaPlayer>(mediaPlayerElementRef)) {
|
|
@@ -152,25 +158,29 @@ export function useMediaSynchronizer(
|
|
|
152
158
|
// Start synchronizing the media session
|
|
153
159
|
mediaSession.initialize(allowedRoles ?? []);
|
|
154
160
|
} else if (initialTrack) {
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
}
|
|
166
|
-
|
|
161
|
+
mediaSession.onLocalUserAllowed(async () => {
|
|
162
|
+
if (!mounted) return;
|
|
163
|
+
try {
|
|
164
|
+
if (isExtendedMediaMetadata(initialTrack)) {
|
|
165
|
+
await synchronizer.setTrack(initialTrack);
|
|
166
|
+
} else if (typeof initialTrack === "string") {
|
|
167
|
+
await synchronizer.setTrack({
|
|
168
|
+
trackIdentifier: initialTrack,
|
|
169
|
+
} as ExtendedMediaMetadata);
|
|
170
|
+
}
|
|
171
|
+
} catch (err) {
|
|
172
|
+
console.error(err);
|
|
173
|
+
}
|
|
174
|
+
});
|
|
167
175
|
}
|
|
168
176
|
setMediaSynchronizer(synchronizer);
|
|
169
177
|
|
|
170
178
|
return () => {
|
|
179
|
+
mounted = false;
|
|
171
180
|
synchronizer.removeAllListeners();
|
|
172
181
|
mediaSession.removeAllListeners();
|
|
173
182
|
synchronizer?.end();
|
|
183
|
+
mediaSession?.dispose();
|
|
174
184
|
};
|
|
175
185
|
}, [mediaSession]);
|
|
176
186
|
|
|
@@ -3,10 +3,7 @@
|
|
|
3
3
|
* Licensed under the Microsoft Live Share SDK License.
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
IFluidContainer,
|
|
8
|
-
LoadableObjectClassRecord,
|
|
9
|
-
} from "fluid-framework";
|
|
6
|
+
import { IFluidContainer, LoadableObjectClassRecord } from "fluid-framework";
|
|
10
7
|
import React from "react";
|
|
11
8
|
import {
|
|
12
9
|
AzureClientProps,
|
|
@@ -58,9 +55,7 @@ interface IAzureProviderProps {
|
|
|
58
55
|
/**
|
|
59
56
|
* React Context provider component for using Fluid data objects & joining/creating a Fluid document `AzureClient`.
|
|
60
57
|
*/
|
|
61
|
-
export const AzureProvider: React.FC<IAzureProviderProps> = (
|
|
62
|
-
props
|
|
63
|
-
) => {
|
|
58
|
+
export const AzureProvider: React.FC<IAzureProviderProps> = (props) => {
|
|
64
59
|
const startedRef = React.useRef<boolean>(false);
|
|
65
60
|
const clientRef = React.useRef<AzureTurboClient>(
|
|
66
61
|
new AzureTurboClient(props.clientOptions)
|
|
@@ -5,18 +5,44 @@
|
|
|
5
5
|
|
|
6
6
|
import { IFluidContainer, LoadableObjectClassRecord } from "fluid-framework";
|
|
7
7
|
import React from "react";
|
|
8
|
-
import { ILiveShareContainerResults } from "../types";
|
|
9
8
|
import { useSharedStateRegistry } from "../internal-hooks";
|
|
10
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
ILiveShareClientOptions,
|
|
11
|
+
ILiveShareHost,
|
|
12
|
+
ILiveShareJoinResults,
|
|
13
|
+
ITimestampProvider,
|
|
14
|
+
} from "@microsoft/live-share";
|
|
11
15
|
import { FluidContext } from "./AzureProvider";
|
|
12
16
|
import { LiveShareTurboClient } from "@microsoft/live-share-turbo";
|
|
13
17
|
|
|
14
|
-
interface ILiveShareContext {
|
|
15
|
-
|
|
18
|
+
export interface ILiveShareContext {
|
|
19
|
+
/**
|
|
20
|
+
* True if the local user created the Fluid container
|
|
21
|
+
*/
|
|
22
|
+
created: boolean;
|
|
23
|
+
/**
|
|
24
|
+
* True if connected to the Live Share container
|
|
25
|
+
*/
|
|
26
|
+
joined: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* An error that will be defined if there was a problem joining the container, or undefined if not.
|
|
29
|
+
*/
|
|
30
|
+
joinError: Error | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* Live Share timestamp provider. Can be used to `.getTimestamp()` for a global clock value.
|
|
33
|
+
* This reference timestamp value should be fairly consistent for all users in the session.
|
|
34
|
+
*/
|
|
35
|
+
timestampProvider: ITimestampProvider | undefined;
|
|
36
|
+
/**
|
|
37
|
+
* Join callback method
|
|
38
|
+
* @param initialObjects Optional. The initial objects for the Fluid container schema.
|
|
39
|
+
* @param onInitializeContainer Optional. Callback for when the container is first created.
|
|
40
|
+
* @returns `ILiveShareJoinResults`, which includes the Fluid container
|
|
41
|
+
*/
|
|
16
42
|
join: (
|
|
17
43
|
initialObjects?: LoadableObjectClassRecord,
|
|
18
44
|
onInitializeContainer?: (container: IFluidContainer) => void
|
|
19
|
-
) => Promise<
|
|
45
|
+
) => Promise<ILiveShareJoinResults>;
|
|
20
46
|
}
|
|
21
47
|
|
|
22
48
|
export const LiveShareContext = React.createContext<ILiveShareContext>(
|
|
@@ -54,15 +80,13 @@ interface ILiveShareProviderProps {
|
|
|
54
80
|
/**
|
|
55
81
|
* React Context provider component for using Live Share data objects & joining a Live Share session using `LiveShareClient`.
|
|
56
82
|
*/
|
|
57
|
-
export const LiveShareProvider: React.FC<
|
|
58
|
-
ILiveShareProviderProps
|
|
59
|
-
> = (props) => {
|
|
83
|
+
export const LiveShareProvider: React.FC<ILiveShareProviderProps> = (props) => {
|
|
60
84
|
const startedRef = React.useRef(false);
|
|
61
85
|
const clientRef = React.useRef(
|
|
62
86
|
new LiveShareTurboClient(props.host, props.clientOptions)
|
|
63
87
|
);
|
|
64
88
|
const [results, setResults] = React.useState<
|
|
65
|
-
|
|
89
|
+
ILiveShareJoinResults | undefined
|
|
66
90
|
>();
|
|
67
91
|
const [joinError, setJoinError] = React.useState<Error | undefined>();
|
|
68
92
|
|
|
@@ -75,10 +99,12 @@ export const LiveShareProvider: React.FC<
|
|
|
75
99
|
async (
|
|
76
100
|
initialObjects?: LoadableObjectClassRecord,
|
|
77
101
|
onInitializeContainer?: (container: IFluidContainer) => void
|
|
78
|
-
): Promise<
|
|
102
|
+
): Promise<ILiveShareJoinResults> => {
|
|
79
103
|
startedRef.current = true;
|
|
80
|
-
const results
|
|
81
|
-
|
|
104
|
+
const results = await clientRef.current.join(
|
|
105
|
+
initialObjects,
|
|
106
|
+
onInitializeContainer
|
|
107
|
+
);
|
|
82
108
|
setResults(results);
|
|
83
109
|
return results;
|
|
84
110
|
},
|
|
@@ -92,9 +118,10 @@ export const LiveShareProvider: React.FC<
|
|
|
92
118
|
// This hook should only be called once, so we use a ref to track if it has been called.
|
|
93
119
|
// This is a workaround for the fact that useEffect is called twice on initial render in React V18.
|
|
94
120
|
// We are not doing this here for backwards compatibility. View the README for more information.
|
|
95
|
-
if (results !== undefined || startedRef.current || !props.joinOnLoad)
|
|
121
|
+
if (results !== undefined || startedRef.current || !props.joinOnLoad)
|
|
122
|
+
return;
|
|
96
123
|
join(props.initialObjects).catch((error) => {
|
|
97
|
-
console.
|
|
124
|
+
console.error(error);
|
|
98
125
|
if (error instanceof Error) {
|
|
99
126
|
setJoinError(error);
|
|
100
127
|
} else {
|
|
@@ -110,7 +137,10 @@ export const LiveShareProvider: React.FC<
|
|
|
110
137
|
return (
|
|
111
138
|
<LiveShareContext.Provider
|
|
112
139
|
value={{
|
|
113
|
-
created: results?.created,
|
|
140
|
+
created: !!results?.created,
|
|
141
|
+
timestampProvider: results?.timestampProvider,
|
|
142
|
+
joined: !!results?.container,
|
|
143
|
+
joinError,
|
|
114
144
|
join,
|
|
115
145
|
}}
|
|
116
146
|
>
|
|
@@ -16,10 +16,12 @@ import { LoadableObjectClass } from "fluid-framework";
|
|
|
16
16
|
* @param onFirstInitialize Optional. Callback function for when the DDS is first loaded
|
|
17
17
|
* @returns the DDS object, which is of type T when loaded and undefined while loading
|
|
18
18
|
*/
|
|
19
|
-
export function useDynamicDDS<
|
|
19
|
+
export function useDynamicDDS<
|
|
20
|
+
T extends IFluidLoadable = FluidObject<any> & IFluidLoadable
|
|
21
|
+
>(
|
|
20
22
|
uniqueKey: string,
|
|
21
23
|
loadableObjectClass: LoadableObjectClass<T>,
|
|
22
|
-
onFirstInitialize?: (dds: T) => void
|
|
24
|
+
onFirstInitialize?: (dds: T) => void
|
|
23
25
|
): {
|
|
24
26
|
dds: T | undefined;
|
|
25
27
|
error: Error | undefined;
|
|
@@ -29,10 +31,7 @@ export function useDynamicDDS<T extends IFluidLoadable = FluidObject<any> & IFlu
|
|
|
29
31
|
/**
|
|
30
32
|
* Import container and DDS object register callbacks from AzureProvider.
|
|
31
33
|
*/
|
|
32
|
-
const {
|
|
33
|
-
container,
|
|
34
|
-
clientRef,
|
|
35
|
-
} = useFluidObjectsContext();
|
|
34
|
+
const { container, clientRef } = useFluidObjectsContext();
|
|
36
35
|
|
|
37
36
|
/**
|
|
38
37
|
* Once container is available, this effect will register the setter method so that the DDS loaded
|
|
@@ -46,7 +45,11 @@ export function useDynamicDDS<T extends IFluidLoadable = FluidObject<any> & IFlu
|
|
|
46
45
|
// Callback method to set the `initialData` into the map when the DDS is first created.
|
|
47
46
|
const onGetDDS = async () => {
|
|
48
47
|
try {
|
|
49
|
-
const dds = await clientRef.current.getDDS<T>(
|
|
48
|
+
const dds = await clientRef.current.getDDS<T>(
|
|
49
|
+
uniqueKey,
|
|
50
|
+
loadableObjectClass,
|
|
51
|
+
onFirstInitialize
|
|
52
|
+
);
|
|
50
53
|
if (mounted) {
|
|
51
54
|
setDDS(dds);
|
|
52
55
|
}
|
|
@@ -54,7 +57,11 @@ export function useDynamicDDS<T extends IFluidLoadable = FluidObject<any> & IFlu
|
|
|
54
57
|
if (error instanceof Error) {
|
|
55
58
|
setError(error);
|
|
56
59
|
} else {
|
|
57
|
-
setError(
|
|
60
|
+
setError(
|
|
61
|
+
new Error(
|
|
62
|
+
"useDynamicDDS: an unknown error occurred while getting the DDS"
|
|
63
|
+
)
|
|
64
|
+
);
|
|
58
65
|
}
|
|
59
66
|
}
|
|
60
67
|
};
|
|
@@ -35,19 +35,26 @@ export function useSharedMap<TData extends object = object>(
|
|
|
35
35
|
getInitialData<TData>(initialData)
|
|
36
36
|
);
|
|
37
37
|
|
|
38
|
-
const onFirstInitialize = React.useCallback(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
const onFirstInitialize = React.useCallback(
|
|
39
|
+
(newDDS: SharedMap): void => {
|
|
40
|
+
/**
|
|
41
|
+
* Callback method to set the `initialData` into the map when the `SharedMap` is first created.
|
|
42
|
+
* Only should be used as a prop to useDynamicDDS.
|
|
43
|
+
*/
|
|
44
|
+
getInitialData(initialData).forEach((value, key) => {
|
|
45
|
+
newDDS.set(key, value);
|
|
46
|
+
});
|
|
47
|
+
},
|
|
48
|
+
[initialData]
|
|
49
|
+
);
|
|
47
50
|
/**
|
|
48
51
|
* User facing: dynamically load the SharedMap DDS for the given unique key.
|
|
49
52
|
*/
|
|
50
|
-
const { dds: sharedMap } = useDynamicDDS<SharedMap>(
|
|
53
|
+
const { dds: sharedMap } = useDynamicDDS<SharedMap>(
|
|
54
|
+
uniqueKey,
|
|
55
|
+
SharedMap,
|
|
56
|
+
onFirstInitialize
|
|
57
|
+
);
|
|
51
58
|
|
|
52
59
|
/**
|
|
53
60
|
* User facing: set a value to the Fluid `SharedMap`.
|
|
@@ -79,7 +79,11 @@ export function useSharedState<S>(
|
|
|
79
79
|
return () => {
|
|
80
80
|
unregisterSharedSetStateAction(uniqueKey, componentIdRef.current);
|
|
81
81
|
};
|
|
82
|
-
}, [
|
|
82
|
+
}, [
|
|
83
|
+
uniqueKey,
|
|
84
|
+
registerSharedSetStateAction,
|
|
85
|
+
unregisterSharedSetStateAction,
|
|
86
|
+
]);
|
|
83
87
|
|
|
84
88
|
return [localState, setSharedState, disposeSharedState];
|
|
85
89
|
}
|
package/src/types/ActionTypes.ts
CHANGED
|
@@ -6,13 +6,19 @@
|
|
|
6
6
|
import React from "react";
|
|
7
7
|
import { IFluidLoadable } from "@fluidframework/core-interfaces";
|
|
8
8
|
import { LoadableObjectClass } from "fluid-framework";
|
|
9
|
-
import { ITimerConfig, PresenceState } from "@microsoft/live-share";
|
|
9
|
+
import { ITimerConfig, ILiveEvent, PresenceState } from "@microsoft/live-share";
|
|
10
10
|
|
|
11
11
|
// React actions
|
|
12
|
+
|
|
12
13
|
export type SetSharedStateAction<T> = (state: T) => void;
|
|
13
14
|
export type SetLocalStateAction = React.Dispatch<React.SetStateAction<any>>;
|
|
14
15
|
|
|
15
16
|
// Fluid actions
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Callback for UnregisterDDSSetStateAction.
|
|
20
|
+
* <T extends IFluidLoadable>(uniqueKey: string, componentId: string, objectClass: LoadableObjectClass<T>, setLocalStateAction: SetLocalStateAction, onDidFirstInitialize?: (dds: T) => void) => void
|
|
21
|
+
*/
|
|
16
22
|
export type RegisterDDSSetStateAction = <T extends IFluidLoadable>(
|
|
17
23
|
uniqueKey: string,
|
|
18
24
|
componentId: string,
|
|
@@ -21,55 +27,127 @@ export type RegisterDDSSetStateAction = <T extends IFluidLoadable>(
|
|
|
21
27
|
onDidFirstInitialize?: (dds: T) => void
|
|
22
28
|
) => void;
|
|
23
29
|
|
|
30
|
+
/**
|
|
31
|
+
* Callback for UnregisterDDSSetStateAction.
|
|
32
|
+
* (uniqueKey: string, componentId: string) => void
|
|
33
|
+
*/
|
|
24
34
|
export type UnregisterDDSSetStateAction = (
|
|
25
35
|
uniqueKey: string,
|
|
26
36
|
componentId: string
|
|
27
37
|
) => void;
|
|
28
38
|
|
|
39
|
+
/**
|
|
40
|
+
* Callback for RegisterSharedSetStateAction.
|
|
41
|
+
* (uniqueKey: string, componentId: string, setLocalStateAction: SetLocalStateAction) => void
|
|
42
|
+
*/
|
|
29
43
|
export type RegisterSharedSetStateAction = (
|
|
30
44
|
uniqueKey: string,
|
|
31
45
|
componentId: string,
|
|
32
46
|
setLocalStateAction: SetLocalStateAction
|
|
33
47
|
) => void;
|
|
34
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Callback for UnregisterSharedSetStateAction.
|
|
51
|
+
* (uniqueKey: string, componentId: string) => void
|
|
52
|
+
*/
|
|
35
53
|
export type UnregisterSharedSetStateAction = (
|
|
36
54
|
uniqueKey: string,
|
|
37
55
|
componentId: string
|
|
38
56
|
) => void;
|
|
39
57
|
|
|
58
|
+
/**
|
|
59
|
+
* Callback for UpdateSharedStateAction.
|
|
60
|
+
* (uniqueKey: string, value: any) => void
|
|
61
|
+
*/
|
|
40
62
|
export type UpdateSharedStateAction = (uniqueKey: string, value: any) => void;
|
|
41
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Callback for DeleteSharedStateAction.
|
|
66
|
+
* (uniqueKey: string) => void
|
|
67
|
+
*/
|
|
42
68
|
export type DeleteSharedStateAction = (uniqueKey: string) => void;
|
|
69
|
+
/**
|
|
70
|
+
* Callback for DisposeSharedStateAction.
|
|
71
|
+
* () => void
|
|
72
|
+
*/
|
|
43
73
|
export type DisposeSharedStateAction = () => void;
|
|
44
74
|
|
|
45
75
|
// Live Share actions
|
|
46
76
|
|
|
77
|
+
/**
|
|
78
|
+
* Callback for SetLiveStateAction<TState = undefined>.
|
|
79
|
+
* (state: TState) => Promise<void>
|
|
80
|
+
*/
|
|
47
81
|
export type SetLiveStateAction<TState = undefined> = (
|
|
48
|
-
state: TState
|
|
49
|
-
) => void
|
|
82
|
+
state: TState
|
|
83
|
+
) => Promise<void>;
|
|
50
84
|
|
|
51
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Callback for SendLiveEventAction<TEvent>.
|
|
87
|
+
* (event: TEvent) => Promise<void>
|
|
88
|
+
*/
|
|
89
|
+
export type SendLiveEventAction<TEvent> = (
|
|
90
|
+
event: TEvent
|
|
91
|
+
) => Promise<ILiveEvent<TEvent>>;
|
|
52
92
|
|
|
93
|
+
/**
|
|
94
|
+
* Callback for OnReceivedLiveEventAction<TEvent>.
|
|
95
|
+
* (event: TEvent, local: boolean) => void
|
|
96
|
+
*/
|
|
53
97
|
export type OnReceivedLiveEventAction<TEvent> = (
|
|
54
98
|
event: TEvent,
|
|
55
99
|
local: boolean
|
|
56
100
|
) => void;
|
|
57
101
|
|
|
102
|
+
/**
|
|
103
|
+
* Callback for OnUpdateLivePresenceAction<TData extends object = object>.
|
|
104
|
+
* (data?: TData | undefined, state?: PresenceState | undefined) => Promise<void>
|
|
105
|
+
*/
|
|
58
106
|
export type OnUpdateLivePresenceAction<TData extends object = object> = (
|
|
59
107
|
data?: TData | undefined,
|
|
60
|
-
state?: PresenceState | undefined
|
|
61
|
-
) => void
|
|
108
|
+
state?: PresenceState | undefined
|
|
109
|
+
) => Promise<void>;
|
|
62
110
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
) => void
|
|
111
|
+
/**
|
|
112
|
+
* Callback for OnStartTimerAction.
|
|
113
|
+
* (duration: number) => Promise<void>
|
|
114
|
+
*/
|
|
115
|
+
export type OnStartTimerAction = (duration: number) => Promise<void>;
|
|
66
116
|
|
|
67
|
-
|
|
117
|
+
/**
|
|
118
|
+
* Callback for OnPlayTimerAction.
|
|
119
|
+
* () => Promise<void>
|
|
120
|
+
*/
|
|
121
|
+
export type OnPlayTimerAction = () => Promise<void>;
|
|
68
122
|
|
|
69
|
-
|
|
123
|
+
/**
|
|
124
|
+
* Callback for OnPauseTimerAction.
|
|
125
|
+
* () => Promise<void>
|
|
126
|
+
*/
|
|
127
|
+
export type OnPauseTimerAction = () => Promise<void>;
|
|
70
128
|
|
|
129
|
+
/**
|
|
130
|
+
* Callback for OnTimerTickAction.
|
|
131
|
+
* (milliRemaining: number) => void
|
|
132
|
+
*/
|
|
71
133
|
export type OnTimerTickAction = (milliRemaining: number) => void;
|
|
134
|
+
/**
|
|
135
|
+
* Callback for OnTimerDidStartAction.
|
|
136
|
+
* (timerConfig: ITimerConfig) => void
|
|
137
|
+
*/
|
|
72
138
|
export type OnTimerDidStartAction = (timerConfig: ITimerConfig) => void;
|
|
139
|
+
/**
|
|
140
|
+
* Callback for OnTimerDidPauseAction.
|
|
141
|
+
* (timerConfig: ITimerConfig) => void
|
|
142
|
+
*/
|
|
73
143
|
export type OnTimerDidPauseAction = (timerConfig: ITimerConfig) => void;
|
|
144
|
+
/**
|
|
145
|
+
* Callback for OnTimerDidPlayAction.
|
|
146
|
+
* (timerConfig: ITimerConfig) => void
|
|
147
|
+
*/
|
|
74
148
|
export type OnTimerDidPlayAction = (timerConfig: ITimerConfig) => void;
|
|
149
|
+
/**
|
|
150
|
+
* Callback for OnTimerDidFinishAction.
|
|
151
|
+
* (timerConfig: ITimerConfig) => void
|
|
152
|
+
*/
|
|
75
153
|
export type OnTimerDidFinishAction = (timerConfig: ITimerConfig) => void;
|