Skip to content

Commit d0489cb

Browse files
authored
Merge pull request #9680 from daily-co/pre-1037
PRE-1037 Remove useRecoilTransactionObserver, simplify screen share state & simplify custom useParticipantIds
2 parents 5a770f3 + 9f61e47 commit d0489cb

20 files changed

+205
-248
lines changed

src/DailyParticipants.tsx

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
import { useThrottledDailyEvent } from './hooks/useThrottledDailyEvent';
1616
import { RECOIL_PREFIX } from './lib/constants';
1717
import { customDeepEqual } from './lib/customDeepEqual';
18+
import { equalSelector } from './lib/recoil-custom';
1819
import { getParticipantPaths } from './utils/getParticipantPaths';
1920
import { resolveParticipantPaths } from './utils/resolveParticipantPaths';
2021

@@ -97,8 +98,9 @@ export const waitingParticipantState = atomFamily<
9798
/**
9899
* Returns all waiting participant objects in an array.
99100
*/
100-
export const allWaitingParticipantsSelector = selector({
101+
export const allWaitingParticipantsSelector = equalSelector({
101102
key: RECOIL_PREFIX + 'waitingParticipantsSelector',
103+
equals: customDeepEqual,
102104
get: ({ get }) => {
103105
const ids = get(waitingParticipantsState);
104106
return ids.map((id) => get(waitingParticipantState(id)));
@@ -205,9 +207,8 @@ export const DailyParticipants: React.FC<React.PropsWithChildren<{}>> = ({
205207
evts.forEach((ev) => {
206208
switch (ev.action) {
207209
case 'active-speaker-change': {
208-
const sessionId = ev.activeSpeaker.peerId;
209-
set(activeIdState, sessionId);
210-
set(participantState(sessionId), (prev) => {
210+
set(activeIdState, ev.activeSpeaker.peerId);
211+
set(participantState(ev.activeSpeaker.peerId), (prev) => {
211212
if (!prev) return null;
212213
return {
213214
...prev,

src/DailyProvider.tsx

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { DailyNetwork } from './DailyNetwork';
1616
import { DailyParticipants } from './DailyParticipants';
1717
import { DailyRecordings } from './DailyRecordings';
1818
import { DailyRoom } from './DailyRoom';
19-
import { DailyScreenShares } from './DailyScreenShares';
2019
import { customDeepEqual } from './lib/customDeepEqual';
2120

2221
type BaseProps =
@@ -212,13 +211,11 @@ export const DailyProvider: React.FC<React.PropsWithChildren<Props>> = ({
212211
<DailyMeeting>
213212
<DailyNetwork>
214213
<DailyParticipants>
215-
<DailyScreenShares>
216-
<DailyRecordings>
217-
<DailyLiveStreaming>
218-
<DailyDevices>{children}</DailyDevices>
219-
</DailyLiveStreaming>
220-
</DailyRecordings>
221-
</DailyScreenShares>
214+
<DailyRecordings>
215+
<DailyLiveStreaming>
216+
<DailyDevices>{children}</DailyDevices>
217+
</DailyLiveStreaming>
218+
</DailyRecordings>
222219
</DailyParticipants>
223220
</DailyNetwork>
224221
</DailyMeeting>

src/DailyScreenShares.tsx

Lines changed: 0 additions & 109 deletions
This file was deleted.

src/components/DailyAudio.tsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,8 @@ export const DailyAudio = memo(
280280
});
281281
},
282282
[assignSpeaker, localSessionId, removeSpeaker]
283-
)
283+
),
284+
200
284285
);
285286

286287
const rmpAudioIds = useParticipantIds({

src/hooks/useParticipantIds.ts

Lines changed: 39 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,6 @@
11
import { DailyEventObject, DailyParticipant } from '@daily-co/daily-js';
22
import { useCallback, useEffect, useState } from 'react';
3-
import {
4-
selectorFamily,
5-
useRecoilCallback,
6-
useRecoilTransactionObserver_UNSTABLE,
7-
useRecoilValue,
8-
} from 'recoil';
3+
import { useRecoilCallback, useRecoilValue } from 'recoil';
94

105
import {
116
ExtendedDailyParticipant,
@@ -14,6 +9,7 @@ import {
149
} from '../DailyParticipants';
1510
import { RECOIL_PREFIX } from '../lib/constants';
1611
import { customDeepEqual } from '../lib/customDeepEqual';
12+
import { equalSelectorFamily } from '../lib/recoil-custom';
1713
import { isTrackOff } from '../utils/isTrackOff';
1814
import {
1915
participantPropertiesState,
@@ -50,14 +46,15 @@ type SortParticipants = SerializableSortParticipants | SortParticipantsFunction;
5046
/**
5147
* Short-cut state selector for useParticipantIds({ filter: 'local' })
5248
*/
53-
export const participantIdsFilteredAndSortedState = selectorFamily<
49+
export const participantIdsFilteredAndSortedState = equalSelectorFamily<
5450
string[],
5551
{
5652
filter: SerializableFilterParticipants | null;
5753
sort: SerializableSortParticipants | null;
5854
}
5955
>({
6056
key: RECOIL_PREFIX + 'participant-ids-filtered-sorted',
57+
equals: customDeepEqual,
6158
get:
6259
({ filter, sort }) =>
6360
({ get }) => {
@@ -153,69 +150,55 @@ export const useParticipantIds = ({
153150
})
154151
);
155152

156-
/**
157-
* For custom filter and/or sort, we need to calculate the returned ids manually.
158-
*/
159-
const [customIds, setCustomIds] = useState<string[]>([]);
160-
/**
161-
* Loads participant state from Recoil store and updates custom ids state,
162-
* in case resulting set of ids is different.
163-
*/
164-
const maybeUpdateCustomIds = useRecoilCallback(
153+
const getCustomFilteredIds = useRecoilCallback(
165154
({ snapshot }) =>
166-
async () => {
155+
() => {
167156
if (
168157
// Ignore if both filter and sort are not functions.
169158
typeof filter !== 'function' &&
170159
typeof sort !== 'function'
171160
)
172-
return;
161+
return [];
173162

174-
const participants: ExtendedDailyParticipant[] = await Promise.all(
163+
const participants: ExtendedDailyParticipant[] =
175164
preFilteredSortedIds.map(
176-
async (id) =>
177-
(await snapshot.getPromise(
178-
participantState(id)
179-
)) as ExtendedDailyParticipant
180-
)
181-
);
182-
const newCustomIds = participants
183-
// Make sure we don't accidentally try to filter/sort `null` participants
184-
// This can happen when a participant's id is already present in store
185-
// but the participant object is not stored, yet.
186-
.filter(Boolean)
187-
// Run custom filter, if it's a function. Otherwise don't filter any participants.
188-
.filter(typeof filter === 'function' ? filter : () => true)
189-
// Run custom sort, if it's a function. Otherwise don't sort.
190-
.sort(typeof sort === 'function' ? sort : () => 0)
191-
// Map back to session_id.
192-
.map((p) => p.session_id)
193-
// Filter any potential null/undefined ids.
194-
// This shouldn't really happen, but better safe than sorry.
195-
.filter(Boolean);
165+
(id) =>
166+
snapshot.getLoadable(participantState(id))
167+
.contents as ExtendedDailyParticipant
168+
);
196169

197-
// Finally compare the new list of ids with the current one.
198-
if (customDeepEqual(customIds, newCustomIds)) return;
199-
200-
setCustomIds(newCustomIds);
170+
return (
171+
participants
172+
// Make sure we don't accidentally try to filter/sort `null` participants
173+
// This can happen when a participant's id is already present in store
174+
// but the participant object is not stored, yet.
175+
.filter(Boolean)
176+
// Run custom filter, if it's a function. Otherwise don't filter any participants.
177+
.filter(typeof filter === 'function' ? filter : () => true)
178+
// Run custom sort, if it's a function. Otherwise don't sort.
179+
.sort(typeof sort === 'function' ? sort : () => 0)
180+
// Map back to session_id.
181+
.map((p) => p.session_id)
182+
// Filter any potential null/undefined ids.
183+
// This shouldn't really happen, but better safe than sorry.
184+
.filter(Boolean)
185+
);
201186
},
202-
[customIds, filter, preFilteredSortedIds, sort]
187+
[filter, preFilteredSortedIds, sort]
203188
);
204189

205-
/**
206-
* Initialize state.
207-
*/
190+
const [customIds, setCustomIds] = useState<string[]>([]);
191+
192+
const maybeUpdateCustomIds = useCallback(() => {
193+
const newIds = getCustomFilteredIds();
194+
if (customDeepEqual(newIds, customIds)) return;
195+
setCustomIds(newIds);
196+
}, [customIds, getCustomFilteredIds]);
197+
208198
useEffect(() => {
209199
maybeUpdateCustomIds();
210200
}, [maybeUpdateCustomIds]);
211201

212-
/**
213-
* Wires up this instance to the Recoil store.
214-
*/
215-
useRecoilTransactionObserver_UNSTABLE(() => {
216-
maybeUpdateCustomIds();
217-
});
218-
219202
useThrottledDailyEvent(
220203
[
221204
'participant-joined',
@@ -242,8 +225,10 @@ export const useParticipantIds = ({
242225
break;
243226
}
244227
});
228+
maybeUpdateCustomIds();
245229
},
246230
[
231+
maybeUpdateCustomIds,
247232
onActiveSpeakerChange,
248233
onParticipantJoined,
249234
onParticipantLeft,

src/hooks/useScreenShare.ts

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,16 @@ import {
44
DailyTrackState,
55
} from '@daily-co/daily-js';
66
import { useCallback } from 'react';
7+
import { useRecoilValue } from 'recoil';
78

8-
import { useScreenSharesContext } from '../DailyScreenShares';
9+
import { RECOIL_PREFIX } from '../lib/constants';
10+
import { customDeepEqual } from '../lib/customDeepEqual';
11+
import { equalSelector } from '../lib/recoil-custom';
912
import { Reconstruct } from '../types/Reconstruct';
1013
import { useDaily } from './useDaily';
1114
import { useDailyEvent } from './useDailyEvent';
15+
import { participantIdsFilteredAndSortedState } from './useParticipantIds';
16+
import { participantPropertyState } from './useParticipantProperty';
1217

1318
export interface ScreenShare {
1419
local: boolean;
@@ -18,6 +23,29 @@ export interface ScreenShare {
1823
session_id: string;
1924
}
2025

26+
const screenSharesState = equalSelector({
27+
key: RECOIL_PREFIX + 'screen-shares',
28+
equals: customDeepEqual,
29+
get: ({ get }) => {
30+
const screenIds = get(
31+
participantIdsFilteredAndSortedState({ filter: 'screen', sort: null })
32+
);
33+
return screenIds.map<ScreenShare>((id) => {
34+
return {
35+
local: get(participantPropertyState({ id, property: 'local' })),
36+
screenAudio: get(
37+
participantPropertyState({ id, property: 'tracks.screenAudio' })
38+
),
39+
screenVideo: get(
40+
participantPropertyState({ id, property: 'tracks.screenVideo' })
41+
),
42+
screenId: `${id}-screen`,
43+
session_id: id,
44+
};
45+
});
46+
},
47+
});
48+
2149
type DailyEventObjectScreenShareError = Reconstruct<
2250
DailyEventObjectNonFatalError,
2351
'type',
@@ -79,7 +107,7 @@ export const useScreenShare = ({
79107
)
80108
);
81109

82-
const { screens } = useScreenSharesContext();
110+
const screens = useRecoilValue(screenSharesState);
83111

84112
return {
85113
isSharingScreen: screens.some((s) => s.local),

0 commit comments

Comments
 (0)