From 064b954a28ecebacb21ae0800200c80718544e04 Mon Sep 17 00:00:00 2001 From: digitalnomad91 Date: Sun, 22 Feb 2026 01:40:59 -0600 Subject: [PATCH 1/4] feat: Add profile screen and various improvements - Add new Profile screen with user information display - Add Google Sign Out and Revoke Access functionality - Add permissions layout for better organization - Add TypeScript types for react-native-console-view - Add misc utilities for time formatting - Add Gradle wrapper files for Android builds - Update tab layout to include Profile tab - Remove deprecated cellular and location components - Improve debug screen and login functionality - Update various permission demos - Update dependencies in package.json --- app/(tabs)/_layout.tsx | 25 +- app/(tabs)/cellular.tsx | 37 - app/(tabs)/index.tsx | 88 +-- app/(tabs)/permissions/_layout.tsx | 11 + app/(tabs)/permissions/index.tsx | 41 +- app/(tabs)/profile.tsx | 285 +++++++ app/_layout.tsx | 56 +- app/debug.tsx | 56 +- app/login.tsx | 146 +--- app/modal.tsx | 33 +- .../android/gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 43764 bytes .../gradle/wrapper/gradle-wrapper.properties | 7 + build/android/gradlew | 251 ++++++ build/android/gradlew.bat | 94 +++ components/CustomHeader.tsx | 9 +- components/Location.tsx | 104 --- components/LogViewer.tsx | 52 +- .../CameraMicrophonePermissionDemo.tsx | 424 ++++++++++- .../permissions/LocationPermissionDemo.tsx | 85 ++- .../NotificationsPermissionDemo.tsx | 5 +- .../TelephonySmsPermissionDemo.tsx | 718 +++++++++++++++++- package-lock.json | 22 + package.json | 8 +- types/react-native-console-view.d.ts | 5 + utils/camera.utils.ts | 11 +- utils/misc.utils.ts | 68 ++ 26 files changed, 2130 insertions(+), 511 deletions(-) delete mode 100644 app/(tabs)/cellular.tsx create mode 100644 app/(tabs)/permissions/_layout.tsx create mode 100644 app/(tabs)/profile.tsx create mode 100644 build/android/gradle/wrapper/gradle-wrapper.jar create mode 100644 build/android/gradle/wrapper/gradle-wrapper.properties create mode 100755 build/android/gradlew create mode 100644 build/android/gradlew.bat delete mode 100644 components/Location.tsx create mode 100644 types/react-native-console-view.d.ts create mode 100644 utils/misc.utils.ts diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx index 41e3084..2b844c3 100644 --- a/app/(tabs)/_layout.tsx +++ b/app/(tabs)/_layout.tsx @@ -1,5 +1,5 @@ import FontAwesome from '@expo/vector-icons/FontAwesome'; -import { Link, Tabs } from 'expo-router'; +import { Tabs, usePathname, useRouter } from 'expo-router'; // You can explore the built-in icon families and icons on the web at https://icons.expo.fyi/ function TabBarIcon(props: { name: React.ComponentProps['name']; color: string }) { @@ -7,6 +7,9 @@ function TabBarIcon(props: { name: React.ComponentProps['nam } export default function TabLayout() { + const pathname = usePathname(); + const router = useRouter(); + return ( , + title: 'Profile', + tabBarIcon: ({ color }: { color: string }) => , }} /> , }} + listeners={{ + tabPress: (e: { preventDefault: () => void }) => { + // If already on a permissions sub-page (not the index), navigate to permissions index + const isOnPermissionsSubPage = pathname.startsWith('/permissions/') && pathname !== '/permissions'; + const isOnPermissionsIndex = pathname === '/permissions' || pathname === '/(tabs)/permissions'; + + if (isOnPermissionsSubPage || isOnPermissionsIndex) { + // Prevent default tab behavior + e.preventDefault(); + // Navigate to permissions index, replacing the current route to reset the stack + router.replace('/(tabs)/permissions'); + } + }, + }} /> ); diff --git a/app/(tabs)/cellular.tsx b/app/(tabs)/cellular.tsx deleted file mode 100644 index 0043c88..0000000 --- a/app/(tabs)/cellular.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import { View, Text, StyleSheet } from 'react-native'; -import CellularDemo from '@/components/CellularDemo'; -import CustomHeader from '@/components/CustomHeader'; - -export default function SimplePage() { - return ( - - - - My Header - This is some example text to show a plain page component. - - - - ); -} - -const styles = StyleSheet.create({ - container: { - flex: 1, - justifyContent: 'center', - alignItems: 'center', - padding: 16, - backgroundColor: '#121212', - }, - header: { - fontSize: 24, - fontWeight: 'bold', - color: '#fff', - marginBottom: 20, - }, - text: { - fontSize: 16, - color: '#ccc', - textAlign: 'center', - }, -}); diff --git a/app/(tabs)/index.tsx b/app/(tabs)/index.tsx index 19d06b5..b381c00 100644 --- a/app/(tabs)/index.tsx +++ b/app/(tabs)/index.tsx @@ -1,21 +1,11 @@ -import { View, Text, Button, ActivityIndicator, StyleSheet, Image, ScrollView } from 'react-native'; -import MapView, { Marker } from 'react-native-maps'; +import { View, Button, StyleSheet, Image, ScrollView } from 'react-native'; import { Link } from 'expo-router'; -import { useLocation } from '@/hooks/useLocation'; import LogViewer from '@/components/LogViewer'; import BatteryInfo from '@/components/BatteryInfo'; -import { triggerLocalSampleNotification } from '@/utils/notifications.utils'; -import { usePushNotifications } from '@/hooks/usePushNotifications'; import CustomHeader from '@/components/CustomHeader'; -import { simulateAsyncGlobalError, triggerNativeTestException } from '@/services/errorHandler.service'; import * as Sentry from '@sentry/react-native'; -export default function LocationComponent() { - const { fcmToken } = usePushNotifications(); - const { location, address, error, loading, fetchLocation } = useLocation(fcmToken); - - const textColor = '#ffffff'; - +export default function HomeScreen() { return ( @@ -28,64 +18,6 @@ export default function LocationComponent() { {/* Battery information */} - {/* Location / Map */} - {loading ? ( - - ) : error ? ( - {error} - ) : location && address ? ( - <> - - Address: {address.name}, {address.city}, {address.region}, {address.country} - - - {location.coords.latitude} - {location.coords.longitude} - - - - - {location && ( - - )} - - - - ) : ( - Waiting for location... - )} - -