Group guest v2 fab controls
Some checks failed
linter / quality (push) Has been cancelled
tests / ci (push) Has been cancelled
tests / ui (push) Has been cancelled

This commit is contained in:
Codex Agent
2026-02-03 21:56:07 +01:00
parent fbb6fd4404
commit b97f5de101
2 changed files with 64 additions and 33 deletions

View File

@@ -1,5 +1,5 @@
import React from 'react'; import React from 'react';
import { YStack } from '@tamagui/stacks'; import { XStack, YStack } from '@tamagui/stacks';
import { Button } from '@tamagui/button'; import { Button } from '@tamagui/button';
import { Sparkles, Share2, Image, Camera, Settings, Home, Menu } from 'lucide-react'; import { Sparkles, Share2, Image, Camera, Settings, Home, Menu } from 'lucide-react';
import { useLocation, useNavigate } from 'react-router-dom'; import { useLocation, useNavigate } from 'react-router-dom';
@@ -34,6 +34,9 @@ export default function AppShell({ children }: AppShellProps) {
const matomoEnabled = typeof window !== 'undefined' && Boolean((window as any).__MATOMO_GUEST__?.enabled); const matomoEnabled = typeof window !== 'undefined' && Boolean((window as any).__MATOMO_GUEST__?.enabled);
const isUploadRoute = /\/upload(?:\/|$)/.test(location.pathname); const isUploadRoute = /\/upload(?:\/|$)/.test(location.pathname);
const showFab = !/\/photo\/\d+/.test(location.pathname); const showFab = !/\/photo\/\d+/.test(location.pathname);
const dockBackground = isDark ? 'rgba(12, 16, 32, 0.72)' : 'rgba(255, 255, 255, 0.9)';
const dockBorder = isDark ? 'rgba(255,255,255,0.16)' : 'rgba(15,23,42,0.12)';
const dockShadow = isDark ? '0 14px 28px rgba(2, 6, 23, 0.5)' : '0 12px 24px rgba(15, 23, 42, 0.14)';
const goTo = (path: string) => () => { const goTo = (path: string) => () => {
setCompassOpen(false); setCompassOpen(false);
@@ -128,28 +131,7 @@ export default function AppShell({ children }: AppShellProps) {
{children} {children}
</YStack> </YStack>
{showFab ? ( {showFab ? (
<> isUploadRoute ? (
{isUploadRoute ? null : (
<Button
size="$3"
circular
position="fixed"
bottom={28}
left="calc(50% - 84px)"
zIndex={1100}
backgroundColor={isDark ? 'rgba(12, 16, 32, 0.75)' : 'rgba(255, 255, 255, 0.9)'}
borderWidth={1}
borderColor={isDark ? 'rgba(255,255,255,0.16)' : 'rgba(15,23,42,0.12)'}
onPress={goTo('/')}
style={{ boxShadow: isDark ? '0 10px 20px rgba(2, 6, 23, 0.45)' : '0 8px 16px rgba(15, 23, 42, 0.14)' }}
>
<Home size={16} color={actionIconColor} />
</Button>
)}
<FloatingActionButton
onPress={goTo('/upload')}
hidden={isUploadRoute}
/>
<Button <Button
size="$5" size="$5"
circular circular
@@ -157,17 +139,61 @@ export default function AppShell({ children }: AppShellProps) {
bottom={28} bottom={28}
right={20} right={20}
zIndex={1100} zIndex={1100}
backgroundColor={isDark ? 'rgba(12, 16, 32, 0.75)' : 'rgba(255, 255, 255, 0.9)'} backgroundColor={dockBackground}
borderWidth={1} borderWidth={1}
borderColor={isDark ? 'rgba(255,255,255,0.16)' : 'rgba(15,23,42,0.12)'} borderColor={dockBorder}
width={72} width={72}
height={72} height={72}
onPress={openCompass} onPress={openCompass}
style={{ boxShadow: isDark ? '0 10px 20px rgba(2, 6, 23, 0.45)' : '0 8px 16px rgba(15, 23, 42, 0.14)' }} style={{ boxShadow: dockShadow }}
> >
<Menu size={24} color={actionIconColor} /> <Menu size={24} color={actionIconColor} />
</Button> </Button>
</> ) : (
<XStack
position="fixed"
bottom={24}
left="50%"
zIndex={1100}
alignItems="center"
gap="$2"
padding="$2"
borderRadius={999}
borderWidth={1}
borderColor={dockBorder}
backgroundColor={dockBackground}
style={{ transform: 'translateX(-50%)', boxShadow: dockShadow }}
>
<Button
size="$3"
circular
backgroundColor={isDark ? 'rgba(12, 16, 32, 0.75)' : 'rgba(255, 255, 255, 0.9)'}
borderWidth={1}
borderColor={dockBorder}
onPress={goTo('/')}
style={{ boxShadow: isDark ? '0 10px 20px rgba(2, 6, 23, 0.45)' : '0 8px 16px rgba(15, 23, 42, 0.14)' }}
>
<Home size={16} color={actionIconColor} />
</Button>
<FloatingActionButton
onPress={goTo('/upload')}
inline
/>
<Button
size="$5"
circular
backgroundColor={isDark ? 'rgba(12, 16, 32, 0.75)' : 'rgba(255, 255, 255, 0.9)'}
borderWidth={1}
borderColor={dockBorder}
width={72}
height={72}
onPress={openCompass}
style={{ boxShadow: isDark ? '0 10px 20px rgba(2, 6, 23, 0.45)' : '0 8px 16px rgba(15, 23, 42, 0.14)' }}
>
<Menu size={24} color={actionIconColor} />
</Button>
</XStack>
)
) : null} ) : null}
<CompassHub <CompassHub
open={compassOpen} open={compassOpen}

View File

@@ -7,12 +7,17 @@ type FloatingActionButtonProps = {
onPress: () => void; onPress: () => void;
onLongPress?: () => void; onLongPress?: () => void;
hidden?: boolean; hidden?: boolean;
inline?: boolean;
}; };
export default function FloatingActionButton({ onPress, onLongPress, hidden = false }: FloatingActionButtonProps) { export default function FloatingActionButton({ onPress, onLongPress, hidden = false, inline = false }: FloatingActionButtonProps) {
const longPressTriggered = React.useRef(false); const longPressTriggered = React.useRef(false);
const { isDark } = useGuestThemeVariant(); const { isDark } = useGuestThemeVariant();
const translateValue = hidden ? 'translateX(-50%) translateY(36px) scale(0.72)' : 'translateX(-50%)'; const translateValue = inline
? 'none'
: hidden
? 'translateX(-50%) translateY(36px) scale(0.72)'
: 'translateX(-50%)';
return ( return (
<Button <Button
@@ -33,9 +38,9 @@ export default function FloatingActionButton({ onPress, onLongPress, hidden = fa
longPressTriggered.current = true; longPressTriggered.current = true;
onLongPress(); onLongPress();
}} }}
position="fixed" position={inline ? 'relative' : 'fixed'}
bottom={20} bottom={inline ? undefined : 20}
left="50%" left={inline ? undefined : '50%'}
zIndex={1100} zIndex={1100}
width={68} width={68}
height={68} height={68}
@@ -51,7 +56,7 @@ export default function FloatingActionButton({ onPress, onLongPress, hidden = fa
pointerEvents={hidden ? 'none' : 'auto'} pointerEvents={hidden ? 'none' : 'auto'}
style={{ style={{
transform: translateValue, transform: translateValue,
transition: 'transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1), opacity 220ms ease', transition: inline ? undefined : 'transform 320ms cubic-bezier(0.22, 0.61, 0.36, 1), opacity 220ms ease',
boxShadow: isDark boxShadow: isDark
? '0 20px 40px rgba(255, 79, 216, 0.38), 0 0 0 8px rgba(255, 79, 216, 0.16)' ? '0 20px 40px rgba(255, 79, 216, 0.38), 0 0 0 8px rgba(255, 79, 216, 0.16)'
: '0 18px 32px rgba(15, 23, 42, 0.2), 0 0 0 8px rgba(255, 255, 255, 0.7)', : '0 18px 32px rgba(15, 23, 42, 0.2), 0 0 0 8px rgba(255, 255, 255, 0.7)',