@100mslive/roomkit-react 0.3.19-alpha.0 → 0.3.19-alpha.10

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.
Files changed (42) hide show
  1. package/dist/{HLSView-6CQOPAJJ.css → HLSView-SQVMLXDB.css} +67 -19
  2. package/dist/{HLSView-6CQOPAJJ.css.map → HLSView-SQVMLXDB.css.map} +2 -2
  3. package/dist/{HLSView-LJQ65VXH.js → HLSView-YHWO3IWB.js} +43 -43
  4. package/dist/{HLSView-LJQ65VXH.js.map → HLSView-YHWO3IWB.js.map} +1 -1
  5. package/dist/Modal/Dialog.d.ts +3 -1
  6. package/dist/Prebuilt/components/EndCallFeedback/Feedback.d.ts +2 -0
  7. package/dist/Prebuilt/components/EndCallFeedback/FeedbackForm.d.ts +28 -0
  8. package/dist/Prebuilt/components/EndCallFeedback/ThankyouView.d.ts +2 -0
  9. package/dist/Prebuilt/components/VirtualBackground/VBCollection.d.ts +1 -1
  10. package/dist/Prebuilt/components/VirtualBackground/VBHandler.d.ts +5 -6
  11. package/dist/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.d.ts +1 -0
  12. package/dist/{chunk-O3I4DN7I.js → chunk-2OV5LOYE.js} +1747 -1226
  13. package/dist/chunk-2OV5LOYE.js.map +7 -0
  14. package/dist/index.cjs.css +66 -18
  15. package/dist/index.cjs.css.map +2 -2
  16. package/dist/index.cjs.js +1773 -1229
  17. package/dist/index.cjs.js.map +4 -4
  18. package/dist/index.css +66 -18
  19. package/dist/index.css.map +2 -2
  20. package/dist/index.js +1 -1
  21. package/dist/meta.cjs.json +416 -149
  22. package/dist/meta.esbuild.json +435 -168
  23. package/package.json +8 -8
  24. package/src/Modal/Dialog.tsx +13 -2
  25. package/src/Prebuilt/App.tsx +3 -0
  26. package/src/Prebuilt/AppStateContext.tsx +1 -2
  27. package/src/Prebuilt/Prebuilt.stories.tsx +1 -0
  28. package/src/Prebuilt/common/PeersSorter.ts +2 -1
  29. package/src/Prebuilt/components/EndCallFeedback/Feedback.tsx +70 -0
  30. package/src/Prebuilt/components/EndCallFeedback/FeedbackForm.tsx +371 -0
  31. package/src/Prebuilt/components/EndCallFeedback/ThankyouView.tsx +44 -0
  32. package/src/Prebuilt/components/LeaveScreen.tsx +2 -0
  33. package/src/Prebuilt/components/PIP/PIPChat.tsx +14 -2
  34. package/src/Prebuilt/components/VideoLayouts/RoleProminence.tsx +2 -9
  35. package/src/Prebuilt/components/VirtualBackground/VBCollection.tsx +3 -1
  36. package/src/Prebuilt/components/VirtualBackground/VBHandler.tsx +14 -4
  37. package/src/Prebuilt/components/VirtualBackground/VBPicker.tsx +46 -31
  38. package/src/Prebuilt/components/VirtualBackground/VBToggle.tsx +15 -1
  39. package/src/Prebuilt/plugins/CaptionsViewer.tsx +4 -1
  40. package/src/Prebuilt/provider/roomLayoutProvider/hooks/useRoomLayoutScreen.ts +1 -0
  41. package/src/Video/Video.tsx +1 -1
  42. package/dist/chunk-O3I4DN7I.js.map +0 -7
package/package.json CHANGED
@@ -10,7 +10,7 @@
10
10
  "prebuilt",
11
11
  "roomkit"
12
12
  ],
13
- "version": "0.3.19-alpha.0",
13
+ "version": "0.3.19-alpha.10",
14
14
  "author": "100ms",
15
15
  "license": "MIT",
