|
@@ -1,10 +1,19 @@
|
|
|
import React, { useEffect, useState } from 'react';
|
|
|
-import { View, Text, TouchableOpacity, Image, Switch, Dimensions } from 'react-native';
|
|
|
+import {
|
|
|
+ View,
|
|
|
+ Text,
|
|
|
+ TouchableOpacity,
|
|
|
+ Image,
|
|
|
+ Switch,
|
|
|
+ Dimensions,
|
|
|
+ Platform,
|
|
|
+ Linking
|
|
|
+} from 'react-native';
|
|
|
import ReactModal from 'react-native-modal';
|
|
|
import { Colors } from 'src/theme';
|
|
|
import { ModalStyles } from '../../TravellersScreen/Components/styles';
|
|
|
import { Dropdown, MultiSelect } from 'react-native-searchable-dropdown-kj';
|
|
|
-import { Button } from 'src/components';
|
|
|
+import { Button, WarningModal } from 'src/components';
|
|
|
import { ButtonVariants } from 'src/types/components';
|
|
|
import { styles } from './styles';
|
|
|
import { TabBar, TabView } from 'react-native-tab-view';
|
|
@@ -15,6 +24,12 @@ import { useGetListQuery } from '@api/series';
|
|
|
import { RadioButton } from 'react-native-paper';
|
|
|
import { storage, StoreType } from 'src/storage';
|
|
|
import moment from 'moment';
|
|
|
+import {
|
|
|
+ usePostGetSettingsQuery,
|
|
|
+ usePostSetSettingsMutation,
|
|
|
+ usePostUpdateLocationMutation
|
|
|
+} from '@api/location';
|
|
|
+import * as Location from 'expo-location';
|
|
|
|
|
|
const FilterModal = ({
|
|
|
isFilterVisible,
|
|
@@ -27,7 +42,9 @@ const FilterModal = ({
|
|
|
setRegionsFilter,
|
|
|
setSeriesFilter,
|
|
|
isPublicView,
|
|
|
- isLogged = true
|
|
|
+ isLogged = true,
|
|
|
+ showNomads,
|
|
|
+ setShowNomads
|
|
|
}: {
|
|
|
isFilterVisible: boolean;
|
|
|
setIsFilterVisible: (isVisible: boolean) => void;
|
|
@@ -40,8 +57,13 @@ const FilterModal = ({
|
|
|
setSeriesFilter?: (filter: any) => void;
|
|
|
isPublicView: boolean;
|
|
|
isLogged: boolean;
|
|
|
+ showNomads?: boolean;
|
|
|
+ setShowNomads?: (showNomads: boolean) => void;
|
|
|
}) => {
|
|
|
const token = storage.get('token', StoreType.STRING) as string;
|
|
|
+ const { data: locationSettings } = usePostGetSettingsQuery(token, isLogged && !isPublicView);
|
|
|
+ const { mutateAsync: setSettings } = usePostSetSettingsMutation();
|
|
|
+ const { mutateAsync: updateLocation } = usePostUpdateLocationMutation();
|
|
|
const [index, setIndex] = useState(0);
|
|
|
const [selectedYear, setSelectedYear] = useState<{ label: string; value: number } | null>(null);
|
|
|
const [allYears, setAllYears] = useState<{ label: string; value: number }[]>([]);
|
|
@@ -52,7 +74,8 @@ const FilterModal = ({
|
|
|
];
|
|
|
const [routes] = useState([
|
|
|
{ key: 'regions', title: 'Travels' },
|
|
|
- { key: 'series', title: 'Series' }
|
|
|
+ { key: 'series', title: 'Series' },
|
|
|
+ { key: 'nomads', title: 'Nomads' }
|
|
|
]);
|
|
|
const { data } = usePostGetMapYearsQuery(token as string, userId, isLogged ? true : false);
|
|
|
const { data: seriesList } = useGetListQuery(true);
|
|
@@ -64,6 +87,21 @@ const FilterModal = ({
|
|
|
? (storage.get('filterSettings', StoreType.STRING) as string)
|
|
|
: null;
|
|
|
|
|
|
+ const [isSharing, setIsSharing] = useState(false);
|
|
|
+ const [askLocationVisible, setAskLocationVisible] = useState<boolean>(false);
|
|
|
+ const [openSettingsVisible, setOpenSettingsVisible] = useState<boolean>(false);
|
|
|
+
|
|
|
+ useEffect(() => {
|
|
|
+ const syncSettings = async () => {
|
|
|
+ if (locationSettings) {
|
|
|
+ let { status } = await Location.getForegroundPermissionsAsync();
|
|
|
+ setIsSharing(locationSettings.sharing !== 0 && status === 'granted');
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ syncSettings();
|
|
|
+ }, [locationSettings]);
|
|
|
+
|
|
|
useEffect(() => {
|
|
|
const loadFilterSettings = () => {
|
|
|
try {
|
|
@@ -192,8 +230,8 @@ const FilterModal = ({
|
|
|
setIsFilterVisible(false);
|
|
|
};
|
|
|
|
|
|
- const renderScene = ({ route }: { route: any }) => {
|
|
|
- return route.key === 'regions' ? (
|
|
|
+ const renderRegions = () => {
|
|
|
+ return (
|
|
|
<View style={styles.sceneContainer}>
|
|
|
<View style={styles.optionsContainer}>
|
|
|
<View style={styles.rowWrapper}>
|
|
@@ -301,7 +339,11 @@ const FilterModal = ({
|
|
|
/>
|
|
|
</View>
|
|
|
</View>
|
|
|
- ) : (
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const renderSeries = () => {
|
|
|
+ return (
|
|
|
<View style={styles.sceneContainer}>
|
|
|
<View style={styles.optionsContainer}>
|
|
|
<View style={[styles.row, { gap: 8 }]}>
|
|
@@ -450,6 +492,154 @@ const FilterModal = ({
|
|
|
);
|
|
|
};
|
|
|
|
|
|
+ const toggleSettingsSwitch = async () => {
|
|
|
+ if (!isSharing) {
|
|
|
+ handleGetLocation();
|
|
|
+ } else {
|
|
|
+ setSettings({ token, sharing: 0 });
|
|
|
+ setShowNomads && setShowNomads(false);
|
|
|
+ storage.set('showNomads', false);
|
|
|
+ setIsSharing(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleGetLocation = async () => {
|
|
|
+ let { status, canAskAgain } = await Location.getForegroundPermissionsAsync();
|
|
|
+
|
|
|
+ if (status === 'granted') {
|
|
|
+ getLocation();
|
|
|
+ } else if (!canAskAgain) {
|
|
|
+ setOpenSettingsVisible(true);
|
|
|
+ } else {
|
|
|
+ setAskLocationVisible(true);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const getLocation = async () => {
|
|
|
+ let currentLocation = await Location.getCurrentPositionAsync({
|
|
|
+ accuracy: Location.Accuracy.Balanced
|
|
|
+ });
|
|
|
+ setSettings(
|
|
|
+ { token, sharing: 1 },
|
|
|
+ {
|
|
|
+ onSuccess: (res) => {
|
|
|
+ console.log('Settings updated', res);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ );
|
|
|
+ setIsSharing(true);
|
|
|
+ updateLocation({
|
|
|
+ token,
|
|
|
+ lat: currentLocation.coords.latitude,
|
|
|
+ lng: currentLocation.coords.longitude
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleAcceptPermission = async () => {
|
|
|
+ setAskLocationVisible(false);
|
|
|
+ let { status, canAskAgain } = await Location.requestForegroundPermissionsAsync();
|
|
|
+
|
|
|
+ if (status === 'granted') {
|
|
|
+ getLocation();
|
|
|
+ } else if (!canAskAgain) {
|
|
|
+ setOpenSettingsVisible(true);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const toggleNomadsSwitch = () => {
|
|
|
+ setShowNomads && setShowNomads(!showNomads);
|
|
|
+ storage.set('showNomads', !showNomads);
|
|
|
+ };
|
|
|
+
|
|
|
+ const renderNomads = () => {
|
|
|
+ return (
|
|
|
+ <View style={[styles.sceneContainer, { flex: 0 }]}>
|
|
|
+ <TouchableOpacity
|
|
|
+ style={[
|
|
|
+ styles.alignStyle,
|
|
|
+ styles.buttonWrapper,
|
|
|
+ {
|
|
|
+ justifyContent: 'space-between'
|
|
|
+ }
|
|
|
+ ]}
|
|
|
+ onPress={toggleNomadsSwitch}
|
|
|
+ disabled={!isSharing}
|
|
|
+ >
|
|
|
+ <View style={styles.alignStyle}>
|
|
|
+ {/* <BellIcon fill={Colors.DARK_BLUE} width={20} height={20} /> */}
|
|
|
+ <Text style={[styles.buttonLabel, !isSharing ? { color: Colors.LIGHT_GRAY } : {}]}>
|
|
|
+ Show nomads
|
|
|
+ </Text>
|
|
|
+ </View>
|
|
|
+ <View>
|
|
|
+ <Switch
|
|
|
+ trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
|
|
|
+ thumbColor={Colors.WHITE}
|
|
|
+ onValueChange={toggleNomadsSwitch}
|
|
|
+ value={showNomads}
|
|
|
+ style={{ transform: 'scale(0.8)' }}
|
|
|
+ disabled={!isSharing}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </TouchableOpacity>
|
|
|
+
|
|
|
+ <TouchableOpacity
|
|
|
+ style={[
|
|
|
+ styles.alignStyle,
|
|
|
+ styles.buttonWrapper,
|
|
|
+ {
|
|
|
+ justifyContent: 'space-between'
|
|
|
+ }
|
|
|
+ ]}
|
|
|
+ onPress={toggleSettingsSwitch}
|
|
|
+ >
|
|
|
+ <View style={styles.alignStyle}>
|
|
|
+ {/* <BellIcon fill={Colors.DARK_BLUE} width={20} height={20} /> */}
|
|
|
+ <Text style={styles.buttonLabel}>Share location</Text>
|
|
|
+ </View>
|
|
|
+ <View>
|
|
|
+ <Switch
|
|
|
+ trackColor={{ false: Colors.LIGHT_GRAY, true: Colors.DARK_BLUE }}
|
|
|
+ thumbColor={Colors.WHITE}
|
|
|
+ onValueChange={toggleSettingsSwitch}
|
|
|
+ value={isSharing}
|
|
|
+ style={{ transform: 'scale(0.8)' }}
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ </TouchableOpacity>
|
|
|
+ <WarningModal
|
|
|
+ type={'success'}
|
|
|
+ isVisible={askLocationVisible}
|
|
|
+ onClose={() => setAskLocationVisible(false)}
|
|
|
+ action={handleAcceptPermission}
|
|
|
+ message="To use this feature we need your permission to access your location. If you press OK your system will ask you to approve location sharing with NomadMania app."
|
|
|
+ />
|
|
|
+ <WarningModal
|
|
|
+ type={'success'}
|
|
|
+ isVisible={openSettingsVisible}
|
|
|
+ onClose={() => setOpenSettingsVisible(false)}
|
|
|
+ action={() =>
|
|
|
+ Platform.OS === 'ios' ? Linking.openURL('app-settings:') : Linking.openSettings()
|
|
|
+ }
|
|
|
+ message="NomadMania app needs location permissions to function properly. Open settings?"
|
|
|
+ />
|
|
|
+ </View>
|
|
|
+ );
|
|
|
+ };
|
|
|
+
|
|
|
+ const renderScene = ({ route }: { route: any }) => {
|
|
|
+ switch (route.key) {
|
|
|
+ case 'regions':
|
|
|
+ return renderRegions();
|
|
|
+ case 'series':
|
|
|
+ return renderSeries();
|
|
|
+ case 'nomads':
|
|
|
+ return renderNomads();
|
|
|
+ default:
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
const isSmallScreen = Dimensions.get('window').width < 383;
|
|
|
|
|
|
return (
|