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

Sign up to get free protection for your applications and to get access to all the features.
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
  );