mirror of
https://github.com/jjbrunton/Sauci.git
synced 2026-10-31 18:19:43 +00:00
Update
This commit is contained in:
1 parent
118dadc69a
commit
358c2be0ee
2 files changed
+32
-35
No files matched your search
@@ -17,17 +17,14 @@ type Message = Database["public"]["Tables"]["messages"]["Row"];
|
|||||||
function TabBarBackground() {
|
function TabBarBackground() {
|
||||||
if (Platform.OS === 'ios') {
|
if (Platform.OS === 'ios') {
|
||||||
return (
|
return (
|
||||||
<View style={StyleSheet.absoluteFill}>
|
<BlurView
|
||||||
<BlurView
|
intensity={80}
|
||||||
intensity={blur.heavy}
|
tint="systemChromeMaterialDark"
|
||||||
tint="dark"
|
style={StyleSheet.absoluteFill}
|
||||||
style={StyleSheet.absoluteFill}
|
/>
|
||||||
/>
|
|
||||||
<View style={[StyleSheet.absoluteFill, { backgroundColor: 'rgba(22, 33, 62, 0.7)' }]} />
|
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return <View style={[StyleSheet.absoluteFill, { backgroundColor: 'rgba(22, 33, 62, 0.9)' }]} />;
|
return <View style={[StyleSheet.absoluteFill, { backgroundColor: 'rgba(22, 33, 62, 0.95)' }]} />;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface PlayTabButtonProps {
|
interface PlayTabButtonProps {
|
||||||
@@ -78,11 +75,14 @@ export default function AppLayout() {
|
|||||||
const messageToastAnim = useRef(new Animated.Value(-100)).current;
|
const messageToastAnim = useRef(new Animated.Value(-100)).current;
|
||||||
const messageTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
const messageTimeoutRef = useRef<NodeJS.Timeout | null>(null);
|
||||||
const [isLocked, setIsLocked] = useState(false);
|
const [isLocked, setIsLocked] = useState(false);
|
||||||
const appStateRef = useRef<AppStateStatus>(AppState.currentState);
|
|
||||||
const hasCheckedInitialBiometric = useRef(false);
|
const hasCheckedInitialBiometric = useRef(false);
|
||||||
|
const wentToBackgroundAt = useRef<number | null>(null);
|
||||||
|
|
||||||
// Check if we're currently on the onboarding screen
|
// Check if we're on screens that should hide the tab bar
|
||||||
const isOnOnboarding = segments.includes("onboarding");
|
const isOnOnboarding = segments.includes("onboarding");
|
||||||
|
const isOnPairing = segments.includes("pairing");
|
||||||
|
const isOnChat = segments.includes("chat");
|
||||||
|
const shouldHideTabBar = isOnOnboarding || isOnPairing || isOnChat;
|
||||||
|
|
||||||
// Redirect to login when not authenticated, or to onboarding if not completed
|
// Redirect to login when not authenticated, or to onboarding if not completed
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -136,18 +136,25 @@ export default function AppLayout() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const subscription = AppState.addEventListener('change', async (nextAppState) => {
|
const subscription = AppState.addEventListener('change', async (nextAppState) => {
|
||||||
const previousState = appStateRef.current;
|
// Track when app goes to background (not just inactive)
|
||||||
appStateRef.current = nextAppState;
|
if (nextAppState === 'background') {
|
||||||
|
wentToBackgroundAt.current = Date.now();
|
||||||
|
}
|
||||||
|
|
||||||
// When app comes to foreground from background
|
// When app becomes active, check if we should lock
|
||||||
if (
|
if (nextAppState === 'active' && isAuthenticated && !isLocked) {
|
||||||
previousState.match(/inactive|background/) &&
|
// Only lock if we actually went to background (not just inactive from modal/control center)
|
||||||
nextAppState === 'active' &&
|
// and we were in background for at least 1 second
|
||||||
isAuthenticated
|
if (wentToBackgroundAt.current) {
|
||||||
) {
|
const timeInBackground = Date.now() - wentToBackgroundAt.current;
|
||||||
const enabled = await isBiometricEnabled();
|
wentToBackgroundAt.current = null;
|
||||||
if (enabled) {
|
|
||||||
setIsLocked(true);
|
if (timeInBackground > 1000) {
|
||||||
|
const enabled = await isBiometricEnabled();
|
||||||
|
if (enabled) {
|
||||||
|
setIsLocked(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -155,7 +162,7 @@ export default function AppLayout() {
|
|||||||
return () => {
|
return () => {
|
||||||
subscription.remove();
|
subscription.remove();
|
||||||
};
|
};
|
||||||
}, [isAuthenticated, isLoading]);
|
}, [isAuthenticated, isLoading, isLocked]);
|
||||||
|
|
||||||
const handleBiometricUnlock = useCallback(() => {
|
const handleBiometricUnlock = useCallback(() => {
|
||||||
setIsLocked(false);
|
setIsLocked(false);
|
||||||
@@ -355,7 +362,7 @@ export default function AppLayout() {
|
|||||||
screenOptions={{
|
screenOptions={{
|
||||||
headerShown: false,
|
headerShown: false,
|
||||||
tabBarBackground: () => <TabBarBackground />,
|
tabBarBackground: () => <TabBarBackground />,
|
||||||
tabBarStyle: {
|
tabBarStyle: shouldHideTabBar ? { display: 'none' } : {
|
||||||
position: 'absolute',
|
position: 'absolute',
|
||||||
backgroundColor: 'transparent',
|
backgroundColor: 'transparent',
|
||||||
borderTopColor: colors.glass.border,
|
borderTopColor: colors.glass.border,
|
||||||
@@ -366,7 +373,7 @@ export default function AppLayout() {
|
|||||||
elevation: 0,
|
elevation: 0,
|
||||||
},
|
},
|
||||||
tabBarActiveTintColor: colors.primary,
|
tabBarActiveTintColor: colors.primary,
|
||||||
tabBarInactiveTintColor: colors.textTertiary,
|
tabBarInactiveTintColor: '#fff',
|
||||||
tabBarLabelStyle: {
|
tabBarLabelStyle: {
|
||||||
fontSize: 11,
|
fontSize: 11,
|
||||||
fontWeight: "600",
|
fontWeight: "600",
|
||||||
@@ -426,21 +433,18 @@ export default function AppLayout() {
|
|||||||
name="pairing"
|
name="pairing"
|
||||||
options={{
|
options={{
|
||||||
href: null, // Hide from tab bar
|
href: null, // Hide from tab bar
|
||||||
tabBarStyle: { display: 'none' }, // Hide tab bar on pairing screen
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="chat/[id]"
|
name="chat/[id]"
|
||||||
options={{
|
options={{
|
||||||
href: null, // Hide from tab bar
|
href: null, // Hide from tab bar
|
||||||
tabBarStyle: { display: 'none' }, // Hide tab bar on chat screen
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="onboarding"
|
name="onboarding"
|
||||||
options={{
|
options={{
|
||||||
href: null, // Hide from tab bar
|
href: null, // Hide from tab bar
|
||||||
tabBarStyle: { display: 'none' }, // Hide tab bar on onboarding screen
|
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|||||||
@@ -30,13 +30,6 @@ export function BiometricLockScreen({ visible, onUnlock }: BiometricLockScreenPr
|
|||||||
loadBiometricType();
|
loadBiometricType();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (visible) {
|
|
||||||
// Auto-trigger authentication when the lock screen appears
|
|
||||||
handleAuthenticate();
|
|
||||||
}
|
|
||||||
}, [visible]);
|
|
||||||
|
|
||||||
const handleAuthenticate = async () => {
|
const handleAuthenticate = async () => {
|
||||||
if (isAuthenticating) return;
|
if (isAuthenticating) return;
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user