upd: notifikasi
Deskripsi: - belom selesai notifikasi No Issues
This commit is contained in:
@@ -3,13 +3,14 @@ import Text from "@/components/Text";
|
|||||||
import ButtonSetting from "@/components/buttonSetting";
|
import ButtonSetting from "@/components/buttonSetting";
|
||||||
import DrawerBottom from "@/components/drawerBottom";
|
import DrawerBottom from "@/components/drawerBottom";
|
||||||
import Styles from "@/constants/Styles";
|
import Styles from "@/constants/Styles";
|
||||||
import { apiRegisteredToken, apiUnregisteredToken } from "@/lib/api";
|
import { apiGetCheckToken, apiRegisteredToken, apiUnregisteredToken } from "@/lib/api";
|
||||||
import { checkPermission, getToken, openSettings, requestPermission } from "@/lib/useNotification";
|
import { checkPermission, getToken, openSettings } from "@/lib/useNotification";
|
||||||
import { useAuthSession } from "@/providers/AuthProvider";
|
import { useAuthSession } from "@/providers/AuthProvider";
|
||||||
import { useTheme } from "@/providers/ThemeProvider";
|
import { useTheme } from "@/providers/ThemeProvider";
|
||||||
import { Feather, Ionicons } from "@expo/vector-icons";
|
import { Feather, Ionicons } from "@expo/vector-icons";
|
||||||
|
import AsyncStorage from "@react-native-async-storage/async-storage";
|
||||||
import { router } from "expo-router";
|
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 { AppState, AppStateStatus, Pressable, View } from "react-native";
|
||||||
import { useSelector } from "react-redux";
|
import { useSelector } from "react-redux";
|
||||||
|
|
||||||
@@ -28,12 +29,13 @@ export default function ListSetting() {
|
|||||||
|
|
||||||
const [showLogoutModal, setShowLogoutModal] = useState(false)
|
const [showLogoutModal, setShowLogoutModal] = useState(false)
|
||||||
const [showThemeModal, setShowThemeModal] = useState(false)
|
const [showThemeModal, setShowThemeModal] = useState(false)
|
||||||
|
const prevOsPermission = useRef<boolean | undefined>(undefined);
|
||||||
|
|
||||||
const registerToken = async () => {
|
const registerToken = async () => {
|
||||||
try {
|
try {
|
||||||
const token = await getToken();
|
const token = await getToken();
|
||||||
if (token) {
|
if (token) {
|
||||||
await apiRegisteredToken({ user: entities.id, token });
|
await apiRegisteredToken({ user: entities.id, token, category: "register" });
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Error registering token:', error);
|
console.warn('Error registering token:', error);
|
||||||
@@ -52,15 +54,31 @@ export default function ListSetting() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const checkNotif = useCallback(async () => {
|
const checkNotif = useCallback(async () => {
|
||||||
const status = await checkPermission();
|
const osPermission = await checkPermission();
|
||||||
setIsNotificationEnabled((prev) => {
|
|
||||||
if (prev === false && status === true) {
|
// Jika dari tidak diijinkan sistem kemudian diijinkan (setelah balik dari pengaturan device)
|
||||||
registerToken();
|
if (prevOsPermission.current === false && osPermission === true) {
|
||||||
} else if (prev === true && status === false) {
|
await registerToken();
|
||||||
unregisterToken();
|
}
|
||||||
|
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]);
|
}, [entities.id]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@@ -78,10 +96,12 @@ export default function ListSetting() {
|
|||||||
}, [checkNotif]);
|
}, [checkNotif]);
|
||||||
|
|
||||||
const handleToggleNotif = async () => {
|
const handleToggleNotif = async () => {
|
||||||
if (isNotificationEnabled) {
|
const osPermission = await checkPermission();
|
||||||
|
|
||||||
|
if (!osPermission) {
|
||||||
setModalConfig({
|
setModalConfig({
|
||||||
title: "Matikan Notifikasi?",
|
title: "Aktifkan Notifikasi?",
|
||||||
message: "Anda akan diarahkan ke pengaturan sistem untuk mematikan notifikasi.",
|
message: "Izin notifikasi tidak diberikan. Buka pengaturan sistem untuk mengaktifkannya?",
|
||||||
confirmText: "Buka Pengaturan",
|
confirmText: "Buka Pengaturan",
|
||||||
onConfirm: () => {
|
onConfirm: () => {
|
||||||
setModalVisible(false);
|
setModalVisible(false);
|
||||||
@@ -90,22 +110,17 @@ export default function ListSetting() {
|
|||||||
});
|
});
|
||||||
setModalVisible(true);
|
setModalVisible(true);
|
||||||
} else {
|
} else {
|
||||||
const granted = await requestPermission();
|
// OS Permission is granted, perform in-app toggle
|
||||||
if (granted) {
|
const targetState = !isNotificationEnabled;
|
||||||
setIsNotificationEnabled(true);
|
if (targetState) {
|
||||||
registerToken();
|
await AsyncStorage.setItem('@notification_permission', "true");
|
||||||
|
await registerToken();
|
||||||
} else {
|
} else {
|
||||||
setModalConfig({
|
await AsyncStorage.setItem('@notification_permission', "false");
|
||||||
title: "Aktifkan Notifikasi?",
|
await unregisterToken();
|
||||||
message: "Izin notifikasi tidak diberikan. Buka pengaturan sistem untuk mengaktifkannya?",
|
|
||||||
confirmText: "Buka Pengaturan",
|
|
||||||
onConfirm: () => {
|
|
||||||
setModalVisible(false);
|
|
||||||
openSettings();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
setModalVisible(true);
|
|
||||||
}
|
}
|
||||||
|
// UI will be updated by checkNotif (triggered by state change or manually here)
|
||||||
|
setIsNotificationEnabled(targetState);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -740,7 +740,7 @@ export const apiShareDocument = async (data: { dataDivision: any[], dataItem: an
|
|||||||
return response.data;
|
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)
|
const response = await api.post(`/mobile/auth-token`, data)
|
||||||
return response.data;
|
return response.data;
|
||||||
};
|
};
|
||||||
@@ -750,6 +750,11 @@ export const apiUnregisteredToken = async (data: { user: string, token: string }
|
|||||||
return response.data;
|
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 }) => {
|
export const apiGetNotification = async ({ user, page }: { user: string, page?: number }) => {
|
||||||
const response = await api.get(`mobile/home/notification?user=${user}&page=${page}`);
|
const response = await api.get(`mobile/home/notification?user=${user}&page=${page}`);
|
||||||
return response.data;
|
return response.data;
|
||||||
|
|||||||
@@ -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 { getApp, getApps, initializeApp } from '@react-native-firebase/app';
|
||||||
import {
|
import {
|
||||||
getMessaging,
|
getMessaging,
|
||||||
@@ -6,8 +8,7 @@ import {
|
|||||||
} from '@react-native-firebase/messaging';
|
} from '@react-native-firebase/messaging';
|
||||||
import * as Notifications from 'expo-notifications';
|
import * as Notifications from 'expo-notifications';
|
||||||
import { useEffect } from 'react';
|
import { useEffect } from 'react';
|
||||||
import { Linking, PermissionsAndroid, Platform } from 'react-native';
|
import { Linking, Platform } from 'react-native';
|
||||||
import { ConstEnv } from '@/constants/ConstEnv';
|
|
||||||
|
|
||||||
const RNfirebaseConfig = {
|
const RNfirebaseConfig = {
|
||||||
apiKey: ConstEnv.firebase.apiKey,
|
apiKey: ConstEnv.firebase.apiKey,
|
||||||
@@ -39,13 +40,15 @@ const initializeFirebase = async () => {
|
|||||||
|
|
||||||
export const checkPermission = async () => {
|
export const checkPermission = async () => {
|
||||||
try {
|
try {
|
||||||
if (Platform.OS === 'android') {
|
// Cek status permission sekarang
|
||||||
return await PermissionsAndroid.check(
|
const { status } = await Notifications.getPermissionsAsync();
|
||||||
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
|
|
||||||
);
|
if (status === 'granted') {
|
||||||
} else if (Platform.OS === 'ios') {
|
return true;
|
||||||
const { status } = await Notifications.getPermissionsAsync();
|
}
|
||||||
return status === 'granted';
|
|
||||||
|
if (status === 'denied') {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Error checking notification permissions:', err);
|
console.warn('Error checking notification permissions:', err);
|
||||||
@@ -63,21 +66,9 @@ export const openSettings = () => {
|
|||||||
|
|
||||||
export const requestPermission = async () => {
|
export const requestPermission = async () => {
|
||||||
try {
|
try {
|
||||||
if (Platform.OS === 'android') {
|
const { status: newStatus } = await Notifications.requestPermissionsAsync();
|
||||||
const cek = await PermissionsAndroid.check(
|
await AsyncStorage.setItem('@notification_permission', newStatus === 'granted' ? "true" : "false");
|
||||||
PermissionsAndroid.PERMISSIONS.POST_NOTIFICATIONS
|
return newStatus === 'granted';
|
||||||
);
|
|
||||||
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';
|
|
||||||
}
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn('Error requesting notification permissions:', err);
|
console.warn('Error requesting notification permissions:', err);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ConstEnv } from '@/constants/ConstEnv';
|
import { ConstEnv } from '@/constants/ConstEnv';
|
||||||
import { apiRegisteredToken, apiUnregisteredToken } from '@/lib/api';
|
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 AsyncStorage from '@react-native-async-storage/async-storage';
|
||||||
import CryptoES from "crypto-es";
|
import CryptoES from "crypto-es";
|
||||||
import { router } from "expo-router";
|
import { router } from "expo-router";
|
||||||
@@ -52,16 +52,12 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea
|
|||||||
|
|
||||||
const signIn = useCallback(async (token: string) => {
|
const signIn = useCallback(async (token: string) => {
|
||||||
const hasil = await decryptToken(String(token))
|
const hasil = await decryptToken(String(token))
|
||||||
const permission = await requestPermission()
|
// const permission = await requestPermission()
|
||||||
if (permission) {
|
const permissionStorage = await AsyncStorage.getItem('@notification_permission')
|
||||||
|
if (permissionStorage === "true") {
|
||||||
|
const tokenDevice = await getToken()
|
||||||
try {
|
try {
|
||||||
// if (Platform.OS === 'android') {
|
|
||||||
const tokenDevice = await getToken()
|
|
||||||
const register = await apiRegisteredToken({ user: hasil, token: String(tokenDevice) })
|
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) {
|
} catch (error) {
|
||||||
console.error(error)
|
console.error(error)
|
||||||
} finally {
|
} finally {
|
||||||
@@ -71,6 +67,7 @@ export default function AuthProvider({ children }: { children: ReactNode }): Rea
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
const register = await apiRegisteredToken({ user: hasil, token: "" })
|
||||||
await AsyncStorage.setItem('@token', token);
|
await AsyncStorage.setItem('@token', token);
|
||||||
tokenRef.current = token;
|
tokenRef.current = token;
|
||||||
router.replace('/home')
|
router.replace('/home')
|
||||||
|
|||||||
Reference in New Issue
Block a user