import {View, Text} from "../../../components/Themed";
import {Linking, StyleSheet} from "react-native";
import Colors from "../../../constants/Colors";
import { useEffect, useState } from "react";
import { VStack, HStack, Switch } from "@gluestack-ui/themed";
import * as Notifications from 'expo-notifications'
import global from "../../../constants/global";
import { getSubscriptions, subscribe, deleteSubscription } from "../../../components/backend";
type NotificationKey =
| "crime_all"
| "crime_low"
| "crime_medium"
| "crime_high"
| "social_comment"
| "social_upvote_post"
| "social_upvote_comment"
| "social_downvote_post"
| "social_downvote_comment"
| "social_remove_post"
| "social_remove_comment"
;
export default function NotificationsScreen() {
type NotificationSettings = Record<NotificationKey, boolean>;
const [notify, setNotify] = useState<NotificationSettings>({
crime_all:false,
crime_high:false,
crime_medium:false,
crime_low:false,
social_comment: false,
social_downvote_post:false,
social_downvote_comment:false,
social_remove_post:false,
social_remove_comment:false,
social_upvote_post:false,
social_upvote_comment:false,
})
const [allow, setAllow] = useState(false)
const [permissions, setPermissions] = useState<Notifications.NotificationPermissionsStatus>()
const [all, setAll] = useState(false)
useEffect(()=>{
const getPerms = async ()=>{
let status = await Notifications.getPermissionsAsync()
setAllow(status.granted)
setPermissions(status)
}
getPerms()
getSubscriptions().then((topics)=>{
const validNotificationKeys: Set<NotificationKey> = new Set([
"crime_all",
"crime_low",
"crime_medium",
"crime_high",
"social_comment",
"social_upvote_post",
"social_upvote_comment",
"social_downvote_post",
"social_downvote_comment",
"social_remove_post",
"social_remove_comment"
]);
console.log(topics)
let newNotify = notify;
for(const topic of topics){
if(validNotificationKeys.has(topic.topic)){
if(topic.topic == 'crime_all'){
setAll(true)
}
newNotify[topic.topic as NotificationKey] = true
}
}
setNotify({...newNotify})
})
},[])
const requestNotificationPerm = async ()=>{
let status = await Notifications.requestPermissionsAsync()
if(!status.granted){
setAllow(false)
}else{
}
}
const handleToggle = (key:NotificationKey) =>{
const newValue = !notify[key];
//Subscribes to topic in backend
if(key == 'crime_all'){
if(newValue){
subscribe(key).then(()=>{
setNotify({...notify,"crime_high":false, "crime_low":false, "crime_medium":false, [key]:newValue})
setAll(newValue)
}).catch((error)=>{
console.log(error)
})
}else{
deleteSubscription(key).then(()=>{
setNotify({...notify,"crime_high":false, "crime_low":false, "crime_medium":false, [key]:newValue})
setAll(newValue);
}).catch((error)=>{
console.log(error)
})
}
}else{
if(newValue){
subscribe(key).then(()=>{
setNotify({ ...notify, [key]: newValue });
}).catch((error)=>{
console.log(error)
})
}else{
deleteSubscription(key).then(()=>{
setNotify({...notify, [key]:newValue})
}).catch((error)=>{
console.log(error)
})
}
}
}
return (
<View style={styles.container}>
<View style={styles.content}>
{/* Notifications toggle */}
<HStack style={[styles.setting, {paddingHorizontal:18, marginVertical:10, marginBottom:30}]}>
<Text style={styles.allowText}>Allow Notifications</Text>
<Switch
size="lg"
sx={{
props:{
trackColor:{
true:Colors.dark.cyan,
false:Colors.dark.text
}
}
}}
value={allow}
onValueChange={(value)=>{
setAllow(value)
if(value && !permissions?.canAskAgain && permissions){
Linking.openSettings()
}else if(value){
requestNotificationPerm()
}else{
deleteSubscription([])
console.log("Setting device status in db")
}
}}
/>
</HStack>
{/* Notification settings */}
{allow&&<Text style={styles.title}>Crime</Text>}
{allow&&<VStack style={styles.card}>
{[
{ label: 'Notify for ALL crime reports', key: 'crime_all' },
{ label: 'High severity crimes', key: 'crime_high' },
{ label: 'Medium severity crimes', key: 'crime_medium' },
{ label: 'Low severity crimes', key: 'crime_low' },
].map(({ label, key }) => (
<HStack
key={key}
style={styles.setting}
>
<Text style={styles.optionText}>{label}</Text>
<Switch
size="md"
isDisabled={key!='crime_all'?all:false}
sx={{
props:{
trackColor:{
true:Colors.dark.redBright,
false:Colors.dark.text
}
}
}}
value={notify[key as NotificationKey]}
onValueChange={() => handleToggle(key as NotificationKey)}
/>
</HStack>
))}
</VStack>}
{allow&&<Text style={styles.title}>Social</Text>}
{allow&&<VStack style={styles.card}>
{[
{ label: 'New comment on your post', key: 'social_comment' },
{ label: 'Your post was up voted', key: 'social_upvote_post' },
{ label: 'Your post was down voted', key: 'social_downvote_post' },
{ label: 'Post removal [down votes]', key: 'social_remove_post' },
{ label: 'Your comment was up voted', key: 'social_upvote_comment' },
{ label: 'Your comment was down voted', key: 'social_downvote_comment' },
{ label: 'Comment removal [down votes]', key: 'social_remove_comment' },
].map(({ label, key }) => (
<HStack
key={key}
style={styles.setting}
>
<Text style={styles.optionText}>{label}</Text>
<Switch
size="md"
sx={{
props:{
trackColor:{
true:Colors.dark.redBright,
false:Colors.dark.text
}
}
}}
value={notify[key as NotificationKey]}
onValueChange={() => handleToggle(key as NotificationKey)}
/>
</HStack>
))}
</VStack>}
</View>
</View>
)
// return (
// <View style={styles.container}>
// <View style={styles.content}>
// <Text style={styles.title}>Notification Preferences</Text>
// <HStack justifyContent="space-between">
// <Text style={styles.label}>Allow Notifications</Text>
// <Switch
// size="md"
// value={allow}
// defaultValue={allow}
// onValueChange={(value)=>{
// console.log('Notifications toggle: ', value)
// if(value){
// setAllow(true)
// }else{
// setAllow(false)
// }
// }}
// sx={{
// props:{
// trackColor:{
// true:Colors.dark.redBright,
// false:Colors.dark.text
// }
// }
// }}
// />
// </HStack>
// {allow&&<VStack space="lg" mt="$4">
// {[
// { label: 'Notify for ALL crime reports', key: 'crime_all' },
// { label: 'High severity crimes', key: 'crime_high' },
// { label: 'Medium severity crimes', key: 'crime_medium' },
// { label: 'Low severity crimes', key: 'crime_low' },
// ].map(({ label, key }) => (
// <HStack
// key={key}
// justifyContent="space-between"
// alignItems="center"
// >
// <Text style={styles.label}>{label}</Text>
// <Switch
// size="md"
// sx={{
// props:{
// trackColor:{
// true:Colors.dark.redBright,
// false:Colors.dark.text
// }
// }
// }}
// value={notify[key as NotificationKey]}
// onValueChange={() => handleToggle(key as NotificationKey)}
// />
// </HStack>
// ))}
// </VStack>}
// </View>
// </View>
// )
}
const styles = StyleSheet.create({
container:{
flex:1,
},
content:{
flex:1,
alignItems:'center',
justifyContent:'flex-start',
backgroundColor:Colors.dark.tabBg,
},
card:{
borderRadius: 10,
backgroundColor: Colors.dark.background,
padding:10,
width: global.width*0.95,
marginBottom: 15,
rowGap:10,
},
title:{
fontSize: 24,
fontWeight: 'bold',
marginBottom: 5,
color: Colors.dark.cyan,
alignSelf:'flex-start',
marginLeft:global.width*0.05-5
},
setting:{
width:'100%',
flexDirection:'row',
justifyContent:'space-between'
},
optionText:{
fontSize:18,
textAlignVertical:'center',
color:Colors.dark.text
},
allowText:{
fontSize:22,
textAlignVertical:'center',
color:Colors.dark.redBright,
fontWeight:'bold'
},
optionToggle:{
color:Colors.dark.cyan
},
selection:{
width:global.width*0.4
}
})