Group guest v2 fab controls
This commit is contained in:
@@ -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}
|
||||||
|
|||||||
@@ -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)',
|
||||||
|
|||||||
Reference in New Issue
Block a user