@stream-io/video-react-sdk 1.7.30 → 1.8.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.
@@ -1,3 +1,4 @@
1
+ import { StreamVideoParticipant } from '@stream-io/video-client';
1
2
  import { ParticipantViewProps } from '../ParticipantView';
2
3
  export type PaginatedGridLayoutProps = {
3
4
  /**
@@ -9,6 +10,10 @@ export type PaginatedGridLayoutProps = {
9
10
  * @default false
10
11
  */
11
12
  excludeLocalParticipant?: boolean;
13
+ /**
14
+ * Predicate to filter call participants.
15
+ */
16
+ filterParticipants?: (participant: StreamVideoParticipant) => boolean;
12
17
  /**
13
18
  * When set to `false` disables mirroring of the local partipant's video.
14
19
  * @default true
@@ -1,3 +1,4 @@
1
+ import { StreamVideoParticipant } from '@stream-io/video-client';
1
2
  import { ParticipantViewProps } from '../ParticipantView';
2
3
  export type SpeakerLayoutProps = {
3
4
  /**
@@ -23,6 +24,10 @@ export type SpeakerLayoutProps = {
23
24
  * @default false
24
25
  */
25
26
  excludeLocalParticipant?: boolean;
27
+ /**
28
+ * Predicate to filter call participants.
29
+ */
30
+ filterParticipants?: (participant: StreamVideoParticipant) => boolean;
26
31
  /**
27
32
  * When set to `false` disables mirroring of the local participant's video.
28
33
  * @default true
@@ -35,6 +40,6 @@ export type SpeakerLayoutProps = {
35
40
  pageArrowsVisible?: boolean;
36
41
  } & Pick<ParticipantViewProps, 'VideoPlaceholder' | 'PictureInPicturePlaceholder'>;
37
42
  export declare const SpeakerLayout: {
38
- ({ ParticipantViewUIBar, ParticipantViewUISpotlight, VideoPlaceholder, PictureInPicturePlaceholder, participantsBarPosition, participantsBarLimit, mirrorLocalParticipantVideo, excludeLocalParticipant, pageArrowsVisible, }: SpeakerLayoutProps): import("react/jsx-runtime").JSX.Element | null;
43
+ ({ ParticipantViewUIBar, ParticipantViewUISpotlight, VideoPlaceholder, PictureInPicturePlaceholder, participantsBarPosition, participantsBarLimit, mirrorLocalParticipantVideo, excludeLocalParticipant, filterParticipants, pageArrowsVisible, }: SpeakerLayoutProps): import("react/jsx-runtime").JSX.Element | null;
39
44
  displayName: string;
40
45
  };
@@ -1,3 +1,7 @@
1
- import { Call } from '@stream-io/video-client';
1
+ import { Call, StreamVideoParticipant } from '@stream-io/video-client';
2
+ export declare const useFilteredParticipants: ({ excludeLocalParticipant, filterParticipants, }: {
3
+ excludeLocalParticipant?: boolean;
4
+ filterParticipants?: (paritcipant: StreamVideoParticipant) => boolean;
5
+ }) => StreamVideoParticipant[];
2
6
  export declare const usePaginatedLayoutSortPreset: (call: Call | undefined) => void;
3
7
  export declare const useSpeakerLayoutSortPreset: (call: Call | undefined, isOneOnOneCall: boolean) => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stream-io/video-react-sdk",
3
- "version": "1.7.30",
3
+ "version": "1.8.0",
4
4
  "packageManager": "yarn@3.2.4",
5
5
  "main": "./dist/index.cjs.js",
6
6
  "module": "./dist/index.es.js",
@@ -32,9 +32,9 @@
32
32
  ],
33
33
  "dependencies": {
34
34
  "@floating-ui/react": "^0.26.24",
35
- "@stream-io/video-client": "1.11.14",
35
+ "@stream-io/video-client": "1.11.15",
36
36
  "@stream-io/video-filters-web": "0.1.6",
37
- "@stream-io/video-react-bindings": "1.2.8",
37
+ "@stream-io/video-react-bindings": "1.2.9",
38
38
  "chart.js": "^4.4.4",
39
39
  "clsx": "^2.0.0",
40
40
  "react-chartjs-2": "^5.2.0"
@@ -11,7 +11,7 @@ import {
11
11
  import { ParticipantsAudio } from '../Audio';
12
12
  import { IconButton } from '../../../components';
13
13
  import { chunk } from '../../../utilities';
14
- import { usePaginatedLayoutSortPreset } from './hooks';
14
+ import { useFilteredParticipants, usePaginatedLayoutSortPreset } from './hooks';
15
15
 
16
16
  const GROUP_SIZE = 16;
17
17
 
@@ -70,6 +70,11 @@ export type PaginatedGridLayoutProps = {
70
70
  */
71
71
  excludeLocalParticipant?: boolean;
72
72
 
73
+ /**
74
+ * Predicate to filter call participants.
75
+ */
76
+ filterParticipants?: (participant: StreamVideoParticipant) => boolean;
77
+
73
78
  /**
74
79
  * When set to `false` disables mirroring of the local partipant's video.
75
80
  * @default true
@@ -89,6 +94,7 @@ export const PaginatedGridLayout = (props: PaginatedGridLayoutProps) => {
89
94
  ? props.groupSize || GROUP_SIZE
90
95
  : GROUP_SIZE,
91
96
  excludeLocalParticipant = false,
97
+ filterParticipants,
92
98
  mirrorLocalParticipantVideo = true,
93
99
  pageArrowsVisible = true,
94
100
  VideoPlaceholder,
@@ -101,9 +107,12 @@ export const PaginatedGridLayout = (props: PaginatedGridLayoutProps) => {
101
107
  ] = useState<HTMLDivElement | null>(null);
102
108
 
103
109
  const call = useCall();
104
- const { useParticipants, useRemoteParticipants } = useCallStateHooks();
105
- const participants = useParticipants();
110
+ const { useRemoteParticipants } = useCallStateHooks();
106
111
  const remoteParticipants = useRemoteParticipants();
112
+ const participants = useFilteredParticipants({
113
+ excludeLocalParticipant,
114
+ filterParticipants,
115
+ });
107
116
 
108
117
  usePaginatedLayoutSortPreset(call);
109
118
 
@@ -117,12 +126,8 @@ export const PaginatedGridLayout = (props: PaginatedGridLayoutProps) => {
117
126
 
118
127
  // only used to render video elements
119
128
  const participantGroups = useMemo(
120
- () =>
121
- chunk(
122
- excludeLocalParticipant ? remoteParticipants : participants,
123
- groupSize,
124
- ),
125
- [excludeLocalParticipant, remoteParticipants, participants, groupSize],
129
+ () => chunk(participants, groupSize),
130
+ [participants, groupSize],
126
131
  );
127
132
 
128
133
  const pageCount = participantGroups.length;
@@ -1,6 +1,9 @@
1
1
  import { useEffect, useState } from 'react';
2
2
  import clsx from 'clsx';
3
- import { hasScreenShare } from '@stream-io/video-client';
3
+ import {
4
+ hasScreenShare,
5
+ StreamVideoParticipant,
6
+ } from '@stream-io/video-client';
4
7
  import { useCall, useCallStateHooks } from '@stream-io/video-react-bindings';
5
8
 
6
9
  import {
@@ -13,7 +16,7 @@ import {
13
16
  useHorizontalScrollPosition,
14
17
  useVerticalScrollPosition,
15
18
  } from '../../../hooks';
16
- import { useSpeakerLayoutSortPreset } from './hooks';
19
+ import { useFilteredParticipants, useSpeakerLayoutSortPreset } from './hooks';
17
20
  import { useCalculateHardLimit } from '../../hooks/useCalculateHardLimit';
18
21
  import { ParticipantsAudio } from '../Audio';
19
22
 
@@ -41,6 +44,10 @@ export type SpeakerLayoutProps = {
41
44
  * @default false
42
45
  */
43
46
  excludeLocalParticipant?: boolean;
47
+ /**
48
+ * Predicate to filter call participants.
49
+ */
50
+ filterParticipants?: (participant: StreamVideoParticipant) => boolean;
44
51
  /**
45
52
  * When set to `false` disables mirroring of the local participant's video.
46
53
  * @default true
@@ -69,15 +76,15 @@ export const SpeakerLayout = ({
69
76
  participantsBarLimit,
70
77
  mirrorLocalParticipantVideo = true,
71
78
  excludeLocalParticipant = false,
79
+ filterParticipants,
72
80
  pageArrowsVisible = true,
73
81
  }: SpeakerLayoutProps) => {
74
82
  const call = useCall();
75
83
  const { useParticipants, useRemoteParticipants } = useCallStateHooks();
76
84
  const allParticipants = useParticipants();
77
85
  const remoteParticipants = useRemoteParticipants();
78
- const [participantInSpotlight, ...otherParticipants] = excludeLocalParticipant
79
- ? remoteParticipants
80
- : allParticipants;
86
+ const [participantInSpotlight, ...otherParticipants] =
87
+ useFilteredParticipants({ excludeLocalParticipant, filterParticipants });
81
88
  const [participantsBarWrapperElement, setParticipantsBarWrapperElement] =
82
89
  useState<HTMLDivElement | null>(null);
83
90
  const [participantsBarElement, setParticipantsBarElement] =
@@ -1,4 +1,4 @@
1
- import { useEffect } from 'react';
1
+ import { useEffect, useMemo } from 'react';
2
2
  import {
3
3
  Call,
4
4
  CallTypes,
@@ -10,6 +10,34 @@ import {
10
10
  speakerLayoutSortPreset,
11
11
  StreamVideoParticipant,
12
12
  } from '@stream-io/video-client';
13
+ import { useCallStateHooks } from '@stream-io/video-react-bindings';
14
+
15
+ export const useFilteredParticipants = ({
16
+ excludeLocalParticipant = false,
17
+ filterParticipants,
18
+ }: {
19
+ excludeLocalParticipant?: boolean;
20
+ filterParticipants?: (paritcipant: StreamVideoParticipant) => boolean;
21
+ }) => {
22
+ const { useParticipants, useRemoteParticipants } = useCallStateHooks();
23
+ const allParticipants = useParticipants();
24
+ const remoteParticipants = useRemoteParticipants();
25
+ return useMemo(() => {
26
+ const unfilteredParticipants = excludeLocalParticipant
27
+ ? remoteParticipants
28
+ : allParticipants;
29
+ return filterParticipants
30
+ ? unfilteredParticipants.filter((participant) =>
31
+ filterParticipants(participant),
32
+ )
33
+ : unfilteredParticipants;
34
+ }, [
35
+ allParticipants,
36
+ remoteParticipants,
37
+ excludeLocalParticipant,
38
+ filterParticipants,
39
+ ]);
40
+ };
13
41
 
14
42
  export const usePaginatedLayoutSortPreset = (call: Call | undefined) => {
15
43
  useEffect(() => {