소스 검색

added anon landmark converion and alert

chase 2 년 전
부모
커밋
d3b560cd08
2개의 변경된 파일61개의 추가작업 그리고 23개의 파일을 삭제
  1. 8 6
      src/components/Map/MainMapComponent/IndoorMap.tsx
  2. 53 17
      src/data/Auth/AuthContext.tsx

+ 8 - 6
src/components/Map/MainMapComponent/IndoorMap.tsx

@@ -1,5 +1,5 @@
 import React, { useState, useEffect, Children } from 'react';
-import { View, Text, StatusBar, StyleSheet, Dimensions, Button, ActivityIndicator, Alert, Modal, PanResponderCallbacks, PanResponderGestureState, GestureResponderEvent, ImageSourcePropType, TouchableOpacity, Platform, Linking, } from 'react-native';
+import { View, Text, StatusBar, StyleSheet, Dimensions, Button, ActivityIndicator, Alert, Modal, PanResponderCallbacks, PanResponderGestureState, GestureResponderEvent, ImageSourcePropType, TouchableOpacity, Platform, Linking, Pressable, } from 'react-native';
 import { Svg, Defs, Rect, Mask, Circle, Marker, Path, Polyline, Image } from 'react-native-svg';
 import { RadioButton } from 'react-native-paper';
 import { Picker as EricPicker } from '@react-native-picker/picker';
