@syra.fm/sdk 0.14.0 → 0.15.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.
- package/lib/commonjs/live/components/CreateRoomSheet.js +73 -15
- package/lib/commonjs/live/components/CreateRoomSheet.js.map +1 -1
- package/lib/commonjs/live/components/InsightsPanel.js +1 -1
- package/lib/commonjs/live/components/LiveRoomSheet.js +1 -1
- package/lib/commonjs/live/components/MiniRoomBar.js +1 -1
- package/lib/commonjs/live/components/PanelHeader.js +1 -1
- package/lib/commonjs/live/components/PanelHeader.js.map +1 -1
- package/lib/commonjs/live/components/PodcastStreamPicker.js +1 -1
- package/lib/commonjs/live/components/RecordingCard.js +1 -1
- package/lib/commonjs/live/components/RecordingsPanel.js +1 -1
- package/lib/commonjs/live/components/RoomCard.js +1 -1
- package/lib/commonjs/live/components/StreamConfigModal.js +5 -3
- package/lib/commonjs/live/components/StreamConfigModal.js.map +1 -1
- package/lib/commonjs/live/components/StreamConfigPanel.js +1 -1
- package/lib/commonjs/live/hooks/useRoomConnection.js +1 -1
- package/lib/commonjs/live/hooks/useRoomConnection.js.map +1 -1
- package/lib/commonjs/live/hooks/useRoomUsers.js +2 -2
- package/lib/commonjs/live/hooks/useRoomUsers.js.map +1 -1
- package/lib/commonjs/live/icons/MaterialCommunityIcons.js +43 -0
- package/lib/commonjs/live/icons/MaterialCommunityIcons.js.map +1 -0
- package/lib/module/live/components/CreateRoomSheet.js +74 -15
- package/lib/module/live/components/CreateRoomSheet.js.map +1 -1
- package/lib/module/live/components/InsightsPanel.js +1 -1
- package/lib/module/live/components/InsightsPanel.js.map +1 -1
- package/lib/module/live/components/LiveRoomSheet.js +1 -1
- package/lib/module/live/components/LiveRoomSheet.js.map +1 -1
- package/lib/module/live/components/MiniRoomBar.js +1 -1
- package/lib/module/live/components/MiniRoomBar.js.map +1 -1
- package/lib/module/live/components/PanelHeader.js +1 -1
- package/lib/module/live/components/PanelHeader.js.map +1 -1
- package/lib/module/live/components/PodcastStreamPicker.js +1 -1
- package/lib/module/live/components/PodcastStreamPicker.js.map +1 -1
- package/lib/module/live/components/RecordingCard.js +1 -1
- package/lib/module/live/components/RecordingCard.js.map +1 -1
- package/lib/module/live/components/RecordingsPanel.js +1 -1
- package/lib/module/live/components/RecordingsPanel.js.map +1 -1
- package/lib/module/live/components/RoomCard.js +1 -1
- package/lib/module/live/components/RoomCard.js.map +1 -1
- package/lib/module/live/components/StreamConfigModal.js +5 -3
- package/lib/module/live/components/StreamConfigModal.js.map +1 -1
- package/lib/module/live/components/StreamConfigPanel.js +1 -1
- package/lib/module/live/components/StreamConfigPanel.js.map +1 -1
- package/lib/module/live/hooks/useRoomConnection.js +1 -1
- package/lib/module/live/hooks/useRoomConnection.js.map +1 -1
- package/lib/module/live/hooks/useRoomUsers.js +2 -2
- package/lib/module/live/hooks/useRoomUsers.js.map +1 -1
- package/lib/module/live/icons/MaterialCommunityIcons.js +36 -0
- package/lib/module/live/icons/MaterialCommunityIcons.js.map +1 -0
- package/lib/typescript/commonjs/live/components/CreateRoomSheet.d.ts +10 -0
- package/lib/typescript/commonjs/live/components/CreateRoomSheet.d.ts.map +1 -1
- package/lib/typescript/commonjs/live/icons/MaterialCommunityIcons.d.ts +26 -0
- package/lib/typescript/commonjs/live/icons/MaterialCommunityIcons.d.ts.map +1 -0
- package/lib/typescript/commonjs/live/validation.d.ts +4 -4
- package/lib/typescript/commonjs/live/validation.d.ts.map +1 -1
- package/lib/typescript/module/live/components/CreateRoomSheet.d.ts +10 -0
- package/lib/typescript/module/live/components/CreateRoomSheet.d.ts.map +1 -1
- package/lib/typescript/module/live/icons/MaterialCommunityIcons.d.ts +26 -0
- package/lib/typescript/module/live/icons/MaterialCommunityIcons.d.ts.map +1 -0
- package/lib/typescript/module/live/validation.d.ts +4 -4
- package/lib/typescript/module/live/validation.d.ts.map +1 -1
- package/package.json +5 -4
- package/src/live/components/CreateRoomSheet.tsx +68 -15
- package/src/live/components/InsightsPanel.tsx +1 -1
- package/src/live/components/LiveRoomSheet.tsx +1 -1
- package/src/live/components/MiniRoomBar.tsx +1 -1
- package/src/live/components/PanelHeader.tsx +1 -1
- package/src/live/components/PodcastStreamPicker.tsx +1 -1
- package/src/live/components/RecordingCard.tsx +1 -1
- package/src/live/components/RecordingsPanel.tsx +1 -1
- package/src/live/components/RoomCard.tsx +1 -1
- package/src/live/components/StreamConfigModal.tsx +3 -3
- package/src/live/components/StreamConfigPanel.tsx +1 -1
- package/src/live/hooks/useRoomConnection.ts +1 -1
- package/src/live/hooks/useRoomUsers.ts +2 -2
- package/src/live/icons/MaterialCommunityIcons.tsx +33 -0
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import type { Room, House } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Failure copy the sheet shows INLINE. It used to go to the host `toast`, but
|
|
5
|
+
* the sheet is usually presented in a native modal window, and a toast renders
|
|
6
|
+
* in the main window underneath it: a failed create (a 401 from an expired
|
|
7
|
+
* session, a network drop) looked like a button that did nothing.
|
|
8
|
+
*/
|
|
9
|
+
export declare const CREATE_ROOM_ERRORS: {
|
|
10
|
+
readonly createFailed: "Couldn't create the room. Check your connection and that you're signed in, then try again.";
|
|
11
|
+
readonly scheduleMissing: "Enter a scheduled start time to schedule the room.";
|
|
12
|
+
};
|
|
3
13
|
export interface CreateRoomSheetRef {
|
|
4
14
|
handleCreateAndStart: () => void;
|
|
5
15
|
handleSchedule: () => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CreateRoomSheet.d.ts","sourceRoot":"","sources":["../../../../../src/live/components/CreateRoomSheet.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+D,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"CreateRoomSheet.d.ts","sourceRoot":"","sources":["../../../../../src/live/components/CreateRoomSheet.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA+D,MAAM,OAAO,CAAC;AAepF,OAAO,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAG5C;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB;;;CAGrB,CAAC;AA0BX,MAAM,WAAW,kBAAkB;IACjC,oBAAoB,EAAE,MAAM,IAAI,CAAC;IACjC,cAAc,EAAE,MAAM,IAAI,CAAC;IAC3B,oBAAoB,EAAE,MAAM,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,UAAU,oBAAoB;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACrC,IAAI,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;IAC9B,mBAAmB,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;QAAE,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAA;KAAE,CAAC,CAAC;IACzE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACzD,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB;AAED,eAAO,MAAM,eAAe,iGAoe1B,CAAC;AAmJH,eAAe,eAAe,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React, { type ComponentProps } from 'react';
|
|
2
|
+
import BaseMaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
|
|
3
|
+
export type MaterialCommunityIconsProps = ComponentProps<typeof BaseMaterialCommunityIcons>;
|
|
4
|
+
/**
|
|
5
|
+
* The live-rooms UI's one entry to the MaterialCommunityIcons glyph font. SDK
|
|
6
|
+
* components import this, never `@expo/vector-icons/MaterialCommunityIcons`
|
|
7
|
+
* directly — `src/live/icons/glyphImports.test.ts` fails the suite if one does.
|
|
8
|
+
*
|
|
9
|
+
* A vector-icons glyph is a `Text` node whose content is a private-use code
|
|
10
|
+
* point. A screen reader reads it like any other text, so the Create Room sheet
|
|
11
|
+
* announced its options as "\U000f036c, Talk, Open conversation" and its button
|
|
12
|
+
* as "\U000f040a, Start Now": on Android RN builds an unlabelled pressable's
|
|
13
|
+
* description from its children's text, code point included.
|
|
14
|
+
*
|
|
15
|
+
* Every glyph in the SDK is decorative — the control around it carries the
|
|
16
|
+
* words, or an `accessibilityLabel` — so the glyph is hidden from assistive
|
|
17
|
+
* technology here, once, rather than at each call site where the next icon
|
|
18
|
+
* would forget it. `aria-hidden` is `importantForAccessibility=
|
|
19
|
+
* "no-hide-descendants"` on Android, `accessibilityElementsHidden` on iOS and
|
|
20
|
+
* `aria-hidden` on web. It is applied AFTER the caller's props so a call site
|
|
21
|
+
* cannot switch it back on: a glyph that needs a name belongs inside a control
|
|
22
|
+
* that has one.
|
|
23
|
+
*/
|
|
24
|
+
export declare function MaterialCommunityIcons(props: MaterialCommunityIconsProps): React.JSX.Element;
|
|
25
|
+
export default MaterialCommunityIcons;
|
|
26
|
+
//# sourceMappingURL=MaterialCommunityIcons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MaterialCommunityIcons.d.ts","sourceRoot":"","sources":["../../../../../src/live/icons/MaterialCommunityIcons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,KAAK,cAAc,EAAE,MAAM,OAAO,CAAC;AAInD,OAAO,0BAA0B,MAAM,2CAA2C,CAAC;AAEnF,MAAM,MAAM,2BAA2B,GAAG,cAAc,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE5F;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,2BAA2B,qBAExE;AAED,eAAe,sBAAsB,CAAC"}
|
|
@@ -71,7 +71,7 @@ export declare const ZRoom: z.ZodPreprocess<z.ZodObject<{
|
|
|
71
71
|
recordingEnabled: z.ZodDefault<z.ZodOptional<z.ZodBoolean>>;
|
|
72
72
|
recordingEgressId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
73
73
|
createdAt: z.ZodString;
|
|
74
|
-
}, z.core.$loose
|
|
74
|
+
}, z.core.$loose>, unknown>;
|
|
75
75
|
export type Room = z.infer<typeof ZRoom>;
|
|
76
76
|
export declare const ZRoomParticipant: z.ZodObject<{
|
|
77
77
|
userId: z.ZodString;
|
|
@@ -152,7 +152,7 @@ export declare const ZHouse: z.ZodPreprocess<z.ZodObject<{
|
|
|
152
152
|
}, z.core.$loose>>;
|
|
153
153
|
tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
|
|
154
154
|
createdAt: z.ZodString;
|
|
155
|
-
}, z.core.$loose
|
|
155
|
+
}, z.core.$loose>, unknown>;
|
|
156
156
|
export type House = z.infer<typeof ZHouse>;
|
|
157
157
|
export declare const ZRecurrence: z.ZodObject<{
|
|
158
158
|
type: z.ZodEnum<{
|
|
@@ -233,7 +233,7 @@ export declare const ZSeries: z.ZodPreprocess<z.ZodObject<{
|
|
|
233
233
|
nextEpisodeNumber: z.ZodDefault<z.ZodNumber>;
|
|
234
234
|
isActive: z.ZodDefault<z.ZodBoolean>;
|
|
235
235
|
createdAt: z.ZodString;
|
|
236
|
-
}, z.core.$loose
|
|
236
|
+
}, z.core.$loose>, unknown>;
|
|
237
237
|
export type Series = z.infer<typeof ZSeries>;
|
|
238
238
|
export declare const ZRecording: z.ZodPreprocess<z.ZodObject<{
|
|
239
239
|
id: z.ZodString;
|
|
@@ -260,7 +260,7 @@ export declare const ZRecording: z.ZodPreprocess<z.ZodObject<{
|
|
|
260
260
|
participantIds: z.ZodDefault<z.ZodArray<z.ZodString>>;
|
|
261
261
|
expiresAt: z.ZodString;
|
|
262
262
|
createdAt: z.ZodString;
|
|
263
|
-
}, z.core.$loose
|
|
263
|
+
}, z.core.$loose>, unknown>;
|
|
264
264
|
export type Recording = z.infer<typeof ZRecording>;
|
|
265
265
|
export declare const ZStartStreamResponse: z.ZodObject<{
|
|
266
266
|
ingressId: z.ZodString;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../src/live/validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiCxB;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB;;;iBAGd,CAAC;AAEjB,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAIjE,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"validation.d.ts","sourceRoot":"","sources":["../../../../src/live/validation.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@syra.fm/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.15.0",
|
|
4
4
|
"description": "Syra SDK — headless, isomorphic catalog client (Node/React-free, public reads + 30s previews) that also ships the Syra live-rooms engine (audio rooms over LiveKit) on React Native and web.",
|
|
5
5
|
"source": "src/index.ts",
|
|
6
6
|
"main": "lib/commonjs/index.js",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"src",
|
|
37
37
|
"lib",
|
|
38
38
|
"!src/**/*.test.ts",
|
|
39
|
-
"!src/**/*.spec.ts"
|
|
39
|
+
"!src/**/*.spec.ts",
|
|
40
|
+
"!src/**/*.test.tsx"
|
|
40
41
|
],
|
|
41
42
|
"keywords": [
|
|
42
43
|
"syra",
|
|
@@ -92,7 +93,7 @@
|
|
|
92
93
|
"react-native": "^0.85.3",
|
|
93
94
|
"react-native-reanimated": "^4.3.1",
|
|
94
95
|
"react-native-safe-area-context": "^5.7.0",
|
|
95
|
-
"@oxy.so/services": "^
|
|
96
|
+
"@oxy.so/services": "^8.0.0",
|
|
96
97
|
"livekit-client": "^2.20.0",
|
|
97
98
|
"@livekit/react-native": "^2.11.1",
|
|
98
99
|
"expo-audio": "~56.0.12",
|
|
@@ -153,7 +154,7 @@
|
|
|
153
154
|
"react-native": "^0.85.3",
|
|
154
155
|
"react-native-reanimated": "^4.3.1",
|
|
155
156
|
"react-native-safe-area-context": "^5.7.0",
|
|
156
|
-
"@oxy.so/services": "^
|
|
157
|
+
"@oxy.so/services": "^8.0.0",
|
|
157
158
|
"livekit-client": "^2.20.0",
|
|
158
159
|
"@livekit/react-native": "^2.11.1",
|
|
159
160
|
"expo-audio": "~56.0.12",
|
|
@@ -7,12 +7,25 @@ import {
|
|
|
7
7
|
TextInput,
|
|
8
8
|
ScrollView,
|
|
9
9
|
FlatList,
|
|
10
|
+
AccessibilityInfo,
|
|
10
11
|
} from 'react-native';
|
|
11
|
-
import MaterialCommunityIcons from '
|
|
12
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
12
13
|
|
|
13
14
|
import { useLiveConfig } from '../context/LiveConfigContext';
|
|
14
15
|
import { useLiveRoom } from '../context/LiveRoomContext';
|
|
15
16
|
import type { Room, House } from '../types';
|
|
17
|
+
import { LIVE_COLOR, LIVE_TINT_COLOR } from '../colors';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Failure copy the sheet shows INLINE. It used to go to the host `toast`, but
|
|
21
|
+
* the sheet is usually presented in a native modal window, and a toast renders
|
|
22
|
+
* in the main window underneath it: a failed create (a 401 from an expired
|
|
23
|
+
* session, a network drop) looked like a button that did nothing.
|
|
24
|
+
*/
|
|
25
|
+
export const CREATE_ROOM_ERRORS = {
|
|
26
|
+
createFailed: "Couldn't create the room. Check your connection and that you're signed in, then try again.",
|
|
27
|
+
scheduleMissing: 'Enter a scheduled start time to schedule the room.',
|
|
28
|
+
} as const;
|
|
16
29
|
|
|
17
30
|
const TOPICS = [
|
|
18
31
|
'Technology',
|
|
@@ -82,6 +95,7 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
82
95
|
const [selectedHouse, setSelectedHouse] = useState<House | null>(null);
|
|
83
96
|
const [recordingEnabled, setRecordingEnabled] = useState(true);
|
|
84
97
|
const [loading, setLoading] = useState(false);
|
|
98
|
+
const [error, setError] = useState<string | null>(null);
|
|
85
99
|
|
|
86
100
|
const isValid = title.trim().length > 0;
|
|
87
101
|
const isBroadcast = roomType === 'broadcast';
|
|
@@ -101,9 +115,17 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
101
115
|
recordingEnabled,
|
|
102
116
|
});
|
|
103
117
|
|
|
118
|
+
// Keep the sheet open and say what went wrong where the user is looking, so
|
|
119
|
+
// they can fix it and retry. Screen readers get it announced too.
|
|
120
|
+
const showError = (message: string) => {
|
|
121
|
+
setError(message);
|
|
122
|
+
AccessibilityInfo.announceForAccessibility?.(message);
|
|
123
|
+
};
|
|
124
|
+
|
|
104
125
|
const handleCreateAndStart = async () => {
|
|
105
126
|
if (!isValid || loading) return;
|
|
106
127
|
|
|
128
|
+
setError(null);
|
|
107
129
|
setLoading(true);
|
|
108
130
|
try {
|
|
109
131
|
const room = await roomsService.createRoom(buildCreatePayload());
|
|
@@ -118,11 +140,11 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
118
140
|
}
|
|
119
141
|
onRoomCreated?.(room);
|
|
120
142
|
} else {
|
|
121
|
-
|
|
143
|
+
showError(CREATE_ROOM_ERRORS.createFailed);
|
|
122
144
|
}
|
|
123
|
-
} catch (
|
|
124
|
-
console.error('Error creating room:',
|
|
125
|
-
|
|
145
|
+
} catch (err) {
|
|
146
|
+
console.error('Error creating room:', err);
|
|
147
|
+
showError(CREATE_ROOM_ERRORS.createFailed);
|
|
126
148
|
} finally {
|
|
127
149
|
setLoading(false);
|
|
128
150
|
}
|
|
@@ -132,10 +154,11 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
132
154
|
if (!isValid || loading) return;
|
|
133
155
|
|
|
134
156
|
if (!scheduledStart.trim()) {
|
|
135
|
-
|
|
157
|
+
showError(CREATE_ROOM_ERRORS.scheduleMissing);
|
|
136
158
|
return;
|
|
137
159
|
}
|
|
138
160
|
|
|
161
|
+
setError(null);
|
|
139
162
|
setLoading(true);
|
|
140
163
|
try {
|
|
141
164
|
const room = await roomsService.createRoom({
|
|
@@ -147,11 +170,11 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
147
170
|
onClose();
|
|
148
171
|
onRoomCreated?.(room);
|
|
149
172
|
} else {
|
|
150
|
-
|
|
173
|
+
showError(CREATE_ROOM_ERRORS.createFailed);
|
|
151
174
|
}
|
|
152
|
-
} catch (
|
|
153
|
-
console.error('Error creating room:',
|
|
154
|
-
|
|
175
|
+
} catch (err) {
|
|
176
|
+
console.error('Error creating room:', err);
|
|
177
|
+
showError(CREATE_ROOM_ERRORS.createFailed);
|
|
155
178
|
} finally {
|
|
156
179
|
setLoading(false);
|
|
157
180
|
}
|
|
@@ -160,6 +183,7 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
160
183
|
const handleCreateForEmbed = async () => {
|
|
161
184
|
if (!isValid || loading) return;
|
|
162
185
|
|
|
186
|
+
setError(null);
|
|
163
187
|
setLoading(true);
|
|
164
188
|
try {
|
|
165
189
|
const room = await roomsService.createRoom(buildCreatePayload());
|
|
@@ -168,11 +192,11 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
168
192
|
onClose();
|
|
169
193
|
onRoomCreated?.(room);
|
|
170
194
|
} else {
|
|
171
|
-
|
|
195
|
+
showError(CREATE_ROOM_ERRORS.createFailed);
|
|
172
196
|
}
|
|
173
|
-
} catch (
|
|
174
|
-
console.error('Error creating room:',
|
|
175
|
-
|
|
197
|
+
} catch (err) {
|
|
198
|
+
console.error('Error creating room:', err);
|
|
199
|
+
showError(CREATE_ROOM_ERRORS.createFailed);
|
|
176
200
|
} finally {
|
|
177
201
|
setLoading(false);
|
|
178
202
|
}
|
|
@@ -260,7 +284,12 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
260
284
|
return (
|
|
261
285
|
<View style={[styles.container, { backgroundColor: theme.colors.background }]}>
|
|
262
286
|
<View style={[styles.header, { borderBottomColor: theme.colors.border }]}>
|
|
263
|
-
<TouchableOpacity
|
|
287
|
+
<TouchableOpacity
|
|
288
|
+
onPress={onClose}
|
|
289
|
+
style={styles.headerCloseBtn}
|
|
290
|
+
accessibilityRole="button"
|
|
291
|
+
accessibilityLabel="Close"
|
|
292
|
+
>
|
|
264
293
|
<MaterialCommunityIcons name="close" size={20} color={theme.colors.text} />
|
|
265
294
|
</TouchableOpacity>
|
|
266
295
|
<Text style={[styles.headerTitle, { color: theme.colors.text }]}>
|
|
@@ -269,6 +298,18 @@ export const CreateRoomSheet = forwardRef<CreateRoomSheetRef, CreateRoomSheetPro
|
|
|
269
298
|
<View style={{ width: 28 }} />
|
|
270
299
|
</View>
|
|
271
300
|
|
|
301
|
+
{error && (
|
|
302
|
+
<View
|
|
303
|
+
testID="create-room-error"
|
|
304
|
+
accessibilityRole="alert"
|
|
305
|
+
accessibilityLiveRegion="assertive"
|
|
306
|
+
style={[styles.errorBanner, { backgroundColor: LIVE_TINT_COLOR, borderColor: LIVE_COLOR }]}
|
|
307
|
+
>
|
|
308
|
+
<MaterialCommunityIcons name="alert-circle-outline" size={18} color={LIVE_COLOR} />
|
|
309
|
+
<Text style={[styles.errorText, { color: theme.colors.text }]}>{error}</Text>
|
|
310
|
+
</View>
|
|
311
|
+
)}
|
|
312
|
+
|
|
272
313
|
<Scroll
|
|
273
314
|
style={{ flex: 1 }}
|
|
274
315
|
contentContainerStyle={[styles.scrollContent, hideFooter && { paddingBottom: 72 }]}
|
|
@@ -532,6 +573,18 @@ const styles = StyleSheet.create({
|
|
|
532
573
|
},
|
|
533
574
|
headerCloseBtn: { width: 28, height: 28, alignItems: 'center', justifyContent: 'center' },
|
|
534
575
|
headerTitle: { fontSize: 16, fontWeight: '600' },
|
|
576
|
+
errorBanner: {
|
|
577
|
+
flexDirection: 'row',
|
|
578
|
+
alignItems: 'flex-start',
|
|
579
|
+
gap: 8,
|
|
580
|
+
marginHorizontal: 16,
|
|
581
|
+
marginTop: 12,
|
|
582
|
+
paddingHorizontal: 12,
|
|
583
|
+
paddingVertical: 10,
|
|
584
|
+
borderRadius: 12,
|
|
585
|
+
borderWidth: 1,
|
|
586
|
+
},
|
|
587
|
+
errorText: { flex: 1, fontSize: 13, lineHeight: 18 },
|
|
535
588
|
scrollContent: { paddingVertical: 16, paddingBottom: 12 },
|
|
536
589
|
sectionPadded: { paddingHorizontal: 16 },
|
|
537
590
|
inputSection: { marginBottom: 16 },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, ScrollView } from 'react-native';
|
|
3
|
-
import MaterialCommunityIcons from '
|
|
3
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
4
4
|
|
|
5
5
|
import { PanelHeader } from './PanelHeader';
|
|
6
6
|
import type { Room, RoomParticipant, LiveTheme } from '../types';
|
|
@@ -8,7 +8,7 @@ import {
|
|
|
8
8
|
ScrollView,
|
|
9
9
|
type ViewStyle,
|
|
10
10
|
} from 'react-native';
|
|
11
|
-
import MaterialCommunityIcons from '
|
|
11
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
12
12
|
import { useAuth } from '@oxy.so/services';
|
|
13
13
|
|
|
14
14
|
import { useLiveConfig } from '../context/LiveConfigContext';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useEffect } from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
|
|
3
|
-
import MaterialCommunityIcons from '
|
|
3
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
4
4
|
import Animated, {
|
|
5
5
|
useSharedValue,
|
|
6
6
|
useAnimatedStyle,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, TouchableOpacity } from 'react-native';
|
|
3
|
-
import MaterialCommunityIcons from '
|
|
3
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
4
4
|
|
|
5
5
|
import type { LiveTheme } from '../types';
|
|
6
6
|
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
Linking,
|
|
11
11
|
} from 'react-native';
|
|
12
12
|
import type { ViewStyle } from 'react-native';
|
|
13
|
-
import MaterialCommunityIcons from '
|
|
13
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
14
14
|
|
|
15
15
|
import { useLiveConfig, type PinnedPodcast } from '../context/LiveConfigContext';
|
|
16
16
|
import type { LiveTheme } from '../types';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, TouchableOpacity, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
-
import MaterialCommunityIcons from '
|
|
3
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
4
4
|
import { useAuth } from '@oxy.so/services';
|
|
5
5
|
|
|
6
6
|
import { useLiveConfig } from '../context/LiveConfigContext';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import { View, Text, StyleSheet, ScrollView, TouchableOpacity, ActivityIndicator } from 'react-native';
|
|
3
|
-
import MaterialCommunityIcons from '
|
|
3
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
4
4
|
|
|
5
5
|
import { PanelHeader } from './PanelHeader';
|
|
6
6
|
import { useLiveConfig } from '../context/LiveConfigContext';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import React, { useMemo } from 'react';
|
|
2
2
|
import { View, Text, TouchableOpacity, StyleProp, ViewStyle } from 'react-native';
|
|
3
|
-
import MaterialCommunityIcons from '
|
|
3
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
4
4
|
import { useAuth } from '@oxy.so/services';
|
|
5
5
|
|
|
6
6
|
import { useLiveConfig } from '../context/LiveConfigContext';
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
ScrollView,
|
|
13
13
|
KeyboardAvoidingView,
|
|
14
14
|
} from 'react-native';
|
|
15
|
-
import MaterialCommunityIcons from '
|
|
15
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
16
16
|
import { useAuth } from '@oxy.so/services';
|
|
17
17
|
import * as ImagePicker from 'expo-image-picker';
|
|
18
18
|
|
|
@@ -98,9 +98,9 @@ export function StreamConfigModal({ visible, onClose, roomId, initialStreamUrl,
|
|
|
98
98
|
return;
|
|
99
99
|
}
|
|
100
100
|
|
|
101
|
-
const uploadResponse = await oxyServices.
|
|
101
|
+
const uploadResponse = await oxyServices.assets.upload(file, { visibility: 'public' });
|
|
102
102
|
|
|
103
|
-
const fileId = uploadResponse
|
|
103
|
+
const fileId = uploadResponse.file?.id;
|
|
104
104
|
|
|
105
105
|
if (fileId) {
|
|
106
106
|
setImageFileId(fileId);
|
|
@@ -10,7 +10,7 @@ import {
|
|
|
10
10
|
Platform,
|
|
11
11
|
ScrollView,
|
|
12
12
|
} from 'react-native';
|
|
13
|
-
import MaterialCommunityIcons from '
|
|
13
|
+
import MaterialCommunityIcons from '../icons/MaterialCommunityIcons';
|
|
14
14
|
import * as ImagePicker from 'expo-image-picker';
|
|
15
15
|
|
|
16
16
|
import { useLiveConfig } from '../context/LiveConfigContext';
|
|
@@ -51,7 +51,7 @@ export function useRoomConnection({
|
|
|
51
51
|
|
|
52
52
|
useEffect(() => {
|
|
53
53
|
if (!enabled || !isAuthenticated || !isReady || !userId) return;
|
|
54
|
-
const token = oxyServices?.
|
|
54
|
+
const token = oxyServices?.session.accessToken ?? undefined;
|
|
55
55
|
if (!token) return;
|
|
56
56
|
roomSocketService.connect(userId, token);
|
|
57
57
|
const interval = setInterval(() => { setIsConnected(roomSocketService.isConnected); }, 500);
|
|
@@ -12,7 +12,7 @@ export function useRoomUsers(userIds: string[]) {
|
|
|
12
12
|
async (id: string) => {
|
|
13
13
|
if (!oxyServices) return null;
|
|
14
14
|
try {
|
|
15
|
-
return await oxyServices.
|
|
15
|
+
return await oxyServices.users.get(id);
|
|
16
16
|
} catch {
|
|
17
17
|
return null;
|
|
18
18
|
}
|
|
@@ -32,7 +32,7 @@ export function useRoomUsers(userIds: string[]) {
|
|
|
32
32
|
|
|
33
33
|
export function getDisplayName(userProfile: UserEntity | undefined, userId: string, isCurrentUser?: boolean): string {
|
|
34
34
|
if (isCurrentUser) return 'You';
|
|
35
|
-
// The user source is always an Oxy user DTO (resolved via `oxyServices.
|
|
35
|
+
// The user source is always an Oxy user DTO (resolved via `oxyServices.users.get`
|
|
36
36
|
// in `useRoomUsers` → `ensureUserById`), so `name.displayName` is the canonical,
|
|
37
37
|
// API-owned display string and is rendered directly. The `userId` slice is a
|
|
38
38
|
// not-yet-resolved loading fallback, NOT a name recompute.
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import React, { type ComponentProps } from 'react';
|
|
2
|
+
// The SUBPATH, never the `@expo/vector-icons` barrel: the barrel re-exports every
|
|
3
|
+
// icon family, so one glyph through it drags every family's font into a web
|
|
4
|
+
// bundle.
|
|
5
|
+
import BaseMaterialCommunityIcons from '@expo/vector-icons/MaterialCommunityIcons';
|
|
6
|
+
|
|
7
|
+
export type MaterialCommunityIconsProps = ComponentProps<typeof BaseMaterialCommunityIcons>;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The live-rooms UI's one entry to the MaterialCommunityIcons glyph font. SDK
|
|
11
|
+
* components import this, never `@expo/vector-icons/MaterialCommunityIcons`
|
|
12
|
+
* directly — `src/live/icons/glyphImports.test.ts` fails the suite if one does.
|
|
13
|
+
*
|
|
14
|
+
* A vector-icons glyph is a `Text` node whose content is a private-use code
|
|
15
|
+
* point. A screen reader reads it like any other text, so the Create Room sheet
|
|
16
|
+
* announced its options as "\U000f036c, Talk, Open conversation" and its button
|
|
17
|
+
* as "\U000f040a, Start Now": on Android RN builds an unlabelled pressable's
|
|
18
|
+
* description from its children's text, code point included.
|
|
19
|
+
*
|
|
20
|
+
* Every glyph in the SDK is decorative — the control around it carries the
|
|
21
|
+
* words, or an `accessibilityLabel` — so the glyph is hidden from assistive
|
|
22
|
+
* technology here, once, rather than at each call site where the next icon
|
|
23
|
+
* would forget it. `aria-hidden` is `importantForAccessibility=
|
|
24
|
+
* "no-hide-descendants"` on Android, `accessibilityElementsHidden` on iOS and
|
|
25
|
+
* `aria-hidden` on web. It is applied AFTER the caller's props so a call site
|
|
26
|
+
* cannot switch it back on: a glyph that needs a name belongs inside a control
|
|
27
|
+
* that has one.
|
|
28
|
+
*/
|
|
29
|
+
export function MaterialCommunityIcons(props: MaterialCommunityIconsProps) {
|
|
30
|
+
return <BaseMaterialCommunityIcons {...props} aria-hidden />;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export default MaterialCommunityIcons;
|