16
16
  "repository": {
@@ -75,13 +75,13 @@
75
75
  "react": ">=17.0.2 <19.0.0"
76
76
  },
77
77
  "dependencies": {
78
- "@100mslive/hls-player": "0.3.19-alpha.0",
78
+ "@100mslive/hls-player": "0.3.19-alpha.10",
79
79
  "@100mslive/hms-noise-cancellation": "0.0.1",
80
- "@100mslive/hms-virtual-background": "1.13.19-alpha.0",
81
- "@100mslive/hms-whiteboard": "0.0.9-alpha.0",
82
- "@100mslive/react-icons": "0.10.19-alpha.0",
83
- "@100mslive/react-sdk": "0.10.19-alpha.0",
84
- "@100mslive/types-prebuilt": "0.12.11",
80
+ "@100mslive/hms-virtual-background": "1.13.19-alpha.10",
81
+ "@100mslive/hms-whiteboard": "0.0.9-alpha.10",
82
+ "@100mslive/react-icons": "0.10.19-alpha.10",
83
+ "@100mslive/react-sdk": "0.10.19-alpha.10",
84
+ "@100mslive/types-prebuilt": "0.12.12",
85
85
  "@emoji-mart/data": "^1.0.6",
86
86
  "@emoji-mart/react": "^1.0.1",
87
87
  "@radix-ui/react-accordion": "1.0.0",
@@ -117,5 +117,5 @@
117
117
  "uuid": "^8.3.2",
118
118
  "worker-timers": "^7.0.40"
119
119
  },
120
- "gitHead": "5de66a04a026c41273f2e5c7726569cf75ee4bc4"
120
+ "gitHead": "ff1d543414b72cd0acb3f4caf867bacb5ba806d5"
121
121
  }
@@ -1,4 +1,4 @@
1
- import React, { ReactNode, useRef } from 'react';
1
+ import React, { ReactNode, useEffect, useRef } from 'react';
2
2
  import { Root } from '@radix-ui/react-dialog';
3
3
  import { styled } from '@stitches/react';
4
4
  import {
@@ -15,6 +15,17 @@ import { useDialogContainerSelector } from '../hooks/useDialogContainerSelector'
15
15
 
16
16
  const StyledDialog = styled(Root, {});
17
17
 
18
+ // Handles race conditions when multiple elements with dismissable layer are present
19
+ // https://github.com/radix-ui/primitives/issues/2122
20
+ const DialogRoot = <T extends React.ComponentProps<typeof StyledDialog>>(props: T) => {
21
+ useEffect(() => {
22
+ return () => {
23
+ if (document) setTimeout(() => (document.body.style.pointerEvents = 'auto'), 0);
24
+ };
25
+ }, []);
26
+ return <StyledDialog {...(props as object)} />;
27
+ };
28
+
18
29
  const CustomDialogPortal = ({ children, container }: { children: ReactNode; container?: HTMLElement | null }) => {
19
30
  const dialogContainerSelector = useDialogContainerSelector();
20
31
  const containerRef = useRef<HTMLElement | null>(null);
@@ -34,7 +45,7 @@ const CustomDialogPortal = ({ children, container }: { children: ReactNode; cont
34
45
  };
35
46
 
36
47
  export const Dialog = {
37
- Root: StyledDialog,
48
+ Root: DialogRoot,
38
49
  Trigger: StyledDialogTrigger,
39
50
  Overlay: CustomDialogOverlay,
40
51
  Content: CustomDialogContent,
@@ -140,10 +140,12 @@ export const HMSPrebuilt = React.forwardRef<HMSPrebuiltRefType, HMSPrebuiltProps
140
140
  init: string;
141
141
  tokenByRoomCode: string;
142
142
  roomLayout: string;
143
+ event: string;
143
144
  }
144
145
  | undefined;
145
146
  const tokenByRoomCodeEndpoint: string = endpointsObj?.tokenByRoomCode || '';
146
147
  const initEndpoint: string = endpointsObj?.init || '';
148
+ const eventEndpoint: string = endpointsObj?.event || '';
147
149
  const roomLayoutEndpoint: string = endpointsObj?.roomLayout || '';
148
150
 
149
151
  const overrideLayout: Partial<Layout> = {
@@ -182,6 +184,7 @@ export const HMSPrebuilt = React.forwardRef<HMSPrebuiltRefType, HMSPrebuiltProps
182
184
  tokenByRoomCode: tokenByRoomCodeEndpoint,
183
185
  init: initEndpoint,
184
186
  roomLayout: roomLayoutEndpoint,
187
+ event: eventEndpoint,
185
188
  },
186
189
  }}
187
190
  >
@@ -84,7 +84,6 @@ export const useAppStateManager = () => {
84
84
  .otherwise(() => {
85
85
  // do nothing
86
86
  });
87
- }, [roomLayout, roomState, isLeaveScreenEnabled, isPreviewScreenEnabled, prevRoomState, redirectToLeave, hmsActions]);
88
-
87
+ }, [roomLayout, roomState, isLeaveScreenEnabled, isPreviewScreenEnabled, prevRoomState, redirectToLeave]);
89
88
  return { activeState, rejoin };