@@ -130,16 +130,18 @@ const IndoorMap: React.FC<IndoorMapProps> = ({ navigation, landmarks, promptAddL
 
         {floor == 0 ? <ArrowButton num={0} fontAweIcon={""} /> : <ArrowButton num={-1} fontAweIcon={"chevron-left"} propEvent={() => changer(-1)} />}
 
-        <View style={{ backgroundColor: colors.red, flex: 5, height: 53.5, width: 200 }}>
+        <View style={{flex: 5, height: 53.5, width: 200 }}>
           <Picker
             placeholder={{}}
             value={floor}
             style={{ 
-              inputAndroid: {textAlign: 'center', color:"white", height: '100%', backgroundColor: 'black'} ,
-              inputIOS: {textAlign: 'center', height: '100%', width: '30%', backgroundColor: 'black', alignSelf: 'center'} ,
-              iconContainer: {backgroundColor: 'black', height: '100%', justifyContent: 'center',}
+              inputIOSContainer: {width:'70%', justifyContent: 'center', alignSelf: 'center'},
+              inputAndroidContainer: {width:'70%', justifyContent: 'center', alignSelf: 'center'},
+              inputAndroid: {textAlign: 'center', color:"white", height: '100%', alignSelf: 'center'},
+              inputIOS: { color: 'white', textAlign: 'center', height: '100%', alignSelf: 'center'} ,
+              iconContainer: {height: '100%', justifyContent: 'center',}
             }}
-            Icon={() => <FontAwesome name="chevron-down"  color='white' size={20} />}
+            Icon={() => <FontAwesome name="chevron-down"  color='white' size={15} />}
             onValueChange={(value) => {
               setFloor(value)
               setShowME(false)

+ 53 - 17
src/data/Auth/AuthContext.tsx

@@ -5,10 +5,12 @@ import jwt_decode from 'jwt-decode'
 import React, { createContext, useContext, useEffect, useMemo, useState } from "react"
 import { useQueryClient } from "react-query"
 import { API_URL, reportAxiosError } from "../../utils/RequestUtils"
-import { Landmark } from "../landmarks"
+import { Landmark, } from "../landmarks"
 import { queryKeys } from "../query-keys"
 import {v4} from 'uuid'
 import { ErrorMessage } from "formik"
+import { Alert } from "react-native"
+import { navigate } from "../../navigation/RootNavigator"
 
 export const SECURESTORE_ACCESSTOKEN = "access"
 export const SECURESTORE_REFRESHTOKEN = "refresh"
@@ -55,8 +57,9 @@ interface AuthenticationResult {
 }
 
 interface GlobalAlert {
+    title: string
     message: string
-    type: 'success' | 'error'
+    type: 'success' | 'error' | 'warning'
     callback: () => void
 }
 
@@ -96,7 +99,7 @@ export const AuthContextProvider: React.FC = ({children}) => {
     const [userId, setUserId] = useState<string>()
     const [anonUserId, setAnonUserId] = useState<string>()
     const [loading, setLoading] = useState<boolean>(false)
-    const [message, setMessage] = useState<string>('')
+    const [alert, setAlert] = useState<GlobalAlert>()
 
     const queryClient = useQueryClient()
 
@@ -143,6 +146,23 @@ export const AuthContextProvider: React.FC = ({children}) => {
         loadAuthStateFromStorageOnAppLoad()
     }, [])
 
+    useEffect(() => {
+        if (alert) {
+            const alertTitle = alert.title
+            Alert.alert(alertTitle, alert.message, [{text: 'OK', onPress: alert.callback}])
+            setAlert(undefined)
+        }
+    }, [alert])
+
+    useEffect(() => {
+        const convertExistingAnonymousLandmarksOnAccessTokenChange = async () => {
+            if (accessToken && anonUserId) {
+                await convertExistingAnonymousLandmarks()
+            }
+        }
+        convertExistingAnonymousLandmarksOnAccessTokenChange()
+    }, [accessToken])
+
     const setAccessTokenAsync = async (token: string) => {
         setAccessToken(token)
         setStorageItem(SECURESTORE_ACCESSTOKEN, token)
@@ -237,11 +257,6 @@ export const AuthContextProvider: React.FC = ({children}) => {
                 await setRefreshTokenAsync(tokenResponse.refresh_token);
                 await setUserIdAsync(idToken.sub)
 
-                // TODO: check for anonymous landmarks on the server, and display a notification if there are any asking the user to convert them
-                await checkForAnonymousLandmarks()
-
-                setAnonUserId('')
-
                 console.log('[Authentication]: Tokens successfully retrieved.')
                 
     
@@ -249,14 +264,14 @@ export const AuthContextProvider: React.FC = ({children}) => {
             } catch (error) {
                 reportAxiosError("Something went wrong when retrieving access token", error);
                 setLoading(false)
-                setError("Something went wrong while logging in. Please try again.")
+                setAlert({title:"Error", message: "Something went wrong when retrieving access token", callback: () => {}, type: 'error'})
             } 
         }
         else if (response.type == "cancel") {
             setLoading(false)
         }
         else {
-            setError("Something went wrong while logging in. Please try again.")
+            setAlert({title: 'Error', message: "Something went wrong while logging in. Please try again.", callback: () => {}, type: 'error'})
         }
     } 
 
@@ -274,11 +289,12 @@ export const AuthContextProvider: React.FC = ({children}) => {
             });  
 
             queryClient.setQueryData(queryKeys.getOwnedProfile, null)
+            await setAnonUserId(await getItemAsync(SECURESTORE_ANONID))
             await clearAuthStorage()
 
         } catch (error) {
             reportAxiosError("Something went wrong when logging out", error);
-            setError("Something went wrong while logging out. Please try again.")
+            setAlert({title: 'Error', message: "Something went wrong while logging out. Please try again.", callback: () => {}, type: 'error'})
         } 
         setLoading(false)
     }
@@ -320,9 +336,7 @@ export const AuthContextProvider: React.FC = ({children}) => {
         return owned
     }
 
-    const createGlobalAlert = (message: string) => {
-
-    const checkForAnonymousLandmarks = async () => {
+    const convertExistingAnonymousLandmarks = async () => {
         try {
             const response = await sendApiRequestAsync({
                 axiosConfig: {
@@ -334,10 +348,33 @@ export const AuthContextProvider: React.FC = ({children}) => {
             })
     
             if (response?.data?.has_landmark) {
+                // send request to convert landarks
+                await sendApiRequestAsync({
+                    axiosConfig: {
+                        method: 'POST',
+                        url: `/api/landmarks/convert/${anonUserId}/`
+                    },
+                    authorized: true,
+                    errorMessage: 'Something went wrong when converting anonymous landmarks'
+                })
 
+                setAnonUserId('')
+                
+                setAlert({
+                    title: 'Heads up',
+                    message: "It looks like you added some landmarks before creating an account, so those landmarks are now owned by your newly created account.", 
+                    callback: () => {},
+                    type: 'warning'
+                })
             }
         } catch (error) {
             reportAxiosError("[Authentication]: Error when checking for anonymous landmarks", error);
+            setAlert({
+                title: 'Error',
+                message: "Failed to convert your old anonymous landmarks to your account. Please try again manually by going to Account -> Information -> Transfer anonymous landmarks.",
+                callback: () => navigate("Account"),
+                type: 'error'
+            })
             return false
         }
     }
@@ -354,15 +391,14 @@ export const AuthContextProvider: React.FC = ({children}) => {
         refreshToken,
         userId,
         loading,
-        error,
         anonUserId,
         setLoading,
-        setError,
+        setAlert,
         sendApiRequestAsync,
         login,
         logout,
         refreshAccessToken,
-    }), [accessToken, refreshToken, userId, loading, error, anonUserId])
+    }), [accessToken, refreshToken, userId, loading, anonUserId])
 
     return (
         <AuthContext.Provider value={authState}>