@syra.fm/sdk 0.5.0 → 0.7.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/README.md +33 -4
- package/lib/commonjs/live/colors.js +54 -0
- package/lib/commonjs/live/colors.js.map +1 -0
- package/lib/commonjs/live/components/LiveRoomSheet.js +9 -8
- package/lib/commonjs/live/components/LiveRoomSheet.js.map +1 -1
- package/lib/commonjs/live/components/MiniRoomBar.js +3 -2
- package/lib/commonjs/live/components/MiniRoomBar.js.map +1 -1
- package/lib/commonjs/live/components/PodcastStreamPicker.js +1 -1
- package/lib/commonjs/live/components/RecordingsPanel.js +3 -2
- package/lib/commonjs/live/components/RecordingsPanel.js.map +1 -1
- package/lib/commonjs/live/components/RoomCard.js +283 -404
- package/lib/commonjs/live/components/RoomCard.js.map +1 -1
- package/lib/commonjs/live/index.js +31 -0
- package/lib/commonjs/live/index.js.map +1 -1
- package/lib/module/live/colors.js +49 -0
- package/lib/module/live/colors.js.map +1 -0
- package/lib/module/live/components/LiveRoomSheet.js +9 -8
- package/lib/module/live/components/LiveRoomSheet.js.map +1 -1
- package/lib/module/live/components/MiniRoomBar.js +3 -2
- package/lib/module/live/components/MiniRoomBar.js.map +1 -1
- package/lib/module/live/components/PodcastStreamPicker.js +1 -1
- package/lib/module/live/components/RecordingsPanel.js +3 -2
- package/lib/module/live/components/RecordingsPanel.js.map +1 -1
- package/lib/module/live/components/RoomCard.js +284 -407
- package/lib/module/live/components/RoomCard.js.map +1 -1
- package/lib/module/live/index.js +4 -0
- package/lib/module/live/index.js.map +1 -1
- package/lib/typescript/commonjs/live/colors.d.ts +35 -0
- package/lib/typescript/commonjs/live/colors.d.ts.map +1 -0
- package/lib/typescript/commonjs/live/components/LiveRoomSheet.d.ts.map +1 -1
- package/lib/typescript/commonjs/live/components/MiniRoomBar.d.ts.map +1 -1
- package/lib/typescript/commonjs/live/components/PodcastStreamPicker.d.ts +1 -1
- package/lib/typescript/commonjs/live/components/RecordingsPanel.d.ts.map +1 -1
- package/lib/typescript/commonjs/live/components/RoomCard.d.ts +18 -0
- package/lib/typescript/commonjs/live/components/RoomCard.d.ts.map +1 -1
- package/lib/typescript/commonjs/live/index.d.ts +1 -0
- package/lib/typescript/commonjs/live/index.d.ts.map +1 -1
- package/lib/typescript/module/live/colors.d.ts +35 -0
- package/lib/typescript/module/live/colors.d.ts.map +1 -0
- package/lib/typescript/module/live/components/LiveRoomSheet.d.ts.map +1 -1
- package/lib/typescript/module/live/components/MiniRoomBar.d.ts.map +1 -1
- package/lib/typescript/module/live/components/PodcastStreamPicker.d.ts +1 -1
- package/lib/typescript/module/live/components/RecordingsPanel.d.ts.map +1 -1
- package/lib/typescript/module/live/components/RoomCard.d.ts +18 -0
- package/lib/typescript/module/live/components/RoomCard.d.ts.map +1 -1
- package/lib/typescript/module/live/index.d.ts +1 -0
- package/lib/typescript/module/live/index.d.ts.map +1 -1
- package/package.json +3 -13
- package/src/live/colors.ts +57 -0
- package/src/live/components/LiveRoomSheet.tsx +9 -8
- package/src/live/components/MiniRoomBar.tsx +3 -2
- package/src/live/components/PodcastStreamPicker.tsx +1 -1
- package/src/live/components/RecordingsPanel.tsx +3 -2
- package/src/live/components/RoomCard.tsx +245 -323
- package/src/live/index.ts +12 -0
|
@@ -11,10 +11,12 @@ var _services = require("@oxyhq/services");
|
|
|
11
11
|
var _LiveConfigContext = require("../context/LiveConfigContext.js");
|
|
12
12
|
var _AnimatedPulse = require("./AnimatedPulse.js");
|
|
13
13
|
var _useRoomUsers = require("../hooks/useRoomUsers.js");
|
|
14
|
+
var _colors = require("../colors.js");
|
|
14
15
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
16
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
|
|
17
18
|
// --- Utility helpers ---
|
|
19
|
+
|
|
18
20
|
function formatCompact(num) {
|
|
19
21
|
if (num >= 1_000_000) return `${(num / 1_000_000).toFixed(1).replace(/\.0$/, '')}M`;
|
|
20
22
|
if (num >= 1_000) return `${(num / 1_000).toFixed(1).replace(/\.0$/, '')}k`;
|
|
@@ -28,48 +30,86 @@ function formatDuration(startedAt, endedAt) {
|
|
|
28
30
|
const m = totalMin % 60;
|
|
29
31
|
return m > 0 ? `${h}h ${m}m` : `${h}h`;
|
|
30
32
|
}
|
|
31
|
-
const
|
|
32
|
-
function
|
|
33
|
-
|
|
34
|
-
return `${d.getDate()} ${MONTH_SHORT[d.getMonth()]} ${d.getFullYear()}`;
|
|
33
|
+
const DAY_MS = 86_400_000;
|
|
34
|
+
function startOfDay(date) {
|
|
35
|
+
return new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime();
|
|
35
36
|
}
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
if (
|
|
41
|
-
|
|
42
|
-
|
|
37
|
+
|
|
38
|
+
/** `Today` / `Tomorrow` / `Yesterday`, else a locale short date (year only when it differs). */
|
|
39
|
+
function formatDay(date, now) {
|
|
40
|
+
const dayDelta = Math.round((startOfDay(date) - startOfDay(now)) / DAY_MS);
|
|
41
|
+
if (dayDelta === 0) return 'Today';
|
|
42
|
+
if (dayDelta === 1) return 'Tomorrow';
|
|
43
|
+
if (dayDelta === -1) return 'Yesterday';
|
|
44
|
+
const options = {
|
|
45
|
+
day: 'numeric',
|
|
46
|
+
month: 'short'
|
|
47
|
+
};
|
|
48
|
+
if (date.getFullYear() !== now.getFullYear()) options.year = 'numeric';
|
|
49
|
+
return date.toLocaleDateString(undefined, options);
|
|
50
|
+
}
|
|
51
|
+
function formatTime(date) {
|
|
52
|
+
return date.toLocaleTimeString(undefined, {
|
|
53
|
+
hour: 'numeric',
|
|
54
|
+
minute: '2-digit'
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The when-label for a room that is NOT live: the start time for a scheduled room
|
|
60
|
+
* (`Tomorrow 18:00`), the day + duration for an ended one (`Yesterday · 45 min`).
|
|
61
|
+
* A live room never uses this — its lead metric is the listener count.
|
|
62
|
+
*/
|
|
63
|
+
function getScheduleLabel(room, now) {
|
|
43
64
|
if (room.status === 'scheduled' && room.scheduledStart) {
|
|
44
|
-
|
|
65
|
+
const start = new Date(room.scheduledStart);
|
|
66
|
+
return `${formatDay(start, now)} ${formatTime(start)}`;
|
|
67
|
+
}
|
|
68
|
+
if (room.status === 'ended' && room.endedAt) {
|
|
69
|
+
const day = formatDay(new Date(room.endedAt), now);
|
|
70
|
+
return room.startedAt ? `${day} · ${formatDuration(room.startedAt, room.endedAt)}` : day;
|
|
45
71
|
}
|
|
46
72
|
if (room.createdAt) {
|
|
47
|
-
return
|
|
73
|
+
return formatDay(new Date(room.createdAt), now);
|
|
48
74
|
}
|
|
49
75
|
return '';
|
|
50
76
|
}
|
|
51
77
|
|
|
52
78
|
// --- Constants ---
|
|
53
79
|
|
|
54
|
-
const
|
|
55
|
-
stage: {
|
|
56
|
-
icon: 'account-voice',
|
|
57
|
-
label: 'Stage',
|
|
58
|
-
color: '#3B82F6'
|
|
59
|
-
},
|
|
60
|
-
broadcast: {
|
|
61
|
-
icon: 'broadcast',
|
|
62
|
-
label: 'Broadcast',
|
|
63
|
-
color: '#FF6B35'
|
|
64
|
-
}
|
|
65
|
-
};
|
|
66
|
-
const MAX_SPEAKER_AVATARS = 4;
|
|
80
|
+
const MAX_SPEAKER_AVATARS = 3;
|
|
67
81
|
const SPEAKER_AVATAR_SIZE = 44;
|
|
82
|
+
const ROW_AVATAR_SIZE = 40;
|
|
83
|
+
const BYLINE_AVATAR_SIZE = 20;
|
|
84
|
+
const ACTION_HIT_SLOP = {
|
|
85
|
+
top: 8,
|
|
86
|
+
bottom: 8,
|
|
87
|
+
left: 8,
|
|
88
|
+
right: 8
|
|
89
|
+
};
|
|
68
90
|
|
|
69
91
|
// --- Types ---
|
|
70
92
|
|
|
71
93
|
// --- Component ---
|
|
72
94
|
|
|
95
|
+
/**
|
|
96
|
+
* A room in a list. The `default` variant renders ONE of two presentations,
|
|
97
|
+
* selected by `room.status`, because a live room and a listing of one are
|
|
98
|
+
* different objects:
|
|
99
|
+
*
|
|
100
|
+
* - **live** → a featured card: the LIVE chip + the listener count (the only
|
|
101
|
+
* number that matters while a room is on air), the speaker faces, the host,
|
|
102
|
+
* and an explicit Join CTA.
|
|
103
|
+
* - **scheduled / ended** → a flush full-width row: host avatar, title + when,
|
|
104
|
+
* byline, and one subtle right-side action. No card chrome, no CTA — there is
|
|
105
|
+
* nothing to join yet (or ever again).
|
|
106
|
+
*
|
|
107
|
+
* At most ONE status chip is ever shown (a live room is not a scheduled one, and
|
|
108
|
+
* the date already says "scheduled"); the room type carries no badge at all.
|
|
109
|
+
*
|
|
110
|
+
* The `compact` variant is the small fixed-width card used by post attachments
|
|
111
|
+
* and the composer preview, and follows the same rules in miniature.
|
|
112
|
+
*/
|
|
73
113
|
const RoomCard = ({
|
|
74
114
|
room,
|
|
75
115
|
onPress,
|
|
@@ -96,6 +136,7 @@ const RoomCard = ({
|
|
|
96
136
|
const isLive = room.status === 'live';
|
|
97
137
|
const isScheduled = room.status === 'scheduled';
|
|
98
138
|
const isCompact = variant === 'compact';
|
|
139
|
+
const isFeatured = isLive && !isCompact;
|
|
99
140
|
|
|
100
141
|
// Resolve host display: an explicit prop wins, then the @handle, then the
|
|
101
142
|
// canonical API-owned `name.displayName` from the Oxy user DTO (never a
|
|
@@ -104,264 +145,261 @@ const RoomCard = ({
|
|
|
104
145
|
const hostName = hostNameProp ?? (hostProfile?.username ? `@${hostProfile.username}` : (typeof hostProfileName === 'object' ? hostProfileName?.displayName : null) || room.host?.slice(0, 10) || 'Unknown');
|
|
105
146
|
const hostAvatarUri = hostAvatarUriProp ?? (0, _useRoomUsers.getAvatarUrl)(hostProfile, oxyServices, getCachedFileDownloadUrlSync);
|
|
106
147
|
|
|
107
|
-
//
|
|
148
|
+
// Speaker faces only earn their space on the featured (live) card.
|
|
108
149
|
const speakerIds = (0, _react.useMemo)(() => {
|
|
109
|
-
if (
|
|
150
|
+
if (!isFeatured) return [];
|
|
110
151
|
const ids = room.speakers?.length ? room.speakers : [room.host];
|
|
111
152
|
return ids.slice(0, MAX_SPEAKER_AVATARS);
|
|
112
|
-
}, [room.speakers, room.host
|
|
153
|
+
}, [isFeatured, room.speakers, room.host]);
|
|
154
|
+
const hiddenSpeakerCount = Math.max(0, (room.speakers?.length ?? 0) - speakerIds.length);
|
|
113
155
|
(0, _useRoomUsers.useRoomUsers)(speakerIds);
|
|
114
|
-
const typeMeta = room.type && room.type !== 'talk' ? ROOM_TYPE_META[room.type] : null;
|
|
115
156
|
const listenerCount = room.participants?.length || room.stats?.totalJoined || 0;
|
|
116
|
-
const
|
|
157
|
+
const scheduleLabel = isLive ? '' : getScheduleLabel(room, new Date());
|
|
158
|
+
const byline = house ? `by ${hostName} · ${house.name}` : `by ${hostName}`;
|
|
117
159
|
|
|
118
|
-
// --- Compact variant (
|
|
160
|
+
// --- Compact variant (post attachments, composer preview) ---
|
|
161
|
+
// It lives inside HORIZONTAL carousels, where a percentage width has no parent
|
|
162
|
+
// to resolve against — hence the intrinsic width, capped at the parent so a
|
|
163
|
+
// constrained host box (the composer preview) can still shrink it. Hosts
|
|
164
|
+
// override any of this through `style`, which wins over the className.
|
|
119
165
|
if (isCompact) {
|
|
120
166
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
borderColor: theme.colors.border
|
|
124
|
-
}, style],
|
|
167
|
+
className: "w-[200px] max-w-full min-h-[140px] justify-between rounded-2xl border border-border bg-surface p-3",
|
|
168
|
+
style: style,
|
|
125
169
|
onPress: onPress,
|
|
126
170
|
activeOpacity: onPress ? 0.7 : 1,
|
|
127
171
|
disabled: !onPress,
|
|
128
172
|
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
129
|
-
|
|
130
|
-
children: [
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
}],
|
|
134
|
-
numberOfLines: 1,
|
|
135
|
-
children: house.name.toUpperCase()
|
|
173
|
+
className: "flex-1",
|
|
174
|
+
children: [isLive && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
175
|
+
className: "mb-1.5 flex-row",
|
|
176
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(LiveBadge, {})
|
|
136
177
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
137
|
-
|
|
138
|
-
color: theme.colors.text
|
|
139
|
-
}],
|
|
178
|
+
className: "text-sm font-semibold leading-[18px] text-foreground",
|
|
140
179
|
numberOfLines: 2,
|
|
141
180
|
children: room.title
|
|
142
|
-
}), (isLive || isScheduled || typeMeta) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
143
|
-
style: styles.compactBadgeRow,
|
|
144
|
-
children: [isLive && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
145
|
-
style: [styles.liveBadge, {
|
|
146
|
-
backgroundColor: '#FF4458'
|
|
147
|
-
}],
|
|
148
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedPulse.AnimatedPulse, {
|
|
149
|
-
size: 6
|
|
150
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
151
|
-
style: styles.liveText,
|
|
152
|
-
children: "LIVE"
|
|
153
|
-
})]
|
|
154
|
-
}), isScheduled && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
155
|
-
style: [styles.scheduledBadge, {
|
|
156
|
-
backgroundColor: theme.colors.backgroundSecondary
|
|
157
|
-
}],
|
|
158
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_MaterialCommunityIcons.default, {
|
|
159
|
-
name: "calendar",
|
|
160
|
-
size: 10,
|
|
161
|
-
color: theme.colors.textSecondary
|
|
162
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
163
|
-
style: [styles.scheduledText, {
|
|
164
|
-
color: theme.colors.textSecondary
|
|
165
|
-
}],
|
|
166
|
-
children: "SCHEDULED"
|
|
167
|
-
})]
|
|
168
|
-
}), typeMeta && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
169
|
-
style: [styles.typeBadge, {
|
|
170
|
-
backgroundColor: typeMeta.color + '20'
|
|
171
|
-
}],
|
|
172
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_MaterialCommunityIcons.default, {
|
|
173
|
-
name: typeMeta.icon,
|
|
174
|
-
size: 10,
|
|
175
|
-
color: typeMeta.color
|
|
176
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
177
|
-
style: [styles.typeText, {
|
|
178
|
-
color: typeMeta.color
|
|
179
|
-
}],
|
|
180
|
-
children: typeMeta.label
|
|
181
|
-
})]
|
|
182
|
-
})]
|
|
183
181
|
})]
|
|
184
182
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
185
|
-
|
|
186
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
183
|
+
className: "mt-2 gap-1",
|
|
184
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
185
|
+
className: "flex-row items-center gap-1",
|
|
186
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(AvatarComponent, {
|
|
187
|
+
size: 14,
|
|
188
|
+
source: hostAvatarUri,
|
|
189
|
+
shape: "squircle"
|
|
190
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
191
|
+
className: "flex-1 text-[11px] text-muted-foreground",
|
|
192
|
+
numberOfLines: 1,
|
|
193
|
+
children: byline
|
|
194
|
+
})]
|
|
195
195
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
196
|
+
className: "text-[11px] text-muted-foreground",
|
|
197
|
+
numberOfLines: 1,
|
|
198
|
+
children: isLive ? `${formatCompact(listenerCount)} listening` : scheduleLabel
|
|
199
|
+
})]
|
|
200
|
+
})]
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// --- Featured card: a LIVE room, with presence and an explicit CTA ---
|
|
205
|
+
if (isFeatured) {
|
|
206
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
207
|
+
className: "mb-3 w-full gap-2.5 rounded-2xl border border-border bg-surface p-3",
|
|
208
|
+
style: style,
|
|
209
|
+
onPress: onPress,
|
|
210
|
+
activeOpacity: onPress ? 0.7 : 1,
|
|
211
|
+
disabled: !onPress,
|
|
212
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
213
|
+
className: "flex-row items-center gap-1.5",
|
|
214
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(LiveBadge, {}), listenerCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
215
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
216
|
+
className: "text-[13px] text-muted-foreground",
|
|
217
|
+
children: "\xB7"
|
|
218
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
219
|
+
className: "text-[13px] font-semibold text-muted-foreground",
|
|
220
|
+
numberOfLines: 1,
|
|
221
|
+
children: [formatCompact(listenerCount), " listening"]
|
|
222
|
+
})]
|
|
223
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
224
|
+
className: "flex-1"
|
|
225
|
+
}), onSave && /*#__PURE__*/(0, _jsxRuntime.jsx)(SaveAction, {
|
|
226
|
+
onSave: onSave,
|
|
227
|
+
isSaved: isSaved,
|
|
228
|
+
isScheduled: false,
|
|
229
|
+
theme: theme
|
|
230
|
+
}), onMenuPress && /*#__PURE__*/(0, _jsxRuntime.jsx)(MenuAction, {
|
|
231
|
+
onMenuPress: onMenuPress,
|
|
232
|
+
theme: theme
|
|
233
|
+
})]
|
|
234
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
235
|
+
className: "text-[17px] font-bold leading-[22px] text-foreground",
|
|
236
|
+
numberOfLines: 2,
|
|
237
|
+
children: room.title
|
|
238
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(SpeakerStack, {
|
|
239
|
+
speakerIds: speakerIds,
|
|
240
|
+
hiddenCount: hiddenSpeakerCount
|
|
241
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
242
|
+
className: "flex-row items-center gap-2",
|
|
243
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(AvatarComponent, {
|
|
244
|
+
size: BYLINE_AVATAR_SIZE,
|
|
203
245
|
source: hostAvatarUri,
|
|
204
|
-
shape: "squircle"
|
|
205
|
-
style: {
|
|
206
|
-
marginRight: 2
|
|
207
|
-
}
|
|
246
|
+
shape: "squircle"
|
|
208
247
|
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
209
|
-
|
|
210
|
-
color: theme.colors.textSecondary
|
|
211
|
-
}],
|
|
248
|
+
className: "flex-1 text-[13px] text-muted-foreground",
|
|
212
249
|
numberOfLines: 1,
|
|
213
|
-
children:
|
|
250
|
+
children: byline
|
|
251
|
+
}), onPress && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
252
|
+
className: "rounded-full px-4 py-1.5",
|
|
253
|
+
style: {
|
|
254
|
+
backgroundColor: _colors.LIVE_COLOR
|
|
255
|
+
},
|
|
256
|
+
onPress: onPress,
|
|
257
|
+
accessibilityRole: "button",
|
|
258
|
+
accessibilityLabel: "Join room",
|
|
259
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
260
|
+
className: "text-[13px] font-bold",
|
|
261
|
+
style: {
|
|
262
|
+
color: _colors.LIVE_FOREGROUND_COLOR
|
|
263
|
+
},
|
|
264
|
+
children: "Join"
|
|
265
|
+
})
|
|
214
266
|
})]
|
|
215
267
|
})]
|
|
216
268
|
});
|
|
217
269
|
}
|
|
218
270
|
|
|
219
|
-
// ---
|
|
271
|
+
// --- Compact row: a SCHEDULED or ENDED room, flush in the feed ---
|
|
220
272
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
borderColor: theme.colors.border
|
|
224
|
-
}, style],
|
|
273
|
+
className: "w-full flex-row items-center gap-3 border-b border-border px-3 py-3",
|
|
274
|
+
style: style,
|
|
225
275
|
onPress: onPress,
|
|
226
276
|
activeOpacity: onPress ? 0.7 : 1,
|
|
227
277
|
disabled: !onPress,
|
|
228
|
-
children: [
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
name: "home",
|
|
233
|
-
size: 16,
|
|
234
|
-
color: theme.colors.primary
|
|
235
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
236
|
-
style: [styles.houseName, {
|
|
237
|
-
color: theme.colors.textSecondary
|
|
238
|
-
}],
|
|
239
|
-
numberOfLines: 1,
|
|
240
|
-
children: house.name.toUpperCase()
|
|
241
|
-
})]
|
|
242
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
243
|
-
style: {
|
|
244
|
-
flex: 1
|
|
245
|
-
}
|
|
246
|
-
}), onMenuPress && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
247
|
-
onPress: onMenuPress,
|
|
248
|
-
hitSlop: {
|
|
249
|
-
top: 8,
|
|
250
|
-
bottom: 8,
|
|
251
|
-
left: 8,
|
|
252
|
-
right: 8
|
|
253
|
-
},
|
|
254
|
-
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MaterialCommunityIcons.default, {
|
|
255
|
-
name: "dots-horizontal",
|
|
256
|
-
size: 20,
|
|
257
|
-
color: theme.colors.textSecondary
|
|
258
|
-
})
|
|
259
|
-
})]
|
|
278
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(AvatarComponent, {
|
|
279
|
+
size: ROW_AVATAR_SIZE,
|
|
280
|
+
source: hostAvatarUri,
|
|
281
|
+
shape: "squircle"
|
|
260
282
|
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
}],
|
|
273
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedPulse.AnimatedPulse, {
|
|
274
|
-
size: 6
|
|
275
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
276
|
-
style: styles.liveText,
|
|
277
|
-
children: "LIVE"
|
|
278
|
-
})]
|
|
279
|
-
}), isScheduled && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
280
|
-
style: [styles.scheduledBadge, {
|
|
281
|
-
backgroundColor: theme.colors.backgroundSecondary
|
|
282
|
-
}],
|
|
283
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_MaterialCommunityIcons.default, {
|
|
284
|
-
name: "calendar",
|
|
285
|
-
size: 12,
|
|
286
|
-
color: theme.colors.textSecondary
|
|
287
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
288
|
-
style: [styles.scheduledText, {
|
|
289
|
-
color: theme.colors.textSecondary
|
|
290
|
-
}],
|
|
291
|
-
children: "SCHEDULED"
|
|
292
|
-
})]
|
|
293
|
-
}), typeMeta && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
294
|
-
style: [styles.typeBadge, {
|
|
295
|
-
backgroundColor: typeMeta.color + '20'
|
|
296
|
-
}],
|
|
297
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_MaterialCommunityIcons.default, {
|
|
298
|
-
name: typeMeta.icon,
|
|
299
|
-
size: 10,
|
|
300
|
-
color: typeMeta.color
|
|
301
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
302
|
-
style: [styles.typeText, {
|
|
303
|
-
color: typeMeta.color
|
|
304
|
-
}],
|
|
305
|
-
children: typeMeta.label
|
|
306
|
-
})]
|
|
283
|
+
className: "flex-1 gap-0.5",
|
|
284
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
285
|
+
className: "flex-row items-baseline gap-1.5",
|
|
286
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
287
|
+
className: "shrink text-[15px] font-semibold text-foreground",
|
|
288
|
+
numberOfLines: 1,
|
|
289
|
+
children: room.title
|
|
290
|
+
}), scheduleLabel !== '' && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
291
|
+
className: "shrink-0 text-[13px] text-muted-foreground",
|
|
292
|
+
numberOfLines: 1,
|
|
293
|
+
children: ["\xB7 ", scheduleLabel]
|
|
307
294
|
})]
|
|
295
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
296
|
+
className: "text-[13px] text-muted-foreground",
|
|
297
|
+
numberOfLines: 1,
|
|
298
|
+
children: byline
|
|
308
299
|
})]
|
|
309
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
310
|
-
|
|
311
|
-
|
|
300
|
+
}), onSave && /*#__PURE__*/(0, _jsxRuntime.jsx)(SaveAction, {
|
|
301
|
+
onSave: onSave,
|
|
302
|
+
isSaved: isSaved,
|
|
303
|
+
isScheduled: isScheduled,
|
|
304
|
+
theme: theme
|
|
305
|
+
}), onMenuPress && /*#__PURE__*/(0, _jsxRuntime.jsx)(MenuAction, {
|
|
306
|
+
onMenuPress: onMenuPress,
|
|
312
307
|
theme: theme
|
|
313
|
-
}), (timeLabel || onSave) && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
314
|
-
style: styles.metaRow,
|
|
315
|
-
children: [timeLabel ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
316
|
-
style: [styles.metaText, {
|
|
317
|
-
color: theme.colors.textSecondary
|
|
318
|
-
}],
|
|
319
|
-
children: timeLabel
|
|
320
|
-
}) : /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {}), onSave && /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.TouchableOpacity, {
|
|
321
|
-
onPress: onSave,
|
|
322
|
-
style: styles.saveButton,
|
|
323
|
-
hitSlop: {
|
|
324
|
-
top: 8,
|
|
325
|
-
bottom: 8,
|
|
326
|
-
left: 8,
|
|
327
|
-
right: 8
|
|
328
|
-
},
|
|
329
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_MaterialCommunityIcons.default, {
|
|
330
|
-
name: isSaved ? 'bookmark' : 'bookmark-outline',
|
|
331
|
-
size: 18,
|
|
332
|
-
color: isSaved ? theme.colors.primary : theme.colors.textSecondary
|
|
333
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
334
|
-
style: [styles.saveText, {
|
|
335
|
-
color: isSaved ? theme.colors.primary : theme.colors.textSecondary
|
|
336
|
-
}],
|
|
337
|
-
children: "Save"
|
|
338
|
-
})]
|
|
339
|
-
})]
|
|
340
308
|
})]
|
|
341
309
|
});
|
|
342
310
|
};
|
|
343
311
|
|
|
344
|
-
// ---
|
|
312
|
+
// --- Badges ---
|
|
313
|
+
|
|
314
|
+
// The LIVE badge is the one surface that must NOT theme with the host: it is the
|
|
315
|
+
// brand's "on air" signal, so its red comes from the shared live palette and its
|
|
316
|
+
// content sits on white regardless of light/dark mode.
|
|
345
317
|
exports.RoomCard = RoomCard;
|
|
346
|
-
function
|
|
347
|
-
|
|
348
|
-
|
|
318
|
+
function LiveBadge() {
|
|
319
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
320
|
+
className: "flex-row items-center gap-1 rounded-[4px] px-2 py-1",
|
|
321
|
+
style: {
|
|
322
|
+
backgroundColor: _colors.LIVE_COLOR
|
|
323
|
+
},
|
|
324
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_AnimatedPulse.AnimatedPulse, {
|
|
325
|
+
size: 6,
|
|
326
|
+
color: _colors.LIVE_FOREGROUND_COLOR
|
|
327
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
328
|
+
className: "text-[10px] font-bold text-white",
|
|
329
|
+
children: "LIVE"
|
|
330
|
+
})]
|
|
331
|
+
});
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
// --- Actions (icon-only, like the surrounding feed) ---
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* The saved-state toggle. On a SCHEDULED room, saving it is how you ask to be
|
|
338
|
+
* pulled back when it starts, so the icon reads as a reminder bell; anywhere
|
|
339
|
+
* else it is a bookmark.
|
|
340
|
+
*/
|
|
341
|
+
function SaveAction({
|
|
342
|
+
onSave,
|
|
343
|
+
isSaved,
|
|
344
|
+
isScheduled,
|
|
349
345
|
theme
|
|
350
346
|
}) {
|
|
347
|
+
const icon = isScheduled ? isSaved ? 'bell' : 'bell-outline' : isSaved ? 'bookmark' : 'bookmark-outline';
|
|
348
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
349
|
+
onPress: onSave,
|
|
350
|
+
hitSlop: ACTION_HIT_SLOP,
|
|
351
|
+
accessibilityRole: "button",
|
|
352
|
+
accessibilityLabel: isScheduled ? 'Remind me about this room' : 'Save room',
|
|
353
|
+
accessibilityState: {
|
|
354
|
+
selected: Boolean(isSaved)
|
|
355
|
+
},
|
|
356
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MaterialCommunityIcons.default, {
|
|
357
|
+
name: icon,
|
|
358
|
+
size: 20,
|
|
359
|
+
color: isSaved ? theme.colors.primary : theme.colors.textSecondary
|
|
360
|
+
})
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
function MenuAction({
|
|
364
|
+
onMenuPress,
|
|
365
|
+
theme
|
|
366
|
+
}) {
|
|
367
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
368
|
+
onPress: onMenuPress,
|
|
369
|
+
hitSlop: ACTION_HIT_SLOP,
|
|
370
|
+
accessibilityRole: "button",
|
|
371
|
+
accessibilityLabel: "Room options",
|
|
372
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_MaterialCommunityIcons.default, {
|
|
373
|
+
name: "dots-horizontal",
|
|
374
|
+
size: 20,
|
|
375
|
+
color: theme.colors.textSecondary
|
|
376
|
+
})
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
// --- Speaker stack (featured card only) ---
|
|
381
|
+
|
|
382
|
+
function SpeakerStack({
|
|
383
|
+
speakerIds,
|
|
384
|
+
hiddenCount
|
|
385
|
+
}) {
|
|
386
|
+
if (speakerIds.length === 0) return null;
|
|
351
387
|
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
352
|
-
|
|
353
|
-
children: [speakerIds.map(id => /*#__PURE__*/(0, _jsxRuntime.jsx)(
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
388
|
+
className: "flex-row items-center",
|
|
389
|
+
children: [speakerIds.map((id, index) => /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
390
|
+
className: index === 0 ? '' : '-ml-3',
|
|
391
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(SpeakerAvatar, {
|
|
392
|
+
userId: id
|
|
393
|
+
})
|
|
394
|
+
}, id)), hiddenCount > 0 && /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
395
|
+
className: "-ml-3 items-center justify-center rounded-full border-2 border-surface bg-muted",
|
|
396
|
+
style: {
|
|
397
|
+
width: SPEAKER_AVATAR_SIZE,
|
|
398
|
+
height: SPEAKER_AVATAR_SIZE
|
|
399
|
+
},
|
|
360
400
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Text, {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
}],
|
|
364
|
-
children: ["+", formatCompact(listenerCount)]
|
|
401
|
+
className: "text-[13px] font-bold text-muted-foreground",
|
|
402
|
+
children: ["+", formatCompact(hiddenCount)]
|
|
365
403
|
})
|
|
366
404
|
})]
|
|
367
405
|
});
|
|
@@ -372,19 +410,17 @@ function SpeakerAvatar({
|
|
|
372
410
|
const {
|
|
373
411
|
useUserById,
|
|
374
412
|
AvatarComponent,
|
|
375
|
-
getCachedFileDownloadUrlSync
|
|
376
|
-
useTheme
|
|
413
|
+
getCachedFileDownloadUrlSync
|
|
377
414
|
} = (0, _LiveConfigContext.useLiveConfig)();
|
|
378
|
-
const theme = useTheme();
|
|
379
415
|
const {
|
|
380
416
|
oxyServices
|
|
381
417
|
} = (0, _services.useAuth)();
|
|
382
418
|
const profile = useUserById(userId);
|
|
383
419
|
const avatarUri = (0, _useRoomUsers.getAvatarUrl)(profile, oxyServices, getCachedFileDownloadUrlSync);
|
|
420
|
+
|
|
421
|
+
// The ring is the card's own surface color, so overlapping faces stay separable.
|
|
384
422
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
385
|
-
|
|
386
|
-
borderColor: theme.colors.border
|
|
387
|
-
}],
|
|
423
|
+
className: "rounded-full border-2 border-surface",
|
|
388
424
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(AvatarComponent, {
|
|
389
425
|
size: SPEAKER_AVATAR_SIZE,
|
|
390
426
|
source: avatarUri,
|
|
@@ -392,162 +428,5 @@ function SpeakerAvatar({
|
|
|
392
428
|
})
|
|
393
429
|
});
|
|
394
430
|
}
|
|
395
|
-
|
|
396
|
-
// --- Styles ---
|
|
397
|
-
|
|
398
|
-
const styles = _reactNative.StyleSheet.create({
|
|
399
|
-
card: {
|
|
400
|
-
borderRadius: 12,
|
|
401
|
-
borderWidth: 1,
|
|
402
|
-
padding: 16,
|
|
403
|
-
marginBottom: 12,
|
|
404
|
-
gap: 12
|
|
405
|
-
},
|
|
406
|
-
compactCard: {
|
|
407
|
-
width: 200,
|
|
408
|
-
minHeight: 140,
|
|
409
|
-
borderRadius: 14,
|
|
410
|
-
borderWidth: 1,
|
|
411
|
-
padding: 12,
|
|
412
|
-
justifyContent: 'space-between'
|
|
413
|
-
},
|
|
414
|
-
// House header
|
|
415
|
-
houseRow: {
|
|
416
|
-
flexDirection: 'row',
|
|
417
|
-
alignItems: 'center',
|
|
418
|
-
gap: 6
|
|
419
|
-
},
|
|
420
|
-
houseName: {
|
|
421
|
-
fontSize: 11,
|
|
422
|
-
fontWeight: '700',
|
|
423
|
-
letterSpacing: 0.5
|
|
424
|
-
},
|
|
425
|
-
// Title
|
|
426
|
-
title: {
|
|
427
|
-
fontSize: 32,
|
|
428
|
-
fontWeight: '700',
|
|
429
|
-
lineHeight: 38
|
|
430
|
-
},
|
|
431
|
-
// Badges
|
|
432
|
-
badgeRow: {
|
|
433
|
-
flexDirection: 'row',
|
|
434
|
-
alignItems: 'center',
|
|
435
|
-
gap: 6,
|
|
436
|
-
marginTop: 6
|
|
437
|
-
},
|
|
438
|
-
liveBadge: {
|
|
439
|
-
flexDirection: 'row',
|
|
440
|
-
alignItems: 'center',
|
|
441
|
-
paddingHorizontal: 8,
|
|
442
|
-
paddingVertical: 4,
|
|
443
|
-
borderRadius: 4,
|
|
444
|
-
gap: 4
|
|
445
|
-
},
|
|
446
|
-
liveText: {
|
|
447
|
-
fontSize: 10,
|
|
448
|
-
fontWeight: '700',
|
|
449
|
-
color: '#FFFFFF'
|
|
450
|
-
},
|
|
451
|
-
scheduledBadge: {
|
|
452
|
-
flexDirection: 'row',
|
|
453
|
-
alignItems: 'center',
|
|
454
|
-
paddingHorizontal: 8,
|
|
455
|
-
paddingVertical: 4,
|
|
456
|
-
borderRadius: 4,
|
|
457
|
-
gap: 4
|
|
458
|
-
},
|
|
459
|
-
scheduledText: {
|
|
460
|
-
fontSize: 10,
|
|
461
|
-
fontWeight: '700'
|
|
462
|
-
},
|
|
463
|
-
typeBadge: {
|
|
464
|
-
flexDirection: 'row',
|
|
465
|
-
alignItems: 'center',
|
|
466
|
-
paddingHorizontal: 6,
|
|
467
|
-
paddingVertical: 3,
|
|
468
|
-
borderRadius: 4,
|
|
469
|
-
gap: 3
|
|
470
|
-
},
|
|
471
|
-
typeText: {
|
|
472
|
-
fontSize: 9,
|
|
473
|
-
fontWeight: '700'
|
|
474
|
-
},
|
|
475
|
-
// Speaker avatars
|
|
476
|
-
avatarRow: {
|
|
477
|
-
flexDirection: 'row',
|
|
478
|
-
alignItems: 'center',
|
|
479
|
-
gap: 8
|
|
480
|
-
},
|
|
481
|
-
avatarRing: {
|
|
482
|
-
borderRadius: 14,
|
|
483
|
-
padding: 2,
|
|
484
|
-
borderWidth: 2
|
|
485
|
-
},
|
|
486
|
-
countTile: {
|
|
487
|
-
width: SPEAKER_AVATAR_SIZE + 4,
|
|
488
|
-
height: SPEAKER_AVATAR_SIZE + 4,
|
|
489
|
-
borderRadius: 14,
|
|
490
|
-
borderWidth: 2,
|
|
491
|
-
alignItems: 'center',
|
|
492
|
-
justifyContent: 'center',
|
|
493
|
-
gap: 2
|
|
494
|
-
},
|
|
495
|
-
countTileText: {
|
|
496
|
-
fontSize: 14,
|
|
497
|
-
fontWeight: '700'
|
|
498
|
-
},
|
|
499
|
-
// Metadata
|
|
500
|
-
metaRow: {
|
|
501
|
-
flexDirection: 'row',
|
|
502
|
-
alignItems: 'center',
|
|
503
|
-
justifyContent: 'space-between'
|
|
504
|
-
},
|
|
505
|
-
metaText: {
|
|
506
|
-
fontSize: 13
|
|
507
|
-
},
|
|
508
|
-
saveButton: {
|
|
509
|
-
flexDirection: 'row',
|
|
510
|
-
alignItems: 'center',
|
|
511
|
-
gap: 4
|
|
512
|
-
},
|
|
513
|
-
saveText: {
|
|
514
|
-
fontSize: 13,
|
|
515
|
-
fontWeight: '500'
|
|
516
|
-
},
|
|
517
|
-
// Compact variant
|
|
518
|
-
compactHeader: {
|
|
519
|
-
flex: 1
|
|
520
|
-
},
|
|
521
|
-
compactHouseName: {
|
|
522
|
-
fontSize: 9,
|
|
523
|
-
fontWeight: '700',
|
|
524
|
-
letterSpacing: 0.5,
|
|
525
|
-
marginBottom: 4
|
|
526
|
-
},
|
|
527
|
-
compactTitle: {
|
|
528
|
-
fontSize: 14,
|
|
529
|
-
fontWeight: '600',
|
|
530
|
-
lineHeight: 18
|
|
531
|
-
},
|
|
532
|
-
compactBadgeRow: {
|
|
533
|
-
flexDirection: 'row',
|
|
534
|
-
marginTop: 4,
|
|
535
|
-
gap: 4,
|
|
536
|
-
flexWrap: 'wrap'
|
|
537
|
-
},
|
|
538
|
-
compactFooter: {
|
|
539
|
-
flexDirection: 'row',
|
|
540
|
-
alignItems: 'center',
|
|
541
|
-
gap: 4,
|
|
542
|
-
marginTop: 8
|
|
543
|
-
},
|
|
544
|
-
compactCount: {
|
|
545
|
-
fontSize: 11
|
|
546
|
-
},
|
|
547
|
-
compactHost: {
|
|
548
|
-
fontSize: 11,
|
|
549
|
-
flex: 1
|
|
550
|
-
}
|
|
551
|
-
});
|
|
552
431
|
var _default = exports.default = RoomCard;
|
|
553
432
|
//# sourceMappingURL=RoomCard.js.map
|