90
89
  };
@@ -28,6 +28,7 @@ const endpoints: HMSPrebuiltOptions['endpoints'] = {
28
28
  roomLayout: process.env.STORYBOOK_ROOM_LAYOUT_ENDPOINT,
29
29
  tokenByRoomCode: process.env.STORYBOOK_TOKEN_BY_ROOM_CODE_ENDPOINT,
30
30
  init: process.env.STORYBOOK_INIT_API_ENDPOINT,
31
+ event: process.env.STORYBOOK_EVENT_API_ENDPOINT,
31
32
  };
32
33
 
33
34
  const hasEndpoints = Object.values(endpoints).some(val => !!val);
@@ -7,13 +7,14 @@ class PeersSorter {
7
7
  lruPeers: Set<HMSPeerID>;
8
8
  tilesPerPage!: number;
9
9
  speaker?: HMSPeer;
10
- listeners: Set<(peers: HMSPeer[]) => void> = new Set();
10
+ listeners: Set<(peers: HMSPeer[]) => void>;
11
11
 
12
12
  constructor(store: IStoreReadOnly<any>) {
13
13
  this.store = store;
14
14
  this.peers = new Map();
15
15
  this.lruPeers = new Set();
16
16
  this.speaker = undefined;
17
+ this.listeners = new Set();
17
18
  }
18
19
 
19
20
  setPeersAndTilesPerPage = ({ peers, tilesPerPage }: { peers: HMSPeer[]; tilesPerPage: number }) => {
@@ -0,0 +1,70 @@
1
+ import React, { useState } from 'react';
2
+ import { useMedia } from 'react-use';
3
+ import { Flex } from '../../../Layout';
4
+ import { config as cssConfig } from '../../../Theme';
5
+ import { FEEBACK_INDEX, FeedbackHeader, FeedbackModal } from './FeedbackForm';
6
+ import { ThankyouView } from './ThankyouView';
7
+ import { useRoomLayoutLeaveScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
8
+
9
+ export const Feedback = () => {
10
+ const { feedback } = useRoomLayoutLeaveScreen();
11
+ const [index, setIndex] = useState(FEEBACK_INDEX.INIT);
12
+ const isMobile = useMedia(cssConfig.media.md);
13
+
14
+ if (!feedback) {
15
+ return null;
16
+ }
17
+ const { ratings } = feedback;
18
+ if (!ratings) {
19
+ return null;
20
+ }
21
+ ratings.sort((a, b) => {
22
+ if (!a.value || !b.value) {
23
+ return 0;
24
+ }
25
+ return a.value - b.value;
26
+ });
27
+ // TO show thank ypu page
28
+ if (index === FEEBACK_INDEX.THANK_YOU) {
29
+ return (
30
+ <Flex
31
+ justify="center"
32
+ css={{
33
+ pt: '$16',
34
+ }}
35
+ >
36
+ <ThankyouView />
37
+ </Flex>
38
+ );
39
+ }
40
+ return (
41
+ <Flex
42
+ justify="center"
43
+ css={{
44
+ pt: '$16',
45
+ w: '528px',
46
+ }}
47
+ >
48
+ {index === FEEBACK_INDEX.INIT ? (
49
+ <Flex
50
+ css={{
51
+ p: '$12',
52
+ border: '1px solid $border_default',
53
+ bg: '$surface_dim',
54
+ borderRadius: !isMobile ? '$3' : '$3 $3 0 0',
55
+ gap: '$10',
56
+ '@md': {
57
+ position: 'absolute',
58
+ bottom: '0',
59
+ },
60
+ }}
61
+ direction="column"
62
+ >
63
+ <FeedbackHeader ratings={ratings} onEmojiClicked={setIndex} />
64
+ </Flex>
65
+ ) : (
66
+ <FeedbackModal ratings={ratings} index={index} setIndex={setIndex} />
67
+ )}
68
+ </Flex>
69
+ );
70
+ };
@@ -0,0 +1,371 @@
1
+ import React, { useState } from 'react';
2
+ import { useMedia } from 'react-use';
3
+ import { Rating } from '@100mslive/types-prebuilt/elements/feedback';
4
+ import { useHMSActions } from '@100mslive/react-sdk';
5
+ import { CheckIcon, CrossIcon } from '@100mslive/react-icons';
6
+ import { Button } from '../../../Button';
7
+ import { Checkbox } from '../../../Checkbox';
8
+ import { Label } from '../../../Label';
9
+ import { Flex } from '../../../Layout';
10
+ import { Dialog } from '../../../Modal';
11
+ import { Sheet } from '../../../Sheet';
12
+ import { Text } from '../../../Text';
13
+ import { TextArea } from '../../../TextArea';
14
+ import { config as cssConfig } from '../../../Theme';
15
+ import { useHMSPrebuiltContext } from '../../AppContext';
16
+ import { useRoomLayoutLeaveScreen } from '../../provider/roomLayoutProvider/hooks/useRoomLayoutScreen';
17
+
18
+ export const FEEBACK_INDEX = {
19
+ THANK_YOU: -10,
20
+ INIT: -1,
21
+ };
22
+ export const FeedbackModal = ({
23
+ ratings,
24
+ index,
25
+ setIndex,
26
+ }: {
27
+ ratings: Rating[];
28
+ index: number;
29
+ setIndex: (index: number) => void;
30
+ }) => {
31
+ const isMobile = useMedia(cssConfig.media.md);
32
+ const onOpenChange = () => {
33
+ setIndex(FEEBACK_INDEX.INIT);
34
+ };
35
+ const avoidDefaultDomBehavior = (e: Event) => {
36
+ e.preventDefault();
37
+ };
38
+ if (isMobile) {
39
+ return (
40
+ <Sheet.Root open={index !== FEEBACK_INDEX.INIT} onOpenChange={onOpenChange}>
41
+ <Sheet.Content
42
+ css={{ bg: '$surface_dim', p: '$12' }}
43
+ onPointerDownOutside={avoidDefaultDomBehavior}
44
+ onInteractOutside={avoidDefaultDomBehavior}
45
+ >
46
+ <FeedbackContent ratings={ratings} indexSelected={index} setIndex={setIndex} />
47
+ </Sheet.Content>
48
+ </Sheet.Root>
49
+ );
50
+ }
51
+ return (
52
+ <Dialog.Root open={index !== FEEBACK_INDEX.INIT} onOpenChange={onOpenChange}>
53
+ <Dialog.Portal>
54
+ <Dialog.Overlay />
55
+ <Dialog.Content
56
+ css={{ bg: '$surface_dim', width: '528px', p: '$12' }}
57
+ onPointerDownOutside={avoidDefaultDomBehavior}
58
+ onInteractOutside={avoidDefaultDomBehavior}
59
+ >
60
+ <FeedbackContent ratings={ratings} indexSelected={index} setIndex={setIndex} />
61
+ </Dialog.Content>
62
+ </Dialog.Portal>
63
+ </Dialog.Root>
64
+ );
65
+ };
66
+
67
+ export const FeedbackContent = ({
68
+ ratings,
69
+ indexSelected,
70
+ setIndex,
71
+ }: {
72
+ ratings: Rating[];
73
+ indexSelected: number;
74
+ setIndex: (index: number) => void;
75
+ }) => {
76
+ const { feedback } = useRoomLayoutLeaveScreen();
77
+ const { endpoints } = useHMSPrebuiltContext();
78
+ const hmsActions = useHMSActions();
79
+ const [comment, setComment] = useState('');
80
+ const [selectedReasons, setSelectedReasons] = useState(new Set<number>());
81
+ const handleCheckedChange = (checked: boolean | string, index: number) => {
82
+ const newSelected = new Set(selectedReasons);
83
+ if (checked) {
84
+ newSelected.add(index);
85
+ } else {
86
+ newSelected.delete(index);
87
+ }
88
+ setSelectedReasons(newSelected);
89
+ };
90
+ const submitFeedback = async () => {
91
+ if (indexSelected < 0 || ratings.length <= indexSelected) {
92
+ return;
93
+ }
94
+ try {
95
+ const reasons = [...selectedReasons].map((value: number) => ratings[indexSelected]?.reasons?.[value] || '');
96
+ await hmsActions.submitSessionFeedback(
97
+ {
98
+ question: ratings[indexSelected].question,
99
+ rating: ratings[indexSelected].value || 1,
100
+ min_rating: 1,
101
+ max_rating: ratings.length,
102
+ reasons: selectedReasons.size === 0 ? [] : reasons,
103
+ comment: comment,
104
+ },
105
+ endpoints?.event,
106
+ );
107
+ } catch (e) {
108
+ console.error(e);
109
+ }
110
+ // always submit and take it to thankyou page
111
+ setIndex(FEEBACK_INDEX.THANK_YOU);
112
+ };
113
+ return (
114
+ <Flex
115
+ css={{
116
+ p: indexSelected === FEEBACK_INDEX.INIT ? '$12 !important' : '0',
117
+ bg: '$surface_dim',
118
+ r: '$3',
119
+ gap: '$10',
120
+ }}
121
+ direction="column"
122
+ >
123
+ <FeedbackHeader
124
+ ratings={ratings}
125
+ indexSelected={indexSelected}
126
+ onEmojiClicked={(value: number) => {
127
+ setSelectedReasons(new Set<number>());
128
+ setIndex(value);
129
+ }}
130
+ />
131
+ <FeedbackForm
132
+ rating={ratings[indexSelected]}
133
+ comment={comment}
134
+ setComment={setComment}
135
+ selectedReasons={selectedReasons}
136
+ handleCheckedChange={handleCheckedChange}
137
+ />
138
+ <Button
139
+ type="submit"
140
+ icon
141
+ css={{
142
+ alignSelf: 'end',
143
+ }}
144
+ onClick={submitFeedback}
145
+ >
146
+ {feedback?.submit_btn_label || 'Submit Feedback'}
147
+ </Button>
148
+ </Flex>
149
+ );
150
+ };
151
+ export const FeedbackHeader = ({
152
+ onEmojiClicked,
153
+ ratings,
154
+ indexSelected = FEEBACK_INDEX.INIT,
155
+ }: {
156
+ onEmojiClicked: (index: number) => void;
157
+ ratings: Rating[];
158
+ indexSelected?: number;
159
+ }) => {
160
+ const { feedback } = useRoomLayoutLeaveScreen();
161
+ return (
162
+ <>
163
+ <Flex align="center">
164
+ <Flex
165
+ direction="column"
166
+ css={{
167
+ flex: '1 1 0',
168
+ }}
169
+ >
170
+ <Text
171
+ variant="h5"
172
+ css={{
173
+ c: '$on_surface_high',
174
+ fontStyle: 'normal',
175
+ }}
176
+ >
177
+ {feedback?.title || 'How was your experience?'}
178
+ </Text>
179
+ <Text
180
+ variant="body1"
181
+ css={{
182
+ c: '$on_surface_medium',
183
+ opacity: 0.9,
184
+ fontWeight: '$regular',
185
+ }}
186
+ >
187
+ {feedback?.sub_title || 'Your answers help us improve the quality.'}
188
+ </Text>
189
+ </Flex>
190
+ {indexSelected !== FEEBACK_INDEX.INIT ? (
191
+ <CrossIcon width="24px" height="24px" color="white" onClick={() => onEmojiClicked(FEEBACK_INDEX.INIT)} />
192
+ ) : null}
193
+ </Flex>
194
+ <Flex
195
+ css={{
196
+ gap: '$17',
197
+ c: '$on_surface_high',
198
+ }}
199
+ >
200
+ {ratings.map((element, index) => {
201
+ return (
202
+ <Flex
203
+ align="center"
204
+ direction="column"
205
+ css={{
206
+ c:
207
+ indexSelected === index || indexSelected === FEEBACK_INDEX.INIT
208
+ ? '$on_surface_high'
209
+ : '$on_surface_default',
210
+ gap: '$4',
211
+ }}
212
+ onClick={() => onEmojiClicked(index)}
213
+ key={`${index}`}
214
+ >
215
+ <Text
216
+ css={{
217
+ fontWeight: '$semiBold',
218
+ fontSize: '$h4',
219
+ pb: '$1',
220
+ cursor: 'pointer',
221
+ opacity: indexSelected === index || indexSelected === FEEBACK_INDEX.INIT ? 1 : 0.2,
222
+ }}
223
+ >
224
+ {element.emoji}
225
+ </Text>
226
+ <Text
227
+ variant="body1"
228
+ css={{
229
+ c:
230
+ indexSelected === index || indexSelected === FEEBACK_INDEX.INIT
231
+ ? '$on_surface_medium'
232
+ : '$on_surface_low',
233
+ fontWeight: '$regular',
234
+ }}
235
+ >
236
+ {element.label}
237
+ </Text>
238
+ </Flex>
239
+ );
240
+ })}
241
+ </Flex>
242
+ </>
243
+ );
244
+ };
245
+ export const FeedbackForm = ({
246
+ rating,
247
+ comment,
248
+ setComment,
249
+ selectedReasons,
250
+ handleCheckedChange,
251
+ }: {
252
+ rating: Rating;
253
+ comment: string;
254
+ setComment: (value: string) => void;
255
+ selectedReasons: Set<number>;
256
+ handleCheckedChange: (checked: string | boolean, index: number) => void;
257
+ }) => {
258
+ const { feedback } = useRoomLayoutLeaveScreen();
259
+ return (
260
+ <>
261
+ {rating.reasons && rating.reasons.length > 0 && (
262
+ <Flex
263
+ direction="column"
264
+ css={{
265
+ gap: '$4',
266
+ }}
267
+ >
268
+ <Text
269
+ variant="sub2"
270
+ css={{
271
+ c: '$on_surface_high',
272
+ fontWeight: '$semiBold',
273
+ fontSize: '$sm',
274
+ px: '$2',
275
+ }}
276
+ >
277
+ {rating.question || 'What do you like/dislike here?'}
278
+ </Text>
279
+ <Flex
280
+ css={{
281
+ alignItems: 'flex-start',
282
+ alignSelf: 'stretch',
283
+ flexWrap: 'wrap',
284
+ gap: '$6',
285
+ flex: '1 1 calc(25% - 12px)',
286
+ '@md': {
287
+ flex: '1 1 calc(50% - 12px)',
288
+ },
289
+ '@sm': {
290
+ flex: '1 1 100%',
291
+ },
292
+ }}
293
+ >
294
+ {rating.reasons.map((option: string, index: number) => {
295
+ return (
296
+ <Flex
297
+ align="center"
298
+ gap="2"
299
+ key={index}
300
+ css={{
301
+ border: '1px solid $border_bright',
302
+ r: '$1',
303
+ p: '$6',
304
+ }}
305
+ >
306
+ <Checkbox.Root
307
+ id={`${option}-${index}`}
308
+ checked={selectedReasons.has(index)}
309
+ onCheckedChange={checked => handleCheckedChange(checked, index)}
310
+ css={{
311
+ cursor: 'pointer',
312
+ flexShrink: 0,
313
+ bg: '$on_secondary_low',
314
+ border: '1px solid $border_bright',
315
+ }}
316
+ >
317
+ <Checkbox.Indicator>
318
+ <CheckIcon width={12} height={12} />
319
+ </Checkbox.Indicator>
320
+ </Checkbox.Root>
321
+ <Label
322
+ css={{
323
+ color: '$on_surface_high',
324
+ fontSize: '$sm',
325
+ fontWeight: '$regular',
326
+ lineHeight: '20px' /* 142.857% */,
327
+ }}
328
+ >
329
+ {option}
330
+ </Label>
331
+ </Flex>
332
+ );
333
+ })}
334
+ </Flex>
335
+ </Flex>
336
+ )}
337
+ {feedback?.comment && (
338
+ <Flex
339
+ direction="column"
340
+ css={{
341
+ gap: '$4',
342
+ }}
343
+ >
344
+ <Text
345
+ variant="body2"
346
+ css={{
347
+ c: '$on_surface_high',
348
+ fontWeight: '$regular',
349
+ fontSize: '$sm',
350
+ }}
351
+ >
352
+ {feedback?.comment.label || 'Additional comments (optional)'}
353
+ </Text>
354
+ <TextArea
355
+ maxLength={1024}
356
+ placeholder={feedback?.comment.placeholder || 'Tell us more...'}
357
+ css={{
358
+ backgroundColor: '$surface_bright',
359
+ border: '1px solid $border_bright',
360
+ resize: 'none',
361
+ height: '$36',
362
+ display: 'flex',
363
+ }}
364
+ value={comment}
365
+ onChange={event => setComment(event.target.value.trimStart())}
366
+ />
367
+ </Flex>
368
+ )}
369
+ </>
370
+ );
371
+ };
@@ -0,0 +1,44 @@
1
+ import React from 'react';
2
+ import { useMedia } from 'react-use';
3
+ import { UserMusicIcon } from '@100mslive/react-icons';
4
+ import { Flex } from '../../../Layout';
5
+ import { Text } from '../../../Text';
6
+ import { config as cssConfig } from '../../../Theme';
7
+
8
+ export const ThankyouView = () => {
9
+ const isMobile = useMedia(cssConfig.media.md);
10
+ return (
11
+ <Flex
12
+ direction={isMobile ? 'column' : 'row'}
13
+ align="center"
14
+ css={{
15
+ gap: '$10',
16
+ border: '1px solid $border_default',
17
+ borderRadius: !isMobile ? '$3' : '$3 $3 0 0',
18
+ bg: '$surface_dim',
19
+ w: !isMobile ? '528px' : '410px',
20
+ p: '$12',
21
+ pb: isMobile ? '$16' : '$12',
22
+ '@md': {
23
+ position: 'absolute',
24
+ bottom: '0',
25
+ },
26
+ }}
27
+ >
28
+ <UserMusicIcon width="64px" height="64px" />
29
+ <Flex direction="column" align={isMobile ? 'center' : 'start'}>
30
+ <Text variant="h5">Thank you for your feedback!</Text>
31
+ <Text
32
+ variant="body1"
33
+ css={{
34
+ fontWeight: '$regular',
35
+ fontSize: '$md',
36
+ opacity: '0.9',
37
+ }}
38
+ >
39
+ Your answers help us improve.
40
+ </Text>
41
+ </Flex>
42
+ </Flex>
43
+ );
44
+ };
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ExitIcon } from '@100mslive/react-icons';
3
+ import { Feedback } from './EndCallFeedback/Feedback';
3
4
  // @ts-ignore: No implicit Any
4
5
  import { ToastManager } from './Toast/ToastManager';
5
6
  import { Button } from '../../Button';
@@ -63,6 +64,7 @@ export const LeaveScreen = () => {
63
64
  <Text css={{ ml: '$3', fontWeight: '$semiBold', color: 'inherit' }}>Rejoin</Text>
64
65
  </Button>
65
66
  </Flex>
67
+ <Feedback />
66
68
  </Flex>
67
69
  </Flex>
68
70
  );
@@ -102,9 +102,21 @@ export const PIPChat = () => {
102
102
  )}
103
103
  {filteredMessages.length === 0 ? (
104
104
  <div
105
- style={{ display: 'flex', height: '100%', width: '100%', alignItems: 'center', justifyContent: 'center' }}
105
+ style={{
106
+ display: 'flex',
107
+ flexDirection: 'column',
108
+ height: '100%',
109
+ width: '100%',
110
+ alignItems: 'center',
111
+ justifyContent: 'center',
112
+ }}
106
113
  >
107
- <Text>No messages here yet</Text>
114
+ <Text variant="h5" css={{ mt: '$8', c: '$on_surface_high' }}>
115
+ {canSendChatMessages ? 'Start a conversation' : 'No messages yet'}
116
+ </Text>
117
+ <Text variant="sm" style={{ maxWidth: '80%', textAlign: 'center', marginTop: '4px' }}>
118
+ There are no messages here yet. Start a conversation by sending a message.
119
+ </Text>
108
120
  </div>
109
121
  ) : (
110
122
  filteredMessages.map(message => (
@@ -5,7 +5,6 @@ import { config as cssConfig } from '../../../Theme';
5
5
  import { InsetTile } from '../InsetTile';
6
6
  import { Pagination } from '../Pagination';
7
7
  import { SecondaryTiles } from '../SecondaryTiles';
8
- import { LayoutMode } from '../Settings/LayoutSettings';
9
8
  import { Grid } from './Grid';
10
9
  import { LayoutProps } from './interface';
11
10
  import { ProminenceLayout } from './ProminenceLayout';
@@ -25,7 +24,6 @@ export function RoleProminence({
25
24
  }: LayoutProps) {
26
25
  const { prominentPeers, secondaryPeers } = useRoleProminencePeers(prominentRoles, peers, isInsetEnabled);
27
26
  const localPeer = useHMSStore(selectLocalPeer);
28
- const layoutMode = useUISettings(UI_SETTINGS.layoutMode);
29
27
  const isMobile = useMedia(cssConfig.media.md);
30
28
  let maxTileCount = useUISettings(UI_SETTINGS.maxTileCount);
31
29
  maxTileCount = isMobile ? 4 : maxTileCount;
@@ -47,7 +45,7 @@ export function RoleProminence({
47
45
  }, [pageSize, onPageSize]);
48
46
 
49
47
  return (
50
- <ProminenceLayout.Root hasSidebar={layoutMode === LayoutMode.SIDEBAR}>
48
+ <ProminenceLayout.Root>
51
49
  <ProminenceLayout.ProminentSection>
52
50
  <Grid ref={ref} tiles={pagesWithTiles[page]} />
53
51
  </ProminenceLayout.ProminentSection>
@@ -61,12 +59,7 @@ export function RoleProminence({
61
59
  numPages={pagesWithTiles.length}
62
60
  />
63
61
  )}
64
- <SecondaryTiles
65
- peers={layoutMode === LayoutMode.SPOTLIGHT ? [] : secondaryPeers}
66
- isInsetEnabled={isInsetEnabled}
67
- edgeToEdge={edgeToEdge}
68
- hasSidebar={layoutMode === LayoutMode.SIDEBAR}
69
- />
62
+ <SecondaryTiles peers={secondaryPeers} isInsetEnabled={isInsetEnabled} edgeToEdge={edgeToEdge} />
70
63
  {isInsetEnabled && localPeer && prominentPeers.length > 0 && !prominentPeers.includes(localPeer) && <InsetTile />}
71
64
  </ProminenceLayout.Root>
72
65
  );