upgrade to tamagui v2 and guest pwa overhaul
This commit is contained in:
@@ -179,7 +179,7 @@ function PhotoGridTile({
|
||||
)}
|
||||
|
||||
{badges.length ? (
|
||||
<XStack position="absolute" top={6} left={6} space="$1.5">
|
||||
<XStack position="absolute" top={6} left={6} gap="$1.5">
|
||||
{badges.map((label) => (
|
||||
<PhotoStatusTag key={`${photo.id}-${label}`} label={label} />
|
||||
))}
|
||||
@@ -194,7 +194,7 @@ function PhotoGridTile({
|
||||
padding="$1"
|
||||
borderRadius={12}
|
||||
backgroundColor={overlayBg}
|
||||
space="$2"
|
||||
gap="$2"
|
||||
justifyContent="space-between"
|
||||
>
|
||||
{actions.map((action) => (
|
||||
@@ -1034,7 +1034,7 @@ export default function MobileEventControlRoomPage() {
|
||||
}, [queuedActions, slug]);
|
||||
|
||||
const headerActions = (
|
||||
<XStack space="$2">
|
||||
<XStack gap="$2">
|
||||
<HeaderActionButton
|
||||
onPress={() => {
|
||||
if (activeTab === 'moderation') {
|
||||
@@ -1070,7 +1070,7 @@ export default function MobileEventControlRoomPage() {
|
||||
value={activeTab}
|
||||
onValueChange={(val) => setActiveTab(val as 'moderation' | 'live')}
|
||||
header={(
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<XStack justifyContent="flex-end">
|
||||
<ContextHelpLink slug="control-room-moderation" />
|
||||
</XStack>
|
||||
@@ -1094,8 +1094,8 @@ export default function MobileEventControlRoomPage() {
|
||||
</XStack>
|
||||
</Accordion.Trigger>
|
||||
<Accordion.Content {...({ paddingTop: '$2' } as any)}>
|
||||
<YStack space="$3">
|
||||
<YStack space="$2">
|
||||
<YStack gap="$3">
|
||||
<YStack gap="$2">
|
||||
<Text fontSize="$sm" fontWeight="800" color={text}>
|
||||
{t('controlRoom.automation.title', 'Automation')}
|
||||
</Text>
|
||||
@@ -1177,7 +1177,7 @@ export default function MobileEventControlRoomPage() {
|
||||
</MobileField>
|
||||
</YStack>
|
||||
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<Text fontSize="$sm" fontWeight="800" color={text}>
|
||||
{t('controlRoom.automation.uploaders.title', 'Uploader overrides')}
|
||||
</Text>
|
||||
@@ -1195,7 +1195,7 @@ export default function MobileEventControlRoomPage() {
|
||||
'Uploads from these devices skip the approval queue.',
|
||||
)}
|
||||
>
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<MobileSelect
|
||||
value={trustedUploaderSelection}
|
||||
onChange={(event) => setTrustedUploaderSelection(event.target.value)}
|
||||
@@ -1215,7 +1215,7 @@ export default function MobileEventControlRoomPage() {
|
||||
/>
|
||||
</YStack>
|
||||
{trustedUploaders.length ? (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
{trustedUploaders.map((rule) => (
|
||||
<XStack
|
||||
key={`trusted-${rule.device_id}`}
|
||||
@@ -1227,7 +1227,7 @@ export default function MobileEventControlRoomPage() {
|
||||
borderColor={border}
|
||||
backgroundColor={surfaceMuted}
|
||||
>
|
||||
<YStack space="$0.5">
|
||||
<YStack gap="$0.5">
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{rule.label ?? t('common.anonymous', 'Anonymous')}
|
||||
</Text>
|
||||
@@ -1267,7 +1267,7 @@ export default function MobileEventControlRoomPage() {
|
||||
'Uploads from these devices always need approval.',
|
||||
)}
|
||||
>
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<MobileSelect
|
||||
value={forceReviewSelection}
|
||||
onChange={(event) => setForceReviewSelection(event.target.value)}
|
||||
@@ -1287,7 +1287,7 @@ export default function MobileEventControlRoomPage() {
|
||||
/>
|
||||
</YStack>
|
||||
{forceReviewUploaders.length ? (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
{forceReviewUploaders.map((rule) => (
|
||||
<XStack
|
||||
key={`force-${rule.device_id}`}
|
||||
@@ -1299,7 +1299,7 @@ export default function MobileEventControlRoomPage() {
|
||||
borderColor={border}
|
||||
backgroundColor={surfaceMuted}
|
||||
>
|
||||
<YStack space="$0.5">
|
||||
<YStack gap="$0.5">
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{rule.label ?? t('common.anonymous', 'Anonymous')}
|
||||
</Text>
|
||||
@@ -1344,11 +1344,11 @@ export default function MobileEventControlRoomPage() {
|
||||
value: 'moderation',
|
||||
label: t('controlRoom.tabs.moderation', 'Moderation'),
|
||||
content: (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
{queuedEventCount > 0 ? (
|
||||
<MobileCard>
|
||||
<XStack alignItems="center" justifyContent="space-between" space="$2">
|
||||
<YStack space="$1" flex={1}>
|
||||
<XStack alignItems="center" justifyContent="space-between" gap="$2">
|
||||
<YStack gap="$1" flex={1}>
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{t('mobilePhotos.queueTitle', 'Changes waiting to sync')}
|
||||
</Text>
|
||||
@@ -1371,7 +1371,7 @@ export default function MobileEventControlRoomPage() {
|
||||
) : null}
|
||||
|
||||
<MobileCard>
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<Text fontSize="$xs" fontWeight="800" color={text}>
|
||||
{t('mobilePhotos.filtersTitle', 'Filter')}
|
||||
</Text>
|
||||
@@ -1390,7 +1390,7 @@ export default function MobileEventControlRoomPage() {
|
||||
value={moderationFilter}
|
||||
onValueChange={(value: string) => value && setModerationFilter(value as ModerationFilter)}
|
||||
>
|
||||
<XStack space="$1.5">
|
||||
<XStack gap="$1.5">
|
||||
{MODERATION_FILTERS.map((option) => {
|
||||
const active = option.value === moderationFilter;
|
||||
const count = moderationCounts[option.value] ?? 0;
|
||||
@@ -1407,7 +1407,7 @@ export default function MobileEventControlRoomPage() {
|
||||
paddingHorizontal="$3"
|
||||
pressStyle={{ opacity: 0.85 }}
|
||||
>
|
||||
<XStack alignItems="center" space="$1.5">
|
||||
<XStack alignItems="center" gap="$1.5">
|
||||
<Text fontSize="$xs" fontWeight="700" color={active ? '#fff' : muted}>
|
||||
{t(option.labelKey, option.fallback)}
|
||||
</Text>
|
||||
@@ -1455,13 +1455,13 @@ export default function MobileEventControlRoomPage() {
|
||||
) : null}
|
||||
|
||||
{moderationLoading && moderationPage === 1 ? (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
{Array.from({ length: 3 }).map((_, idx) => (
|
||||
<SkeletonCard key={`moderation-skeleton-${idx}`} height={120} />
|
||||
))}
|
||||
</YStack>
|
||||
) : moderationPhotos.length === 0 ? (
|
||||
<MobileCard alignItems="center" justifyContent="center" space="$2">
|
||||
<MobileCard alignItems="center" justifyContent="center" gap="$2">
|
||||
<ImageIcon size={28} color={muted} />
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{t('controlRoom.emptyModeration', 'No uploads match this filter.')}
|
||||
@@ -1543,7 +1543,7 @@ export default function MobileEventControlRoomPage() {
|
||||
value: 'live',
|
||||
label: t('controlRoom.tabs.live', 'Live Show'),
|
||||
content: (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<MobileCard borderColor={border} backgroundColor="transparent">
|
||||
<Text fontSize="$sm" color={muted}>
|
||||
{t(
|
||||
@@ -1559,7 +1559,7 @@ export default function MobileEventControlRoomPage() {
|
||||
</MobileCard>
|
||||
|
||||
<MobileCard>
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
<Text fontSize="$xs" fontWeight="800" color={text}>
|
||||
{t('liveShowQueue.filterLabel', 'Live status')}
|
||||
</Text>
|
||||
@@ -1578,7 +1578,7 @@ export default function MobileEventControlRoomPage() {
|
||||
value={liveStatusFilter}
|
||||
onValueChange={(value: string) => value && setLiveStatusFilter(value as LiveShowQueueStatus)}
|
||||
>
|
||||
<XStack space="$1.5">
|
||||
<XStack gap="$1.5">
|
||||
{LIVE_STATUS_OPTIONS.map((option) => {
|
||||
const active = option.value === liveStatusFilter;
|
||||
const count = liveCounts[option.value] ?? 0;
|
||||
@@ -1595,7 +1595,7 @@ export default function MobileEventControlRoomPage() {
|
||||
paddingHorizontal="$3"
|
||||
pressStyle={{ opacity: 0.85 }}
|
||||
>
|
||||
<XStack alignItems="center" space="$1.5">
|
||||
<XStack alignItems="center" gap="$1.5">
|
||||
<Text fontSize="$xs" fontWeight="700" color={active ? '#fff' : muted}>
|
||||
{t(option.labelKey, option.fallback)}
|
||||
</Text>
|
||||
@@ -1631,13 +1631,13 @@ export default function MobileEventControlRoomPage() {
|
||||
) : null}
|
||||
|
||||
{liveLoading && livePage === 1 ? (
|
||||
<YStack space="$2">
|
||||
<YStack gap="$2">
|
||||
{Array.from({ length: 3 }).map((_, idx) => (
|
||||
<SkeletonCard key={`live-skeleton-${idx}`} height={120} />
|
||||
))}
|
||||
</YStack>
|
||||
) : livePhotos.length === 0 ? (
|
||||
<MobileCard alignItems="center" justifyContent="center" space="$2">
|
||||
<MobileCard alignItems="center" justifyContent="center" gap="$2">
|
||||
<Text fontSize="$sm" fontWeight="700" color={text}>
|
||||
{t('controlRoom.emptyLive', 'No photos waiting for Live Show.')}
|
||||
</Text>
|
||||
|
||||
Reference in New Issue
Block a user