From 135b26d29fac12ef664c76590c7b9c050b9c037d Mon Sep 17 00:00:00 2001 From: Kamal Kishor Joshi Date: Sun, 3 Nov 2024 23:43:12 +0530 Subject: [PATCH] use async storage instead of encrypted storage to avoid problem with user login (#260) * use async storage instead of encrypted storage to avoid problem with login * call reloadPalettes instead of loadInitPaletteFromStore * fix incorrect condition which was causing login to fail * fix crash in ios due to ads library * use /p for color palette preview deep link --- android/app/src/main/AndroidManifest.xml | 2 +- app.json | 2 +- components/AdBanner.js | 1 - components/AppAuthProvider.js | 6 +- components/Login.js | 6 +- components/SignUp.js | 6 +- hooks/useApplicationStore.js | 6 ++ hooks/useUserData.js | 2 +- ios/Podfile.lock | 44 +++++++++++--- ios/croma.xcodeproj/project.pbxproj | 22 +++++-- ios/croma/PrivacyInfo.xcprivacy | 16 +++-- ...cryptedStoreage.js => EncryptedStorage.js} | 8 +-- network/axios.client.js | 58 ++++++++++++------- package.json | 1 - screens/ChatSessionScreen.js | 3 +- screens/MyPalettesScreen.js | 5 +- screens/SavePaletteScreen.js | 4 +- screens/UserProfileScreen.js | 8 +-- yarn.lock | 11 ---- 19 files changed, 135 insertions(+), 76 deletions(-) rename libs/{EncryptedStoreage.js => EncryptedStorage.js} (61%) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 6d0a803a..d98c15a4 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -25,7 +25,7 @@ + android:pathPrefix="/p/" /> diff --git a/app.json b/app.json index 34918301..9b19724e 100644 --- a/app.json +++ b/app.json @@ -3,7 +3,7 @@ "displayName": "croma", "react-native-google-mobile-ads": { "android_app_id": "ca-app-pub-6847037498271557~7057578612", - "ios_app_id": "ca-app-pub-xxxxxxxx~xxxxxxxx", + "ios_app_id": "ca-app-pub-3940256099942544~1458002511", "delay_app_measurement_init": true, "user_tracking_usage_description": "This identifier will be used to deliver personalized ads to you." diff --git a/components/AdBanner.js b/components/AdBanner.js index b5522402..e188c381 100644 --- a/components/AdBanner.js +++ b/components/AdBanner.js @@ -1,4 +1,3 @@ -// AdBanner.js import React, { useEffect, useState } from 'react'; import { View, Platform } from 'react-native'; import mobileAds, { BannerAd, BannerAdSize, TestIds, AdsConsent } from 'react-native-google-mobile-ads'; diff --git a/components/AppAuthProvider.js b/components/AppAuthProvider.js index 32ec9e8b..7f8d67a0 100644 --- a/components/AppAuthProvider.js +++ b/components/AppAuthProvider.js @@ -10,7 +10,7 @@ import useUserData from '../hooks/useUserData'; import { useNavigation } from '@react-navigation/native'; import { PRIVATE_ROUTES } from '../libs/constants'; import GoogleButton from './GoogleButton'; -import { storeUserSession } from '../libs/EncryptedStoreage'; +import { storeUserSession } from '../libs/EncryptedStorage'; import { notifyMessage, sendClientError } from '../libs/Helpers'; import { useTranslation } from 'react-i18next'; import { googleLogin } from '../network/login-and-signup'; @@ -24,7 +24,7 @@ const SCREEN_TYPES = { export const AuthForm = function () { const applicationState = useApplicationStore(); - const { loadInitPaletteFromStore } = applicationState; + const { reloadPalettes } = applicationState; const { t } = useTranslation(); const { loadUserData } = useUserData(); const [screenType, setScreenType] = useState(SCREEN_TYPES.SIGN_UP); @@ -60,7 +60,7 @@ export const AuthForm = function () { ); await loadUserData(); - loadInitPaletteFromStore(); + reloadPalettes(); } catch (error) { sendClientError('google_sign_in', error?.message || '', error); notifyMessage(t('Google login failed!' + error?.message || '')); diff --git a/components/Login.js b/components/Login.js index c45a3084..09a282f8 100644 --- a/components/Login.js +++ b/components/Login.js @@ -3,7 +3,7 @@ import React, { useState } from 'react'; import { View, Text, TextInput, StyleSheet, TouchableOpacity, Linking } from 'react-native'; import { useTranslation } from 'react-i18next'; import { login } from '../network/login-and-signup'; -import { storeUserSession } from '../libs/EncryptedStoreage'; +import { storeUserSession } from '../libs/EncryptedStorage'; import CromaButton from './CromaButton'; import useUserData from '../hooks/useUserData'; import { notifyMessage, sendClientError } from '../libs/Helpers'; @@ -21,7 +21,7 @@ const LOGIN_AND_SIGNUP_TEXT = { const Login = function ({ setScreenSignup }) { const applicationState = useApplicationStore(); - const { loadInitPaletteFromStore } = applicationState; + const { reloadPalettes } = applicationState; const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); const { t } = useTranslation(); @@ -59,7 +59,7 @@ const Login = function ({ setScreenSignup }) { res.data.user.avatar_url ); await loadUserData(); - loadInitPaletteFromStore(); + reloadPalettes(); } catch (error) { sendClientError('login_failed', error?.message || '', error); notifyMessage(t('Login failed: ' + error?.message)); diff --git a/components/SignUp.js b/components/SignUp.js index 379101b4..f2e105c0 100644 --- a/components/SignUp.js +++ b/components/SignUp.js @@ -3,7 +3,7 @@ import React, { useState } from 'react'; import { View, Text, TextInput, StyleSheet } from 'react-native'; import { useTranslation } from 'react-i18next'; import { signUp } from '../network/login-and-signup'; -import { storeUserSession } from '../libs/EncryptedStoreage'; +import { storeUserSession } from '../libs/EncryptedStorage'; import CromaButton from './CromaButton'; import useUserData from '../hooks/useUserData'; import { notifyMessage, sendClientError } from '../libs/Helpers'; @@ -21,7 +21,7 @@ const LOGIN_AND_SIGNUP_TEXT = { const SignUp = function ({ setScreenLogin }) { const applicationState = useApplicationStore(); - const { loadInitPaletteFromStore } = applicationState; + const { reloadPalettes } = applicationState; const [email, setEmail] = useState(''); const [fullname, setFullname] = useState(''); const [password, setPassword] = useState(''); @@ -71,7 +71,7 @@ const SignUp = function ({ setScreenLogin }) { res.data.user.avatar_url ); await loadUserData(); - loadInitPaletteFromStore(); + reloadPalettes(); } catch (error) { console.log(error); sendClientError('signup_failed', error?.message || '', error); diff --git a/hooks/useApplicationStore.js b/hooks/useApplicationStore.js index 0f6e0fa7..91c63261 100644 --- a/hooks/useApplicationStore.js +++ b/hooks/useApplicationStore.js @@ -55,6 +55,12 @@ const useApplicationStore = create((set) => ({ set({ allPalettes }); }, + reloadPalettes: async () => { + set({ isLoading: true }); + const allPalettes = await useApplicationStore.getState().loadPalettes(); + set({ allPalettes, isLoading: false }); + }, + loadInitPaletteFromStore: async () => { set({ isLoading: true }); const isUserAlreadyExits = await Storage.checkUserAlreadyExists(); diff --git a/hooks/useUserData.js b/hooks/useUserData.js index 0d32ab4f..a55806e6 100644 --- a/hooks/useUserData.js +++ b/hooks/useUserData.js @@ -1,5 +1,5 @@ import { create } from 'zustand'; -import { retrieveUserSession } from '../libs/EncryptedStoreage'; +import { retrieveUserSession } from '../libs/EncryptedStorage'; const useUserData = create((set) => ({ userData: undefined, diff --git a/ios/Podfile.lock b/ios/Podfile.lock index e00cbafa..9e7524b6 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -12,10 +12,13 @@ PODS: - FBLazyVector (0.75.3) - fmt (9.1.0) - glog (0.3.5) + - Google-Mobile-Ads-SDK (11.7.0): + - GoogleUserMessagingPlatform (>= 1.1) - GoogleSignIn (7.1.0): - AppAuth (< 2.0, >= 1.7.3) - GTMAppAuth (< 5.0, >= 4.1.1) - GTMSessionFetcher/Core (~> 3.3) + - GoogleUserMessagingPlatform (2.5.0) - GTMAppAuth (4.1.1): - AppAuth/Core (~> 1.7) - GTMSessionFetcher/Core (< 4.0, >= 3.3) @@ -1283,8 +1286,6 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - react-native-encrypted-storage (4.0.3): - - React-Core - react-native-get-random-values (1.11.0): - React-Core - react-native-image-picker (7.1.2): @@ -1601,10 +1602,33 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga + - RNGoogleMobileAds (14.2.5): + - DoubleConversion + - glog + - Google-Mobile-Ads-SDK (= 11.7.0) + - GoogleUserMessagingPlatform (= 2.5.0) + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCodegen + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - RNGoogleSignin (12.2.1): - GoogleSignIn (~> 7.1) - React-Core - - RNIap (12.15.3): + - RNIap (12.15.7): - React-Core - RNReanimated (3.15.1): - DoubleConversion @@ -1785,7 +1809,6 @@ DEPENDENCIES: - react-native-color-thief (from `../node_modules/react-native-color-thief`) - react-native-config (from `../node_modules/react-native-config`) - react-native-document-picker (from `../node_modules/react-native-document-picker`) - - react-native-encrypted-storage (from `../node_modules/react-native-encrypted-storage`) - react-native-get-random-values (from `../node_modules/react-native-get-random-values`) - react-native-image-picker (from `../node_modules/react-native-image-picker`) - react-native-safe-area-context (from `../node_modules/react-native-safe-area-context`) @@ -1821,6 +1844,7 @@ DEPENDENCIES: - "RNCClipboard (from `../node_modules/@react-native-clipboard/clipboard`)" - RNFS (from `../node_modules/react-native-fs`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) + - RNGoogleMobileAds (from `../node_modules/react-native-google-mobile-ads`) - "RNGoogleSignin (from `../node_modules/@react-native-google-signin/google-signin`)" - RNIap (from `../node_modules/react-native-iap`) - RNReanimated (from `../node_modules/react-native-reanimated`) @@ -1834,7 +1858,9 @@ DEPENDENCIES: SPEC REPOS: trunk: - AppAuth + - Google-Mobile-Ads-SDK - GoogleSignIn + - GoogleUserMessagingPlatform - GTMAppAuth - GTMSessionFetcher - SocketRocket @@ -1921,8 +1947,6 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-config" react-native-document-picker: :path: "../node_modules/react-native-document-picker" - react-native-encrypted-storage: - :path: "../node_modules/react-native-encrypted-storage" react-native-get-random-values: :path: "../node_modules/react-native-get-random-values" react-native-image-picker: @@ -1993,6 +2017,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-fs" RNGestureHandler: :path: "../node_modules/react-native-gesture-handler" + RNGoogleMobileAds: + :path: "../node_modules/react-native-google-mobile-ads" RNGoogleSignin: :path: "../node_modules/@react-native-google-signin/google-signin" RNIap: @@ -2020,7 +2046,9 @@ SPEC CHECKSUMS: FBLazyVector: 7b438dceb9f904bd85ca3c31d64cce32a035472b fmt: 4c2741a687cc09f0634a2e2c72a838b99f1ff120 glog: 69ef571f3de08433d766d614c73a9838a06bf7eb + Google-Mobile-Ads-SDK: 204b517c9765169144cf39763c7f5d23c57a9db0 GoogleSignIn: d4281ab6cf21542b1cfaff85c191f230b399d2db + GoogleUserMessagingPlatform: 6b4f48a370e77ce121d034c908cc6ee4fdafaf13 GTMAppAuth: f69bd07d68cd3b766125f7e072c45d7340dea0de GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 hermes-engine: 8d2103d6c0176779aea4e25df6bb1410f9946680 @@ -2057,7 +2085,6 @@ SPEC CHECKSUMS: react-native-color-thief: c66137a6364a626fd9834f143bdf00c5a8b05fe7 react-native-config: 8f7283449bbb048902f4e764affbbf24504454af react-native-document-picker: 7343222102ece8aec51390717f47ad7119c7921f - react-native-encrypted-storage: db300a3f2f0aba1e818417c1c0a6be549038deb7 react-native-get-random-values: 21325b2244dfa6b58878f51f9aa42821e7ba3d06 react-native-image-picker: 2fbbafdae7a7c6db9d25df2f2b1db4442d2ca2ad react-native-safe-area-context: 851c62c48dce80ccaa5637b6aa5991a1bc36eca9 @@ -2093,8 +2120,9 @@ SPEC CHECKSUMS: RNCClipboard: 5e503962f0719ace8f7fdfe9c60282b526305c85 RNFS: 4ac0f0ea233904cb798630b3c077808c06931688 RNGestureHandler: 3b6fa2bfa341c413d3d08444b838515b58e48ee7 + RNGoogleMobileAds: b8bedba3b7accb437585f07413a4a530aac96cd8 RNGoogleSignin: 08dc4ba7eac2096c7fecfe109f0950fa4683c803 - RNIap: 76bb8783a92a6e6bd2ad7a1e91a8b2e75930db36 + RNIap: f3ca6e7597afccb2c1631de97d88f2e33b10dafd RNReanimated: b0912c8ba12f6c03db07c851c4de71c3eed6c83c RNScreens: 19719a9c326e925498ac3b2d35c4e50fe87afc06 RNShare: e655d9afb56a76d46022eb2e33f9d3240bdbbe45 diff --git a/ios/croma.xcodeproj/project.pbxproj b/ios/croma.xcodeproj/project.pbxproj index 9d37148d..007a1488 100644 --- a/ios/croma.xcodeproj/project.pbxproj +++ b/ios/croma.xcodeproj/project.pbxproj @@ -188,6 +188,7 @@ 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 00EEFC60759A1932668264C0 /* [CP] Embed Pods Frameworks */, E235C05ADACE081382539298 /* [CP] Copy Pods Resources */, + 9D103ED1C44B2AFD62050736 /* [CP-User] [RNGoogleMobileAds] Configuration */, ); buildRules = ( ); @@ -288,6 +289,19 @@ shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-croma/Pods-croma-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; + 9D103ED1C44B2AFD62050736 /* [CP-User] [RNGoogleMobileAds] Configuration */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "$(BUILT_PRODUCTS_DIR)/$(INFOPLIST_PATH)", + ); + name = "[CP-User] [RNGoogleMobileAds] Configuration"; + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "#!/usr/bin/env bash\n#\n# Copyright (c) 2016-present Invertase Limited & Contributors\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this library except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##########################################################################\n##########################################################################\n#\n# NOTE THAT IF YOU CHANGE THIS FILE YOU MUST RUN pod install AFTERWARDS\n#\n# This file is installed as an Xcode build script in the project file\n# by cocoapods, and you will not see your changes until you pod install\n#\n##########################################################################\n##########################################################################\n\nset -e\n\n_MAX_LOOKUPS=2;\n_SEARCH_RESULT=''\n_RN_ROOT_EXISTS=''\n_CURRENT_LOOKUPS=1\n_PROJECT_ABBREVIATION=\"RNGoogleMobileAds\"\n_JSON_ROOT=\"'react-native-google-mobile-ads'\"\n_JSON_FILE_NAME='app.json'\n_JSON_OUTPUT_BASE64='e30=' # { }\n_CURRENT_SEARCH_DIR=${PROJECT_DIR}\n_PLIST_BUDDY=/usr/libexec/PlistBuddy\n_TARGET_PLIST=\"${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\"\n_DSYM_PLIST=\"${DWARF_DSYM_FOLDER_PATH}/${DWARF_DSYM_FILE_NAME}/Contents/Info.plist\"\n_PACKAGE_JSON_NAME='package.json'\n\n# plist arrays\n_PLIST_ENTRY_KEYS=()\n_PLIST_ENTRY_TYPES=()\n_PLIST_ENTRY_VALUES=()\n\nfunction setPlistValue {\n echo \"info: setting plist entry '$1' of type '$2' in file '$4'\"\n ${_PLIST_BUDDY} -c \"Add :$1 $2 '$3'\" $4 || echo \"info: '$1' already exists\"\n}\n\nfunction getJsonKeyValue () {\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n ruby -KU -e \"require 'rubygems';require 'json'; output=JSON.parse('$1'); puts output[$_JSON_ROOT]['$2']\"\n else\n echo \"\"\n fi;\n}\n\nfunction jsonBoolToYesNo () {\n if [[ $1 == \"false\" ]]; then\n echo \"NO\"\n elif [[ $1 == \"true\" ]]; then\n echo \"YES\"\n else echo \"NO\"\n fi\n}\n\necho \"info: -> ${_PROJECT_ABBREVIATION} build script started\"\necho \"info: 1) Locating ${_JSON_FILE_NAME} file:\"\n\nif [[ -z ${_CURRENT_SEARCH_DIR} ]]; then\n _CURRENT_SEARCH_DIR=$(pwd)\nfi;\n\nwhile true; do\n _CURRENT_SEARCH_DIR=$(dirname \"$_CURRENT_SEARCH_DIR\")\n if [[ \"$_CURRENT_SEARCH_DIR\" == \"/\" ]] || [[ ${_CURRENT_LOOKUPS} -gt ${_MAX_LOOKUPS} ]]; then break; fi;\n echo \"info: ($_CURRENT_LOOKUPS of $_MAX_LOOKUPS) Searching in '$_CURRENT_SEARCH_DIR' for a ${_JSON_FILE_NAME} file.\"\n _SEARCH_RESULT=$(find \"$_CURRENT_SEARCH_DIR\" -maxdepth 2 -name ${_JSON_FILE_NAME} -print | /usr/bin/head -n 1)\n if [[ ${_SEARCH_RESULT} ]]; then\n echo \"info: ${_JSON_FILE_NAME} found at $_SEARCH_RESULT\"\n break;\n fi;\n _CURRENT_LOOKUPS=$((_CURRENT_LOOKUPS+1))\ndone\n\nif [[ ${_SEARCH_RESULT} ]]; then\n _JSON_OUTPUT_RAW=$(cat \"${_SEARCH_RESULT}\")\n _RN_ROOT_EXISTS=$(ruby -KU -e \"require 'rubygems';require 'json'; output=JSON.parse('$_JSON_OUTPUT_RAW'); puts output[$_JSON_ROOT]\" || echo '')\n\n if [[ ${_RN_ROOT_EXISTS} ]]; then\n if ! python3 --version >/dev/null 2>&1; then echo \"python3 not found, app.json file processing error.\" && exit 1; fi\n _JSON_OUTPUT_BASE64=$(python3 -c 'import json,sys,base64;print(base64.b64encode(bytes(json.dumps(json.loads(open('\"'${_SEARCH_RESULT}'\"', '\"'rb'\"').read())['${_JSON_ROOT}']), '\"'utf-8'\"')).decode())' || echo \"e30=\")\n fi\n\n _PLIST_ENTRY_KEYS+=(\"google_mobile_ads_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n\n # config.delay_app_measurement_init\n _DELAY_APP_MEASUREMENT=$(getJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"delay_app_measurement_init\")\n if [[ $_DELAY_APP_MEASUREMENT == \"true\" ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADDelayAppMeasurementInit\")\n _PLIST_ENTRY_TYPES+=(\"bool\")\n _PLIST_ENTRY_VALUES+=(\"YES\")\n fi\n\n # config.ios_app_id\n _IOS_APP_ID=$(getJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"ios_app_id\")\n if [[ $_IOS_APP_ID ]]; then\n _PLIST_ENTRY_KEYS+=(\"GADApplicationIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_IOS_APP_ID\")\n fi\n\n # config.sk_ad_network_items\n _SK_AD_NETWORK_ITEMS=$(getJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"sk_ad_network_items\")\n if [[ $_SK_AD_NETWORK_ITEMS ]]; then\n _PLIST_ENTRY_KEYS+=(\"SKAdNetworkItems\")\n _PLIST_ENTRY_TYPES+=(\"array\")\n _PLIST_ENTRY_VALUES+=(\"\")\n\n oldifs=$IFS\n IFS=\"\n\"\n array=($(echo \"$_SK_AD_NETWORK_ITEMS\"))\n IFS=$oldifs\n for i in \"${!array[@]}\"; do\n _PLIST_ENTRY_KEYS+=(\"SKAdNetworkItems:$i:SKAdNetworkIdentifier\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"${array[i]}\") \n done\n fi\n\n # config.user_tracking_usage_description\n _USER_TRACKING_USAGE_DESCRIPTION=$(getJsonKeyValue \"$_JSON_OUTPUT_RAW\" \"user_tracking_usage_description\")\n if [[ $_USER_TRACKING_USAGE_DESCRIPTION ]]; then\n _PLIST_ENTRY_KEYS+=(\"NSUserTrackingUsageDescription\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_USER_TRACKING_USAGE_DESCRIPTION\")\n fi\nelse\n _PLIST_ENTRY_KEYS+=(\"google_mobile_ads_json_raw\")\n _PLIST_ENTRY_TYPES+=(\"string\")\n _PLIST_ENTRY_VALUES+=(\"$_JSON_OUTPUT_BASE64\")\n echo \"warning: A ${_JSON_FILE_NAME} file was not found, whilst this file is optional it is recommended to include it to auto-configure services.\"\nfi;\n\necho \"info: 2) Injecting Info.plist entries: \"\n\n# Log out the keys we're adding\nfor i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n echo \" -> $i) ${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\"\ndone\n\nif ! [[ -f \"${_TARGET_PLIST}\" ]]; then\n echo \"error: unable to locate Info.plist to set properties. App will crash without GADApplicationIdentifier set.\"\n exit 1\nfi\n\nif ! [[ $_IOS_APP_ID ]]; then\n echo \"warning: ios_app_id key not found in react-native-google-mobile-ads key in app.json. App will crash without it.\"\n echo \" You can safely ignore this warning if you are using our Expo config plugin.\"\n exit 0\nfi\n\nfor plist in \"${_TARGET_PLIST}\" \"${_DSYM_PLIST}\" ; do\n if [[ -f \"${plist}\" ]]; then\n\n # paths with spaces break the call to setPlistValue. temporarily modify\n # the shell internal field separator variable (IFS), which normally\n # includes spaces, to consist only of line breaks\n oldifs=$IFS\n IFS=\"\n\"\n\n for i in \"${!_PLIST_ENTRY_KEYS[@]}\"; do\n setPlistValue \"${_PLIST_ENTRY_KEYS[$i]}\" \"${_PLIST_ENTRY_TYPES[$i]}\" \"${_PLIST_ENTRY_VALUES[$i]}\" \"${plist}\"\n done\n\n # restore the original internal field separator value\n IFS=$oldifs\n else\n echo \"warning: A Info.plist build output file was not found (${plist})\"\n fi\ndone\n\necho \"info: <- ${_PROJECT_ABBREVIATION} build script finished\"\n"; + }; A55EABD7B0C7F3A422A6CC61 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -473,7 +487,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 61; + CURRENT_PROJECT_VERSION = 62; DEVELOPMENT_TEAM = FH9K879287; ENABLE_BITCODE = NO; INFOPLIST_FILE = croma/Info.plist; @@ -481,7 +495,7 @@ "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.2; + MARKETING_VERSION = 3.3; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", @@ -501,14 +515,14 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CLANG_ENABLE_MODULES = YES; - CURRENT_PROJECT_VERSION = 61; + CURRENT_PROJECT_VERSION = 62; DEVELOPMENT_TEAM = FH9K879287; INFOPLIST_FILE = croma/Info.plist; LD_RUNPATH_SEARCH_PATHS = ( "$(inherited)", "@executable_path/Frameworks", ); - MARKETING_VERSION = 3.2; + MARKETING_VERSION = 3.3; OTHER_LDFLAGS = ( "$(inherited)", "-ObjC", diff --git a/ios/croma/PrivacyInfo.xcprivacy b/ios/croma/PrivacyInfo.xcprivacy index bad32761..0f3880a4 100644 --- a/ios/croma/PrivacyInfo.xcprivacy +++ b/ios/croma/PrivacyInfo.xcprivacy @@ -14,18 +14,26 @@ NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPICategorySystemBootTime NSPrivacyAccessedAPITypeReasons - C617.1 + 35F9.1 NSPrivacyAccessedAPIType - NSPrivacyAccessedAPICategorySystemBootTime + NSPrivacyAccessedAPICategoryDiskSpace NSPrivacyAccessedAPITypeReasons - 35F9.1 + E174.1 + + + + NSPrivacyAccessedAPIType + NSPrivacyAccessedAPICategoryFileTimestamp + NSPrivacyAccessedAPITypeReasons + + C617.1 diff --git a/libs/EncryptedStoreage.js b/libs/EncryptedStorage.js similarity index 61% rename from libs/EncryptedStoreage.js rename to libs/EncryptedStorage.js index 70771f40..97df8738 100644 --- a/libs/EncryptedStoreage.js +++ b/libs/EncryptedStorage.js @@ -1,7 +1,7 @@ -import EncryptedStorage from 'react-native-encrypted-storage'; +import AsyncStorage from '@react-native-async-storage/async-storage'; export async function storeUserSession(fullName, email, token, avatar_url) { - return EncryptedStorage.setItem( + return AsyncStorage.setItem( 'user_session', JSON.stringify({ token, @@ -13,12 +13,12 @@ export async function storeUserSession(fullName, email, token, avatar_url) { } export async function retrieveUserSession() { - const session = await EncryptedStorage.getItem('user_session'); + const session = await AsyncStorage.getItem('user_session'); if (session !== undefined) { return JSON.parse(session); } } export async function removeUserSession() { - return EncryptedStorage.removeItem('user_session'); + return AsyncStorage.removeItem('user_session'); } diff --git a/network/axios.client.js b/network/axios.client.js index c5237467..5773bb26 100644 --- a/network/axios.client.js +++ b/network/axios.client.js @@ -1,5 +1,5 @@ import axios from 'axios'; -import { retrieveUserSession } from '../libs/EncryptedStoreage'; +import { retrieveUserSession } from '../libs/EncryptedStorage'; import Storage from '../libs/Storage'; import { notifyMessage, sendClientError } from '../libs/Helpers'; @@ -15,7 +15,7 @@ axiosInstance.interceptors.request.use(async (config) => { const userAuthInfo = await retrieveUserSession(); const userDeviceId = await Storage.getUserDeviceId(); - if (!userDeviceId?.trim() || userAuthInfo?.email) { + if (!(userDeviceId?.trim() || userAuthInfo?.email)) { throw new Error('Device ID or auth is not defined, null, or empty.'); } @@ -29,30 +29,44 @@ axiosInstance.interceptors.request.use(async (config) => { }); axiosInstance.interceptors.response.use( - (response) => { - return response; - }, + (response) => response, (error) => { - // If the response status is not in the 2xx range - if (error.response) { - const status = error.response.status; - const errorMessage = error.response.data?.message || 'An error occurred'; - - // Handle different status codes here - if (status >= 400 && status < 500) { - notifyMessage(`Client error: ${errorMessage}`); - } else if (status >= 500) { - notifyMessage('Server error, please try again later.'); + let errorMessage = 'An unexpected error occurred'; + + try { + if (error.response) { + const { status, data } = error.response; + + // Handle different status codes + if (status >= 400 && status < 500) { + errorMessage = data?.message || 'A client error occurred'; + notifyMessage(errorMessage); // Single argument + } else if (status >= 500) { + notifyMessage('Server error, please try again later.'); + } + } else if (error.request) { + notifyMessage('No response received from the server.'); + } else { + // Fixed error message handling + sendClientError('error_setting_up_request', error.toString()); + notifyMessage(`Error setting up the request: ${error.toString() || 'Unknown error'}`); // Properly formatted string } - } else if (error.request) { - notifyMessage('No response received from the server.'); - } else { - sendClientError('error_setting_up_request', error.toString()); - notifyMessage('Error setting up the request:', error.message); + + // Log the full error for debugging + console.warn('Axios Error:', { + message: errorMessage, + originalError: error, + response: error.response, + request: error.request, + }); + + } catch (handlingError) { + // Fallback error handling + console.error('Error while handling axios error:', handlingError); + sendClientError('error_handling_axios_error','An unexpected error occurred' + handlingError); } - // Optionally, you can also return a custom error message or rethrow the error - return Promise.reject(errorMessage || 'An unexpected error occurred'); + return Promise.reject(error); } ); diff --git a/package.json b/package.json index 8af6360d..7c798443 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,6 @@ "react-native-config": "^1.5.3", "react-native-document-picker": "^9.3.1", "react-native-draggable-flatlist": "^4.0.1", - "react-native-encrypted-storage": "^4.0.3", "react-native-exception-handler": "^2.10.10", "react-native-flash-message": "^0.4.2", "react-native-fs": "^2.20.0", diff --git a/screens/ChatSessionScreen.js b/screens/ChatSessionScreen.js index 268df4be..ecc9df0d 100644 --- a/screens/ChatSessionScreen.js +++ b/screens/ChatSessionScreen.js @@ -8,6 +8,7 @@ import { ActivityIndicator, Text, ImageBackground, + Platform, } from 'react-native'; import Colors from '../constants/Styles'; import React, { useState, useEffect, useRef } from 'react'; @@ -162,7 +163,7 @@ const ChatSessionScreen = (props) => { )} - { messages.length < 2 && } + { messages.length < 2 && Platform.OS == 'android' && } diff --git a/screens/MyPalettesScreen.js b/screens/MyPalettesScreen.js index 749877cf..f14266ca 100644 --- a/screens/MyPalettesScreen.js +++ b/screens/MyPalettesScreen.js @@ -5,7 +5,8 @@ import { ScrollView, StyleSheet, View, - Text + Text, + Platform } from 'react-native'; import { PaletteCard } from '../components/PaletteCard'; @@ -60,7 +61,7 @@ const MyPalettesScreen = function ({ navigation, route }) { })} - + {Platform.OS=='android' && } ); } diff --git a/screens/SavePaletteScreen.js b/screens/SavePaletteScreen.js index 30eaf820..92770ce5 100644 --- a/screens/SavePaletteScreen.js +++ b/screens/SavePaletteScreen.js @@ -1,6 +1,6 @@ /* eslint-disable react/prop-types */ import React, { useState, useEffect, useRef } from 'react'; -import { Text, View, StyleSheet, TextInput, ScrollView } from 'react-native'; +import { Text, View, StyleSheet, TextInput, ScrollView, Platform } from 'react-native'; import { PalettePreviewCard } from '../components/PalettePreviewCard'; import Colors from '../constants/Styles'; import CromaButton from '../components/CromaButton'; @@ -103,7 +103,7 @@ export default function SavePaletteScreen({ navigation, route }) { )} - + {Platform.OS =='android' && } ); } diff --git a/screens/UserProfileScreen.js b/screens/UserProfileScreen.js index 8e5a2e24..c8ced28c 100644 --- a/screens/UserProfileScreen.js +++ b/screens/UserProfileScreen.js @@ -5,7 +5,7 @@ import CromaButton from '../components/CromaButton'; import { useTranslation } from 'react-i18next'; import PropTypes from 'prop-types'; import useUserData from '../hooks/useUserData'; -import { removeUserSession } from '../libs/EncryptedStoreage'; +import { removeUserSession } from '../libs/EncryptedStorage'; import { GoogleSignin } from '@react-native-google-signin/google-signin'; import { ROUTE_NAMES } from '../libs/constants'; import useApplicationStore from '../hooks/useApplicationStore'; @@ -17,7 +17,7 @@ import { AdsConsent, AdsConsentStatus } from 'react-native-google-mobile-ads'; function UserProfile(props) { const applicationState = useApplicationStore(); - const { loadInitPaletteFromStore } = applicationState; + const { reloadPalettes } = applicationState; const { userData, loadUserData } = useUserData(); const { openAuthOverlay } = useAuth(); const [consentInfo, setConsentInfo] = useState(false); @@ -61,14 +61,14 @@ function UserProfile(props) { await logout(); await removeUserSession(); await loadUserData(); - loadInitPaletteFromStore(); + reloadPalettes(); props.navigation.navigate(ROUTE_NAMES.HOME); try { await GoogleSignin.revokeAccess(); } catch (error) { console.error(error); } - }, [loadInitPaletteFromStore, loadUserData, props.navigation]); + }, [reloadPalettes, loadUserData, props.navigation]); return ( diff --git a/yarn.lock b/yarn.lock index f6d043fb..c9633e30 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3534,7 +3534,6 @@ __metadata: react-native-config: ^1.5.3 react-native-document-picker: ^9.3.1 react-native-draggable-flatlist: ^4.0.1 - react-native-encrypted-storage: ^4.0.3 react-native-exception-handler: ^2.10.10 react-native-flash-message: ^0.4.2 react-native-fs: ^2.20.0 @@ -10237,16 +10236,6 @@ __metadata: languageName: node linkType: hard -"react-native-encrypted-storage@npm:^4.0.3": - version: 4.0.3 - resolution: "react-native-encrypted-storage@npm:4.0.3" - peerDependencies: - react: "*" - react-native: "*" - checksum: 9d2999c58559f1e4f66d1baf2c3edeff96cf42027900850d94c6bbea24ac9715047ce69bf6e8a73b68aff4508cf35dd88ac494ad5905933286ef3b75cd123e30 - languageName: node - linkType: hard - "react-native-exception-handler@npm:^2.10.10": version: 2.10.10 resolution: "react-native-exception-handler@npm:2.10.10"