amalia/05-mar-26 #35
@@ -33,6 +33,7 @@ export default function ListSetting() {
|
|||||||
|
|
||||||
const registerToken = async () => {
|
const registerToken = async () => {
|
||||||
try {
|
try {
|
||||||
|
await AsyncStorage.setItem('@notification_permission', "true");
|
||||||
const token = await getToken();
|
const token = await getToken();
|
||||||
if (token) {
|
if (token) {
|
||||||
await apiRegisteredToken({ user: entities.id, token, category: "register" });
|
await apiRegisteredToken({ user: entities.id, token, category: "register" });
|
||||||
@@ -44,6 +45,7 @@ export default function ListSetting() {
|
|||||||
|
|
||||||
const unregisterToken = async () => {
|
const unregisterToken = async () => {
|
||||||
try {
|
try {
|
||||||
|
await AsyncStorage.setItem('@notification_permission', "false");
|
||||||
const token = await getToken();
|
const token = await getToken();
|
||||||
if (token) {
|
if (token) {
|
||||||
await apiUnregisteredToken({ user: entities.id, token, category: "unregister" });
|
await apiUnregisteredToken({ user: entities.id, token, category: "unregister" });
|
||||||
@@ -113,10 +115,8 @@ export default function ListSetting() {
|
|||||||
// OS Permission is granted, perform in-app toggle
|
// OS Permission is granted, perform in-app toggle
|
||||||
const targetState = !isNotificationEnabled;
|
const targetState = !isNotificationEnabled;
|
||||||
if (targetState) {
|
if (targetState) {
|
||||||
await AsyncStorage.setItem('@notification_permission', "true");
|
|
||||||
await registerToken();
|
await registerToken();
|
||||||
} else {
|
} else {
|
||||||
await AsyncStorage.setItem('@notification_permission', "false");
|
|
||||||
await unregisterToken();
|
await unregisterToken();
|
||||||
}
|
}
|
||||||
// UI will be updated by checkNotif (triggered by state change or manually here)
|
// UI will be updated by checkNotif (triggered by state change or manually here)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ export default function ViewLogin({ onValidate }: Props) {
|
|||||||
} else {
|
} else {
|
||||||
return Toast.show({ type: 'small', text1: response.message, position: 'bottom' })
|
return Toast.show({ type: 'small', text1: response.message, position: 'bottom' })
|
||||||
}
|
}
|
||||||
} catch (error : any ) {
|
} catch (error: any) {
|
||||||
console.error(error);
|
console.error(error);
|
||||||
const message = error?.response?.data?.message || "Gagal login"
|
const message = error?.response?.data?.message || "Gagal login"
|
||||||
|
|
||||||
|
|||||||
11
lib/api.ts
11
lib/api.ts
@@ -13,18 +13,21 @@ export const apiCheckPhoneLogin = async (body: { phone: string }) => {
|
|||||||
export const apiSendOtp = async (body: { phone: string, otp: number }) => {
|
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 message = "Desa+\nMasukkan kode ini " + body.otp + " pada aplikasi Desa+ anda. Jangan berikan pada siapapun."
|
||||||
const textFix = encodeURIComponent(message)
|
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(
|
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: {
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
Authorization: `Bearer ${Constants.expoConfig?.extra?.WA_SERVER_TOKEN}`,
|
Authorization: `Bearer ${Constants.expoConfig?.extra?.WA_SERVER_TOKEN}`,
|
||||||
},
|
},
|
||||||
|
body: JSON.stringify({
|
||||||
|
number: body.phone,
|
||||||
|
text: message
|
||||||
|
})
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
return res.status
|
return res.status
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -66,32 +66,41 @@ export const openSettings = () => {
|
|||||||
|
|
||||||
export const requestPermission = async () => {
|
export const requestPermission = async () => {
|
||||||
try {
|
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
|
// Jika baru pertama kali (fresh install / storage belum ada)
|
||||||
if (currentStatus === 'undetermined') {
|
if (existing === null) {
|
||||||
|
// Cek apakah OS memungkinkan untuk memunculkan popup
|
||||||
|
if (currentStatus === 'undetermined' || (currentStatus === 'denied' && canAskAgain)) {
|
||||||
const { status: newStatus } = await Notifications.requestPermissionsAsync();
|
const { status: newStatus } = await Notifications.requestPermissionsAsync();
|
||||||
await AsyncStorage.setItem('@notification_permission', newStatus === 'granted' ? 'true' : 'false');
|
await AsyncStorage.setItem('@notification_permission', newStatus === 'granted' ? 'true' : 'false');
|
||||||
return newStatus === 'granted';
|
return newStatus === 'granted';
|
||||||
}
|
}
|
||||||
|
|
||||||
// Jika sudah pernah ditentukan (granted/denied), update storage sesuai OS
|
// Jika OS sudah granted (sudah diijinkan entah lewat mana), simpan true
|
||||||
// Tapi jika granted, kita cek storage dlu sapa tau user pernah matiin manual di app
|
if (currentStatus === 'granted') {
|
||||||
const osPermission = await checkPermission();
|
await AsyncStorage.setItem('@notification_permission', 'true');
|
||||||
const existing = await AsyncStorage.getItem('@notification_permission');
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Jika OS denied dan tidak bisa minta lagi (disables)
|
||||||
|
if (currentStatus === 'denied' && !canAskAgain) {
|
||||||
|
await AsyncStorage.setItem('@notification_permission', 'false');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const osPermission = await checkPermission();
|
||||||
|
// Jika sudah pernah di-request sebelumnya (storage sudah ada)
|
||||||
|
// Selalu sinkronkan jika OS menyatakan Denied
|
||||||
if (osPermission === false) {
|
if (osPermission === false) {
|
||||||
await AsyncStorage.setItem('@notification_permission', 'false');
|
await AsyncStorage.setItem('@notification_permission', 'false');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Jika OS Granted, ikuti nilai tersimpan di storage (menghargai in-app toggle user)
|
||||||
if (osPermission === true) {
|
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';
|
return existing === 'true';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user