diff --git a/frontend/index.tsx b/frontend/index.tsx index e863d41..b8b9687 100644 --- a/frontend/index.tsx +++ b/frontend/index.tsx @@ -2,46 +2,69 @@ import "./globals.css"; -import React, {useState} from "react"; +import React, { useState } from "react"; import { useColorScheme } from "react-native"; import { NavigationContainer, DefaultTheme, DarkTheme } from "@react-navigation/native"; import { createBottomTabNavigator } from "@react-navigation/bottom-tabs"; import { Ionicons } from "@expo/vector-icons"; +import { enableScreens } from "react-native-screens"; +import { SafeAreaProvider } from "react-native-safe-area-context"; +import messaging from "@react-native-firebase/messaging"; +import notifee, { AndroidImportance } from "@notifee/react-native"; import SubscribedFeed from "@/screens/SubscribedFeed"; import AllFeed from "@/screens/AllFeed"; import Profile from "@/screens/Profile"; -import {enableScreens} from "react-native-screens"; -import {SafeAreaProvider} from "react-native-safe-area-context"; import AuthGate from "@/screens/AuthGate"; -import {AuthProvider, useAuth} from "@/context/AuthContext"; -import messaging, {setBackgroundMessageHandler} from "@react-native-firebase/messaging"; - +import { AuthProvider, useAuth } from "@/context/AuthContext"; import { useUpdatecheck } from "./hooks/useUpdatecheck"; -import { UpdatePrompt } from './components/UpdatePrompt'; +import { UpdatePrompt } from "./components/UpdatePrompt"; import { usePushNotifications } from "./hooks/usePushNotifications"; -messaging().setBackgroundMessageHandler(async () => {}); +// Handles data-only FCM messages when the app is in the background or closed. +messaging().setBackgroundMessageHandler(async remoteMessage => { + const title = remoteMessage.data?.title as string | undefined; + const body = remoteMessage.data?.body as string | undefined; + + if (!title && !body) return; + + const channelId = await notifee.createChannel({ + id: "default", + name: "General", + importance: AndroidImportance.HIGH, + }); + + await notifee.displayNotification({ + title, + body, + android: { + channelId, + pressAction: { id: "default" }, + }, + }); +}); + // Must be called before any navigator renders enableScreens(); + const Tab = createBottomTabNavigator(); const LIGHT_TAB = { - bg: "#FFFFFF", - border: "#E8E2D5", - active: "#C4622D", - inactive: "#8A8278", - label: "#1A1714", -}; -const DARK_TAB = { - bg: "#161513", - border: "#2C2A27", - active: "#E07B45", - inactive: "#706D67", - label: "#F0EDE8", + bg: "#FFFFFF", + border: "#E8E2D5", + active: "#C4622D", + inactive: "#8A8278", + label: "#1A1714", }; +const DARK_TAB = { + bg: "#161513", + border: "#2C2A27", + active: "#E07B45", + inactive: "#706D67", + label: "#F0EDE8", +}; function ProfileTab() { const { user, loading } = useAuth(); @@ -56,13 +79,12 @@ export default function App() { const tab = dark ? DARK_TAB : LIGHT_TAB; const navTheme = dark - ? { ...DarkTheme, colors: { ...DarkTheme.colors, background: "#0E0D0C" } } + ? { ...DarkTheme, colors: { ...DarkTheme.colors, background: "#0E0D0C" } } : { ...DefaultTheme, colors: { ...DefaultTheme.colors, background: "#FDFAF5" } }; const { updateInfo } = useUpdatecheck(); const [updateDismissed, setUpdateDismissed] = useState(false); - usePushNotifications(); return ( @@ -75,19 +97,19 @@ export default function App() { tabBarStyle: { backgroundColor: tab.bg, - borderTopColor: tab.border, - borderTopWidth: 1, - height: 60, - paddingBottom: 8, - paddingTop: 6, + borderTopColor: tab.border, + borderTopWidth: 1, + height: 60, + paddingBottom: 8, + paddingTop: 6, }, tabBarActiveTintColor: tab.active, tabBarInactiveTintColor: tab.inactive, tabBarLabelStyle: { - fontSize: 10, - fontWeight: "600", + fontSize: 10, + fontWeight: "600", letterSpacing: 0.3, }, @@ -96,9 +118,9 @@ export default function App() { string, { active: keyof typeof Ionicons.glyphMap; inactive: keyof typeof Ionicons.glyphMap } > = { - "Subscribed": { active: "bookmark", inactive: "bookmark-outline" }, - "Discover": { active: "compass", inactive: "compass-outline" }, - "Profile": { active: "person-circle", inactive: "person-circle-outline" }, + "Subscribed": { active: "bookmark", inactive: "bookmark-outline" }, + "Discover": { active: "compass", inactive: "compass-outline" }, + "Profile": { active: "person-circle", inactive: "person-circle-outline" }, }; const set = icons[route.name]; @@ -130,7 +152,7 @@ export default function App() { - {/* Overlays the entire app, including the nav bar */} + {/* Overlays the entire app including the tab bar */} {updateInfo && !updateDismissed && ( ); -} +} \ No newline at end of file