From 6c3a474bb05d86255ac404fdfabec3c2580d6aeb Mon Sep 17 00:00:00 2001 From: Joshua Higgins Date: Tue, 20 Oct 2026 17:20:25 -0400 Subject: [PATCH] misc: upgrade to Expo SDK 58 Move the app from SDK 55 onto React Native 0.88 so later widget and auth work can use the SDK 58 packages. Co-authored-by: Cursor --- app/(tabs)/_layout.tsx | 2 +- app/(tabs)/devices/index.tsx | 46 +- app/(tabs)/settings/index.tsx | 135 +- app/action/[action]/[deviceId].tsx | 4 +- app/scan-devices.tsx | 4 +- hooks/use-theme-color.ts | 21 - package-lock.json | 8278 ++++++++++------------ package.json | 57 +- src/components/DeviceContextMenu.ios.tsx | 26 + src/components/DeviceContextMenu.tsx | 10 + src/context/AuthContext.tsx | 65 +- 11 files changed, 3786 insertions(+), 4862 deletions(-) delete mode 100644 hooks/use-theme-color.ts create mode 100644 src/components/DeviceContextMenu.ios.tsx create mode 100644 src/components/DeviceContextMenu.tsx diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index a63cc84..2c87cc2 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -1,4 +1,4 @@ -import { NativeTabs } from 'expo-router/unstable-native-tabs'; +import { NativeTabs } from 'expo-router/native-tabs'; export default function TabLayout() { return ( diff --git a/app/(tabs)/devices/index.tsx b/app/(tabs)/devices/index.tsx index 80b6dee..ea7e218 100644 --- a/app/(tabs)/devices/index.tsx +++ b/app/(tabs)/devices/index.tsx @@ -1,4 +1,3 @@ -import { Button, ContextMenu, Host } from '@expo/ui/swift-ui'; import { Ionicons } from '@expo/vector-icons'; import * as Burnt from 'burnt'; import { SymbolView } from 'expo-symbols'; @@ -19,6 +18,7 @@ import api from '../../../src/services/api'; import { syncDevicesToWidget } from '../../../src/services/widgetSync'; import { Device } from '../../../src/types'; import { useAuth } from '@/src/context/AuthContext'; +import { DeviceContextMenu } from '@/src/components/DeviceContextMenu'; const isAuthError = (error: unknown) => typeof error === 'object' && @@ -43,7 +43,6 @@ export default function DeviceListScreen() { const fetchDevices = useCallback(async (showLoading = false) => { try { - if (showLoading) setIsLoading(true); const data = await api.getDevices(); setDevices(data); // Sync devices to iOS widget @@ -66,8 +65,31 @@ export default function DeviceListScreen() { useEffect(() => { if (!isAuthenticated) return; - fetchDevices(true); - }, [fetchDevices, isAuthenticated]); + let cancelled = false; + void api.getDevices().then( + data => { + if (cancelled) return; + setDevices(data); + syncDevicesToWidget(data); + setIsLoading(false); + }, + (error: unknown) => { + if (cancelled) return; + if (isAuthError(error)) { + setDevices([]); + } else { + const message = + error instanceof Error ? error.message : 'Failed to load devices'; + Alert.alert('Error', message); + } + setIsLoading(false); + } + ); + + return () => { + cancelled = true; + }; + }, [isAuthenticated]); useEffect(() => { if (!isAuthenticated) return; @@ -301,17 +323,7 @@ export default function DeviceListScreen() { const isOffline = item.status?.toLowerCase() === 'offline'; return ( - - - -