upd: notifikasi

Deskripsi:
- belom selesai notifikasi

No Issues
This commit is contained in:
2026-03-03 16:44:02 +08:00
parent a53b99b39d
commit 868b712fbb
4 changed files with 71 additions and 63 deletions

View File

@@ -3,13 +3,14 @@ import Text from "@/components/Text";
import ButtonSetting from "@/components/buttonSetting";
import DrawerBottom from "@/components/drawerBottom";
import Styles from "@/constants/Styles";
import { apiRegisteredToken, apiUnregisteredToken } from "@/lib/api";
import { checkPermission, getToken, openSettings, requestPermission } from "@/lib/useNotification";
import { apiGetCheckToken, apiRegisteredToken, apiUnregisteredToken } from "@/lib/api";
import { checkPermission, getToken, openSettings } from "@/lib/useNotification";
import { useAuthSession } from "@/providers/AuthProvider";
import { useTheme } from "@/providers/ThemeProvider";
import { Feather, Ionicons } from "@expo/vector-icons";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { router } from "expo-router";
import { useCallback, useEffect, useState } from "react";
import { useCallback, useEffect, useRef, useState } from "react";
import { AppState, AppStateStatus, Pressable, View } from "react-native";
import { useSelector } from "react-redux";
@@ -28,12 +29,13 @@ export default function ListSetting() {
const [showLogoutModal, setShowLogoutModal] = useState(false)
const [showThemeModal, setShowThemeModal] = useState(false)
const prevOsPermission = useRef<boolean | undefined>(undefined);
const registerToken = async () => {
try {
const token = await getToken();
if (token) {
await apiRegisteredToken({ user: entities.id, token });
await apiRegisteredToken({ user: entities.id, token, category: "register" });
}
} catch (error) {
console.warn('Error registering token:', error);
@@ -52,15 +54,31 @@ export default function ListSetting() {
};
const checkNotif = useCallback(async () => {
const status = await checkPermission();
setIsNotificationEnabled((prev) => {
if (prev === false && status === true) {
registerToken();
} else if (prev === true && status === false) {
unregisterToken();
const osPermission = await checkPermission();
// Jika dari tidak diijinkan sistem kemudian diijinkan (setelah balik dari pengaturan device)
if (prevOsPermission.current === false && osPermission === true) {
await registerToken();
}
prevOsPermission.current = osPermission;
if (!osPermission) {
setIsNotificationEnabled(false);
return;
}
try {
const token = await getToken();
if (token) {
const response = await apiGetCheckToken({ user: entities.id, token });
setIsNotificationEnabled(!!response.data);
} else {
setIsNotificationEnabled(false);
}
return !!status;
});
} catch (error) {
console.warn('Error checking token status:', error);
setIsNotificationEnabled(false);
}
}, [entities.id]);
useEffect(() => {
@@ -78,10 +96,12 @@ export default function ListSetting() {
}, [checkNotif]);
const handleToggleNotif = async () => {
if (isNotificationEnabled) {
const osPermission = await checkPermission();
if (!osPermission) {
setModalConfig({
title: "Matikan Notifikasi?",
message: "Anda akan diarahkan ke pengaturan sistem untuk mematikan notifikasi.",
title: "Aktifkan Notifikasi?",
message: "Izin notifikasi tidak diberikan. Buka pengaturan sistem untuk mengaktifkannya?",
confirmText: "Buka Pengaturan",
onConfirm: () => {
setModalVisible(false);
@@ -90,22 +110,17 @@ export default function ListSetting() {
});
setModalVisible(true);
} else {
const granted = await requestPermission();
if (granted) {
setIsNotificationEnabled(true);
registerToken();
// OS Permission is granted, perform in-app toggle
const targetState = !isNotificationEnabled;
if (targetState) {
await AsyncStorage.setItem('@notification_permission', "true");
await registerToken();
} else {
setModalConfig({
title: "Aktifkan Notifikasi?",
message: "Izin notifikasi tidak diberikan. Buka pengaturan sistem untuk mengaktifkannya?",
confirmText: "Buka Pengaturan",
onConfirm: () => {
setModalVisible(false);
openSettings();
}
});
setModalVisible(true);
await AsyncStorage.setItem('@notification_permission', "false");
await unregisterToken();
}
// UI will be updated by checkNotif (triggered by state change or manually here)
setIsNotificationEnabled(targetState);
}
};

View File

@@ -740,7 +740,7 @@ export const apiShareDocument = async (data: { dataDivision: any[], dataItem: an
return response.data;
};
export const apiRegisteredToken = async (data: { user: string, token: string }) => {
export const apiRegisteredToken = async (data: { user: string, token: string, category?: string }) => {
const response = await api.post(`/mobile/auth-token`, data)
return response.data;
};
@@ -750,6 +750,11 @@ export const apiUnregisteredToken = async (data: { user: string, token: string }
return response.data;
};
export const apiGetCheckToken = async (data: { user: string, token: string }) => {
const response = await api.post(`mobile/auth-token/check`, data);
return response.data;
};
export const apiGetNotification = async ({ user, page }: { user: string, page?: number }) => {
const response = await api.get(`mobile/home/notification?user=${user}&page=${page}`);
return response.data;

View File

@@ -1,3 +1,5 @@
import { ConstEnv } from '@/constants/ConstEnv';
import AsyncStorage from '@react-native-async-storage/async-storage';
import { getApp, getApps, initializeApp } from '@react-native-firebase/app';
import {
getMessaging,
@@ -6,8 +8,7 @@ import {
} from '@react-native-firebase/messaging';
import * as Notifications from 'expo-notifications';
import { useEffect } from 'react';
import { Linking, PermissionsAndroid, Platform } from 'react-native';
import { ConstEnv } from '@/constants/ConstEnv';
import { Linking, Platform } from 'react-native';
const RNfirebaseConfig = {
apiKey: ConstEnv.firebase.apiKey,
@@ -39,13 +40,15 @@ const initializeFirebase = async () => {
export const checkPermission = async () => {
try {
if (Platform.OS === 'android') {
return await PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
} else if (Platform.OS === 'ios') {
const { status } = await Notifications.getPermissionsAsync();
return status === 'granted';
// Cek status permission sekarang
const { status } = await Notifications.getPermissionsAsync();
if (status === 'granted') {
return true;
}
if (status === 'denied') {
return false;
}
} catch (err) {
console.warn('Error checking notification permissions:', err);
@@ -63,21 +66,9 @@ export const openSettings = () => {
export const requestPermission = async () => {
try {
if (Platform.OS === 'android') {
const cek = await PermissionsAndroid.check(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
if (!cek) {
const granted = await PermissionsAndroid.request(
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
);
return granted === PermissionsAndroid.RESULTS.GRANTED;
}
return true;
} else if (Platform.OS === 'ios') {
const { status } = await Notifications.requestPermissionsAsync();
return status === 'granted';
}
const { status: newStatus } = await Notifications.requestPermissionsAsync();
await AsyncStorage.setItem('@notification_permission', newStatus === 'granted' ? "true" : "false");
return newStatus === 'granted';
} catch (err) {
console.warn('Error requesting notification permissions:', err);
}

View File

@@ -1,6 +1,6 @@
import { ConstEnv } from '@/constants/ConstEnv';
import { apiRegisteredToken, apiUnregisteredToken } from '@/lib/api';
import { getToken, requestPermission } from '@/lib/useNotification';
import { getToken } from '@/lib/useNotification';
import AsyncStorage from '@react-native-async-storage/async-storage';
import CryptoES from "crypto-es";
import { router } from "expo-router";
@@ -52,16 +52,12 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea
const signIn = useCallback(async (token: string) => {
const hasil = await decryptToken(String(token))
const permission = await requestPermission()
if (permission) {
// const permission = await requestPermission()
const permissionStorage = await AsyncStorage.getItem('@notification_permission')
if (permissionStorage === "true") {
const tokenDevice = await getToken()
try {
// if (Platform.OS === 'android') {
const tokenDevice = await getToken()
const register = await apiRegisteredToken({ user: hasil, token: String(tokenDevice) })
// }else{
// const tokenDevice = await getToken()
// const register = await apiRegisteredToken({ user: hasil, token: String(tokenDevice) })
// }
} catch (error) {
console.error(error)
} finally {
@@ -71,6 +67,7 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea
return true
}
} else {
const register = await apiRegisteredToken({ user: hasil, token: "" })
await AsyncStorage.setItem('@token', token);
tokenRef.current = token;
router.replace('/home')