diff --git a/app/(application)/setting/index.tsx b/app/(application)/setting/index.tsx index 0102231..ffb3b71 100644 --- a/app/(application)/setting/index.tsx +++ b/app/(application)/setting/index.tsx @@ -33,6 +33,7 @@ export default function ListSetting() { const registerToken = async () => { try { + await AsyncStorage.setItem('@notification_permission', "true"); const token = await getToken(); if (token) { await apiRegisteredToken({ user: entities.id, token, category: "register" }); @@ -44,6 +45,7 @@ export default function ListSetting() { const unregisterToken = async () => { try { + await AsyncStorage.setItem('@notification_permission', "false"); const token = await getToken(); if (token) { await apiUnregisteredToken({ user: entities.id, token, category: "unregister" }); @@ -113,10 +115,8 @@ export default function ListSetting() { // OS Permission is granted, perform in-app toggle const targetState = !isNotificationEnabled; if (targetState) { - await AsyncStorage.setItem('@notification_permission', "true"); await registerToken(); } else { - await AsyncStorage.setItem('@notification_permission', "false"); await unregisterToken(); } // UI will be updated by checkNotif (triggered by state change or manually here) diff --git a/components/auth/viewLogin.tsx b/components/auth/viewLogin.tsx index 92068f1..ea358a2 100644 --- a/components/auth/viewLogin.tsx +++ b/components/auth/viewLogin.tsx @@ -45,7 +45,7 @@ export default function ViewLogin({ onValidate }: Props) { } else { return Toast.show({ type: 'small', text1: response.message, position: 'bottom' }) } - } catch (error : any ) { + } catch (error: any) { console.error(error); const message = error?.response?.data?.message || "Gagal login" diff --git a/lib/api.ts b/lib/api.ts index 78e8e43..5d7f772 100644 --- a/lib/api.ts +++ b/lib/api.ts @@ -13,18 +13,21 @@ export const apiCheckPhoneLogin = async (body: { phone: string }) => { export const apiSendOtp = async (body: { phone: string, otp: number }) => { const message = "Desa+\nMasukkan kode ini " + body.otp + " pada aplikasi Desa+ anda. Jangan berikan pada siapapun." const textFix = encodeURIComponent(message) - // const res = await axios.get(`${Constants.expoConfig?.extra?.URL_OTP}/code?nom=${body.phone}&text=*Desa%2B*%0AMasukkan%20kode%20ini%20*${encodeURIComponent(body.otp)}*%20pada%20aplikasi%20Desa%2B%20anda.%20Jangan%20berikan%20pada%20siapapun.`) const res = await fetch( - `${Constants.expoConfig?.extra?.URL_OTP}/code?nom=${body.phone}&text=${textFix}`, + `${Constants.expoConfig?.extra?.URL_OTP}/api/wa/send-text`, { - cache: "no-cache", + method: 'POST', headers: { + 'Content-Type': 'application/json', Authorization: `Bearer ${Constants.expoConfig?.extra?.WA_SERVER_TOKEN}`, }, + body: JSON.stringify({ + number: body.phone, + text: message + }) } ); - return res.status } diff --git a/lib/useNotification.ts b/lib/useNotification.ts index a0cff32..93d3315 100644 --- a/lib/useNotification.ts +++ b/lib/useNotification.ts @@ -66,32 +66,41 @@ export const openSettings = () => { export const requestPermission = async () => { try { - const { status: currentStatus } = await Notifications.getPermissionsAsync(); + const existing = await AsyncStorage.getItem('@notification_permission'); + const { status: currentStatus, canAskAgain } = await Notifications.getPermissionsAsync(); - // Jika belum pernah ditentukan (undetermined), baru panggil request - if (currentStatus === 'undetermined') { - const { status: newStatus } = await Notifications.requestPermissionsAsync(); - await AsyncStorage.setItem('@notification_permission', newStatus === 'granted' ? 'true' : 'false'); - return newStatus === 'granted'; + // Jika baru pertama kali (fresh install / storage belum ada) + if (existing === null) { + // Cek apakah OS memungkinkan untuk memunculkan popup + if (currentStatus === 'undetermined' || (currentStatus === 'denied' && canAskAgain)) { + const { status: newStatus } = await Notifications.requestPermissionsAsync(); + await AsyncStorage.setItem('@notification_permission', newStatus === 'granted' ? 'true' : 'false'); + return newStatus === 'granted'; + } + + // Jika OS sudah granted (sudah diijinkan entah lewat mana), simpan true + if (currentStatus === 'granted') { + await AsyncStorage.setItem('@notification_permission', 'true'); + return true; + } + + // Jika OS denied dan tidak bisa minta lagi (disables) + if (currentStatus === 'denied' && !canAskAgain) { + await AsyncStorage.setItem('@notification_permission', 'false'); + return false; + } } - // Jika sudah pernah ditentukan (granted/denied), update storage sesuai OS - // Tapi jika granted, kita cek storage dlu sapa tau user pernah matiin manual di app const osPermission = await checkPermission(); - const existing = await AsyncStorage.getItem('@notification_permission'); - + // Jika sudah pernah di-request sebelumnya (storage sudah ada) + // Selalu sinkronkan jika OS menyatakan Denied if (osPermission === false) { await AsyncStorage.setItem('@notification_permission', 'false'); return false; } + // Jika OS Granted, ikuti nilai tersimpan di storage (menghargai in-app toggle user) if (osPermission === true) { - // Jika OS ijinkan, tapi di storage belum ada, set true - if (existing === null) { - await AsyncStorage.setItem('@notification_permission', 'true'); - return true; - } - // Jika OS ijinkan dan di storage ada, ikuti storage (toggle manual user) return existing === 'true'; }