From 32908e1362310a6088b0e1ac22abd7b14f5de091 Mon Sep 17 00:00:00 2001 From: amel Date: Thu, 26 Jun 2025 14:30:40 +0800 Subject: [PATCH] upd: notifikasi Deskripsi: - update notifikasi push routing ketika di klik No Issues --- app/(application)/_layout.tsx | 61 ++++++++++----------------- app/(application)/notification.tsx | 64 ++++++++++++++++------------- components/home/headerRightHome.tsx | 4 +- lib/notificationSlice.ts | 14 +++++++ lib/pushToPage.ts | 28 +++++++++++++ lib/store.ts | 2 + 6 files changed, 105 insertions(+), 68 deletions(-) create mode 100644 lib/notificationSlice.ts create mode 100644 lib/pushToPage.ts diff --git a/app/(application)/_layout.tsx b/app/(application)/_layout.tsx index 41cbb60..9bec0ab 100644 --- a/app/(application)/_layout.tsx +++ b/app/(application)/_layout.tsx @@ -7,10 +7,12 @@ import HeaderMemberList from "@/components/member/headerMemberList"; import HeaderRightPositionList from "@/components/position/headerRightPositionList"; import HeaderRightProjectList from "@/components/project/headerProjectList"; import { Headers } from "@/constants/Headers"; +import { apiReadOneNotification } from "@/lib/api"; +import { pushToPage } from "@/lib/pushToPage"; import store from "@/lib/store"; import { useAuthSession } from "@/providers/AuthProvider"; import messaging from "@react-native-firebase/messaging"; -import { Redirect, router, Stack, usePathname } from "expo-router"; +import { Redirect, router, Stack } from "expo-router"; import { StatusBar } from 'expo-status-bar'; import { useEffect } from "react"; import { Text } from "react-native"; @@ -18,56 +20,37 @@ import { Easing, Notifier } from 'react-native-notifier'; import { Provider } from "react-redux"; export default function RootLayout() { - const pathname = usePathname(); + const { token, decryptToken, isLoading } = useAuthSession() - const handleNotificationPress = (category: any, content: any) => { - switch (category) { - case 'announcement': - router.push(`/announcement/${content}`); - break; - case 'discussion': - router.push(`/discussion/${content}`); - break; - case 'division': - router.push(`/division/${content}`); - break; - case 'member': - router.push(`/member/${content}`); - break; - case 'project': - router.push(`/project/${content}`); - break; - case 'announcement': - router.push(`/announcement/${content}`); - break; - // Add other cases as needed - default: - // Handle unknown category - console.warn(`Unknown category: ${category}`); + async function handleReadNotification(id: string, category: string, idContent: string) { + try { + const hasil = await decryptToken(String(token?.current)) + const response = await apiReadOneNotification({ user: hasil, id: id }) + pushToPage(category, idContent) + } catch (error) { + console.error(error) } - }; + } useEffect(() => { const unsubscribe = messaging().onMessage(async remoteMessage => { + const id = remoteMessage?.data?.id; const category = remoteMessage?.data?.category; const content = remoteMessage?.data?.content; - if (category != pathname.substring(1)) { - Notifier.showNotification({ - title: remoteMessage.notification?.title, - description: remoteMessage.notification?.body, - duration: 3000, - animationDuration: 300, - showEasing: Easing.ease, - onPress: () => handleNotificationPress(category, content), - hideOnPress: true, - }); - } + Notifier.showNotification({ + title: remoteMessage.notification?.title, + description: remoteMessage.notification?.body, + duration: 3000, + animationDuration: 300, + showEasing: Easing.ease, + onPress: () => handleReadNotification(String(id), String(category), String(content)), + hideOnPress: true, + }); }); return unsubscribe; }, []); - const { token, isLoading } = useAuthSession() if (isLoading) { return Loading...; diff --git a/app/(application)/notification.tsx b/app/(application)/notification.tsx index 686f105..cbd2e92 100644 --- a/app/(application)/notification.tsx +++ b/app/(application)/notification.tsx @@ -3,11 +3,13 @@ import SkeletonTwoItem from "@/components/skeletonTwoItem"; import { ColorsStatus } from "@/constants/ColorsStatus"; import Styles from "@/constants/Styles"; import { apiGetNotification, apiReadOneNotification } from "@/lib/api"; +import { setUpdateNotification } from "@/lib/notificationSlice"; +import { pushToPage } from "@/lib/pushToPage"; import { useAuthSession } from "@/providers/AuthProvider"; import { Feather } from "@expo/vector-icons"; -import { router } from "expo-router"; import { useEffect, useState } from "react"; import { SafeAreaView, Text, View, VirtualizedList } from "react-native"; +import { useDispatch, useSelector } from "react-redux"; type Props = { id: string @@ -26,6 +28,8 @@ export default function Notification() { const [page, setPage] = useState(1) const [waiting, setWaiting] = useState(false) const arrSkeleton = Array.from({ length: 5 }, (_, index) => index) + const dispatch = useDispatch() + const updateNotification = useSelector((state: any) => state.notificationUpdate) async function handleLoad(loading: boolean, thisPage: number) { try { @@ -77,37 +81,38 @@ export default function Notification() { const hasil = await decryptToken(String(token?.current)) const response = await apiReadOneNotification({ user: hasil, id: id }) pushToPage(category, idContent) + dispatch(setUpdateNotification(!updateNotification)) } catch (error) { console.error(error) } } - function pushToPage(category: string, idContent: string) { - const cat = category.split('/') - if (cat.length > 1) { - if (cat[2] == 'calendar') { - router.push(`/division/${cat[1]}/calendar/${idContent}`) - } else if (cat[2] == 'discussion') { - router.push(`/division/${cat[1]}/discussion/${idContent}`) - } else if (cat[2] == 'document') { - router.push(`/division/${cat[1]}/document/${idContent}`) - } else if (cat[2] == 'task') { - router.push(`/division/${cat[1]}/task/${idContent}`) - } - } else { - if (cat[0] == 'announcement') { - router.push(`/announcement/${idContent}`) - } else if (cat[0] == 'discussion-general') { - router.push(`/discussion/${idContent}`) - } else if (cat[0] == 'division') { - router.push(`/division/${idContent}`) - } else if (cat[0] == 'member') { - router.push(`/member/${idContent}`) - } else if (cat[0] == 'project') { - router.push(`/project/${idContent}`) - } - } - } + // function pushToPage(category: string, idContent: string) { + // const cat = category.split('/') + // if (cat.length > 1) { + // if (cat[2] == 'calendar') { + // router.push(`/division/${cat[1]}/calendar/${idContent}`) + // } else if (cat[2] == 'discussion') { + // router.push(`/division/${cat[1]}/discussion/${idContent}`) + // } else if (cat[2] == 'document') { + // router.push(`/division/${cat[1]}/document/${idContent}`) + // } else if (cat[2] == 'task') { + // router.push(`/division/${cat[1]}/task/${idContent}`) + // } + // } else { + // if (cat[0] == 'announcement') { + // router.push(`/announcement/${idContent}`) + // } else if (cat[0] == 'discussion-general') { + // router.push(`/discussion/${idContent}`) + // } else if (cat[0] == 'division') { + // router.push(`/division/${idContent}`) + // } else if (cat[0] == 'member') { + // router.push(`/member/${idContent}`) + // } else if (cat[0] == 'project') { + // router.push(`/project/${idContent}`) + // } + // } + // } return ( @@ -140,7 +145,10 @@ export default function Notification() { rightTopInfo={item.createdAt} desc={item.desc} textColor={item.isRead ? 'gray' : 'black'} - onPress={() => handleReadNotification(item.id, item.category, item.idContent)} + onPress={() => { + handleReadNotification(item.id, item.category, item.idContent) + + }} /> ) }} diff --git a/components/home/headerRightHome.tsx b/components/home/headerRightHome.tsx index 7d204f7..df5cdb9 100644 --- a/components/home/headerRightHome.tsx +++ b/components/home/headerRightHome.tsx @@ -5,11 +5,13 @@ import Feather from '@expo/vector-icons/Feather'; import { router } from "expo-router"; import { useEffect, useState } from "react"; import { View } from "react-native"; +import { useSelector } from "react-redux"; import { ButtonHeader } from "../buttonHeader"; export function HeaderRightHome() { const { decryptToken, token } = useAuthSession() const [notification, setNotification] = useState(0) + const updateNotification = useSelector((state: any) => state.notificationUpdate) async function handleData() { try { @@ -23,7 +25,7 @@ export function HeaderRightHome() { useEffect(() => { handleData() - }, []); + }, [updateNotification]); return ( diff --git a/lib/notificationSlice.ts b/lib/notificationSlice.ts new file mode 100644 index 0000000..2185f85 --- /dev/null +++ b/lib/notificationSlice.ts @@ -0,0 +1,14 @@ +import { createSlice } from '@reduxjs/toolkit'; + +const notificationUpdate = createSlice({ + name: 'notificationUpdate', + initialState: false, + reducers: { + setUpdateNotification: (state, action) => { + return action.payload; + }, + }, +}); + +export const { setUpdateNotification } = notificationUpdate.actions; +export default notificationUpdate.reducer; \ No newline at end of file diff --git a/lib/pushToPage.ts b/lib/pushToPage.ts new file mode 100644 index 0000000..e510536 --- /dev/null +++ b/lib/pushToPage.ts @@ -0,0 +1,28 @@ +import { router } from "expo-router" + +export function pushToPage(category: string, idContent: string) { + const cat = category.split('/') + if (cat.length > 1) { + if (cat[2] == 'calendar') { + return router.push(`/division/${cat[1]}/calendar/${idContent}`) + } else if (cat[2] == 'discussion') { + return router.push(`/division/${cat[1]}/discussion/${idContent}`) + } else if (cat[2] == 'document') { + return router.push(`/division/${cat[1]}/document/${idContent}`) + } else if (cat[2] == 'task') { + return router.push(`/division/${cat[1]}/task/${idContent}`) + } + } else { + if (cat[0] == 'announcement') { + return router.push(`/announcement/${idContent}`) + } else if (cat[0] == 'discussion-general') { + return router.push(`/discussion/${idContent}`) + } else if (cat[0] == 'division') { + return router.push(`/division/${idContent}`) + } else if (cat[0] == 'member') { + return router.push(`/member/${idContent}`) + } else if (cat[0] == 'project') { + return router.push(`/project/${idContent}`) + } + } +} \ No newline at end of file diff --git a/lib/store.ts b/lib/store.ts index 04607c6..661d053 100644 --- a/lib/store.ts +++ b/lib/store.ts @@ -12,6 +12,7 @@ import filterSlice from './filterSlice'; import groupUpdate from './groupSlice'; import memberChoose from './memberChoose'; import memberUpdate from './memberSlice'; +import notificationUpdate from './notificationSlice'; import positionUpdate from './positionSlice'; import projectUpdate from './projectUpdate'; import taskCreate from './taskCreate'; @@ -38,6 +39,7 @@ const store = configureStore({ taskUpdate: taskUpdate, divisionCreate: divisionCreate, dokumenUpdate: dokumenUpdate, + notificationUpdate: notificationUpdate, } });