|
@@ -1,4 +1,4 @@
|
|
|
-import React, { useEffect, useState } from 'react';
|
|
|
+import React, { useCallback, useEffect, useState } from 'react';
|
|
|
import {
|
|
|
View,
|
|
|
Linking,
|
|
@@ -21,6 +21,7 @@ import { useFocusEffect } from '@react-navigation/native';
|
|
|
import {
|
|
|
usePostGetSettingsQuery,
|
|
|
usePostSetSettingsMutation,
|
|
|
+ usePostSetSettingsRegionsMutation,
|
|
|
usePostUpdateLocationMutation
|
|
|
} from '@api/location';
|
|
|
import LocationIcon from 'assets/icons/location.svg';
|
|
@@ -33,12 +34,15 @@ const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
|
|
|
const token = storage.get('token', StoreType.STRING) as string;
|
|
|
const { data: locationSettings, refetch } = usePostGetSettingsQuery(token, !!token);
|
|
|
const { mutateAsync: setSettings } = usePostSetSettingsMutation();
|
|
|
+ const { mutateAsync: setSettingsRegions } = usePostSetSettingsRegionsMutation();
|
|
|
+
|
|
|
const { mutateAsync: updateLocation } = usePostUpdateLocationMutation();
|
|
|
|
|
|
const [initialPermissionStatus, setInitialPermissionStatus] = useState<
|
|
|
'granted' | 'denied' | 'undetermined' | null
|
|
|
>(null);
|
|
|
const [isSharingWithEveryone, setIsSharingWithEveryone] = useState(false);
|
|
|
+ const [canMarkRegions, setCanMarkRegions] = useState(false);
|
|
|
const [askLocationVisible, setAskLocationVisible] = useState<boolean>(false);
|
|
|
const [openSettingsVisible, setOpenSettingsVisible] = useState<boolean>(false);
|
|
|
const [openSettingsBackgroundVisible, setOpenSettingsBackgroundVisible] =
|
|
@@ -53,6 +57,9 @@ const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
|
|
|
setIsSharingWithEveryone(
|
|
|
locationSettings.sharing !== 0 && status === 'granted' && isServicesEnabled
|
|
|
);
|
|
|
+ setCanMarkRegions(
|
|
|
+ locationSettings.sharing_regions !== 0 && status === 'granted' && isServicesEnabled
|
|
|
+ );
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -68,11 +75,14 @@ const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
|
|
|
setInitialPermissionStatus(currentStatus);
|
|
|
} else if (
|
|
|
currentStatus !== 'granted' &&
|
|
|
- (isSharingWithEveryone || initialPermissionStatus === 'granted')
|
|
|
+ (isSharingWithEveryone || canMarkRegions || initialPermissionStatus === 'granted')
|
|
|
) {
|
|
|
setSettings({ token, sharing: 0 });
|
|
|
+ setSettingsRegions({ token, sharing: 0 });
|
|
|
+
|
|
|
storage.set('showNomads', false);
|
|
|
setIsSharingWithEveryone(false);
|
|
|
+ setCanMarkRegions(false);
|
|
|
await stopBackgroundLocationUpdates();
|
|
|
}
|
|
|
}
|
|
@@ -88,10 +98,16 @@ const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
|
|
|
const status = await checkLocationPermissions();
|
|
|
const isServicesEnabled = await Location.hasServicesEnabledAsync();
|
|
|
|
|
|
- if ((status !== 'granted' && isSharingWithEveryone) || !isServicesEnabled) {
|
|
|
+ if (
|
|
|
+ (status !== 'granted' && (isSharingWithEveryone || canMarkRegions)) ||
|
|
|
+ !isServicesEnabled
|
|
|
+ ) {
|
|
|
setSettings({ token, sharing: 0 });
|
|
|
+ setSettingsRegions({ token, sharing: 0 });
|
|
|
+
|
|
|
storage.set('showNomads', false);
|
|
|
setIsSharingWithEveryone(false);
|
|
|
+ setCanMarkRegions(false);
|
|
|
await stopBackgroundLocationUpdates();
|
|
|
}
|
|
|
setInitialPermissionStatus(status);
|
|
@@ -100,9 +116,11 @@ const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
|
|
|
getInitialPermissionsStatus();
|
|
|
}, []);
|
|
|
|
|
|
- useFocusEffect(() => {
|
|
|
- refetchData();
|
|
|
- });
|
|
|
+ useFocusEffect(
|
|
|
+ useCallback(() => {
|
|
|
+ refetchData();
|
|
|
+ }, [navigation])
|
|
|
+ );
|
|
|
|
|
|
const refetchData = async () => {
|
|
|
await refetch();
|
|
@@ -115,21 +133,30 @@ const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
|
|
|
|
|
|
const toggleSettingsSwitch = async () => {
|
|
|
if (!isSharingWithEveryone) {
|
|
|
- handleGetLocation();
|
|
|
+ handleGetLocation(true);
|
|
|
} else {
|
|
|
setSettings({ token, sharing: 0 });
|
|
|
storage.set('showNomads', false);
|
|
|
setIsSharingWithEveryone(false);
|
|
|
- await stopBackgroundLocationUpdates();
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- const handleGetLocation = async () => {
|
|
|
+ const toggleRegionSettingsSwitch = async () => {
|
|
|
+ if (!canMarkRegions) {
|
|
|
+ handleGetLocation(false);
|
|
|
+ } else {
|
|
|
+ setSettingsRegions({ token, sharing: 0 });
|
|
|
+
|
|
|
+ setCanMarkRegions(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleGetLocation = async (isSettings: boolean) => {
|
|
|
let { status, canAskAgain } = await Location.getForegroundPermissionsAsync();
|
|
|
const isServicesEnabled = await Location.hasServicesEnabledAsync();
|
|
|
|
|
|
if (status === 'granted' && isServicesEnabled) {
|
|
|
- getLocation();
|
|
|
+ getLocationToggle(isSettings);
|
|
|
const bgStatus = await Location.getBackgroundPermissionsAsync();
|
|
|
if (bgStatus.status !== 'granted') {
|
|
|
const { status } = await Location.requestBackgroundPermissionsAsync();
|
|
@@ -155,6 +182,28 @@ const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
|
|
|
});
|
|
|
setSettings({ token, sharing: 1 });
|
|
|
setIsSharingWithEveryone(true);
|
|
|
+ setSettingsRegions({ token, sharing: 1 });
|
|
|
+ setCanMarkRegions(true);
|
|
|
+
|
|
|
+ updateLocation({
|
|
|
+ token,
|
|
|
+ lat: currentLocation.coords.latitude,
|
|
|
+ lng: currentLocation.coords.longitude
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const getLocationToggle = async (isSettings: boolean) => {
|
|
|
+ if (isSettings) {
|
|
|
+ setSettings({ token, sharing: 1 });
|
|
|
+ setIsSharingWithEveryone(true);
|
|
|
+ } else {
|
|
|
+ setSettingsRegions({ token, sharing: 1 });
|
|
|
+ setCanMarkRegions(true);
|
|
|
+ }
|
|
|
+
|
|
|
+ let currentLocation = await Location.getCurrentPositionAsync({
|
|
|
+ accuracy: Location.Accuracy.Balanced
|
|
|
+ });
|
|
|
updateLocation({
|
|
|
token,
|
|
|
lat: currentLocation.coords.latitude,
|
|
@@ -217,6 +266,88 @@ const LocationSharingScreen = ({ navigation }: { navigation: any }) => {
|
|
|
</View>
|
|
|
</TouchableOpacity>
|
|
|
|
|
|
+ <TouchableOpacity
|
|
|
+ style={[
|
|
|
+ styles.alignStyle,
|
|
|
+ styles.buttonWrapper,
|
|
|
+ {
|
|
|
+ justifyContent: 'space-between',
|
|
|
+ height: undefined,
|
|
|
+ paddingVertical: 8
|
|
|
+ }
|
|
|
+ ]}
|
|
|
+ onPress={toggleRegionSettingsSwitch}
|
|
|
+ >
|
|
|
+ <View style={[styles.alignStyle, { flex: 1 }]}>
|
|
|
+ <UsersIcon fill={Colors.DARK_BLUE} width={20} height={20} />
|
|
|
+ <Text style={[styles.buttonLabel, { flex: 1 }]}>
|
|
|
+ Share location to automatically mark a region or DARE place as visited
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ <View>
|
|
|
+ <Switch
|
|
|
+ trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
|
|
|
+ thumbColor={Colors.WHITE}
|
|
|
+ onValueChange={toggleRegionSettingsSwitch}
|
|
|
+ value={canMarkRegions}
|
|
|
+ style={{ transform: 'scale(0.8)' }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </TouchableOpacity>
|
|
|
+
|
|
|
+ <View style={{ marginVertical: 12, gap: 6 }}>
|
|
|
+ <Text style={[textStyles.text, textStyles.boldText]}>
|
|
|
+ At NomadMania, we respect your privacy.
|
|
|
+ </Text>
|
|
|
+ <Text style={[textStyles.text]}>
|
|
|
+ If you choose to share your location, it can be used to:
|
|
|
+ </Text>
|
|
|
+ <View style={[textStyles.bulletItem]}>
|
|
|
+ <Text style={textStyles.bulletIcon}>{'\u2022'}</Text>
|
|
|
+ <Text style={[textStyles.text, { flex: 1 }]}>
|
|
|
+ show your current location to other users who also share theirs
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ <View style={textStyles.bulletItem}>
|
|
|
+ <Text style={textStyles.bulletIcon}>{'\u2022'}</Text>
|
|
|
+ <Text style={[textStyles.text, { flex: 1 }]}>
|
|
|
+ automatically mark regions (and DARE places) as visited in the Regions section as well
|
|
|
+ as in the Trips section
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+
|
|
|
+ <Text style={[textStyles.text, { marginTop: 6 }]}>
|
|
|
+ You can choose how you want to share your location:
|
|
|
+ </Text>
|
|
|
+ <View style={[textStyles.bulletItem]}>
|
|
|
+ <Text style={textStyles.bulletIcon}>{'\u2022'}</Text>
|
|
|
+ <Text style={[textStyles.text, { flex: 1 }]}>
|
|
|
+ <Text style={textStyles.boldText}>Only when the app is open</Text> – Your location
|
|
|
+ updates only when you open the app. This uses less battery but may be less accurate.
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ <View style={textStyles.bulletItem}>
|
|
|
+ <Text style={textStyles.bulletIcon}>{'\u2022'}</Text>
|
|
|
+ <Text style={[textStyles.text, { flex: 1 }]}>
|
|
|
+ <Text style={textStyles.boldText}>In the background</Text> – Your location stays up to
|
|
|
+ date even when the app is closed. Other users see your latest location, and visited
|
|
|
+ regions and DARE places are marked automatically.
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ <Text style={[textStyles.text]}>
|
|
|
+ You’re always in control, and you can change these settings anytime in the app{' '}
|
|
|
+ <Text
|
|
|
+ style={{ color: Colors.ORANGE }}
|
|
|
+ onPress={() =>
|
|
|
+ Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings()
|
|
|
+ }
|
|
|
+ >
|
|
|
+ Settings
|
|
|
+ </Text>{' '}
|
|
|
+ section.
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+
|
|
|
<WarningModal
|
|
|
type={'success'}
|
|
|
isVisible={askLocationVisible}
|
|
@@ -268,6 +399,20 @@ const textStyles = StyleSheet.create({
|
|
|
shadowRadius: 4,
|
|
|
shadowOpacity: 1,
|
|
|
elevation: 8
|
|
|
+ },
|
|
|
+ boldText: {
|
|
|
+ fontWeight: '700'
|
|
|
+ },
|
|
|
+ bulletItem: {
|
|
|
+ flexDirection: 'row',
|
|
|
+ alignItems: 'center',
|
|
|
+ width: '100%'
|
|
|
+ },
|
|
|
+ bulletIcon: {
|
|
|
+ fontSize: 12,
|
|
|
+ fontWeight: '700',
|
|
|
+ marginHorizontal: 6,
|
|
|
+ alignSelf: 'flex-start'
|
|
|
}
|
|
|
});
|
|
|
|