diff --git a/babel.config.js b/babel.config.js index 8408012a5..8029e1c0f 100644 --- a/babel.config.js +++ b/babel.config.js @@ -20,16 +20,14 @@ const baseConfig = { '@helium/crypto': './node_modules/@helium/crypto-react-native', '@assets': './src/assets', '@components': './src/components', - '@constants': './src/constants', '@hooks': './src/hooks', - '@theme': './src/theme', '@utils': './src/utils', - '@storage': './src/storage', + '@config': './src/config', '@types': './src/types', '@features': './src/features', - '@services': './src/services', + '@services': './src/app/services', '@store': './src/store', - '@/solana': './src/solana', + '@app': './src/app', }, extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'], root: ['./src'], diff --git a/index.js b/index.js index 172ef565a..0807a1438 100644 --- a/index.js +++ b/index.js @@ -8,12 +8,12 @@ import 'react-native-url-polyfill/auto' import { Provider as ReduxProvider } from 'react-redux' import { PersistGate } from 'redux-persist/integration/react' import { name as appName } from './app.json' -import App from './src/App' +import App from './src/app/App' import { GlobalError } from './src/components/GlobalError' -import AccountStorageProvider from './src/storage/AccountStorageProvider' -import AppStorageProvider from './src/storage/AppStorageProvider' -import LanguageProvider from './src/storage/LanguageProvider' -import NotificationStorageProvider from './src/storage/NotificationStorageProvider' +import AccountStorageProvider from './src/config/storage/AccountStorageProvider' +import AppStorageProvider from './src/config/storage/AppStorageProvider' +import LanguageProvider from './src/config/storage/LanguageProvider' +import NotificationStorageProvider from './src/config/storage/NotificationStorageProvider' import { persistor } from './src/store/persistence' import store from './src/store/store' import './src/utils/i18n' diff --git a/ios/Podfile b/ios/Podfile index 0d64adb7d..6349f49dd 100644 --- a/ios/Podfile +++ b/ios/Podfile @@ -56,8 +56,11 @@ target 'HeliumWallet' do permissions_path = '../node_modules/react-native-permissions/ios' setup_permissions(['BluetoothPeripheral']) + $RNMapboxMapsImpl = 'mapbox' + $RNMapboxMapsVersion = '= 11.4.0' + post_install do |installer| - $RNMBGL.post_install(installer) + $RNMapboxMaps.post_install(installer) # https://github.com/facebook/react-native/blob/main/packages/react-native/scripts/react_native_pods.rb#L197-L202 react_native_post_install( diff --git a/ios/Podfile.lock b/ios/Podfile.lock index cbfaf840e..4a38b3db0 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -22,6 +22,8 @@ PODS: - EXImageLoader (4.7.0): - ExpoModulesCore - React-Core + - EXLocation (17.0.1): + - ExpoModulesCore - Expo (51.0.24): - ExpoModulesCore - ExpoAsset (10.0.10): @@ -118,13 +120,13 @@ PODS: - ReactCommon/turbomodule/bridging - ReactCommon/turbomodule/core - Yoga - - maplibre-react-native (9.1.0): - - maplibre-react-native/DynamicLibrary (= 9.1.0) - - React - - React-Core - - maplibre-react-native/DynamicLibrary (9.1.0): - - React - - React-Core + - MapboxCommon (24.4.0) + - MapboxCoreMaps (11.4.0): + - MapboxCommon (~> 24.4) + - MapboxMaps (11.4.0): + - MapboxCommon (= 24.4.0) + - MapboxCoreMaps (= 11.4.0) + - Turf (= 2.8.0) - MultiplatformBleAdapter (0.1.9) - OneSignalXCFramework (5.2.2): - OneSignalXCFramework/OneSignalComplete (= 5.2.2) @@ -1109,6 +1111,8 @@ PODS: - Charts (= 4.1.0) - React - SwiftyJSON (= 5.0) + - react-native-compass-heading (1.5.0): + - React-Core - react-native-config (1.4.6): - react-native-config/App (= 1.4.6) - react-native-config/App (1.4.6): @@ -1421,6 +1425,27 @@ PODS: - React-Core - RNCClipboard (1.5.1): - React-Core + - RNCMaskedView (0.3.2): + - DoubleConversion + - glog + - hermes-engine + - RCT-Folly (= 2024.01.01.00) + - RCTRequired + - RCTTypeSafety + - React-Codegen + - React-Core + - React-debug + - React-Fabric + - React-featureflags + - React-graphics + - React-ImageManager + - React-NativeModulesApple + - React-RCTFabric + - React-rendererdebug + - React-utils + - ReactCommon/turbomodule/bridging + - ReactCommon/turbomodule/core + - Yoga - RNDeviceInfo (8.7.1): - React-Core - RNGestureHandler (2.18.1): @@ -1448,6 +1473,17 @@ PODS: - React - RNLocalize (2.2.3): - React-Core + - rnmapbox-maps (10.1.31): + - MapboxMaps (= 11.4.0) + - React + - React-Core + - rnmapbox-maps/DynamicLibrary (= 10.1.31) + - Turf + - rnmapbox-maps/DynamicLibrary (10.1.31): + - MapboxMaps (= 11.4.0) + - React + - React-Core + - Turf - RNOS (1.2.6): - React - RNPermissions (3.9.2): @@ -1509,6 +1545,13 @@ PODS: - TcpSockets (3.3.2): - React - Toast (4.0.0) + - Turf (2.8.0) + - VisionCamera (4.5.3): + - VisionCamera/Core (= 4.5.3) + - VisionCamera/React (= 4.5.3) + - VisionCamera/Core (4.5.3) + - VisionCamera/React (4.5.3): + - React-Core - Yoga (0.0.0) - ZXingObjC/Core (3.6.9) - ZXingObjC/OneD (3.6.9): @@ -1524,6 +1567,7 @@ DEPENDENCIES: - EXBarCodeScanner (from `../node_modules/expo-barcode-scanner/ios`) - EXConstants (from `../node_modules/expo-constants/ios`) - EXImageLoader (from `../node_modules/expo-image-loader/ios`) + - EXLocation (from `../node_modules/expo-location/ios`) - Expo (from `../node_modules/expo`) - ExpoAsset (from `../node_modules/expo-asset/ios`) - ExpoCamera (from `../node_modules/expo-camera/ios`) @@ -1542,7 +1586,6 @@ DEPENDENCIES: - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) - lottie-ios (from `../node_modules/lottie-ios`) - lottie-react-native (from `../node_modules/lottie-react-native`) - - "maplibre-react-native (from `../node_modules/@maplibre/maplibre-react-native`)" - OneSignalXCFramework (< 6.0, >= 5.0) - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) - RCT-Folly/Fabric (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) @@ -1573,6 +1616,7 @@ DEPENDENCIES: - react-native-ble-plx (from `../node_modules/react-native-ble-plx`) - "react-native-blur (from `../node_modules/@react-native-community/blur`)" - react-native-charts-wrapper (from `../node_modules/react-native-charts-wrapper`) + - react-native-compass-heading (from `../node_modules/react-native-compass-heading`) - react-native-config (from `../node_modules/react-native-config`) - react-native-config/Extension (from `../node_modules/react-native-config`) - react-native-get-random-values (from `../node_modules/react-native-get-random-values`) @@ -1615,10 +1659,12 @@ DEPENDENCIES: - "RNCAsyncStorage (from `../node_modules/@react-native-async-storage/async-storage`)" - "RNCCheckbox (from `../node_modules/@react-native-community/checkbox`)" - "RNCClipboard (from `../node_modules/@react-native-community/clipboard`)" + - "RNCMaskedView (from `../node_modules/@react-native-masked-view/masked-view`)" - RNDeviceInfo (from `../node_modules/react-native-device-info`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNICloudStore (from `../node_modules/react-native-icloudstore`) - RNLocalize (from `../node_modules/react-native-localize`) + - "rnmapbox-maps (from `../node_modules/@rnmapbox/maps`)" - RNOS (from `../node_modules/react-native-os`) - RNPermissions (from `../node_modules/react-native-permissions`) - RNReactNativeSharedGroupPreferences (from `../node_modules/react-native-shared-group-preferences`) @@ -1628,6 +1674,7 @@ DEPENDENCIES: - RNSVG (from `../node_modules/react-native-svg`) - RNTestFlight (from `../node_modules/react-native-test-flight`) - TcpSockets (from `../node_modules/react-native-tcp`) + - VisionCamera (from `../node_modules/react-native-vision-camera`) - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) SPEC REPOS: @@ -1635,12 +1682,16 @@ SPEC REPOS: - BCrypt - BEMCheckBox - Charts + - MapboxCommon + - MapboxCoreMaps + - MapboxMaps - MultiplatformBleAdapter - OneSignalXCFramework - SocketRocket - SwiftAlgorithms - SwiftyJSON - Toast + - Turf - ZXingObjC EXTERNAL SOURCES: @@ -1658,6 +1709,8 @@ EXTERNAL SOURCES: :path: "../node_modules/expo-constants/ios" EXImageLoader: :path: "../node_modules/expo-image-loader/ios" + EXLocation: + :path: "../node_modules/expo-location/ios" Expo: :path: "../node_modules/expo" ExpoAsset: @@ -1695,8 +1748,6 @@ EXTERNAL SOURCES: :path: "../node_modules/lottie-ios" lottie-react-native: :path: "../node_modules/lottie-react-native" - maplibre-react-native: - :path: "../node_modules/@maplibre/maplibre-react-native" RCT-Folly: :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" RCTDeprecation: @@ -1751,6 +1802,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/blur" react-native-charts-wrapper: :path: "../node_modules/react-native-charts-wrapper" + react-native-compass-heading: + :path: "../node_modules/react-native-compass-heading" react-native-config: :path: "../node_modules/react-native-config" react-native-get-random-values: @@ -1833,6 +1886,8 @@ EXTERNAL SOURCES: :path: "../node_modules/@react-native-community/checkbox" RNCClipboard: :path: "../node_modules/@react-native-community/clipboard" + RNCMaskedView: + :path: "../node_modules/@react-native-masked-view/masked-view" RNDeviceInfo: :path: "../node_modules/react-native-device-info" RNGestureHandler: @@ -1841,6 +1896,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-icloudstore" RNLocalize: :path: "../node_modules/react-native-localize" + rnmapbox-maps: + :path: "../node_modules/@rnmapbox/maps" RNOS: :path: "../node_modules/react-native-os" RNPermissions: @@ -1859,6 +1916,8 @@ EXTERNAL SOURCES: :path: "../node_modules/react-native-test-flight" TcpSockets: :path: "../node_modules/react-native-tcp" + VisionCamera: + :path: "../node_modules/react-native-vision-camera" Yoga: :path: "../node_modules/react-native/ReactCommon/yoga" @@ -1873,6 +1932,7 @@ SPEC CHECKSUMS: EXBarCodeScanner: e2dd9b42c1b522a2adc9202b1dfbc64cb34456d1 EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59 EXImageLoader: ab589d67d6c5f2c33572afea9917304418566334 + EXLocation: 43e9b582ca63a23c6f0a18d8cbe2145b3a388b55 Expo: 798848eae1daf13363d69790986146b08d0cf92f ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875 ExpoCamera: a5d000b22cd7dfd2c5904ed960e549de42c96da0 @@ -1891,7 +1951,9 @@ SPEC CHECKSUMS: hermes-engine: 8c1577f3fdb849cbe7729c2e7b5abc4b845e88f8 lottie-ios: e047b1d2e6239b787cc5e9755b988869cf190494 lottie-react-native: f851c0e235f171d99083c803f728f644be1dcf65 - maplibre-react-native: 3a0d9beca427ff9000d75e0974c366ecd3c5375e + MapboxCommon: 6acbd8ff41d66abf498e1558b0739f25c562945a + MapboxCoreMaps: f306bb1b10ebe995a2247b40e99322ab7f9b8071 + MapboxMaps: 82044383ae19ec124ff444ec4b5d3ce82cb36ba5 MultiplatformBleAdapter: 5a6a897b006764392f9cef785e4360f54fb9477d OneSignalXCFramework: f06edd9b146c7ac5935136a117ce2a5fdd6420f6 RCT-Folly: 02617c592a293bd6d418e0a88ff4ee1f88329b47 @@ -1921,6 +1983,7 @@ SPEC CHECKSUMS: react-native-ble-plx: f10240444452dfb2d2a13a0e4f58d7783e92d76e react-native-blur: 50c9feabacbc5f49b61337ebc32192c6be7ec3c3 react-native-charts-wrapper: 4268219d67a6fd7e94453d77d31b38ef1cd23860 + react-native-compass-heading: 1b4403d1c99dfd8311073ca8fc52bfc8e365cfac react-native-config: 7cd105e71d903104e8919261480858940a6b9c0e react-native-get-random-values: a6ea6a8a65dc93e96e24a11105b1a9c8cfe1d72a react-native-mail: 8fdcd3aef007c33a6877a18eb4cf7447a1d4ce4a @@ -1962,10 +2025,12 @@ SPEC CHECKSUMS: RNCAsyncStorage: b90b71f45b8b97be43bc4284e71a6af48ac9f547 RNCCheckbox: a3ca9978cb0846b981d28da4e9914bd437403d77 RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495 + RNCMaskedView: da52ec927af4b4c3f3f6b5b5e816a69be62fe642 RNDeviceInfo: aad3c663b25752a52bf8fce93f2354001dd185aa RNGestureHandler: efed690b8493a00b99654043daeb1335276ac4a2 RNICloudStore: bc6e225811637c09bd1eb055d6cd7448e61cd451 RNLocalize: a64514b46a01375fdfae9349036b4dc7130333b5 + rnmapbox-maps: 961b998761de9672c448aa17144b987410890992 RNOS: 6f2f9a70895bbbfbdad7196abd952e7b01d45027 RNPermissions: 2af759cf053542b2b4b3c4cf9f43874796106f2c RNReactNativeSharedGroupPreferences: 29092869fc2e40d5baca5e15d82fa5c24a668977 @@ -1979,9 +2044,11 @@ SPEC CHECKSUMS: SwiftyJSON: 36413e04c44ee145039d332b4f4e2d3e8d6c4db7 TcpSockets: 14306fb79f9750ea7d2ddd02d8bed182abb01797 Toast: 91b396c56ee72a5790816f40d3a94dd357abc196 + Turf: aa2ede4298009639d10db36aba1a7ebaad072a5e + VisionCamera: cb84d0d8485b3e67c91b62931d3aa88f49747c92 Yoga: 950bbfd7e6f04790fdb51149ed51df41f329fcc8 ZXingObjC: 8898711ab495761b2dbbdec76d90164a6d7e14c5 -PODFILE CHECKSUM: d44dfed27ca86fe0b1eb67aab0856b7cc9e24ff7 +PODFILE CHECKSUM: af8e0f0904c0f9cc43a95eef4e1feb504870ee6e -COCOAPODS: 1.15.2 +COCOAPODS: 1.16.1 diff --git a/package.json b/package.json index b3ee602cf..14848b8f4 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,8 @@ "bump-patch": "npx react-native bump-version --skip-semver-for android --skip-code-for all --type patch", "bump-minor": "npx react-native bump-version --skip-semver-for android --skip-code-for all --type minor", "bump-major": "npx react-native bump-version --skip-semver-for android --skip-code-for all --type major", + "gen-ims-api": "graphql-codegen --config src/store/apis/ims/dashboard/codegen.yml", + "gen-ims-payments-api": "graphql-codegen --config src/store/apis/ims/payments/codegen.yml", "prettier": "prettier --write *.ts*", "gen-types:all": "yarn gen-types", "prepare": "husky install" @@ -29,10 +31,14 @@ "@babel/preset-typescript": "7.21.0", "@bonfida/spl-name-service": "^1.1.1", "@coral-xyz/anchor": "^0.28.0", - "@gorhom/bottom-sheet": "4.6.4", + "@gorhom/bottom-sheet": "5.0.4", "@gorhom/portal": "1.0.14", - "@helium/account-fetch-cache": "0.9.14", - "@helium/account-fetch-cache-hooks": "0.9.14", + "@graphql-codegen/cli": "^5.0.0", + "@graphql-codegen/typescript": "^4.0.1", + "@graphql-codegen/typescript-operations": "^4.0.1", + "@graphql-codegen/typescript-rtk-query": "^3.1.1", + "@helium/account-fetch-cache": "0.9.7", + "@helium/account-fetch-cache-hooks": "0.9.7", "@helium/address": "4.10.2", "@helium/circuit-breaker-sdk": "^0.9.14", "@helium/crypto-react-native": "4.8.0", @@ -66,12 +72,11 @@ "@ledgerhq/react-native-hid": "6.30.0", "@ledgerhq/react-native-hw-transport-ble": "6.29.5", "@ledgerhq/types-devices": "^6.22.4", - "@maplibre/maplibre-react-native": "^9.1.0", "@metaplex-foundation/js": "^0.19.5", "@metaplex-foundation/mpl-bubblegum": "0.6.0", "@metaplex-foundation/mpl-token-metadata": "2.10.0", "@ngraveio/bc-ur": "^1.1.13", - "@novalabsxyz/mobile-theme": "2.0.0-y.25", + "@novalabsxyz/mobile-theme": "2.0.0-y.26", "@onsol/tldparser": "^0.5.3", "@react-native-async-storage/async-storage": "1.18.1", "@react-native-community/blur": "4.3.0", @@ -80,12 +85,14 @@ "@react-native-community/hooks": "2.8.1", "@react-native-community/netinfo": "9.3.7", "@react-native-community/slider": "^4.5.2", + "@react-native-masked-view/masked-view": "^0.3.2", "@react-navigation/bottom-tabs": "6.4.0", "@react-navigation/material-top-tabs": "6.5.1", "@react-navigation/native": "6.0.11", "@react-navigation/native-stack": "6.7.0", "@react-navigation/stack": "6.2.2", "@reduxjs/toolkit": "1.9.1", + "@rnmapbox/maps": "^10.1.31", "@shopify/restyle": "2.4.2", "@solana/spl-account-compression": "0.1.4", "@solana/spl-memo": "0.2.3", @@ -134,9 +141,11 @@ "expo-haptics": "13.0.1", "expo-linking": "6.3.1", "expo-local-authentication": "14.0.1", + "expo-location": "^17.0.1", "expo-secure-store": "13.0.2", "expo-splash-screen": "0.27.5", "fuse.js": "6.6.2", + "geolib": "^3.3.4", "h3-js": "4.1.0", "https-browserify": "0.0.1", "i18next": "21.9.1", @@ -162,10 +171,13 @@ "react-native-appstate-hook": "1.0.6", "react-native-ble-plx": "2.0.3", "react-native-charts-wrapper": "0.5.10", + "react-native-compass-heading": "^1.5.0", + "react-native-confetti-cannon": "^1.5.2", "react-native-config": "1.4.6", "react-native-crypto": "2.2.0", "react-native-device-info": "8.7.1", "react-native-flash-message": "0.2.1", + "react-native-geocoding": "^0.5.0", "react-native-gesture-handler": "2.18.1", "react-native-get-random-values": "1.8.0", "react-native-icloudstore": "0.9.0", @@ -190,6 +202,7 @@ "react-native-share": "7.9.0", "react-native-shared-group-preferences": "1.1.24", "react-native-simple-toast": "1.1.4", + "react-native-skeleton-placeholder": "^5.2.4", "react-native-snap-carousel": "4.0.0-beta.6", "react-native-sodium": "^0.4.0", "react-native-svg": "13.4.0", @@ -200,6 +213,7 @@ "react-native-udp": "2.7.0", "react-native-url-polyfill": "^2.0.0", "react-native-video": "5.2.1", + "react-native-vision-camera": "^4.5.3", "react-native-webview": "13.10.5", "react-redux": "8.0.4", "readable-stream": "3.6.0", diff --git a/patches/@maplibre+maplibre-react-native+9.1.0.patch b/patches/@maplibre+maplibre-react-native+9.1.0.patch deleted file mode 100644 index 61d3b0349..000000000 --- a/patches/@maplibre+maplibre-react-native+9.1.0.patch +++ /dev/null @@ -1,316 +0,0 @@ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/generated/source/buildConfig/debug/com/mapbox/rctmgl/BuildConfig.java b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/generated/source/buildConfig/debug/com/mapbox/rctmgl/BuildConfig.java -new file mode 100644 -index 0000000..ea64509 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/generated/source/buildConfig/debug/com/mapbox/rctmgl/BuildConfig.java -@@ -0,0 +1,10 @@ -+/** -+ * Automatically generated file. DO NOT MODIFY -+ */ -+package com.mapbox.rctmgl; -+ -+public final class BuildConfig { -+ public static final boolean DEBUG = Boolean.parseBoolean("true"); -+ public static final String LIBRARY_PACKAGE_NAME = "com.mapbox.rctmgl"; -+ public static final String BUILD_TYPE = "debug"; -+} -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml -new file mode 100644 -index 0000000..eecf75d ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/AndroidManifest.xml -@@ -0,0 +1,10 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -\ No newline at end of file -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json -new file mode 100644 -index 0000000..67b2315 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aapt_friendly_merged_manifests/debug/aapt/output-metadata.json -@@ -0,0 +1,18 @@ -+{ -+ "version": 3, -+ "artifactType": { -+ "type": "AAPT_FRIENDLY_MERGED_MANIFESTS", -+ "kind": "Directory" -+ }, -+ "applicationId": "com.mapbox.rctmgl", -+ "variantName": "debug", -+ "elements": [ -+ { -+ "type": "SINGLE", -+ "filters": [], -+ "attributes": [], -+ "outputFile": "AndroidManifest.xml" -+ } -+ ], -+ "elementType": "File" -+} -\ No newline at end of file -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aar_metadata/debug/aar-metadata.properties b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aar_metadata/debug/aar-metadata.properties -new file mode 100644 -index 0000000..1211b1e ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/aar_metadata/debug/aar-metadata.properties -@@ -0,0 +1,6 @@ -+aarFormatVersion=1.0 -+aarMetadataVersion=1.0 -+minCompileSdk=1 -+minCompileSdkExtension=0 -+minAndroidGradlePluginVersion=1.0.0 -+coreLibraryDesugaringEnabled=false -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/annotation_processor_list/debug/annotationProcessors.json b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/annotation_processor_list/debug/annotationProcessors.json -new file mode 100644 -index 0000000..9e26dfe ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/annotation_processor_list/debug/annotationProcessors.json -@@ -0,0 +1 @@ -+{} -\ No newline at end of file -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compile_r_class_jar/debug/R.jar b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compile_r_class_jar/debug/R.jar -new file mode 100644 -index 0000000..190e46b -Binary files /dev/null and b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compile_r_class_jar/debug/R.jar differ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compile_symbol_list/debug/R.txt b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compile_symbol_list/debug/R.txt -new file mode 100644 -index 0000000..e6bb791 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compile_symbol_list/debug/R.txt -@@ -0,0 +1,8 @@ -+int drawable empty 0x0 -+int drawable empty_drawable 0x0 -+int drawable red_marker 0x0 -+int id annotation_img 0x0 -+int id annotation_layout 0x0 -+int id annotation_view_container 0x0 -+int layout annotation 0x0 -+int string app_name 0x0 -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable-xxhdpi-v4_red_marker.png.flat b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable-xxhdpi-v4_red_marker.png.flat -new file mode 100644 -index 0000000..5b0aa33 -Binary files /dev/null and b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable-xxhdpi-v4_red_marker.png.flat differ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable_empty.xml.flat b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable_empty.xml.flat -new file mode 100644 -index 0000000..8a833ad -Binary files /dev/null and b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable_empty.xml.flat differ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable_empty_drawable.png.flat b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable_empty_drawable.png.flat -new file mode 100644 -index 0000000..b53aa0c -Binary files /dev/null and b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/drawable_empty_drawable.png.flat differ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/layout_annotation.xml.flat b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/layout_annotation.xml.flat -new file mode 100644 -index 0000000..942d161 -Binary files /dev/null and b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/compiled_local_resources/debug/out/layout_annotation.xml.flat differ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties -new file mode 100644 -index 0000000..62539fb ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/compile-file-map.properties -@@ -0,0 +1,5 @@ -+#Mon Aug 05 14:40:58 PDT 2024 -+com.mapbox.rctmgl.maplibre_maplibre-react-native-main-6\:/drawable-xxhdpi/red_marker.png=/Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable-xxhdpi-v4/red_marker.png -+com.mapbox.rctmgl.maplibre_maplibre-react-native-main-6\:/drawable/empty.xml=/Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable/empty.xml -+com.mapbox.rctmgl.maplibre_maplibre-react-native-main-6\:/layout/annotation.xml=/Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/layout/annotation.xml -+com.mapbox.rctmgl.maplibre_maplibre-react-native-main-6\:/drawable/empty_drawable.png=/Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable/empty_drawable.png -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/merged.dir/values/values.xml b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/merged.dir/values/values.xml -new file mode 100644 -index 0000000..1b0b5d6 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/merged.dir/values/values.xml -@@ -0,0 +1,4 @@ -+ -+ -+ RCTMGL -+ -\ No newline at end of file -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/merger.xml b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/merger.xml -new file mode 100644 -index 0000000..5f8b0ab ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/incremental/debug/packageDebugResources/merger.xml -@@ -0,0 +1,2 @@ -+ -+RCTMGL -\ No newline at end of file -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/local_only_symbol_list/debug/R-def.txt b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/local_only_symbol_list/debug/R-def.txt -new file mode 100644 -index 0000000..826dbbd ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/local_only_symbol_list/debug/R-def.txt -@@ -0,0 +1,10 @@ -+R_DEF: Internal format may change without notice -+local -+drawable empty -+drawable empty_drawable -+drawable red_marker -+id annotation_img -+id annotation_layout -+id annotation_view_container -+layout annotation -+string app_name -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt -new file mode 100644 -index 0000000..9065ef8 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/manifest_merge_blame_file/debug/manifest-merger-blame-debug-report.txt -@@ -0,0 +1,14 @@ -+1 -+2 -+4 -+5 -+6 -+7 -+7-->/Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:2:5-67 -+7-->/Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:2:22-64 -+8 -+8-->/Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:3:5-78 -+8-->/Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:3:22-76 -+9 -+10 -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/merged_manifest/debug/AndroidManifest.xml b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/merged_manifest/debug/AndroidManifest.xml -new file mode 100644 -index 0000000..eecf75d ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/merged_manifest/debug/AndroidManifest.xml -@@ -0,0 +1,10 @@ -+ -+ -+ -+ -+ -+ -+ -+ -+ -\ No newline at end of file -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/navigation_json/debug/navigation.json b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/navigation_json/debug/navigation.json -new file mode 100644 -index 0000000..0637a08 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/navigation_json/debug/navigation.json -@@ -0,0 +1 @@ -+[] -\ No newline at end of file -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable-xxhdpi-v4/red_marker.png b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable-xxhdpi-v4/red_marker.png -new file mode 100644 -index 0000000..be782e1 -Binary files /dev/null and b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable-xxhdpi-v4/red_marker.png differ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable/empty.xml b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable/empty.xml -new file mode 100644 -index 0000000..1f83bff ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable/empty.xml -@@ -0,0 +1,5 @@ -+ -+ -+ -+ -+ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable/empty_drawable.png b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable/empty_drawable.png -new file mode 100644 -index 0000000..9da19ea -Binary files /dev/null and b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/drawable/empty_drawable.png differ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/layout/annotation.xml b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/layout/annotation.xml -new file mode 100644 -index 0000000..4994bd0 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/layout/annotation.xml -@@ -0,0 +1,17 @@ -+ -+ -+ -+ -+ -+ -+ -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/values/values.xml b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/values/values.xml -new file mode 100644 -index 0000000..1b0b5d6 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/packaged_res/debug/values/values.xml -@@ -0,0 +1,4 @@ -+ -+ -+ RCTMGL -+ -\ No newline at end of file -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt -new file mode 100644 -index 0000000..44307d6 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/intermediates/symbol_list_with_package_name/debug/package-aware-r.txt -@@ -0,0 +1,9 @@ -+com.mapbox.rctmgl -+drawable empty -+drawable empty_drawable -+drawable red_marker -+id annotation_img -+id annotation_layout -+id annotation_view_container -+layout annotation -+string app_name -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/outputs/logs/manifest-merger-debug-report.txt b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/outputs/logs/manifest-merger-debug-report.txt -new file mode 100644 -index 0000000..3581c51 ---- /dev/null -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/build/outputs/logs/manifest-merger-debug-report.txt -@@ -0,0 +1,25 @@ -+-- Merging decision tree log --- -+manifest -+ADDED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:1:1-4:12 -+INJECTED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:1:1-4:12 -+ package -+ ADDED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:1:70-97 -+ INJECTED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml -+ xmlns:android -+ ADDED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:1:11-69 -+uses-permission#android.permission.INTERNET -+ADDED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:2:5-67 -+ android:name -+ ADDED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:2:22-64 -+uses-permission#android.permission.ACCESS_FINE_LOCATION -+ADDED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:3:5-78 -+ android:name -+ ADDED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml:3:22-76 -+uses-sdk -+INJECTED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml reason: use-sdk injection requested -+INJECTED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml -+INJECTED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml -+ android:targetSdkVersion -+ INJECTED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml -+ android:minSdkVersion -+ INJECTED from /Users/noahprince/source/wallet-app/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/AndroidManifest.xml -diff --git a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/styles/RCTMGLStyleFunctionParser.java b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/styles/RCTMGLStyleFunctionParser.java -index 3aa0522..9a2248f 100644 ---- a/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/styles/RCTMGLStyleFunctionParser.java -+++ b/node_modules/@maplibre/maplibre-react-native/android/rctmgl/src/main/java/com/mapbox/rctmgl/components/styles/RCTMGLStyleFunctionParser.java -@@ -3,7 +3,7 @@ package com.mapbox.rctmgl.components.styles; - import android.util.Log; - - import com.facebook.react.bridge.Dynamic; --import com.facebook.react.bridge.DynamicFromMap; -+// import com.facebook.react.bridge.DynamicFromMap; - import com.facebook.react.bridge.NoSuchKeyException; - import com.facebook.react.bridge.ReadableArray; - import com.facebook.react.bridge.ReadableMap; diff --git a/project-structure.md b/project-structure.md new file mode 100644 index 000000000..ca4df77c2 --- /dev/null +++ b/project-structure.md @@ -0,0 +1,71 @@ +# 🗄️ Project Structure + +Most of the code lives in the `src` folder and looks something like this: + +```sh +src +| ++-- app # application layer containing: +| | # this folder might differ based on the meta framework used +| +-- services # application services. The super app top level navigation is defined as a set of services +| +-- RootNavigator.tsx # Main navigator for the app that determines the initial route. Either app onboarding UI or the top level service navigator +| +-- App.tsx # main application component ++-- assets # assets folder can contain all the static files such as images, fonts, etc. +| ++-- components # shared components used across the entire application +| ++-- config # global configurations, exported env variables etc. +| ++-- features # feature based modules +| ++-- hooks # shared hooks used across the entire application +| ++-- lib # reusable libraries preconfigured for the application +| ++-- stores # global state stores +| ++-- testing # test utilities and mocks +| ++-- types # shared types used across the application +| ++-- utils # shared utility functions +``` + +A service could have the following structure: + +```sh +src/services/srcful +| ++-- pages # pages scoped to a specific service +| ++-- index.tsx # service entry point +``` + +For easy scalability and maintenance, organize most of the code within the features folder. Each feature folder should contain code specific to that feature, keeping things neatly separated. This approach helps prevent mixing feature-related code with shared components, making it simpler to manage and maintain the codebase compared to having many files in a flat folder structure. By adopting this method, you can enhance collaboration, readability, and scalability in the application's architecture. + +A feature could have the following structure: + +```sh +src/features/awesome-feature +| ++-- api # exported API request declarations and api hooks related to a specific feature +| ++-- assets # assets folder can contain all the static files for a specific feature +| ++-- components # components scoped to a specific feature +| ++-- screens # screens scoped to a specific feature +| ++-- hooks # hooks scoped to a specific feature +| ++-- stores # state stores for a specific feature +| ++-- types # typescript types used within the feature +| ++-- utils # utility functions for a specific feature +``` + +NOTE: You don't need all of these folders for every feature. Only include the ones that are necessary for the feature. + +By following these practices, you can ensure that your codebase is well-organized, scalable, and maintainable. This will help you and your team to work more efficiently and effectively on the project. +This approach can also make it easier to apply similar architecture to apps built with Next.js, Remix or React Native. diff --git a/src/Input.tsx b/src/Input.tsx deleted file mode 100644 index 0ecb1e4a0..000000000 --- a/src/Input.tsx +++ /dev/null @@ -1,27 +0,0 @@ -/* eslint-disable react/jsx-props-no-spreading */ -import React from 'react' -import { - Text, - TextInput, - TextInputProps, - TextProps, - View, - ViewStyle, -} from 'react-native' - -type Props = { - title: string - textProps?: TextProps - inputProps?: TextInputProps - style?: ViewStyle -} -const Input = ({ style, title, textProps, inputProps }: Props) => { - return ( - - {title} - - - ) -} - -export default Input diff --git a/src/App.tsx b/src/app/App.tsx similarity index 81% rename from src/App.tsx rename to src/app/App.tsx index 46f815982..5e3bd0983 100644 --- a/src/App.tsx +++ b/src/app/App.tsx @@ -2,16 +2,16 @@ import AutoGasBanner from '@components/AutoGasBanner' import { BottomSheetModalProvider } from '@gorhom/bottom-sheet' import { PortalProvider } from '@gorhom/portal' import { OnboardingProvider as HotspotOnboardingProvider } from '@helium/react-native-sdk' -import MapLibreGL from '@maplibre/maplibre-react-native' import { DarkTheme, NavigationContainer } from '@react-navigation/native' import { ThemeProvider } from '@shopify/restyle' -import { ModalProvider } from '@storage/ModalsProvider' -import TokensProvider from '@storage/TokensProvider' +import { ModalProvider } from '@config/storage/ModalsProvider' +import TokensProvider from '@config/storage/TokensProvider' import { QueryClient, QueryClientProvider } from '@tanstack/react-query' -import globalStyles from '@theme/globalStyles' -import { darkTheme } from '@theme/theme' +import globalStyles from '@config/theme/globalStyles' +import { darkTheme } from '@config/theme/theme' import * as SplashLib from 'expo-splash-screen' import React, { useMemo } from 'react' +import Mapbox from '@rnmapbox/maps' import { LogBox, Platform, StatusBar, UIManager } from 'react-native' import useAppState from 'react-native-appstate-hook' import Config from 'react-native-config' @@ -19,24 +19,24 @@ import { GestureHandlerRootView } from 'react-native-gesture-handler' import { OneSignal } from 'react-native-onesignal' import { SafeAreaProvider } from 'react-native-safe-area-context' import 'text-encoding-polyfill' -import SplashScreen from './components/SplashScreen' -import WalletConnectProvider from './features/dappLogin/WalletConnectProvider' -import LockScreen from './features/lock/LockScreen' -import InsufficientSolConversionModal from './features/modals/InsufficientSolConversionModal' -import WalletOnboardingProvider from './features/onboarding/OnboardingProvider' -import SecurityScreen from './features/security/SecurityScreen' -import useMount from './hooks/useMount' -import { navigationRef } from './navigation/NavigationHelper' -import RootNavigator from './navigation/RootNavigator' -import './polyfill' -import SolanaProvider from './solana/SolanaProvider' -import WalletSignProvider from './solana/WalletSignProvider' -import { useAccountStorage } from './storage/AccountStorageProvider' -import { GovernanceProvider } from './storage/GovernanceProvider' -import { useNotificationStorage } from './storage/NotificationStorageProvider' -import { BalanceProvider } from './utils/Balance' -import { useDeepLinking } from './utils/linking' -import KeystoneOnboardingProvider from './features/keystone/KeystoneOnboardingProvider' +import SolanaProvider from '@features/solana/SolanaProvider' +import WalletSignProvider from '@features/solana/WalletSignProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { GovernanceProvider } from '@config/storage/GovernanceProvider' +import { useNotificationStorage } from '@config/storage/NotificationStorageProvider' +import { BalanceProvider } from '@utils/Balance' +import { useDeepLinking } from '@utils/linking' +import KeystoneOnboardingProvider from '@features/keystone/KeystoneOnboardingProvider' +import SplashScreen from '../components/SplashScreen' +import WalletConnectProvider from '../features/dappLogin/WalletConnectProvider' +import LockScreen from '../features/lock/LockScreen' +import InsufficientSolConversionModal from '../features/modals/InsufficientSolConversionModal' +import WalletOnboardingProvider from '../features/onboarding/OnboardingProvider' +import SecurityScreen from '../features/security/SecurityScreen' +import useMount from '../hooks/useMount' +import { navigationRef } from './NavigationHelper' +import RootNavigator from './RootNavigator' +import '../polyfill' SplashLib.preventAutoHideAsync().catch(() => { /* reloading the app might trigger some race conditions, ignore them */ @@ -46,7 +46,8 @@ const App = () => { // Note that the Android SDK is slightly peculiar // in that it requires setting an access token, // even though it will be null for most users(only Mapbox authenticates this way) - MapLibreGL.setAccessToken(null) + // MapLibreGL.setAccessToken(null) + Mapbox.setAccessToken(Config.MAPBOX_ACCESS_TOKEN) LogBox.ignoreLogs([ 'Module iCloudStorage', diff --git a/src/navigation/NavigationHelper.ts b/src/app/NavigationHelper.ts similarity index 84% rename from src/navigation/NavigationHelper.ts rename to src/app/NavigationHelper.ts index 65783beb2..e887d1886 100644 --- a/src/navigation/NavigationHelper.ts +++ b/src/app/NavigationHelper.ts @@ -1,5 +1,5 @@ import { createNavigationContainerRef } from '@react-navigation/native' -import { AccountsServiceStackParamList } from '@services/AccountsService' +import { AccountsServiceStackParamList } from 'src/app/services/AccountsService' import { RootStackParamList } from './rootTypes' export const navigationRef = createNavigationContainerRef() diff --git a/src/navigation/RootNavigator.tsx b/src/app/RootNavigator.tsx similarity index 77% rename from src/navigation/RootNavigator.tsx rename to src/app/RootNavigator.tsx index f9cbeecd1..1535cdc85 100644 --- a/src/navigation/RootNavigator.tsx +++ b/src/app/RootNavigator.tsx @@ -2,19 +2,19 @@ import { StackNavigationOptions, createStackNavigator, } from '@react-navigation/stack' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import React, { memo, useEffect, useMemo } from 'react' import changeNavigationBarColor from 'react-native-navigation-bar-color' import ServiceSheetNavigator from '@services/ServiceSheetNavigator' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import ScanQrCodeScreen from '../features/keystone/ScanQrCodeScreen' -import SelectKeystoneAccountsScreen from '../features/keystone/SelectKeystoneAccountsScreen' -import DappLoginScreen from '../features/dappLogin/DappLoginScreen' -import OnboardingNavigator from '../features/onboarding/OnboardingNavigator' -import ImportPrivateKey from '../features/onboarding/import/ImportPrivateKey' -import PaymentScreen from '../features/payment/PaymentScreen' -import LinkWallet from '../features/txnDelegation/LinkWallet' -import SignHotspot from '../features/txnDelegation/SignHotspot' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import ScanQrCodeScreen from '@features/keystone/ScanQrCodeScreen' +import SelectKeystoneAccountsScreen from '@features/keystone/SelectKeystoneAccountsScreen' +import DappLoginScreen from '@features/dappLogin/DappLoginScreen' +import OnboardingNavigator from '@features/onboarding/OnboardingNavigator' +import ImportPrivateKey from '@features/onboarding/import/ImportPrivateKey' +import PaymentScreen from '@features/payment/PaymentScreen' +import LinkWallet from '@features/txnDelegation/LinkWallet' +import SignHotspot from '@features/txnDelegation/SignHotspot' import { RootStackParamList } from './rootTypes' const screenOptions = { headerShown: false } as StackNavigationOptions diff --git a/src/navigation/rootTypes.ts b/src/app/rootTypes.ts similarity index 93% rename from src/navigation/rootTypes.ts rename to src/app/rootTypes.ts index f74bac82f..95b145444 100644 --- a/src/navigation/rootTypes.ts +++ b/src/app/rootTypes.ts @@ -1,7 +1,7 @@ import { LinkWalletRequest, SignHotspotRequest } from '@helium/wallet-link' import { StackNavigationProp } from '@react-navigation/stack' import { KeystoneAccountType } from 'src/features/keystone/SelectKeystoneAccountsScreen' -import { PaymentRouteParam } from '@services/WalletService' +import { PaymentRouteParam } from 'src/app/services/WalletService' export type RootStackParamList = { OnboardingNavigator: undefined diff --git a/src/services/AccountsService/accountServiceTypes.ts b/src/app/services/AccountsService/accountServiceTypes.ts similarity index 100% rename from src/services/AccountsService/accountServiceTypes.ts rename to src/app/services/AccountsService/accountServiceTypes.ts diff --git a/src/services/AccountsService/index.tsx b/src/app/services/AccountsService/index.tsx similarity index 97% rename from src/services/AccountsService/index.tsx rename to src/app/services/AccountsService/index.tsx index 866a6f30a..b2aea7e1d 100644 --- a/src/services/AccountsService/index.tsx +++ b/src/app/services/AccountsService/index.tsx @@ -4,7 +4,7 @@ import { StackNavigationProp, createStackNavigator, } from '@react-navigation/stack' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import AddNewAccountNavigator from '@features/home/addNewAccount/AddNewAccountNavigator' import AccountAssignScreen from '@features/onboarding/AccountAssignScreen' import { RouteAccount } from '@features/onboarding/create/createAccountNavTypes' diff --git a/src/services/AccountsService/pages/YourWalletsPage.tsx b/src/app/services/AccountsService/pages/YourWalletsPage.tsx similarity index 96% rename from src/services/AccountsService/pages/YourWalletsPage.tsx rename to src/app/services/AccountsService/pages/YourWalletsPage.tsx index d2cbf8e3e..395af534b 100644 --- a/src/services/AccountsService/pages/YourWalletsPage.tsx +++ b/src/app/services/AccountsService/pages/YourWalletsPage.tsx @@ -5,30 +5,30 @@ import { ReAnimatedBox } from '@components/AnimatedBox' import { FadeIn } from 'react-native-reanimated' import Box from '@components/Box' import { Image, SectionList } from 'react-native' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { NetTypes } from '@helium/address' -import { CSAccount } from '@storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import TouchableContainer from '@components/TouchableContainer' import AccountIcon from '@components/AccountIcon' import { ellipsizeAddress } from '@utils/accountUtils' -import { useColors, useSpacing } from '@theme/themeHooks' -import SmallAdd from '@assets/images/smallAdd.svg' -import BigAdd from '@assets/images/bigAdd.svg' -import Checkmark from '@assets/images/checkmark.svg' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import SmallAdd from '@assets/svgs/smallAdd.svg' +import BigAdd from '@assets/svgs/bigAdd.svg' +import Checkmark from '@assets/svgs/checkmark.svg' import { useNavigation } from '@react-navigation/native' import { HELIUM_DERIVATION, keypairFromSeed, solanaDerivation, } from '@hooks/useDerivationAccounts' -import { getSecureAccount } from '@storage/secureStorage' +import { getSecureAccount } from '@config/storage/secureStorage' import * as bip39 from 'bip39' import { useOnboarding } from '@features/onboarding/OnboardingProvider' import Toast from 'react-native-simple-toast' import { useSafeAreaInsets } from 'react-native-safe-area-context' import TouchableOpacityBox from '@components/TouchableOpacityBox' import useLayoutHeight from '@hooks/useLayoutHeight' -import { ServiceSheetNavigationProp } from '@services/serviceSheetTypes' +import { ServiceSheetNavigationProp } from 'src/app/services/serviceSheetTypes' import CircleLoader from '@components/CircleLoader' import ScrollBox from '@components/ScrollBox' import { AccountsServiceNavigationProp } from '../accountServiceTypes' diff --git a/src/services/BrowserService/index.tsx b/src/app/services/BrowserService/index.tsx similarity index 100% rename from src/services/BrowserService/index.tsx rename to src/app/services/BrowserService/index.tsx diff --git a/src/services/GovernanceService/index.tsx b/src/app/services/GovernanceService/index.tsx similarity index 100% rename from src/services/GovernanceService/index.tsx rename to src/app/services/GovernanceService/index.tsx diff --git a/src/app/services/HotspotService/index.tsx b/src/app/services/HotspotService/index.tsx new file mode 100644 index 000000000..502959672 --- /dev/null +++ b/src/app/services/HotspotService/index.tsx @@ -0,0 +1,50 @@ +import React, { useMemo } from 'react' +import Hotspot from '@assets/svgs/hotspot.svg' +import Map from '@assets/svgs/map.svg' +import Add from '@assets/svgs/add.svg' +import Coin from '@assets/svgs/coin.svg' +import ServiceSheetPage, { + ServiceNavBarOption, +} from '@components/ServiceSheetPage' +import { StackNavigationProp } from '@react-navigation/stack' +import { PortalHost } from '@gorhom/portal' +import Box from '@components/Box' +import { HotspotWithPendingRewards } from '../../../types/solana' +import HotspotPage from './pages/HotspotPage' +import ExplorerPage from './pages/ExplorerPage' +import AddHotspotPage from './pages/AddHotspotPage' +import ClaimTokensPage from './pages/ClaimTokensPage' + +export type HotspotServiceStackParamList = { + Hotspot: { + newHotspot?: HotspotWithPendingRewards + } + Explorer: undefined + AddHotspot: undefined + ClaimTokens: undefined +} + +export type HotspotServiceNavigationProp = + StackNavigationProp + +const HotspotService = () => { + const options = useMemo((): Array => { + return [ + { name: 'Hotspot', Icon: Hotspot, component: HotspotPage }, + { name: 'Explorer', Icon: Map, component: ExplorerPage }, + { name: 'AddHotspot', Icon: Add, component: AddHotspotPage }, + { name: 'ClaimTokens', Icon: Coin, component: ClaimTokensPage }, + ] + }, []) + + return ( + + + + + + + ) +} + +export default HotspotService diff --git a/src/app/services/HotspotService/pages/AddHotspotPage.tsx b/src/app/services/HotspotService/pages/AddHotspotPage.tsx new file mode 100644 index 000000000..3a3237a42 --- /dev/null +++ b/src/app/services/HotspotService/pages/AddHotspotPage.tsx @@ -0,0 +1,106 @@ +import Box from '@components/Box' +import ButtonPressable from '@components/ButtonPressable' +import Text from '@components/Text' +import React, { useCallback, useMemo, useRef } from 'react' +import { useTranslation } from 'react-i18next' +import { Image } from 'react-native' +import Add from '@assets/svgs/add.svg' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import RightArrow from '@assets/svgs/rightArrow.svg' +import ScrollBox from '@components/ScrollBox' +import { NavBarHeight } from '@components/ServiceNavBar' +import { useSafeAreaInsets } from 'react-native-safe-area-context' +import { + OnboardingSheetWrapper, + OnboardingSheetRef, +} from '@features/hotspot-onboarding/OnboardingSheet' + +const AddHotspotPage = () => { + const { t } = useTranslation() + const { bottom } = useSafeAreaInsets() + const colors = useColors() + const spacing = useSpacing() + const onboardingSheetRef = useRef(null) + + const showOnboardingSheet = useCallback(() => { + onboardingSheetRef.current?.show() + }, [onboardingSheetRef]) + + const contentContainerStyle = useMemo(() => { + return { + padding: spacing['2xl'], + } + }, [spacing]) + + return ( + <> + + + + + + + {t('AddHotspotPage.title')} + + + {t('AddHotspotPage.subtitle')} + + + } + backgroundColor="primaryText" + titleColor="primaryBackground" + title={t('AddHotspotPage.addHotspot')} + onPress={showOnboardingSheet} + marginBottom="3xl" + /> + + + {t('AddHotspotPage.locationAndMountingTips')} + + + + + + + + ) +} + +export default AddHotspotPage diff --git a/src/app/services/HotspotService/pages/ClaimTokensPage.tsx b/src/app/services/HotspotService/pages/ClaimTokensPage.tsx new file mode 100644 index 000000000..d8d346402 --- /dev/null +++ b/src/app/services/HotspotService/pages/ClaimTokensPage.tsx @@ -0,0 +1,226 @@ +import Box from '@components/Box' +import ButtonPressable from '@components/ButtonPressable' +import ScrollBox from '@components/ScrollBox' +import Text from '@components/Text' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import React, { useCallback, useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import { Image, RefreshControl } from 'react-native' +import MobileIcon from '@assets/svgs/mobileIconNew.svg' +import IotIcon from '@assets/svgs/iotIconNew.svg' +import TouchableContainer from '@components/TouchableContainer' +import BalanceText from '@components/BalanceText' +import useHotspots from '@hooks/useHotspots' +import { toNumber } from '@helium/spl-utils' +import { + MOBILE_LAZY_KEY, + IOT_LAZY_KEY, + MIN_BALANCE_THRESHOLD, +} from '@utils/constants' +import useSubmitTxn from '@hooks/useSubmitTxn' +import { useBN } from '@hooks/useBN' +import { useSolOwnedAmount } from '@helium/helium-react-hooks' +import { useCurrentWallet } from '@hooks/useCurrentWallet' +import { BN } from 'bn.js' +import { useModal } from '@config/storage/ModalsProvider' +import ProgressBar from '@components/ProgressBar' +import { ReAnimatedBox } from '@components/AnimatedBox' +import { FadeIn, FadeOut } from 'react-native-reanimated' +import { RootState } from '@store/rootReducer' +import { useSelector } from 'react-redux' + +const ClaimTokensPage = () => { + const { t } = useTranslation() + const spacing = useSpacing() + const { submitClaimAllRewards } = useSubmitTxn() + const wallet = useCurrentWallet() + const { showModal } = useModal() + const solBalance = useBN(useSolOwnedAmount(wallet).amount) + const colors = useColors() + + const hasEnoughSol = useMemo(() => { + return (solBalance || new BN(0)).gt(new BN(MIN_BALANCE_THRESHOLD)) + }, [solBalance]) + + const { + pendingIotRewards, + pendingMobileRewards, + hotspotsWithMeta, + totalHotspots, + loading: hotspotsLoading, + fetchAll, + } = useHotspots() + + const contentContainerStyle = useMemo(() => { + return { + padding: spacing['2xl'], + } + }, [spacing]) + + const totalPendingIot = useMemo(() => { + if (!pendingIotRewards) return 0 + return toNumber(pendingIotRewards, 6) + }, [pendingIotRewards]) + + const totalPendingMobile = useMemo(() => { + if (!pendingMobileRewards) return 0 + return toNumber(pendingMobileRewards, 6) + }, [pendingMobileRewards]) + + const solanaPayment = useSelector( + (reduxState: RootState) => reduxState.solana.payment, + ) + + const claiming = useMemo(() => { + return solanaPayment?.loading + }, [solanaPayment]) + + const claimError = useMemo(() => { + return solanaPayment?.error + }, [solanaPayment]) + + const claimingDisabled = useMemo(() => { + return ( + claiming || + !hasEnoughSol || + (totalPendingIot === 0 && totalPendingMobile === 0) + ) + }, [claiming, hasEnoughSol, totalPendingIot, totalPendingMobile]) + + const onClaim = useCallback(async () => { + try { + const claim = async () => { + await submitClaimAllRewards( + [IOT_LAZY_KEY, MOBILE_LAZY_KEY], + hotspotsWithMeta, + totalHotspots, + ) + } + + if (!hasEnoughSol) { + showModal({ + type: 'InsufficientSolConversion', + onCancel: async () => {}, + onSuccess: claim, + }) + } else { + await claim() + } + } catch {} + }, [ + hasEnoughSol, + submitClaimAllRewards, + hotspotsWithMeta, + totalHotspots, + showModal, + ]) + + return ( + + } + > + + + + + {t('ClaimTokensPage.title')} + + + {t('ClaimTokensPage.subtitle')} + + + + + + + + + MOBILE + + + + + + + + + + + IOT + + + + + + + {claiming && ( + + + + )} + {claimError && ( + + {claimError?.message} + + )} + + ) +} + +export default ClaimTokensPage diff --git a/src/app/services/HotspotService/pages/ExplorerPage.tsx b/src/app/services/HotspotService/pages/ExplorerPage.tsx new file mode 100644 index 000000000..712b544e1 --- /dev/null +++ b/src/app/services/HotspotService/pages/ExplorerPage.tsx @@ -0,0 +1,120 @@ +import Box from '@components/Box' +import ImageBox from '@components/ImageBox' +import Map from '@components/Map' +import useHotspots from '@hooks/useHotspots' +import { + Camera, + Location, + MapState, + MarkerView, + UserLocation, +} from '@rnmapbox/maps' +import React, { useCallback, useState } from 'react' +import TotalHotspotPuck from '@assets/svgs/totalHotspotPuck.svg' +import { useSpacing } from '@config/theme/themeHooks' +import Text from '@components/Text' +import { ReAnimatedBox } from '@components/AnimatedBox' +import { FadeIn, FadeOut } from 'react-native-reanimated' + +const ExplorerPage = () => { + const { hotspotsWithMeta } = useHotspots() + const spacing = useSpacing() + const [userLocation, setUserLocation] = useState() + const [showTotalHotspotPuck, setShowTotalHotspotPuck] = useState(false) + + const handleCameraChanged = useCallback((state: MapState) => { + if (state.properties.zoom > 12) { + setShowTotalHotspotPuck(true) + } else { + setShowTotalHotspotPuck(false) + } + }, []) + + const TotalHotspotPuckContainer = useCallback(() => { + if (!showTotalHotspotPuck) return null + + return ( + + + + {hotspotsWithMeta?.length} + + + + + ) + }, [showTotalHotspotPuck, hotspotsWithMeta, spacing]) + + return ( + + + + + + + + + + {hotspotsWithMeta.map((hotspot) => { + const subDao = hotspot?.content?.metadata?.hotspot_infos?.iot + ?.device_type + ? 'iot' + : 'mobile' + const { long, lat } = hotspot.content.metadata.hotspot_infos[subDao] + + if (!long || !lat) return null + + return ( + + + + ) + })} + + + ) +} + +export default ExplorerPage diff --git a/src/app/services/HotspotService/pages/HotspotPage.tsx b/src/app/services/HotspotService/pages/HotspotPage.tsx new file mode 100644 index 000000000..89b0ad3fe --- /dev/null +++ b/src/app/services/HotspotService/pages/HotspotPage.tsx @@ -0,0 +1,96 @@ +import { + StackNavigationOptions, + StackNavigationProp, + createStackNavigator, +} from '@react-navigation/stack' +import { HotspotBleProvider } from '@helium/react-native-sdk' +import React, { useMemo } from 'react' +import { useColors } from '@config/theme/themeHooks' +import AssertLocationScreen from '@features/hotspots/AssertLocationScreen' +import TransferCollectableScreen from '@features/collectables/TransferCollectableScreen' +import ChangeRewardsRecipientScreen from '@features/hotspots/ChangeRewardsRecipientScreen' +import AntennaSetupScreen from '@features/hotspots/AntennaSetupScreen' +import Diagnostics from '@features/hotspots/Diagnostics' +import ModifyWifiScreen from '@features/hotspots/ModifyWifiScreen' +import HotspotPage from '@features/hotspots/HotspotPage' +import HotspotDetails from '@features/hotspots/HotspotDetails' +import HotspotConfig from '@features/hotspots/HotspotConfig' +import { HotspotWithPendingRewards } from '../../../../types/solana' + +export type HotspotStackParamList = { + HotspotPage: undefined + HotspotDetails: { + hotspot: HotspotWithPendingRewards + } + HotspotConfig: { + hotspot: HotspotWithPendingRewards + hotspotAddress: string + } + AssertLocationScreen: { + collectable: HotspotWithPendingRewards + } + TransferCollectableScreen: { + collectable: HotspotWithPendingRewards + } + ChangeRewardsRecipientScreen: { + hotspot: HotspotWithPendingRewards + } + AntennaSetupScreen: { + collectable: HotspotWithPendingRewards + } + DiagnosticsScreen: { + collectable: HotspotWithPendingRewards + } + ModifyWifiScreen: { + collectable: HotspotWithPendingRewards + } +} + +export type HotspotNavigationProp = StackNavigationProp + +const HotspotStack = createStackNavigator() + +const HotspotPageNavigator = () => { + const colors = useColors() + const navigatorScreenOptions = useMemo( + () => + ({ + headerShown: false, + cardStyle: { backgroundColor: colors.primaryBackground }, + } as StackNavigationOptions), + [colors], + ) + + return ( + + + + + + + + + + + + + + ) +} + +export default HotspotPageNavigator diff --git a/src/services/NotificationsService/index.tsx b/src/app/services/NotificationsService/index.tsx similarity index 100% rename from src/services/NotificationsService/index.tsx rename to src/app/services/NotificationsService/index.tsx diff --git a/src/services/ServiceSheet.tsx b/src/app/services/ServiceSheet.tsx similarity index 62% rename from src/services/ServiceSheet.tsx rename to src/app/services/ServiceSheet.tsx index 2e993c38f..6267d42ed 100644 --- a/src/services/ServiceSheet.tsx +++ b/src/app/services/ServiceSheet.tsx @@ -1,8 +1,21 @@ import React, { useCallback, useMemo, useRef, useState } from 'react' import Box from '@components/Box' import BottomSheet from '@gorhom/bottom-sheet' -import { useColors, useSpacing } from '@theme/themeHooks' -import { FadeIn, FadeOut } from 'react-native-reanimated' +import { + useBackgroundStyle, + useBorderRadii, + useColors, + useSpacing, +} from '@config/theme/themeHooks' +import { + FadeIn, + FadeOut, + useAnimatedStyle, + interpolate, + Extrapolation, + withSpring, + withTiming, +} from 'react-native-reanimated' import { ReAnimatedBox, Text } from '@components' import TouchableOpacityBox from '@components/TouchableOpacityBox' import AccountIcon from '@components/AccountIcon' @@ -10,26 +23,39 @@ import SideDrawer from '@components/SideDrawer' import MenuButton from '@components/MenuButton' import { useNavigation } from '@react-navigation/native' import { ThemeProvider } from '@shopify/restyle' -import { lightTheme } from '@theme/theme' +import { lightTheme } from '@config/theme/theme' import HeliumBottomSheet from '@components/HeliumBottomSheet' -import { FadeInSlow } from '@components/FadeInOut' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import changeNavigationBarColor from 'react-native-navigation-bar-color' +import { Platform, StyleProp, ViewStyle } from 'react-native' +import { wh } from '@utils/layout' +import { useSelector } from 'react-redux' +import { RootState } from '@store/rootReducer' import { ServiceSheetNavigationProp } from './serviceSheetTypes' type ServiceSheetProps = { currentService: string + isChild?: boolean children?: React.ReactNode } -const ServiceSheet = ({ children, currentService }: ServiceSheetProps) => { +const ServiceSheet = ({ + children, + currentService, + isChild, +}: ServiceSheetProps) => { const [isExpanded, setIsExpanded] = useState(false) const [bottomSheetOpen, setBottomSheetOpen] = useState(true) const bottomSheetRef = useRef(null) const serviceNav = useNavigation() const { top } = useSafeAreaInsets() const colors = useColors() + const spacing = useSpacing() + const bottomSheetStyle = useBackgroundStyle('primaryText') + const borderRadii = useBorderRadii() + + const { rootSheetPosition } = useSelector((state: RootState) => state.app) const onRoute = useCallback( (value: string) => { @@ -97,8 +123,62 @@ const ServiceSheet = ({ children, currentService }: ServiceSheetProps) => { setBottomSheetOpen(index === 0) }, []) + const snapPoints = useMemo(() => { + if (Platform.OS === 'ios') { + return [ + wh - + top - + spacing[20] + + interpolate( + rootSheetPosition || 0, + [0, wh], + [0, 14], + Extrapolation.CLAMP, + ), + ] + } + + return [wh - top - spacing[20] - spacing[2]] + }, [top, spacing, rootSheetPosition]) + + const backgroundStyle = useMemo( + () => + ({ + ...bottomSheetStyle, + height: '100%', + borderRadius: borderRadii['4xl'] + borderRadii['4xl'], + backgroundColor: colors['fg.white'], + } as StyleProp), + [bottomSheetStyle, borderRadii, colors], + ) + + const sheetStyle = useAnimatedStyle(() => { + if (!rootSheetPosition) + return { + transform: [{ scaleX: withSpring(1) }], + opacity: withTiming(1), + } + + return { + transform: [ + { + scaleX: withSpring( + interpolate( + rootSheetPosition, + [0, wh], + [1, 0.9], + Extrapolation.CLAMP, + ), + ), + }, + ], + opacity: withTiming( + interpolate(rootSheetPosition, [0, wh], [1, 0.15], Extrapolation.CLAMP), + ), + } + }, [isChild, rootSheetPosition]) return ( - + { walletsSelected={bottomSheetOpen && currentService === 'wallets'} onClose={onCloseSheet} /> - - - - {children} - - - - + + + + + {children} + + + + + ) } @@ -157,9 +241,10 @@ const Header = ({ return ( { const colors = useColors() const borderRadii = useBorderRadii() const [currentService, setCurrentService] = useState('wallet') - + const dispatch = useAppDispatch() const navigatorScreenOptions = useMemo( () => ({ @@ -33,32 +35,36 @@ const ServiceSheetNavigator = () => { [borderRadii, colors], ) - const onFocus = useCallback((target: string | undefined) => { - switch (target?.split('-')[0]) { - default: - case 'WalletService': - setCurrentService('wallet') - break - case 'HotspotService': - setCurrentService('hotspots') - break - case 'AccountsService': - setCurrentService('wallets') - break - case 'GovernanceService': - setCurrentService('governance') - break - case 'BrowserService': - setCurrentService('browser') - break - case 'NotificationsService': - setCurrentService('notifications') - break - case 'SettingsService': - setCurrentService('settings') - break - } - }, []) + const onFocus = useCallback( + (target: string | undefined) => { + dispatch(appSlice.actions.setRootSheetPosition(undefined)) + switch (target?.split('-')[0]) { + default: + case 'WalletService': + setCurrentService('wallet') + break + case 'HotspotService': + setCurrentService('hotspots') + break + case 'AccountsService': + setCurrentService('wallets') + break + case 'GovernanceService': + setCurrentService('governance') + break + case 'BrowserService': + setCurrentService('browser') + break + case 'NotificationsService': + setCurrentService('notifications') + break + case 'SettingsService': + setCurrentService('settings') + break + } + }, + [dispatch], + ) return ( diff --git a/src/services/SettingsService/index.tsx b/src/app/services/SettingsService/index.tsx similarity index 100% rename from src/services/SettingsService/index.tsx rename to src/app/services/SettingsService/index.tsx diff --git a/src/services/WalletService/index.tsx b/src/app/services/WalletService/index.tsx similarity index 85% rename from src/services/WalletService/index.tsx rename to src/app/services/WalletService/index.tsx index 439aa93df..bb7528592 100644 --- a/src/services/WalletService/index.tsx +++ b/src/app/services/WalletService/index.tsx @@ -1,9 +1,9 @@ import React, { useMemo } from 'react' -import Wallet from '@assets/images/wallet.svg' -import Receive from '@assets/images/receive.svg' -import Send from '@assets/images/send.svg' -import Swap from '@assets/images/swap.svg' -import Transactions from '@assets/images/transactionsTabIcon.svg' +import Wallet from '@assets/svgs/wallet.svg' +import Receive from '@assets/svgs/receive.svg' +import Send from '@assets/svgs/send.svg' +import Swap from '@assets/svgs/swap.svg' +import Transactions from '@assets/svgs/transactionsTabIcon.svg' import ServiceSheetPage, { ServiceNavBarOption, } from '@components/ServiceSheetPage' diff --git a/src/services/WalletService/pages/ReceivePage/index.tsx b/src/app/services/WalletService/pages/ReceivePage/index.tsx similarity index 96% rename from src/services/WalletService/pages/ReceivePage/index.tsx rename to src/app/services/WalletService/pages/ReceivePage/index.tsx index 163afa2de..078419993 100644 --- a/src/services/WalletService/pages/ReceivePage/index.tsx +++ b/src/app/services/WalletService/pages/ReceivePage/index.tsx @@ -6,8 +6,8 @@ import React, { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { Image } from 'react-native' import QRCode from 'react-native-qrcode-svg' -import CarotRight from '@assets/images/carot-right.svg' -import { useColors } from '@theme/themeHooks' +import CarotRight from '@assets/svgs/carot-right.svg' +import { useColors } from '@config/theme/themeHooks' import useCopyText from '@hooks/useCopyText' import TouchableContainer from '@components/TouchableContainer' import { ReAnimatedBox } from '@components/AnimatedBox' diff --git a/src/services/WalletService/pages/SendPage/SentPageNavigator.tsx b/src/app/services/WalletService/pages/SendPage/index.tsx similarity index 61% rename from src/services/WalletService/pages/SendPage/SentPageNavigator.tsx rename to src/app/services/WalletService/pages/SendPage/index.tsx index 34eee8c98..4c6ff0387 100644 --- a/src/services/WalletService/pages/SendPage/SentPageNavigator.tsx +++ b/src/app/services/WalletService/pages/SendPage/index.tsx @@ -4,10 +4,12 @@ import { createStackNavigator, } from '@react-navigation/stack' import React, { useMemo } from 'react' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import PaymentScreen from '@features/payment/PaymentScreen' import AddressBookNavigator from '@features/addressBook/AddressBookNavigator' -import { PaymentRouteParam } from '@services/WalletService' +import { PaymentRouteParam } from 'src/app/services/WalletService' +import { ReAnimatedBox } from '@components/AnimatedBox' +import { FadeIn } from 'react-native-reanimated' export type SendStackParamList = { PaymentScreen: undefined | PaymentRouteParam @@ -30,10 +32,12 @@ const SendPageNavigator = () => { ) return ( - - - - + + + + + + ) } diff --git a/src/services/WalletService/pages/SwapPage/index.tsx b/src/app/services/WalletService/pages/SwapPage/index.tsx similarity index 100% rename from src/services/WalletService/pages/SwapPage/index.tsx rename to src/app/services/WalletService/pages/SwapPage/index.tsx diff --git a/src/services/WalletService/pages/TransactionsPage/index.tsx b/src/app/services/WalletService/pages/TransactionsPage/index.tsx similarity index 100% rename from src/services/WalletService/pages/TransactionsPage/index.tsx rename to src/app/services/WalletService/pages/TransactionsPage/index.tsx diff --git a/src/services/WalletService/pages/WalletPage/WalletPageNavigator.tsx b/src/app/services/WalletService/pages/WalletPage/index.tsx similarity index 89% rename from src/services/WalletService/pages/WalletPage/WalletPageNavigator.tsx rename to src/app/services/WalletService/pages/WalletPage/index.tsx index 4b1714e9b..5d38b2801 100644 --- a/src/services/WalletService/pages/WalletPage/WalletPageNavigator.tsx +++ b/src/app/services/WalletService/pages/WalletPage/index.tsx @@ -4,20 +4,20 @@ import { createStackNavigator, } from '@react-navigation/stack' import React, { useMemo } from 'react' -import AccountTokenScreen from '@features/account/AccountTokenScreen' -import { useColors } from '@theme/themeHooks' -import AirdropScreen from '@features/account/AirdropScreen' +import AccountTokenScreen from '@features/wallet/AccountTokenScreen' +import { useColors } from '@config/theme/themeHooks' +import AirdropScreen from '@features/wallet/AirdropScreen' import ConfirmPinScreen from '@components/ConfirmPinScreen' import BurnScreen from '@features/burn/BurnScreen' -import AccountManageTokenListScreen from '@features/account/AccountManageTokenListScreen' +import AccountManageTokenListScreen from '@features/wallet/AccountManageTokenListScreen' import PaymentQrScanner from '@features/payment/PaymentQrScanner' import NftDetailsScreen from '@features/collectables/NftDetailsScreen' import CollectionScreen from '@features/collectables/CollectionScreen' import ManageCollectables from '@features/collectables/ManageCollectables' import TransferCollectableScreen from '@features/collectables/TransferCollectableScreen' import TransferCompleteScreen from '@features/collectables/TransferCompleteScreen' -import { CompressedNFT } from '../../../../types/solana' -import TokensTabs from './TokensTabs' +import TokensTabs from '@features/wallet/TokensTabs' +import { CompressedNFT } from '../../../../../types/solana' export type BurnRouteParam = { address: string diff --git a/src/services/serviceSheetTypes.ts b/src/app/services/serviceSheetTypes.ts similarity index 100% rename from src/services/serviceSheetTypes.ts rename to src/app/services/serviceSheetTypes.ts diff --git a/src/assets/images/account.svg b/src/assets/images/account.svg deleted file mode 100644 index d3fdd19c2..000000000 --- a/src/assets/images/account.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/assets/images/accountIntroIconOne.svg b/src/assets/images/accountIntroIconOne.svg deleted file mode 100644 index 0bd00bd56..000000000 --- a/src/assets/images/accountIntroIconOne.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/assets/images/add.svg b/src/assets/images/add.svg deleted file mode 100644 index 4598139bf..000000000 --- a/src/assets/images/add.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/addHotspotImage.png b/src/assets/images/addHotspotImage.png new file mode 100644 index 000000000..ef4650b85 Binary files /dev/null and b/src/assets/images/addHotspotImage.png differ diff --git a/src/assets/images/addHotspotImage@2x.png b/src/assets/images/addHotspotImage@2x.png new file mode 100644 index 000000000..f5e94b195 Binary files /dev/null and b/src/assets/images/addHotspotImage@2x.png differ diff --git a/src/assets/images/addHotspotImage@3x.png b/src/assets/images/addHotspotImage@3x.png new file mode 100644 index 000000000..7c38ee20a Binary files /dev/null and b/src/assets/images/addHotspotImage@3x.png differ diff --git a/src/assets/images/bigClose.svg b/src/assets/images/bigClose.svg deleted file mode 100644 index 491258957..000000000 --- a/src/assets/images/bigClose.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/images/bluetooth.svg b/src/assets/images/bluetooth.svg deleted file mode 100644 index 43e690a02..000000000 --- a/src/assets/images/bluetooth.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/assets/images/boxTriangleTop.svg b/src/assets/images/boxTriangleTop.svg deleted file mode 100644 index 24c5dadae..000000000 --- a/src/assets/images/boxTriangleTop.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/building.png b/src/assets/images/building.png new file mode 100644 index 000000000..fdd695e08 Binary files /dev/null and b/src/assets/images/building.png differ diff --git a/src/assets/images/building@2x.png b/src/assets/images/building@2x.png new file mode 100644 index 000000000..8cae3ad89 Binary files /dev/null and b/src/assets/images/building@2x.png differ diff --git a/src/assets/images/building@3x.png b/src/assets/images/building@3x.png new file mode 100644 index 000000000..5271d56dd Binary files /dev/null and b/src/assets/images/building@3x.png differ diff --git a/src/assets/images/buy.svg b/src/assets/images/buy.svg deleted file mode 100644 index 44803aa95..000000000 --- a/src/assets/images/buy.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/chevronDown.svg b/src/assets/images/chevronDown.svg deleted file mode 100644 index 5cf6154fd..000000000 --- a/src/assets/images/chevronDown.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/claimTokensIcon.png b/src/assets/images/claimTokensIcon.png new file mode 100644 index 000000000..25a36fb46 Binary files /dev/null and b/src/assets/images/claimTokensIcon.png differ diff --git a/src/assets/images/claimTokensIcon@2x.png b/src/assets/images/claimTokensIcon@2x.png new file mode 100644 index 000000000..b47d61c7d Binary files /dev/null and b/src/assets/images/claimTokensIcon@2x.png differ diff --git a/src/assets/images/claimTokensIcon@3x.png b/src/assets/images/claimTokensIcon@3x.png new file mode 100644 index 000000000..c388d6986 Binary files /dev/null and b/src/assets/images/claimTokensIcon@3x.png differ diff --git a/src/assets/images/cog.svg b/src/assets/images/cog.svg deleted file mode 100644 index 831241c60..000000000 --- a/src/assets/images/cog.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/assets/images/collectableIcon.svg b/src/assets/images/collectableIcon.svg deleted file mode 100644 index 092e0bfbe..000000000 --- a/src/assets/images/collectableIcon.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/assets/images/courthouse.svg b/src/assets/images/courthouse.svg deleted file mode 100644 index 39df878fd..000000000 --- a/src/assets/images/courthouse.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/src/assets/images/crowdspot-question.svg b/src/assets/images/crowdspot-question.svg deleted file mode 100644 index a6f7c4c4b..000000000 --- a/src/assets/images/crowdspot-question.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/images/dc.svg b/src/assets/images/dc.svg deleted file mode 100644 index b34a8badc..000000000 --- a/src/assets/images/dc.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/assets/images/dollar.svg b/src/assets/images/dollar.svg deleted file mode 100644 index 91cb894f9..000000000 --- a/src/assets/images/dollar.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/images/earth-globe.svg b/src/assets/images/earth-globe.svg deleted file mode 100644 index 131eb002f..000000000 --- a/src/assets/images/earth-globe.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/src/assets/images/expandedViewIcon.svg b/src/assets/images/expandedViewIcon.svg deleted file mode 100644 index 8a7c148cb..000000000 --- a/src/assets/images/expandedViewIcon.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/assets/images/ffiHotspot.png b/src/assets/images/ffiHotspot.png new file mode 100644 index 000000000..0b2dd5ac2 Binary files /dev/null and b/src/assets/images/ffiHotspot.png differ diff --git a/src/assets/images/ffiHotspot@2x.png b/src/assets/images/ffiHotspot@2x.png new file mode 100644 index 000000000..addbcc02d Binary files /dev/null and b/src/assets/images/ffiHotspot@2x.png differ diff --git a/src/assets/images/ffiHotspot@3x.png b/src/assets/images/ffiHotspot@3x.png new file mode 100644 index 000000000..6cda88e44 Binary files /dev/null and b/src/assets/images/ffiHotspot@3x.png differ diff --git a/src/assets/images/hex.svg b/src/assets/images/hex.svg deleted file mode 100644 index 71831a536..000000000 --- a/src/assets/images/hex.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/hotspotBeam.png b/src/assets/images/hotspotBeam.png new file mode 100644 index 000000000..6752129aa Binary files /dev/null and b/src/assets/images/hotspotBeam.png differ diff --git a/src/assets/images/hotspotBeam@2x.png b/src/assets/images/hotspotBeam@2x.png new file mode 100644 index 000000000..5777361ef Binary files /dev/null and b/src/assets/images/hotspotBeam@2x.png differ diff --git a/src/assets/images/hotspotBeam@3x.png b/src/assets/images/hotspotBeam@3x.png new file mode 100644 index 000000000..7eaaf3930 Binary files /dev/null and b/src/assets/images/hotspotBeam@3x.png differ diff --git a/src/assets/images/hotspotBlackMarker.png b/src/assets/images/hotspotBlackMarker.png new file mode 100644 index 000000000..9efb61872 Binary files /dev/null and b/src/assets/images/hotspotBlackMarker.png differ diff --git a/src/assets/images/hotspotBlackMarker@2x.png b/src/assets/images/hotspotBlackMarker@2x.png new file mode 100644 index 000000000..36b8d9971 Binary files /dev/null and b/src/assets/images/hotspotBlackMarker@2x.png differ diff --git a/src/assets/images/hotspotBlackMarker@3x.png b/src/assets/images/hotspotBlackMarker@3x.png new file mode 100644 index 000000000..2f9947c0e Binary files /dev/null and b/src/assets/images/hotspotBlackMarker@3x.png differ diff --git a/src/assets/images/hotspotBox.png b/src/assets/images/hotspotBox.png new file mode 100644 index 000000000..9f4dfa6f1 Binary files /dev/null and b/src/assets/images/hotspotBox.png differ diff --git a/src/assets/images/hotspotBox@2x.png b/src/assets/images/hotspotBox@2x.png new file mode 100644 index 000000000..1d5b36f73 Binary files /dev/null and b/src/assets/images/hotspotBox@2x.png differ diff --git a/src/assets/images/hotspotBox@3x.png b/src/assets/images/hotspotBox@3x.png new file mode 100644 index 000000000..d925826ca Binary files /dev/null and b/src/assets/images/hotspotBox@3x.png differ diff --git a/src/assets/images/hotspotEthernet.png b/src/assets/images/hotspotEthernet.png new file mode 100644 index 000000000..216ea14a3 Binary files /dev/null and b/src/assets/images/hotspotEthernet.png differ diff --git a/src/assets/images/hotspotEthernet@2x.png b/src/assets/images/hotspotEthernet@2x.png new file mode 100644 index 000000000..e6fe77504 Binary files /dev/null and b/src/assets/images/hotspotEthernet@2x.png differ diff --git a/src/assets/images/hotspotEthernet@3x.png b/src/assets/images/hotspotEthernet@3x.png new file mode 100644 index 000000000..0a2383bf8 Binary files /dev/null and b/src/assets/images/hotspotEthernet@3x.png differ diff --git a/src/assets/images/hotspotOutdoorSmall.png b/src/assets/images/hotspotOutdoorSmall.png new file mode 100644 index 000000000..3fefbef4d Binary files /dev/null and b/src/assets/images/hotspotOutdoorSmall.png differ diff --git a/src/assets/images/hotspotOutdoorSmall@2x.png b/src/assets/images/hotspotOutdoorSmall@2x.png new file mode 100644 index 000000000..69f85ebef Binary files /dev/null and b/src/assets/images/hotspotOutdoorSmall@2x.png differ diff --git a/src/assets/images/hotspotOutdoorSmall@3x.png b/src/assets/images/hotspotOutdoorSmall@3x.png new file mode 100644 index 000000000..e5b440a03 Binary files /dev/null and b/src/assets/images/hotspotOutdoorSmall@3x.png differ diff --git a/src/assets/images/hotspotQR.png b/src/assets/images/hotspotQR.png new file mode 100644 index 000000000..777dcca2c Binary files /dev/null and b/src/assets/images/hotspotQR.png differ diff --git a/src/assets/images/hotspotQR@2x.png b/src/assets/images/hotspotQR@2x.png new file mode 100644 index 000000000..26f9c7a85 Binary files /dev/null and b/src/assets/images/hotspotQR@2x.png differ diff --git a/src/assets/images/hotspotQR@3x.png b/src/assets/images/hotspotQR@3x.png new file mode 100644 index 000000000..46b41cc12 Binary files /dev/null and b/src/assets/images/hotspotQR@3x.png differ diff --git a/src/assets/images/indoorHotspot.png b/src/assets/images/indoorHotspot.png new file mode 100644 index 000000000..3047b4410 Binary files /dev/null and b/src/assets/images/indoorHotspot.png differ diff --git a/src/assets/images/indoorHotspot@2x.png b/src/assets/images/indoorHotspot@2x.png new file mode 100644 index 000000000..d76b96d69 Binary files /dev/null and b/src/assets/images/indoorHotspot@2x.png differ diff --git a/src/assets/images/indoorHotspot@3x.png b/src/assets/images/indoorHotspot@3x.png new file mode 100644 index 000000000..ee3db6413 Binary files /dev/null and b/src/assets/images/indoorHotspot@3x.png differ diff --git a/src/assets/images/indoorHotspotBig.png b/src/assets/images/indoorHotspotBig.png new file mode 100644 index 000000000..e6043fd29 Binary files /dev/null and b/src/assets/images/indoorHotspotBig.png differ diff --git a/src/assets/images/indoorHotspotBig@2x.png b/src/assets/images/indoorHotspotBig@2x.png new file mode 100644 index 000000000..a7fff3db3 Binary files /dev/null and b/src/assets/images/indoorHotspotBig@2x.png differ diff --git a/src/assets/images/indoorHotspotBig@3x.png b/src/assets/images/indoorHotspotBig@3x.png new file mode 100644 index 000000000..03e3cfe4f Binary files /dev/null and b/src/assets/images/indoorHotspotBig@3x.png differ diff --git a/src/assets/images/indoorHotspotBox.png b/src/assets/images/indoorHotspotBox.png new file mode 100644 index 000000000..c7562b2a5 Binary files /dev/null and b/src/assets/images/indoorHotspotBox.png differ diff --git a/src/assets/images/indoorHotspotBox@2x.png b/src/assets/images/indoorHotspotBox@2x.png new file mode 100644 index 000000000..185872879 Binary files /dev/null and b/src/assets/images/indoorHotspotBox@2x.png differ diff --git a/src/assets/images/indoorHotspotBox@3x.png b/src/assets/images/indoorHotspotBox@3x.png new file mode 100644 index 000000000..78b13f9fc Binary files /dev/null and b/src/assets/images/indoorHotspotBox@3x.png differ diff --git a/src/assets/images/indoorHotspotEthernet.png b/src/assets/images/indoorHotspotEthernet.png new file mode 100644 index 000000000..114fdccb7 Binary files /dev/null and b/src/assets/images/indoorHotspotEthernet.png differ diff --git a/src/assets/images/indoorHotspotEthernet@2x.png b/src/assets/images/indoorHotspotEthernet@2x.png new file mode 100644 index 000000000..433d265aa Binary files /dev/null and b/src/assets/images/indoorHotspotEthernet@2x.png differ diff --git a/src/assets/images/indoorHotspotEthernet@3x.png b/src/assets/images/indoorHotspotEthernet@3x.png new file mode 100644 index 000000000..dfd16fc24 Binary files /dev/null and b/src/assets/images/indoorHotspotEthernet@3x.png differ diff --git a/src/assets/images/indoorHotspotQR.png b/src/assets/images/indoorHotspotQR.png new file mode 100644 index 000000000..f04ba29ba Binary files /dev/null and b/src/assets/images/indoorHotspotQR.png differ diff --git a/src/assets/images/indoorHotspotQR@2x.png b/src/assets/images/indoorHotspotQR@2x.png new file mode 100644 index 000000000..ac2e26dfb Binary files /dev/null and b/src/assets/images/indoorHotspotQR@2x.png differ diff --git a/src/assets/images/indoorHotspotQR@3x.png b/src/assets/images/indoorHotspotQR@3x.png new file mode 100644 index 000000000..d21d384cf Binary files /dev/null and b/src/assets/images/indoorHotspotQR@3x.png differ diff --git a/src/assets/images/intro.svg b/src/assets/images/intro.svg deleted file mode 100644 index 0e724a332..000000000 --- a/src/assets/images/intro.svg +++ /dev/null @@ -1,33 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/images/iotCircle.svg b/src/assets/images/iotCircle.svg deleted file mode 100644 index a1541dffd..000000000 --- a/src/assets/images/iotCircle.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/iotRewardIcon.svg b/src/assets/images/iotRewardIcon.svg deleted file mode 100644 index a03ec27be..000000000 --- a/src/assets/images/iotRewardIcon.svg +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/images/kerlinkHotspot.png b/src/assets/images/kerlinkHotspot.png new file mode 100644 index 000000000..4e9d9dceb Binary files /dev/null and b/src/assets/images/kerlinkHotspot.png differ diff --git a/src/assets/images/kerlinkHotspot@2x.png b/src/assets/images/kerlinkHotspot@2x.png new file mode 100644 index 000000000..912454ac1 Binary files /dev/null and b/src/assets/images/kerlinkHotspot@2x.png differ diff --git a/src/assets/images/kerlinkHotspot@3x.png b/src/assets/images/kerlinkHotspot@3x.png new file mode 100644 index 000000000..b6a231f1a Binary files /dev/null and b/src/assets/images/kerlinkHotspot@3x.png differ diff --git a/src/assets/images/listViewIcon.svg b/src/assets/images/listViewIcon.svg deleted file mode 100644 index 4f8e83c2f..000000000 --- a/src/assets/images/listViewIcon.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/assets/images/mapPin.svg b/src/assets/images/mapPin.svg deleted file mode 100644 index 35a5c3a49..000000000 --- a/src/assets/images/mapPin.svg +++ /dev/null @@ -1,10 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/src/assets/images/merryIotHotspot.png b/src/assets/images/merryIotHotspot.png new file mode 100644 index 000000000..a3da7c84c Binary files /dev/null and b/src/assets/images/merryIotHotspot.png differ diff --git a/src/assets/images/merryIotHotspot@2x.png b/src/assets/images/merryIotHotspot@2x.png new file mode 100644 index 000000000..d2b7cd184 Binary files /dev/null and b/src/assets/images/merryIotHotspot@2x.png differ diff --git a/src/assets/images/merryIotHotspot@3x.png b/src/assets/images/merryIotHotspot@3x.png new file mode 100644 index 000000000..19cc1612b Binary files /dev/null and b/src/assets/images/merryIotHotspot@3x.png differ diff --git a/src/assets/images/mini-icon.svg b/src/assets/images/mini-icon.svg deleted file mode 100644 index 57923cc14..000000000 --- a/src/assets/images/mini-icon.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/images/mntdHotspot.png b/src/assets/images/mntdHotspot.png new file mode 100644 index 000000000..450ac498e Binary files /dev/null and b/src/assets/images/mntdHotspot.png differ diff --git a/src/assets/images/mntdHotspot@2x.png b/src/assets/images/mntdHotspot@2x.png new file mode 100644 index 000000000..a17694e40 Binary files /dev/null and b/src/assets/images/mntdHotspot@2x.png differ diff --git a/src/assets/images/mntdHotspot@3x.png b/src/assets/images/mntdHotspot@3x.png new file mode 100644 index 000000000..840c056af Binary files /dev/null and b/src/assets/images/mntdHotspot@3x.png differ diff --git a/src/assets/images/mobileCircle.svg b/src/assets/images/mobileCircle.svg deleted file mode 100644 index 19d06cc4d..000000000 --- a/src/assets/images/mobileCircle.svg +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - - - - - - - - diff --git a/src/assets/images/mobileHotspot.png b/src/assets/images/mobileHotspot.png new file mode 100644 index 000000000..f39c94659 Binary files /dev/null and b/src/assets/images/mobileHotspot.png differ diff --git a/src/assets/images/mobileHotspot@2x.png b/src/assets/images/mobileHotspot@2x.png new file mode 100644 index 000000000..61b80bcec Binary files /dev/null and b/src/assets/images/mobileHotspot@2x.png differ diff --git a/src/assets/images/mobileHotspot@3x.png b/src/assets/images/mobileHotspot@3x.png new file mode 100644 index 000000000..81e30ccf3 Binary files /dev/null and b/src/assets/images/mobileHotspot@3x.png differ diff --git a/src/assets/images/mobileRewardIcon.svg b/src/assets/images/mobileRewardIcon.svg deleted file mode 100644 index 87f68cb12..000000000 --- a/src/assets/images/mobileRewardIcon.svg +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/images/multiply.svg b/src/assets/images/multiply.svg deleted file mode 100644 index 92b40f669..000000000 --- a/src/assets/images/multiply.svg +++ /dev/null @@ -1 +0,0 @@ - diff --git a/src/assets/images/nft.svg b/src/assets/images/nft.svg deleted file mode 100644 index 33ef0c378..000000000 --- a/src/assets/images/nft.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/notificationBell.svg b/src/assets/images/notificationBell.svg deleted file mode 100644 index 39e2fe56a..000000000 --- a/src/assets/images/notificationBell.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/notifications.svg b/src/assets/images/notifications.svg deleted file mode 100644 index 456708765..000000000 --- a/src/assets/images/notifications.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/images/ogHotspot.png b/src/assets/images/ogHotspot.png new file mode 100644 index 000000000..4e6193e78 Binary files /dev/null and b/src/assets/images/ogHotspot.png differ diff --git a/src/assets/images/ogHotspot@2x.png b/src/assets/images/ogHotspot@2x.png new file mode 100644 index 000000000..3b5bac409 Binary files /dev/null and b/src/assets/images/ogHotspot@2x.png differ diff --git a/src/assets/images/ogHotspot@3x.png b/src/assets/images/ogHotspot@3x.png new file mode 100644 index 000000000..cd2e6a5c7 Binary files /dev/null and b/src/assets/images/ogHotspot@3x.png differ diff --git a/src/assets/images/outdoorHotspot.png b/src/assets/images/outdoorHotspot.png new file mode 100644 index 000000000..768ee59fd Binary files /dev/null and b/src/assets/images/outdoorHotspot.png differ diff --git a/src/assets/images/outdoorHotspot@2x.png b/src/assets/images/outdoorHotspot@2x.png new file mode 100644 index 000000000..1c3a92c41 Binary files /dev/null and b/src/assets/images/outdoorHotspot@2x.png differ diff --git a/src/assets/images/outdoorHotspot@3x.png b/src/assets/images/outdoorHotspot@3x.png new file mode 100644 index 000000000..879039c13 Binary files /dev/null and b/src/assets/images/outdoorHotspot@3x.png differ diff --git a/src/assets/images/passwordIcon.png b/src/assets/images/passwordIcon.png new file mode 100644 index 000000000..2486fc5c5 Binary files /dev/null and b/src/assets/images/passwordIcon.png differ diff --git a/src/assets/images/passwordIcon@2x.png b/src/assets/images/passwordIcon@2x.png new file mode 100644 index 000000000..295211c8f Binary files /dev/null and b/src/assets/images/passwordIcon@2x.png differ diff --git a/src/assets/images/passwordIcon@3x.png b/src/assets/images/passwordIcon@3x.png new file mode 100644 index 000000000..1637d2b13 Binary files /dev/null and b/src/assets/images/passwordIcon@3x.png differ diff --git a/src/assets/images/puck.png b/src/assets/images/puck.png new file mode 100644 index 000000000..55fb9e412 Binary files /dev/null and b/src/assets/images/puck.png differ diff --git a/src/assets/images/puck@2x.png b/src/assets/images/puck@2x.png new file mode 100644 index 000000000..6ecc82b81 Binary files /dev/null and b/src/assets/images/puck@2x.png differ diff --git a/src/assets/images/puck@3x.png b/src/assets/images/puck@3x.png new file mode 100644 index 000000000..25b249097 Binary files /dev/null and b/src/assets/images/puck@3x.png differ diff --git a/src/assets/images/puckNoBearing.png b/src/assets/images/puckNoBearing.png new file mode 100644 index 000000000..28fa149af Binary files /dev/null and b/src/assets/images/puckNoBearing.png differ diff --git a/src/assets/images/puckNoBearing@2x.png b/src/assets/images/puckNoBearing@2x.png new file mode 100644 index 000000000..92e1cb302 Binary files /dev/null and b/src/assets/images/puckNoBearing@2x.png differ diff --git a/src/assets/images/puckNoBearing@3x.png b/src/assets/images/puckNoBearing@3x.png new file mode 100644 index 000000000..322e2bca5 Binary files /dev/null and b/src/assets/images/puckNoBearing@3x.png differ diff --git a/src/assets/images/rewardBg.svg b/src/assets/images/rewardBg.svg deleted file mode 100644 index d45130276..000000000 --- a/src/assets/images/rewardBg.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - - - - - - - - - - - - - - - diff --git a/src/assets/images/satellite.png b/src/assets/images/satellite.png new file mode 100644 index 000000000..30207b0a0 Binary files /dev/null and b/src/assets/images/satellite.png differ diff --git a/src/assets/images/satellite@2x.png b/src/assets/images/satellite@2x.png new file mode 100644 index 000000000..1fe51a709 Binary files /dev/null and b/src/assets/images/satellite@2x.png differ diff --git a/src/assets/images/satellite@3x.png b/src/assets/images/satellite@3x.png new file mode 100644 index 000000000..5586b4a1d Binary files /dev/null and b/src/assets/images/satellite@3x.png differ diff --git a/src/assets/images/share.svg b/src/assets/images/share.svg deleted file mode 100644 index 110d97ace..000000000 --- a/src/assets/images/share.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/assets/images/solanaCircle.svg b/src/assets/images/solanaCircle.svg deleted file mode 100644 index 44e2d9fa7..000000000 --- a/src/assets/images/solanaCircle.svg +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - - - - diff --git a/src/assets/images/store.svg b/src/assets/images/store.svg deleted file mode 100644 index 6764d2dd2..000000000 --- a/src/assets/images/store.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/tip-up.svg b/src/assets/images/tip-up.svg deleted file mode 100644 index 1ac8554bb..000000000 --- a/src/assets/images/tip-up.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - \ No newline at end of file diff --git a/src/assets/images/tokenDC.svg b/src/assets/images/tokenDC.svg deleted file mode 100644 index 111b82708..000000000 --- a/src/assets/images/tokenDC.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/assets/images/tokenIOT.svg b/src/assets/images/tokenIOT.svg deleted file mode 100644 index a1541dffd..000000000 --- a/src/assets/images/tokenIOT.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/tokenMOBILE.svg b/src/assets/images/tokenMOBILE.svg deleted file mode 100644 index 757420796..000000000 --- a/src/assets/images/tokenMOBILE.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/tokenSolana.svg b/src/assets/images/tokenSolana.svg deleted file mode 100644 index ed6f34d95..000000000 --- a/src/assets/images/tokenSolana.svg +++ /dev/null @@ -1,13 +0,0 @@ - - - - - - - - - - - - - diff --git a/src/assets/images/trash.svg b/src/assets/images/trash.svg deleted file mode 100644 index 1fde57329..000000000 --- a/src/assets/images/trash.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/triangleDown.svg b/src/assets/images/triangleDown.svg deleted file mode 100644 index b043c4986..000000000 --- a/src/assets/images/triangleDown.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/src/assets/images/vote.svg b/src/assets/images/vote.svg deleted file mode 100644 index 41254dcce..000000000 --- a/src/assets/images/vote.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/src/assets/images/CloseCircle.svg b/src/assets/svgs/CloseCircle.svg similarity index 100% rename from src/assets/images/CloseCircle.svg rename to src/assets/svgs/CloseCircle.svg diff --git a/src/assets/images/activeCircle.svg b/src/assets/svgs/activeCircle.svg similarity index 100% rename from src/assets/images/activeCircle.svg rename to src/assets/svgs/activeCircle.svg diff --git a/src/assets/svgs/add.svg b/src/assets/svgs/add.svg new file mode 100644 index 000000000..41e96f224 --- /dev/null +++ b/src/assets/svgs/add.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/addDapp.svg b/src/assets/svgs/addDapp.svg similarity index 100% rename from src/assets/images/addDapp.svg rename to src/assets/svgs/addDapp.svg diff --git a/src/assets/images/addressIcon.svg b/src/assets/svgs/addressIcon.svg similarity index 100% rename from src/assets/images/addressIcon.svg rename to src/assets/svgs/addressIcon.svg diff --git a/src/assets/images/airdrop.svg b/src/assets/svgs/airdrop.svg similarity index 100% rename from src/assets/images/airdrop.svg rename to src/assets/svgs/airdrop.svg diff --git a/src/assets/images/alert.svg b/src/assets/svgs/alert.svg similarity index 100% rename from src/assets/images/alert.svg rename to src/assets/svgs/alert.svg diff --git a/src/assets/images/anchorAccount.svg b/src/assets/svgs/anchorAccount.svg similarity index 100% rename from src/assets/images/anchorAccount.svg rename to src/assets/svgs/anchorAccount.svg diff --git a/src/assets/svgs/arrowDown.svg b/src/assets/svgs/arrowDown.svg new file mode 100644 index 000000000..175c220d3 --- /dev/null +++ b/src/assets/svgs/arrowDown.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/arrowRight.svg b/src/assets/svgs/arrowRight.svg similarity index 100% rename from src/assets/images/arrowRight.svg rename to src/assets/svgs/arrowRight.svg diff --git a/src/assets/images/arrowUp.svg b/src/assets/svgs/arrowUp.svg similarity index 100% rename from src/assets/images/arrowUp.svg rename to src/assets/svgs/arrowUp.svg diff --git a/src/assets/images/backArrow.svg b/src/assets/svgs/backArrow.svg similarity index 100% rename from src/assets/images/backArrow.svg rename to src/assets/svgs/backArrow.svg diff --git a/src/assets/images/backspace.svg b/src/assets/svgs/backspace.svg similarity index 100% rename from src/assets/images/backspace.svg rename to src/assets/svgs/backspace.svg diff --git a/src/assets/images/bigAdd.svg b/src/assets/svgs/bigAdd.svg similarity index 100% rename from src/assets/images/bigAdd.svg rename to src/assets/svgs/bigAdd.svg diff --git a/src/assets/images/blueCheck.svg b/src/assets/svgs/blueCheck.svg similarity index 100% rename from src/assets/images/blueCheck.svg rename to src/assets/svgs/blueCheck.svg diff --git a/src/assets/svgs/bluetooth.svg b/src/assets/svgs/bluetooth.svg new file mode 100644 index 000000000..8df0cf50b --- /dev/null +++ b/src/assets/svgs/bluetooth.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/images/bookmark.svg b/src/assets/svgs/bookmark.svg similarity index 100% rename from src/assets/images/bookmark.svg rename to src/assets/svgs/bookmark.svg diff --git a/src/assets/images/bookmarkFilled.svg b/src/assets/svgs/bookmarkFilled.svg similarity index 100% rename from src/assets/images/bookmarkFilled.svg rename to src/assets/svgs/bookmarkFilled.svg diff --git a/src/assets/images/browseVoters.svg b/src/assets/svgs/browseVoters.svg similarity index 96% rename from src/assets/images/browseVoters.svg rename to src/assets/svgs/browseVoters.svg index a29154e6f..53ff1119d 100644 --- a/src/assets/images/browseVoters.svg +++ b/src/assets/svgs/browseVoters.svg @@ -1,6 +1,6 @@ - - - + + + diff --git a/src/assets/svgs/cameraCheck.svg b/src/assets/svgs/cameraCheck.svg new file mode 100644 index 000000000..1e0d2cae6 --- /dev/null +++ b/src/assets/svgs/cameraCheck.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/cancelledCircle.svg b/src/assets/svgs/cancelledCircle.svg similarity index 100% rename from src/assets/images/cancelledCircle.svg rename to src/assets/svgs/cancelledCircle.svg diff --git a/src/assets/images/carot-down.svg b/src/assets/svgs/carot-down.svg similarity index 100% rename from src/assets/images/carot-down.svg rename to src/assets/svgs/carot-down.svg diff --git a/src/assets/images/carot-right.svg b/src/assets/svgs/carot-right.svg similarity index 100% rename from src/assets/images/carot-right.svg rename to src/assets/svgs/carot-right.svg diff --git a/src/assets/images/carotDownFull.svg b/src/assets/svgs/carotDownFull.svg similarity index 100% rename from src/assets/images/carotDownFull.svg rename to src/assets/svgs/carotDownFull.svg diff --git a/src/assets/images/checkIco.svg b/src/assets/svgs/checkIco.svg similarity index 100% rename from src/assets/images/checkIco.svg rename to src/assets/svgs/checkIco.svg diff --git a/src/assets/images/checkmark.svg b/src/assets/svgs/checkmark.svg similarity index 100% rename from src/assets/images/checkmark.svg rename to src/assets/svgs/checkmark.svg diff --git a/src/assets/svgs/checkmarkCircle.svg b/src/assets/svgs/checkmarkCircle.svg new file mode 100644 index 000000000..a0f40733a --- /dev/null +++ b/src/assets/svgs/checkmarkCircle.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/checkmarkFill.svg b/src/assets/svgs/checkmarkFill.svg similarity index 100% rename from src/assets/images/checkmarkFill.svg rename to src/assets/svgs/checkmarkFill.svg diff --git a/src/assets/svgs/chevronDown.svg b/src/assets/svgs/chevronDown.svg new file mode 100644 index 000000000..08f7de437 --- /dev/null +++ b/src/assets/svgs/chevronDown.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/circleLoader.svg b/src/assets/svgs/circleLoader.svg similarity index 100% rename from src/assets/images/circleLoader.svg rename to src/assets/svgs/circleLoader.svg diff --git a/src/assets/svgs/clock.svg b/src/assets/svgs/clock.svg new file mode 100644 index 000000000..6ae655919 --- /dev/null +++ b/src/assets/svgs/clock.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/close.svg b/src/assets/svgs/close.svg similarity index 100% rename from src/assets/images/close.svg rename to src/assets/svgs/close.svg diff --git a/src/assets/images/closeCircleFilled.svg b/src/assets/svgs/closeCircleFilled.svg similarity index 100% rename from src/assets/images/closeCircleFilled.svg rename to src/assets/svgs/closeCircleFilled.svg diff --git a/src/assets/images/closeModal.svg b/src/assets/svgs/closeModal.svg similarity index 100% rename from src/assets/images/closeModal.svg rename to src/assets/svgs/closeModal.svg diff --git a/src/assets/svgs/coin.svg b/src/assets/svgs/coin.svg new file mode 100644 index 000000000..194e302cb --- /dev/null +++ b/src/assets/svgs/coin.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/collectables.svg b/src/assets/svgs/collectables.svg similarity index 100% rename from src/assets/images/collectables.svg rename to src/assets/svgs/collectables.svg diff --git a/src/assets/images/config.svg b/src/assets/svgs/config.svg similarity index 100% rename from src/assets/images/config.svg rename to src/assets/svgs/config.svg diff --git a/src/assets/images/copyAddress.svg b/src/assets/svgs/copyAddress.svg similarity index 100% rename from src/assets/images/copyAddress.svg rename to src/assets/svgs/copyAddress.svg diff --git a/src/assets/images/createAccount.svg b/src/assets/svgs/createAccount.svg similarity index 100% rename from src/assets/images/createAccount.svg rename to src/assets/svgs/createAccount.svg diff --git a/src/assets/images/crowdspot.svg b/src/assets/svgs/crowdspot.svg similarity index 100% rename from src/assets/images/crowdspot.svg rename to src/assets/svgs/crowdspot.svg diff --git a/src/assets/svgs/crown.svg b/src/assets/svgs/crown.svg new file mode 100644 index 000000000..3dd55b9f1 --- /dev/null +++ b/src/assets/svgs/crown.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/customWarning.svg b/src/assets/svgs/customWarning.svg similarity index 100% rename from src/assets/images/customWarning.svg rename to src/assets/svgs/customWarning.svg diff --git a/src/assets/images/dapp-ellipsis.svg b/src/assets/svgs/dapp-ellipsis.svg similarity index 100% rename from src/assets/images/dapp-ellipsis.svg rename to src/assets/svgs/dapp-ellipsis.svg diff --git a/src/assets/images/detailArrow.svg b/src/assets/svgs/detailArrow.svg similarity index 100% rename from src/assets/images/detailArrow.svg rename to src/assets/svgs/detailArrow.svg diff --git a/src/assets/images/dots.svg b/src/assets/svgs/dots.svg similarity index 100% rename from src/assets/images/dots.svg rename to src/assets/svgs/dots.svg diff --git a/src/assets/images/downArrow.svg b/src/assets/svgs/downArrow.svg similarity index 100% rename from src/assets/images/downArrow.svg rename to src/assets/svgs/downArrow.svg diff --git a/src/assets/images/dripLogo.svg b/src/assets/svgs/dripLogo.svg similarity index 100% rename from src/assets/images/dripLogo.svg rename to src/assets/svgs/dripLogo.svg diff --git a/src/assets/svgs/electricity.svg b/src/assets/svgs/electricity.svg new file mode 100644 index 000000000..0a761a71a --- /dev/null +++ b/src/assets/svgs/electricity.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/error.svg b/src/assets/svgs/error.svg similarity index 100% rename from src/assets/images/error.svg rename to src/assets/svgs/error.svg diff --git a/src/assets/svgs/expand.svg b/src/assets/svgs/expand.svg new file mode 100644 index 000000000..61f5e5bbc --- /dev/null +++ b/src/assets/svgs/expand.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/externalLink.svg b/src/assets/svgs/externalLink.svg similarity index 100% rename from src/assets/images/externalLink.svg rename to src/assets/svgs/externalLink.svg diff --git a/src/assets/svgs/eyeIcon.svg b/src/assets/svgs/eyeIcon.svg new file mode 100644 index 000000000..bf0394bd2 --- /dev/null +++ b/src/assets/svgs/eyeIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/face.svg b/src/assets/svgs/face.svg similarity index 100% rename from src/assets/images/face.svg rename to src/assets/svgs/face.svg diff --git a/src/assets/images/fail.svg b/src/assets/svgs/fail.svg similarity index 100% rename from src/assets/images/fail.svg rename to src/assets/svgs/fail.svg diff --git a/src/assets/images/filter.svg b/src/assets/svgs/filter.svg similarity index 100% rename from src/assets/images/filter.svg rename to src/assets/svgs/filter.svg diff --git a/src/assets/images/flag.svg b/src/assets/svgs/flag.svg similarity index 100% rename from src/assets/images/flag.svg rename to src/assets/svgs/flag.svg diff --git a/src/assets/images/globe.svg b/src/assets/svgs/globe.svg similarity index 100% rename from src/assets/images/globe.svg rename to src/assets/svgs/globe.svg diff --git a/src/assets/images/helium.svg b/src/assets/svgs/helium.svg similarity index 100% rename from src/assets/images/helium.svg rename to src/assets/svgs/helium.svg diff --git a/src/assets/images/heliumUpdateIcon.svg b/src/assets/svgs/heliumUpdateIcon.svg similarity index 100% rename from src/assets/images/heliumUpdateIcon.svg rename to src/assets/svgs/heliumUpdateIcon.svg diff --git a/src/assets/svgs/hex.svg b/src/assets/svgs/hex.svg new file mode 100644 index 000000000..40644d5eb --- /dev/null +++ b/src/assets/svgs/hex.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/hnt.svg b/src/assets/svgs/hnt.svg similarity index 100% rename from src/assets/images/hnt.svg rename to src/assets/svgs/hnt.svg diff --git a/src/assets/images/hotspot.svg b/src/assets/svgs/hotspot.svg similarity index 100% rename from src/assets/images/hotspot.svg rename to src/assets/svgs/hotspot.svg diff --git a/src/assets/svgs/hotspotMarker.svg b/src/assets/svgs/hotspotMarker.svg new file mode 100644 index 000000000..8b4bafde7 --- /dev/null +++ b/src/assets/svgs/hotspotMarker.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/importIcon.svg b/src/assets/svgs/importIcon.svg similarity index 100% rename from src/assets/images/importIcon.svg rename to src/assets/svgs/importIcon.svg diff --git a/src/assets/images/indentArrow.svg b/src/assets/svgs/indentArrow.svg similarity index 100% rename from src/assets/images/indentArrow.svg rename to src/assets/svgs/indentArrow.svg diff --git a/src/assets/images/info.svg b/src/assets/svgs/info.svg similarity index 100% rename from src/assets/images/info.svg rename to src/assets/svgs/info.svg diff --git a/src/assets/images/infoError.svg b/src/assets/svgs/infoError.svg similarity index 100% rename from src/assets/images/infoError.svg rename to src/assets/svgs/infoError.svg diff --git a/src/assets/svgs/infoIcon.svg b/src/assets/svgs/infoIcon.svg new file mode 100644 index 000000000..913596728 --- /dev/null +++ b/src/assets/svgs/infoIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/iot.svg b/src/assets/svgs/iot.svg similarity index 100% rename from src/assets/images/iot.svg rename to src/assets/svgs/iot.svg diff --git a/src/assets/svgs/iotIconNew.svg b/src/assets/svgs/iotIconNew.svg new file mode 100644 index 000000000..e7e5ed5de --- /dev/null +++ b/src/assets/svgs/iotIconNew.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/iotSymbol.svg b/src/assets/svgs/iotSymbol.svg similarity index 100% rename from src/assets/images/iotSymbol.svg rename to src/assets/svgs/iotSymbol.svg diff --git a/src/assets/images/kabob.svg b/src/assets/svgs/kabob.svg similarity index 100% rename from src/assets/images/kabob.svg rename to src/assets/svgs/kabob.svg diff --git a/src/assets/images/keystoneLogo.svg b/src/assets/svgs/keystoneLogo.svg similarity index 100% rename from src/assets/images/keystoneLogo.svg rename to src/assets/svgs/keystoneLogo.svg diff --git a/src/assets/images/ledger-circle.svg b/src/assets/svgs/ledger-circle.svg similarity index 100% rename from src/assets/images/ledger-circle.svg rename to src/assets/svgs/ledger-circle.svg diff --git a/src/assets/images/ledger.svg b/src/assets/svgs/ledger.svg similarity index 100% rename from src/assets/images/ledger.svg rename to src/assets/svgs/ledger.svg diff --git a/src/assets/images/lightningBolt.svg b/src/assets/svgs/lightningBolt.svg similarity index 100% rename from src/assets/images/lightningBolt.svg rename to src/assets/svgs/lightningBolt.svg diff --git a/src/assets/images/link.svg b/src/assets/svgs/link.svg similarity index 100% rename from src/assets/images/link.svg rename to src/assets/svgs/link.svg diff --git a/src/assets/images/listItemRight.svg b/src/assets/svgs/listItemRight.svg similarity index 100% rename from src/assets/images/listItemRight.svg rename to src/assets/svgs/listItemRight.svg diff --git a/src/assets/svgs/locationCheckmark.svg b/src/assets/svgs/locationCheckmark.svg new file mode 100644 index 000000000..dd2a6212c --- /dev/null +++ b/src/assets/svgs/locationCheckmark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/lock.svg b/src/assets/svgs/lock.svg similarity index 100% rename from src/assets/images/lock.svg rename to src/assets/svgs/lock.svg diff --git a/src/assets/images/lockClosed.svg b/src/assets/svgs/lockClosed.svg similarity index 100% rename from src/assets/images/lockClosed.svg rename to src/assets/svgs/lockClosed.svg diff --git a/src/assets/images/majorityCircle.svg b/src/assets/svgs/majorityCircle.svg similarity index 100% rename from src/assets/images/majorityCircle.svg rename to src/assets/svgs/majorityCircle.svg diff --git a/src/assets/svgs/map.svg b/src/assets/svgs/map.svg new file mode 100644 index 000000000..c3f03cc9d --- /dev/null +++ b/src/assets/svgs/map.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/svgs/mapPin.svg b/src/assets/svgs/mapPin.svg new file mode 100644 index 000000000..a3d1bd761 --- /dev/null +++ b/src/assets/svgs/mapPin.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/mapUserLocation.svg b/src/assets/svgs/mapUserLocation.svg similarity index 100% rename from src/assets/images/mapUserLocation.svg rename to src/assets/svgs/mapUserLocation.svg diff --git a/src/assets/images/menu.svg b/src/assets/svgs/menu.svg similarity index 100% rename from src/assets/images/menu.svg rename to src/assets/svgs/menu.svg diff --git a/src/assets/images/minorityCircle.svg b/src/assets/svgs/minorityCircle.svg similarity index 100% rename from src/assets/images/minorityCircle.svg rename to src/assets/svgs/minorityCircle.svg diff --git a/src/assets/images/mobile.svg b/src/assets/svgs/mobile.svg similarity index 100% rename from src/assets/images/mobile.svg rename to src/assets/svgs/mobile.svg diff --git a/src/assets/images/mobileIcon.svg b/src/assets/svgs/mobileIcon.svg similarity index 100% rename from src/assets/images/mobileIcon.svg rename to src/assets/svgs/mobileIcon.svg diff --git a/src/assets/svgs/mobileIconNew.svg b/src/assets/svgs/mobileIconNew.svg new file mode 100644 index 000000000..c1b543b3f --- /dev/null +++ b/src/assets/svgs/mobileIconNew.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/mobileSymbol.svg b/src/assets/svgs/mobileSymbol.svg similarity index 100% rename from src/assets/images/mobileSymbol.svg rename to src/assets/svgs/mobileSymbol.svg diff --git a/src/assets/svgs/mobileTextLogo.svg b/src/assets/svgs/mobileTextLogo.svg new file mode 100644 index 000000000..483d499f1 --- /dev/null +++ b/src/assets/svgs/mobileTextLogo.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/svgs/modalBackButton.svg b/src/assets/svgs/modalBackButton.svg new file mode 100644 index 000000000..f7e10d41a --- /dev/null +++ b/src/assets/svgs/modalBackButton.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/svgs/modalCheckButton.svg b/src/assets/svgs/modalCheckButton.svg new file mode 100644 index 000000000..622e26553 --- /dev/null +++ b/src/assets/svgs/modalCheckButton.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/svgs/modalCheckOnDarkButton.svg b/src/assets/svgs/modalCheckOnDarkButton.svg new file mode 100644 index 000000000..92b30dad2 --- /dev/null +++ b/src/assets/svgs/modalCheckOnDarkButton.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/svgs/modalForwardButton.svg b/src/assets/svgs/modalForwardButton.svg new file mode 100644 index 000000000..51f510009 --- /dev/null +++ b/src/assets/svgs/modalForwardButton.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/svgs/noCamera.svg b/src/assets/svgs/noCamera.svg new file mode 100644 index 000000000..f511b9b3a --- /dev/null +++ b/src/assets/svgs/noCamera.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/payment.svg b/src/assets/svgs/payment.svg similarity index 100% rename from src/assets/images/payment.svg rename to src/assets/svgs/payment.svg diff --git a/src/assets/images/paymentArrow.svg b/src/assets/svgs/paymentArrow.svg similarity index 100% rename from src/assets/images/paymentArrow.svg rename to src/assets/svgs/paymentArrow.svg diff --git a/src/assets/images/paymentFailure.svg b/src/assets/svgs/paymentFailure.svg similarity index 100% rename from src/assets/images/paymentFailure.svg rename to src/assets/svgs/paymentFailure.svg diff --git a/src/assets/images/paymentSuccess.svg b/src/assets/svgs/paymentSuccess.svg similarity index 100% rename from src/assets/images/paymentSuccess.svg rename to src/assets/svgs/paymentSuccess.svg diff --git a/src/assets/images/pending.svg b/src/assets/svgs/pending.svg similarity index 100% rename from src/assets/images/pending.svg rename to src/assets/svgs/pending.svg diff --git a/src/assets/svgs/person.svg b/src/assets/svgs/person.svg new file mode 100644 index 000000000..1b989ec5e --- /dev/null +++ b/src/assets/svgs/person.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/plus.svg b/src/assets/svgs/plus.svg similarity index 100% rename from src/assets/images/plus.svg rename to src/assets/svgs/plus.svg diff --git a/src/assets/images/qr.svg b/src/assets/svgs/qr.svg similarity index 100% rename from src/assets/images/qr.svg rename to src/assets/svgs/qr.svg diff --git a/src/assets/images/questionMark.svg b/src/assets/svgs/questionMark.svg similarity index 100% rename from src/assets/images/questionMark.svg rename to src/assets/svgs/questionMark.svg diff --git a/src/assets/images/receive.svg b/src/assets/svgs/receive.svg similarity index 100% rename from src/assets/images/receive.svg rename to src/assets/svgs/receive.svg diff --git a/src/assets/images/refresh.svg b/src/assets/svgs/refresh.svg similarity index 100% rename from src/assets/images/refresh.svg rename to src/assets/svgs/refresh.svg diff --git a/src/assets/images/remixArrowRight.svg b/src/assets/svgs/remixArrowRight.svg similarity index 100% rename from src/assets/images/remixArrowRight.svg rename to src/assets/svgs/remixArrowRight.svg diff --git a/src/assets/images/remixCancel.svg b/src/assets/svgs/remixCancel.svg similarity index 100% rename from src/assets/images/remixCancel.svg rename to src/assets/svgs/remixCancel.svg diff --git a/src/assets/images/remixChevronDown.svg b/src/assets/svgs/remixChevronDown.svg similarity index 100% rename from src/assets/images/remixChevronDown.svg rename to src/assets/svgs/remixChevronDown.svg diff --git a/src/assets/images/remixChevronUp.svg b/src/assets/svgs/remixChevronUp.svg similarity index 100% rename from src/assets/images/remixChevronUp.svg rename to src/assets/svgs/remixChevronUp.svg diff --git a/src/assets/images/remove.svg b/src/assets/svgs/remove.svg similarity index 100% rename from src/assets/images/remove.svg rename to src/assets/svgs/remove.svg diff --git a/src/assets/svgs/rightArrow.svg b/src/assets/svgs/rightArrow.svg new file mode 100644 index 000000000..ab580e6a7 --- /dev/null +++ b/src/assets/svgs/rightArrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/svgs/rotateIcon.svg b/src/assets/svgs/rotateIcon.svg new file mode 100644 index 000000000..c06901b72 --- /dev/null +++ b/src/assets/svgs/rotateIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/search.svg b/src/assets/svgs/search.svg similarity index 100% rename from src/assets/images/search.svg rename to src/assets/svgs/search.svg diff --git a/src/assets/svgs/searchIcon.svg b/src/assets/svgs/searchIcon.svg new file mode 100644 index 000000000..567d7b23b --- /dev/null +++ b/src/assets/svgs/searchIcon.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/send.svg b/src/assets/svgs/send.svg similarity index 100% rename from src/assets/images/send.svg rename to src/assets/svgs/send.svg diff --git a/src/assets/svgs/settings.svg b/src/assets/svgs/settings.svg new file mode 100644 index 000000000..2fac8a39b --- /dev/null +++ b/src/assets/svgs/settings.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/shareAddress.svg b/src/assets/svgs/shareAddress.svg similarity index 100% rename from src/assets/images/shareAddress.svg rename to src/assets/svgs/shareAddress.svg diff --git a/src/assets/images/smallAdd.svg b/src/assets/svgs/smallAdd.svg similarity index 100% rename from src/assets/images/smallAdd.svg rename to src/assets/svgs/smallAdd.svg diff --git a/src/assets/images/stake.svg b/src/assets/svgs/stake.svg similarity index 100% rename from src/assets/images/stake.svg rename to src/assets/svgs/stake.svg diff --git a/src/assets/images/swap.svg b/src/assets/svgs/swap.svg similarity index 100% rename from src/assets/images/swap.svg rename to src/assets/svgs/swap.svg diff --git a/src/assets/images/swaps.svg b/src/assets/svgs/swaps.svg similarity index 100% rename from src/assets/images/swaps.svg rename to src/assets/svgs/swaps.svg diff --git a/src/assets/images/swipeIcon.svg b/src/assets/svgs/swipeIcon.svg similarity index 100% rename from src/assets/images/swipeIcon.svg rename to src/assets/svgs/swipeIcon.svg diff --git a/src/assets/images/terminal.svg b/src/assets/svgs/terminal.svg similarity index 100% rename from src/assets/images/terminal.svg rename to src/assets/svgs/terminal.svg diff --git a/src/assets/images/tokenHNT.svg b/src/assets/svgs/tokenHNT.svg similarity index 100% rename from src/assets/images/tokenHNT.svg rename to src/assets/svgs/tokenHNT.svg diff --git a/src/assets/images/tokenSOL.svg b/src/assets/svgs/tokenSOL.svg similarity index 100% rename from src/assets/images/tokenSOL.svg rename to src/assets/svgs/tokenSOL.svg diff --git a/src/assets/images/tokens.svg b/src/assets/svgs/tokens.svg similarity index 100% rename from src/assets/images/tokens.svg rename to src/assets/svgs/tokens.svg diff --git a/src/assets/svgs/totalHotspotPuck.svg b/src/assets/svgs/totalHotspotPuck.svg new file mode 100644 index 000000000..175db764f --- /dev/null +++ b/src/assets/svgs/totalHotspotPuck.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/transactions.svg b/src/assets/svgs/transactions.svg similarity index 100% rename from src/assets/images/transactions.svg rename to src/assets/svgs/transactions.svg diff --git a/src/assets/images/transactionsTabIcon.svg b/src/assets/svgs/transactionsTabIcon.svg similarity index 100% rename from src/assets/images/transactionsTabIcon.svg rename to src/assets/svgs/transactionsTabIcon.svg diff --git a/src/assets/images/txnReceive.svg b/src/assets/svgs/txnReceive.svg similarity index 100% rename from src/assets/images/txnReceive.svg rename to src/assets/svgs/txnReceive.svg diff --git a/src/assets/images/txnSend.svg b/src/assets/svgs/txnSend.svg similarity index 100% rename from src/assets/images/txnSend.svg rename to src/assets/svgs/txnSend.svg diff --git a/src/assets/images/unknownAccount.svg b/src/assets/svgs/unknownAccount.svg similarity index 100% rename from src/assets/images/unknownAccount.svg rename to src/assets/svgs/unknownAccount.svg diff --git a/src/assets/images/userShare.svg b/src/assets/svgs/userShare.svg similarity index 100% rename from src/assets/images/userShare.svg rename to src/assets/svgs/userShare.svg diff --git a/src/assets/images/userStar.svg b/src/assets/svgs/userStar.svg similarity index 100% rename from src/assets/images/userStar.svg rename to src/assets/svgs/userStar.svg diff --git a/src/assets/images/userX.svg b/src/assets/svgs/userX.svg similarity index 100% rename from src/assets/images/userX.svg rename to src/assets/svgs/userX.svg diff --git a/src/assets/svgs/visibility.svg b/src/assets/svgs/visibility.svg new file mode 100644 index 000000000..24dd516e8 --- /dev/null +++ b/src/assets/svgs/visibility.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/src/assets/images/visibilityOff.svg b/src/assets/svgs/visibilityOff.svg similarity index 100% rename from src/assets/images/visibilityOff.svg rename to src/assets/svgs/visibilityOff.svg diff --git a/src/assets/images/voteChevron.svg b/src/assets/svgs/voteChevron.svg similarity index 100% rename from src/assets/images/voteChevron.svg rename to src/assets/svgs/voteChevron.svg diff --git a/src/assets/images/wallet.svg b/src/assets/svgs/wallet.svg similarity index 100% rename from src/assets/images/wallet.svg rename to src/assets/svgs/wallet.svg diff --git a/src/assets/images/walletUpdateIcon.svg b/src/assets/svgs/walletUpdateIcon.svg similarity index 100% rename from src/assets/images/walletUpdateIcon.svg rename to src/assets/svgs/walletUpdateIcon.svg diff --git a/src/assets/images/warning.svg b/src/assets/svgs/warning.svg similarity index 100% rename from src/assets/images/warning.svg rename to src/assets/svgs/warning.svg diff --git a/src/assets/images/warning2.svg b/src/assets/svgs/warning2.svg similarity index 100% rename from src/assets/images/warning2.svg rename to src/assets/svgs/warning2.svg diff --git a/src/assets/images/warningKeystone.svg b/src/assets/svgs/warningKeystone.svg similarity index 100% rename from src/assets/images/warningKeystone.svg rename to src/assets/svgs/warningKeystone.svg diff --git a/src/components/AccountButton.tsx b/src/components/AccountButton.tsx index 15ff99e3a..2ae04d9a5 100644 --- a/src/components/AccountButton.tsx +++ b/src/components/AccountButton.tsx @@ -1,10 +1,10 @@ /* eslint-disable react/jsx-props-no-spreading */ import React, { memo, useCallback, useMemo } from 'react' -import ChevronDown from '@assets/images/chevronDown.svg' +import ChevronDown from '@assets/svgs/chevronDown.svg' import { Keyboard, StyleSheet } from 'react-native' import { BoxProps } from '@shopify/restyle' -import { useColors, useHitSlop } from '@theme/themeHooks' -import { Color, Theme } from '@theme/theme' +import { useColors, useHitSlop } from '@config/theme/themeHooks' +import { Color, Theme } from '@config/theme/theme' import useHaptic from '@hooks/useHaptic' import AccountIcon from './AccountIcon' import Box from './Box' diff --git a/src/components/AccountIcon.tsx b/src/components/AccountIcon.tsx index 976ef7292..72dc47872 100644 --- a/src/components/AccountIcon.tsx +++ b/src/components/AccountIcon.tsx @@ -1,6 +1,6 @@ import React, { memo, useMemo } from 'react' import Jazzicon, { IJazziconProps } from 'react-native-jazzicon' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { useAsync } from 'react-async-hook' import { getJazzSeed } from '../utils/accountUtils' import { ImageBox } from '.' diff --git a/src/components/AccountListItem.tsx b/src/components/AccountListItem.tsx index d32565a9f..cc7584e05 100644 --- a/src/components/AccountListItem.tsx +++ b/src/components/AccountListItem.tsx @@ -1,13 +1,13 @@ import React, { memo, useCallback, useMemo } from 'react' -import Checkmark from '@assets/images/checkIco.svg' -import { useColors } from '@theme/themeHooks' +import Checkmark from '@assets/svgs/checkIco.svg' +import { useColors } from '@config/theme/themeHooks' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' +import { CSAccount } from '@config/storage/cloudStorage' import Text from './Text' import Box from './Box' import AccountIcon from './AccountIcon' import { ellipsizeAddress, formatAccountAlias } from '../utils/accountUtils' -import { CSAccount } from '../storage/cloudStorage' import TouchableContainer from './TouchableContainer' type Props = { diff --git a/src/components/AccountSelector.tsx b/src/components/AccountSelector.tsx index 0bb69cec7..9ae2b3d16 100644 --- a/src/components/AccountSelector.tsx +++ b/src/components/AccountSelector.tsx @@ -16,12 +16,12 @@ import { BottomSheetModalProvider, } from '@gorhom/bottom-sheet' import { GestureResponderEvent } from 'react-native' -import { useColors, useOpacity, useSpacing } from '@theme/themeHooks' +import { useColors, useOpacity, useSpacing } from '@config/theme/themeHooks' import useBackHandler from '@hooks/useBackHandler' -import { useAccountStorage } from '../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { CSAccount } from '@config/storage/cloudStorage' import { AccountNetTypeOpt } from '../utils/accountUtils' import AccountListItem from './AccountListItem' -import { CSAccount } from '../storage/cloudStorage' export type AccountSelectorRef = { show: (_type?: AccountNetTypeOpt | GestureResponderEvent) => void diff --git a/src/components/ActivityIndicator.tsx b/src/components/ActivityIndicator.tsx index 52c3f6dc5..308ed26f9 100644 --- a/src/components/ActivityIndicator.tsx +++ b/src/components/ActivityIndicator.tsx @@ -3,8 +3,8 @@ import { ActivityIndicatorProps, ActivityIndicator as RNActivityIndicator, } from 'react-native' -import { Color } from '@theme/theme' -import { useColors } from '@theme/themeHooks' +import { Color } from '@config/theme/theme' +import { useColors } from '@config/theme/themeHooks' type Props = { color?: Color } & ActivityIndicatorProps const ActivityIndicator = ({ color, ...props }: Props) => { diff --git a/src/components/AddressBookSelector.tsx b/src/components/AddressBookSelector.tsx index 218e2e566..5013d4ede 100644 --- a/src/components/AddressBookSelector.tsx +++ b/src/components/AddressBookSelector.tsx @@ -14,12 +14,12 @@ import BottomSheet, { } from '@gorhom/bottom-sheet' import { useNavigation } from '@react-navigation/native' import { BoxProps, ThemeProvider } from '@shopify/restyle' -import { lightTheme, Theme } from '@theme/theme' +import { lightTheme, Theme } from '@config/theme/theme' import ContactsList from '@features/addressBook/ContactsList' -import { CSAccount } from '@storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import { Portal } from '@gorhom/portal' import { useTranslation } from 'react-i18next' -import { SendNavigationProp } from '@services/WalletService/pages/SendPage/SentPageNavigator' +import { SendNavigationProp } from 'src/app/services/WalletService/pages/SendPage' import { AddressBookNavigationProp } from '@features/addressBook/addressBookTypes' import HeliumBottomSheet from './HeliumBottomSheet' import { SafeAreaBox, Text } from '.' diff --git a/src/components/AutoGasBanner.tsx b/src/components/AutoGasBanner.tsx index 7285a7822..4da2fd99d 100644 --- a/src/components/AutoGasBanner.tsx +++ b/src/components/AutoGasBanner.tsx @@ -1,5 +1,5 @@ -import CloseCircle from '@assets/images/closeCircleFilled.svg' -import Warning from '@assets/images/warning.svg' +import CloseCircle from '@assets/svgs/closeCircleFilled.svg' +import Warning from '@assets/svgs/warning.svg' import { useMint, useOwnedAmount, @@ -13,8 +13,8 @@ import { VersionedTransaction, sendAndConfirmRawTransaction, } from '@solana/web3.js' -import { useAppStorage } from '@storage/AppStorageProvider' -import { Theme } from '@theme/theme' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { Theme } from '@config/theme/theme' import { MIN_BALANCE_THRESHOLD } from '@utils/constants' import axios from 'axios' import BN from 'bn.js' @@ -29,9 +29,9 @@ import { useSafeAreaInsets, } from 'react-native-safe-area-context' import { useDispatch } from 'react-redux' -import { useSolana } from '../solana/SolanaProvider' -import { useWalletSign } from '../solana/WalletSignProvider' -import { WalletStandardMessageTypes } from '../solana/walletSignBottomSheetTypes' +import { useSolana } from '@features/solana/SolanaProvider' +import { useWalletSign } from '@features/solana/WalletSignProvider' +import { WalletStandardMessageTypes } from '@features/solana/walletSignBottomSheetTypes' import { appSlice } from '../store/slices/appSlice' import { ReAnimatedBox } from './AnimatedBox' import Box from './Box' diff --git a/src/components/BackButton.tsx b/src/components/BackButton.tsx index e419bcbc9..5ea1808f1 100644 --- a/src/components/BackButton.tsx +++ b/src/components/BackButton.tsx @@ -2,9 +2,9 @@ import React from 'react' import { BoxProps } from '@shopify/restyle' import { Insets } from 'react-native' -import BackArrow from '@assets/images/backArrow.svg' -import { Color, Spacing, Theme } from '@theme/theme' -import { useColors } from '@theme/themeHooks' +import BackArrow from '@assets/svgs/backArrow.svg' +import { Color, Spacing, Theme } from '@config/theme/theme' +import { useColors } from '@config/theme/themeHooks' import Box from './Box' import IconPressedContainer from './IconPressedContainer' diff --git a/src/components/BackScreen.tsx b/src/components/BackScreen.tsx index d2396a58b..e9a0a2715 100644 --- a/src/components/BackScreen.tsx +++ b/src/components/BackScreen.tsx @@ -5,8 +5,8 @@ import React, { memo, useCallback, useMemo } from 'react' import { LayoutChangeEvent, Platform } from 'react-native' import { Edge } from 'react-native-safe-area-context' import { SvgProps } from 'react-native-svg' -import { Color, Spacing, Theme } from '@theme/theme' -import { useColors, useHitSlop } from '@theme/themeHooks' +import { Color, Spacing, Theme } from '@config/theme/theme' +import { useColors, useHitSlop } from '@config/theme/themeHooks' import BackButton from './BackButton' import Box from './Box' import CloseButton from './CloseButton' diff --git a/src/components/BackgroundFill.tsx b/src/components/BackgroundFill.tsx index 889f7ddb6..a5e47b8a4 100644 --- a/src/components/BackgroundFill.tsx +++ b/src/components/BackgroundFill.tsx @@ -1,7 +1,7 @@ import { BoxProps } from '@shopify/restyle' import React, { memo } from 'react' import { StyleSheet } from 'react-native' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import Box from './Box' type Props = BoxProps diff --git a/src/components/BalanceText.tsx b/src/components/BalanceText.tsx new file mode 100644 index 000000000..018ad72c0 --- /dev/null +++ b/src/components/BalanceText.tsx @@ -0,0 +1,47 @@ +import React, { memo, useMemo } from 'react' +import { TextVariant } from '@config/theme/theme' +import Box from './Box' +import Text from './Text' + +const BalanceText = ({ + amount, + variant = 'textLgSemibold', +}: { + amount: number + variant?: TextVariant +}) => { + const integral = useMemo(() => Math.floor(amount || 0), [amount]) + + const firstFractional = useMemo(() => { + if (amount === undefined) return 0 + const decimal = amount - integral + const fraction = decimal.toString().split('.')[1] + // Fraction with max length of decimals + const fractionWithMaxDecimals = fraction?.slice(0, 1) + return fraction ? Number(fractionWithMaxDecimals) : 0 + }, [amount, integral]) + + const secondFractional = useMemo(() => { + if (amount === undefined) return 0 + const decimal = amount - integral + const fraction = decimal.toString().split('.')[1] + // Fraction with max length of decimals + const fractionWithMaxDecimals = fraction?.slice(1, 2) + return fraction ? Number(fractionWithMaxDecimals) : 0 + }, [amount, integral]) + + return ( + + + + {`${integral.toLocaleString()}`} + + + {`.${firstFractional}${secondFractional}`} + + + + ) +} + +export default memo(BalanceText) diff --git a/src/components/BlurActionSheet.tsx b/src/components/BlurActionSheet.tsx index 18b0819c7..5997bf82e 100644 --- a/src/components/BlurActionSheet.tsx +++ b/src/components/BlurActionSheet.tsx @@ -1,17 +1,16 @@ -import React, { memo, useCallback, useMemo, useRef } from 'react' -import BottomSheet, { - BottomSheetBackdrop, - BottomSheetScrollView, -} from '@gorhom/bottom-sheet' -import { Edge } from 'react-native-safe-area-context' +import React, { memo, useCallback, useRef } from 'react' +import BottomSheet, { BottomSheetBackdrop } from '@gorhom/bottom-sheet' +import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useAsync } from 'react-async-hook' import { Portal } from '@gorhom/portal' import { ThemeProvider } from '@shopify/restyle' -import { lightTheme } from '@theme/theme' +import { lightTheme } from '@config/theme/theme' import { useTranslation } from 'react-i18next' -import SafeAreaBox from './SafeAreaBox' +import { useSpacing } from '@config/theme/themeHooks' import HeliumBottomSheet from './HeliumBottomSheet' import Text from './Text' +import Box from './Box' +import ScrollBox from './ScrollBox' type Props = { title: string @@ -23,6 +22,8 @@ type Props = { const BlurActionSheet = ({ title, open, children, onClose }: Props) => { const bottomSheetModalRef = useRef(null) const { t } = useTranslation() + const { top, bottom } = useSafeAreaInsets() + const spacing = useSpacing() const handleOnClose = useCallback(() => { if (onClose) { @@ -48,7 +49,7 @@ const BlurActionSheet = ({ title, open, children, onClose }: Props) => { opacity={1} {...props} > - + { > {t('blurActionSheet.selectAnOption')} - + ), - [handleOnClose, title, t], + [handleOnClose, title, top, t], ) - const safeEdges = useMemo(() => ['bottom'] as Edge[], []) - return ( { onClose={handleOnClose} > - - + + {children} - - + + diff --git a/src/components/BlurBox.tsx b/src/components/BlurBox.tsx index 5b2f9c8f7..57feae9b3 100644 --- a/src/components/BlurBox.tsx +++ b/src/components/BlurBox.tsx @@ -2,7 +2,7 @@ import React from 'react' import { createBox } from '@shopify/restyle' import { BlurView, BlurViewProps } from '@react-native-community/blur' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' const BlurBox = createBox< Theme, diff --git a/src/components/Box.tsx b/src/components/Box.tsx index 0d175fbfe..4a667b3df 100644 --- a/src/components/Box.tsx +++ b/src/components/Box.tsx @@ -1,5 +1,5 @@ import { createBox } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' const Box = createBox() diff --git a/src/components/ButtonPressAnimation.tsx b/src/components/ButtonPressAnimation.tsx index f37f35279..13e962e36 100644 --- a/src/components/ButtonPressAnimation.tsx +++ b/src/components/ButtonPressAnimation.tsx @@ -1,6 +1,6 @@ import useHaptic from '@hooks/useHaptic' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import React from 'react' import { GestureResponderEvent, diff --git a/src/components/ButtonPressable.tsx b/src/components/ButtonPressable.tsx index 6d7c422bb..92a579f13 100644 --- a/src/components/ButtonPressable.tsx +++ b/src/components/ButtonPressable.tsx @@ -4,8 +4,8 @@ import React, { FC, memo, useState, useMemo } from 'react' import { GestureResponderEvent, ViewStyle } from 'react-native' import { SvgProps } from 'react-native-svg' import { useDebouncedCallback } from 'use-debounce' -import { Color, FontWeight, Theme } from '@theme/theme' -import { useCreateOpacity } from '@theme/themeHooks' +import { Color, FontWeight, Theme } from '@config/theme/theme' +import { useCreateOpacity } from '@config/theme/themeHooks' import Box from './Box' import ButtonPressAnimation from './ButtonPressAnimation' import Text from './Text' @@ -181,7 +181,7 @@ const ButtonPressable = ({ {title && ( diff --git a/src/components/CopyAddress.tsx b/src/components/CopyAddress.tsx index 2ec6860c5..f56f46c0b 100644 --- a/src/components/CopyAddress.tsx +++ b/src/components/CopyAddress.tsx @@ -4,10 +4,10 @@ import { BoxProps } from '@shopify/restyle' import { useTranslation } from 'react-i18next' import Clipboard from '@react-native-community/clipboard' import Toast from 'react-native-simple-toast' -import CopyAddressIcon from '@assets/images/copyAddress.svg' -import { Theme } from '@theme/theme' +import CopyAddressIcon from '@assets/svgs/copyAddress.svg' +import { Theme } from '@config/theme/theme' import useHaptic from '@hooks/useHaptic' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import TouchableOpacityBox from './TouchableOpacityBox' import Text from './Text' import { ellipsizeAddress } from '../utils/accountUtils' diff --git a/src/components/CopyAddressPill.tsx b/src/components/CopyAddressPill.tsx index 2563c8f3a..e44964de3 100644 --- a/src/components/CopyAddressPill.tsx +++ b/src/components/CopyAddressPill.tsx @@ -1,13 +1,13 @@ import React, { memo, useCallback, useMemo } from 'react' import useCopyText from '@hooks/useCopyText' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import useHaptic from '@hooks/useHaptic' import { ellipsizeAddress } from '@utils/accountUtils' import { ViewStyle } from 'react-native' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' -import CopyAddress from '@assets/images/copyAddress.svg' +import { Theme } from '@config/theme/theme' +import CopyAddress from '@assets/svgs/copyAddress.svg' import ButtonPressAnimation from './ButtonPressAnimation' import Text from './Text' import Box from './Box' diff --git a/src/components/CountdownTimer.tsx b/src/components/CountdownTimer.tsx index 9704c2e84..d3112ba10 100644 --- a/src/components/CountdownTimer.tsx +++ b/src/components/CountdownTimer.tsx @@ -9,13 +9,13 @@ import React, { useRef, useState, } from 'react' -import Lock from '@assets/images/lockClosed.svg' +import Lock from '@assets/svgs/lockClosed.svg' import { LayoutChangeEvent } from 'react-native' import { BoxProps } from '@shopify/restyle' import { format } from 'date-fns' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import useDisappear from '@hooks/useDisappear' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import Text from './Text' import Box from './Box' diff --git a/src/components/DynamicQrScanner.tsx b/src/components/DynamicQrScanner.tsx index e3d8a3571..644180cfa 100644 --- a/src/components/DynamicQrScanner.tsx +++ b/src/components/DynamicQrScanner.tsx @@ -6,7 +6,7 @@ import { useNavigation } from '@react-navigation/native' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' import useAlert from '@hooks/useAlert' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { CameraScannerLayout } from './CameraScannerLayout' import Box from './Box' import BackScreen from './BackScreen' diff --git a/src/components/FabButton.tsx b/src/components/FabButton.tsx index c8b8a2be9..f58f31f14 100644 --- a/src/components/FabButton.tsx +++ b/src/components/FabButton.tsx @@ -8,24 +8,26 @@ import { StyleSheet, ViewStyle, } from 'react-native' -import ArrowDown from '@assets/images/downArrow.svg' -import FatArrowUp from '@assets/images/arrowUp.svg' -import Payment from '@assets/images/payment.svg' -import Stake from '@assets/images/stake.svg' -import Lock from '@assets/images/lock.svg' -import Plus from '@assets/images/plus.svg' -import Close from '@assets/images/close.svg' -import Dots from '@assets/images/dots.svg' -import Filter from '@assets/images/filter.svg' -import { Color, FontWeight, Theme } from '@theme/theme' -import { useColors, useCreateOpacity } from '@theme/themeHooks' -import Swaps from '@assets/images/swaps.svg' -import Airdrop from '@assets/images/airdrop.svg' -import MapUserLocation from '@assets/images/mapUserLocation.svg' -import Search from '@assets/images/search.svg' -import Info from '@assets/images/info.svg' -import QuestionMark from '@assets/images/questionMark.svg' -import BrowseVoters from '@assets/images/browseVoters.svg' +import ArrowDown from '@assets/svgs/arrowDown.svg' +import Settings from '@assets/svgs/settings.svg' +import FatArrowUp from '@assets/svgs/arrowUp.svg' +import Payment from '@assets/svgs/payment.svg' +import Stake from '@assets/svgs/stake.svg' +import Lock from '@assets/svgs/lock.svg' +import Plus from '@assets/svgs/plus.svg' +import Close from '@assets/svgs/close.svg' +import Dots from '@assets/svgs/dots.svg' +import Filter from '@assets/svgs/filter.svg' +import { Color, FontWeight, Theme } from '@config/theme/theme' +import { useColors, useCreateOpacity } from '@config/theme/themeHooks' +import Swaps from '@assets/svgs/swaps.svg' +import Airdrop from '@assets/svgs/airdrop.svg' +import MapUserLocation from '@assets/svgs/mapUserLocation.svg' +import Search from '@assets/svgs/search.svg' +import Info from '@assets/svgs/info.svg' +import QuestionMark from '@assets/svgs/questionMark.svg' +import BrowseVoters from '@assets/svgs/browseVoters.svg' +import Expand from '@assets/svgs/expand.svg' import Box from './Box' import Text from './Text' import ButtonPressAnimation from './ButtonPressAnimation' @@ -49,7 +51,9 @@ type IconName = | 'info' | 'questionMark' | 'browseVoters' - + | 'expand' + | 'settings' + | 'arrowLeft' type Props = BoxProps & { backgroundColorOpacity?: number backgroundColorPressed?: Color @@ -247,6 +251,13 @@ const FabIcon = ({ icon, pressed, color, colorPressed }: IconProps) => { style={{ transform: [{ rotate: '270deg' }] }} /> ) + case 'arrowLeft': + return ( + + ) case 'arrowDown': return case 'fatArrowUp': @@ -287,6 +298,10 @@ const FabIcon = ({ icon, pressed, color, colorPressed }: IconProps) => { return case 'browseVoters': return + case 'expand': + return + case 'settings': + return } } diff --git a/src/components/FinePrint.tsx b/src/components/FinePrint.tsx index 683311123..f1a9e548b 100644 --- a/src/components/FinePrint.tsx +++ b/src/components/FinePrint.tsx @@ -3,9 +3,9 @@ import React, { memo, useCallback } from 'react' import { Linking, TouchableOpacity } from 'react-native' import { useTranslation } from 'react-i18next' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import Text from './Text' -import { PRIVACY_POLICY, TERMS_OF_SERVICE } from '../constants/urls' +import { PRIVACY_POLICY, TERMS_OF_SERVICE } from '../utils/constants/urls' import Box from './Box' type Props = BoxProps diff --git a/src/components/GlobalError.tsx b/src/components/GlobalError.tsx index cfac64bd8..319b99c50 100644 --- a/src/components/GlobalError.tsx +++ b/src/components/GlobalError.tsx @@ -1,4 +1,4 @@ -import CopyAddress from '@assets/images/copyAddress.svg' +import CopyAddress from '@assets/svgs/copyAddress.svg' import useCopyText from '@hooks/useCopyText' import useHaptic from '@hooks/useHaptic' import React, { useCallback } from 'react' diff --git a/src/components/HNTKeyboard.tsx b/src/components/HNTKeyboard.tsx index b597917c5..387ca993e 100644 --- a/src/components/HNTKeyboard.tsx +++ b/src/components/HNTKeyboard.tsx @@ -1,4 +1,4 @@ -import PaymentArrow from '@assets/images/paymentArrow.svg' +import PaymentArrow from '@assets/svgs/paymentArrow.svg' import BottomSheet, { BottomSheetBackdrop, BottomSheetModalProvider, @@ -14,8 +14,8 @@ import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { BoxProps, ThemeProvider } from '@shopify/restyle' import { NATIVE_MINT } from '@solana/spl-token' import { PublicKey } from '@solana/web3.js' -import { Theme, lightTheme } from '@theme/theme' -import { useSafeTopPaddingStyle } from '@theme/themeHooks' +import { Theme, lightTheme } from '@config/theme/theme' +import { useSafeTopPaddingStyle } from '@config/theme/themeHooks' import BN from 'bn.js' import React, { ReactNode, @@ -31,8 +31,8 @@ import React, { import { useTranslation } from 'react-i18next' import { LayoutChangeEvent } from 'react-native' import { Edge } from 'react-native-safe-area-context' -import { Payment } from '../features/payment/PaymentItem' -import { CSAccount } from '../storage/cloudStorage' +import { Payment } from '@features/payment/PaymentItem' +import { CSAccount } from '@config/storage/cloudStorage' import { decimalSeparator, groupSeparator } from '../utils/i18n' import { humanReadable } from '../utils/solanaUtils' import AccountIcon from './AccountIcon' @@ -177,7 +177,10 @@ const HNTKeyboardSelector = forwardRef( : undefined setValue(val || '0') - bottomSheetModalRef.current?.expand() + // wait 1 render cycle to expand + setTimeout(() => { + bottomSheetModalRef.current?.expand() + }, 100) }, [handleVisible, decimals], ) diff --git a/src/components/HandleBasic.tsx b/src/components/HandleBasic.tsx index f097bc6d3..394e72a51 100644 --- a/src/components/HandleBasic.tsx +++ b/src/components/HandleBasic.tsx @@ -1,7 +1,7 @@ /* eslint-disable react/jsx-props-no-spreading */ import { BoxProps } from '@shopify/restyle' import React from 'react' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import Box from './Box' type Props = BoxProps diff --git a/src/components/HeliumActionSheet.tsx b/src/components/HeliumActionSheet.tsx index ee5442d51..948bd2e24 100644 --- a/src/components/HeliumActionSheet.tsx +++ b/src/components/HeliumActionSheet.tsx @@ -10,13 +10,13 @@ import React, { useState, } from 'react' import { BoxProps } from '@shopify/restyle' -import CarotDown from '@assets/images/carot-down.svg' -import Kabob from '@assets/images/kabob.svg' +import CarotDown from '@assets/svgs/carot-down.svg' +import Kabob from '@assets/svgs/kabob.svg' import { useTranslation } from 'react-i18next' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { FlatList } from 'react-native-gesture-handler' -import { Color, Theme } from '@theme/theme' -import { useColors, useHitSlop } from '@theme/themeHooks' +import { Color, Theme } from '@config/theme/theme' +import { useColors, useHitSlop } from '@config/theme/themeHooks' import HeliumActionSheetItem, { HeliumActionSheetItemHeight, HeliumActionSheetItemType, diff --git a/src/components/HeliumActionSheetItem.tsx b/src/components/HeliumActionSheetItem.tsx index 45860b4d4..0db5945f7 100644 --- a/src/components/HeliumActionSheetItem.tsx +++ b/src/components/HeliumActionSheetItem.tsx @@ -1,7 +1,7 @@ import React, { memo, useMemo } from 'react' import { SvgProps } from 'react-native-svg' -import { Color } from '@theme/theme' -import { useColors } from '@theme/themeHooks' +import { Color } from '@config/theme/theme' +import { useColors } from '@config/theme/themeHooks' import Text from './Text' import TouchableOpacityBox from './TouchableOpacityBox' diff --git a/src/components/HeliumBottomActionSheet.tsx b/src/components/HeliumBottomActionSheet.tsx index 91a3caecc..bc455c7ae 100644 --- a/src/components/HeliumBottomActionSheet.tsx +++ b/src/components/HeliumBottomActionSheet.tsx @@ -1,14 +1,14 @@ import React, { memo, useCallback, useEffect } from 'react' import { BoxProps } from '@shopify/restyle' -import Close from '@assets/images/close.svg' +import Close from '@assets/svgs/close.svg' import { Modal } from 'react-native' import { useAnimatedStyle, useSharedValue, withSpring, } from 'react-native-reanimated' -import { Theme } from '@theme/theme' -import { useColors } from '@theme/themeHooks' +import { Theme } from '@config/theme/theme' +import { useColors } from '@config/theme/themeHooks' import useDisappear from '@hooks/useDisappear' import Text from './Text' import Box from './Box' diff --git a/src/components/HeliumBottomSheet.tsx b/src/components/HeliumBottomSheet.tsx index 8bb36145b..7c12781c3 100644 --- a/src/components/HeliumBottomSheet.tsx +++ b/src/components/HeliumBottomSheet.tsx @@ -5,7 +5,7 @@ import { useBorderRadii, useColors, useSpacing, -} from '@theme/themeHooks' +} from '@config/theme/themeHooks' import { wh } from '@utils/layout' import { Platform, StyleProp, ViewStyle } from 'react-native' import { useSharedValue } from 'react-native-reanimated' @@ -33,7 +33,7 @@ const HeliumBottomSheet = forwardRef( return { width: 90, height: 4, - backgroundColor: colors.secondaryText, + backgroundColor: colors['base.black'], } }, [colors]) @@ -44,7 +44,7 @@ const HeliumBottomSheet = forwardRef( top: 0, left: 0, right: 0, - backgroundColor: 'transparent', + opacity: 0.1, } as StyleProp), [], ) @@ -64,6 +64,7 @@ const HeliumBottomSheet = forwardRef( (Image) diff --git a/src/components/IndeterminateProgressBar.tsx b/src/components/IndeterminateProgressBar.tsx index 0e3d579a0..8d170952d 100644 --- a/src/components/IndeterminateProgressBar.tsx +++ b/src/components/IndeterminateProgressBar.tsx @@ -9,7 +9,7 @@ import { withRepeat, withTiming, } from 'react-native-reanimated' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import { ReAnimatedBox } from './AnimatedBox' import Box from './Box' diff --git a/src/components/Keypad.tsx b/src/components/Keypad.tsx index 3339d3891..46e86af24 100644 --- a/src/components/Keypad.tsx +++ b/src/components/Keypad.tsx @@ -1,7 +1,7 @@ import React, { memo, useCallback } from 'react' import { BoxProps } from '@shopify/restyle' import useHaptic from '@hooks/useHaptic' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import Box from './Box' import KeypadButton, { KeypadCustomInput, KeypadInput } from './KeypadButton' diff --git a/src/components/KeypadButton.tsx b/src/components/KeypadButton.tsx index 8f081c0d8..24dba2ce0 100644 --- a/src/components/KeypadButton.tsx +++ b/src/components/KeypadButton.tsx @@ -1,9 +1,9 @@ /* eslint-disable react/jsx-props-no-spreading */ import React, { useCallback } from 'react' import { Pressable } from 'react-native' -import Backspace from '@assets/images/backspace.svg' +import Backspace from '@assets/svgs/backspace.svg' import { useTranslation } from 'react-i18next' -import { useColors, useHitSlop, useOpacity } from '@theme/themeHooks' +import { useColors, useHitSlop, useOpacity } from '@config/theme/themeHooks' import Box from './Box' import Text from './Text' import { decimalSeparator } from '../utils/i18n' diff --git a/src/components/ListItem.tsx b/src/components/ListItem.tsx index a03410b62..ab3cbfd72 100644 --- a/src/components/ListItem.tsx +++ b/src/components/ListItem.tsx @@ -1,7 +1,7 @@ import React from 'react' -import CheckMarkFill from '@assets/images/checkmarkFill.svg' -import { useColors } from '@theme/themeHooks' -import { Color, Theme } from '@theme/theme' +import CheckMarkFill from '@assets/svgs/checkmarkFill.svg' +import { useColors } from '@config/theme/themeHooks' +import { Color, Theme } from '@config/theme/theme' import { Insets } from 'react-native' import { BoxProps } from '@shopify/restyle' import Box from './Box' diff --git a/src/components/ListSeperator.tsx b/src/components/ListSeperator.tsx new file mode 100644 index 000000000..b93c707b3 --- /dev/null +++ b/src/components/ListSeperator.tsx @@ -0,0 +1,10 @@ +import { BoxProps } from '@shopify/restyle' +import React from 'react' +import { Theme } from '@config/theme/theme' +import Box from './Box' + +const ListSeparator = (props: BoxProps) => ( + +) + +export default ListSeparator diff --git a/src/components/MakerHotspotImage.tsx b/src/components/MakerHotspotImage.tsx new file mode 100644 index 000000000..bb3fe993c --- /dev/null +++ b/src/components/MakerHotspotImage.tsx @@ -0,0 +1,570 @@ +import React, { useCallback } from 'react' +import { BoxProps } from '@shopify/restyle' +import { Theme } from '@config/theme/theme' +import ImageBox from './ImageBox' + +const MakerHotspotImage = ({ + maker, + deviceType, + subDao, + ...rest +}: { + maker: string + deviceType: string + subDao: 'iot' | 'mobile' +} & BoxProps) => { + const Image = useCallback( + ({ + deviceType: dType, + subDao: dao, + ...boxProps + }: { deviceType: string; subDao: 'iot' | 'mobile' } & BoxProps) => { + switch (maker) { + default: + case 'Nova Labs': + if (dType === 'cbrs') { + return ( + + ) + } + if (dao === 'iot') { + return ( + + ) + } + return ( + + ) + case 'Nebra Ltd': + return ( + + ) + case 'Maker Integration Tests': + return ( + + ) + case 'Smart Harvest': + return ( + + ) + case 'Osprey': + return ( + + ) + case 'COTX Networks': + return ( + + ) + case 'OPTION': + return ( + + ) + case 'Heltec Automation': + return ( + + ) + case 'Bobcat': + return ( + + ) + case 'Helium Inc': + return ( + + ) + case 'Dusun': + return ( + + ) + case 'RAKwireless': + return ( + + ) + case 'SONoC': + return ( + + ) + case 'Mimiq': + return ( + + ) + case 'DeWi Foundation': + return ( + + ) + case 'CalChip Connect': + return ( + + ) + case 'Polyhex': + return ( + + ) + case 'SenseCAP': + return ( + + ) + case 'Atom': + return ( + + ) + case 'embit': + return ( + + ) + case 'KS Technologies': + return ( + + ) + case 'FreedomFi': + return ( + + ) + case 'RisingHF': + return ( + + ) + case 'MNTD': + return ( + + ) + case 'Dragino': + return ( + + ) + case 'hummingbird': + return ( + + ) + case 'Migrated Helium Hotspot': + return ( + + ) + case 'Milesight': + return ( + + ) + case 'Pisces Miner': + return ( + + ) + case 'PantherX': + return ( + + ) + case 'Nebra 5G': + return ( + + ) + case 'ClodPi': + return ( + + ) + case 'Deeper': + return ( + + ) + case 'LongAP': + return ( + + ) + case 'Aitek Inc': + return ( + + ) + case 'Kerlink': + return ( + + ) + case 'ResIOT.io': + return ( + + ) + case 'SyncroB.it': + return ( + + ) + case 'Bobcat 5G': + return ( + + ) + case 'Linxdot': + return ( + + ) + case 'Controllino': + return ( + + ) + case 'EDA-IoT': + return ( + + ) + case 'TMG': + return ( + + ) + case 'Midas': + return ( + + ) + case 'uG Miner': + return ( + + ) + case 'Pycom': + return ( + + ) + case 'Browan/MerryIoT': + return ( + + ) + } + }, + [maker], + ) + + return +} + +export default MakerHotspotImage diff --git a/src/components/Map.tsx b/src/components/Map.tsx new file mode 100644 index 000000000..804c48310 --- /dev/null +++ b/src/components/Map.tsx @@ -0,0 +1,26 @@ +import Mapbox from '@rnmapbox/maps' +import { HELIUM_WORLD_NO_LABELS } from '@utils/constants' +import React, { forwardRef } from 'react' + +const Map = forwardRef< + Mapbox.MapView, + React.ComponentProps & { children?: React.ReactNode } +>(({ children, ...rest }, ref) => { + return ( + + {children} + + ) +}) + +export default Map diff --git a/src/components/Markdown.tsx b/src/components/Markdown.tsx index 9fd69f2b7..e9e2fbe6f 100644 --- a/src/components/Markdown.tsx +++ b/src/components/Markdown.tsx @@ -1,5 +1,5 @@ import { useTheme } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import React from 'react' import MarkdownDisplay from 'react-native-markdown-display' diff --git a/src/components/MemoInput.tsx b/src/components/MemoInput.tsx index b6b584c29..bf367c615 100644 --- a/src/components/MemoInput.tsx +++ b/src/components/MemoInput.tsx @@ -1,7 +1,7 @@ import { BoxProps } from '@shopify/restyle' import React, { memo, useMemo } from 'react' import { useTranslation } from 'react-i18next' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import Box from './Box' import Text from './Text' import TextInput from './TextInput' diff --git a/src/components/MiniMap.tsx b/src/components/MiniMap.tsx new file mode 100644 index 000000000..b7be0ed25 --- /dev/null +++ b/src/components/MiniMap.tsx @@ -0,0 +1,107 @@ +import Mapbox, { + Location, + Camera, + Images, + MarkerView, + UserLocation, +} from '@rnmapbox/maps' +import { Box, FabButton, ImageBox } from '@components/index' +import React, { useCallback, useRef, useState } from 'react' +import { useSpacing } from '@config/theme/themeHooks' +import { useNavigation } from '@react-navigation/native' +import Map from '@components/Map' +import HotspotMarker from '@assets/svgs/hotspotMarker.svg' +import { HotspotServiceNavigationProp } from '../app/services/HotspotService' + +type MiniMapProps = { + hasExpandButton?: boolean + height?: number + lat?: number + long?: number + children?: React.ReactNode + onUserLocationUpdate?: (location: Location) => void +} + +const MiniMap = ({ + hasExpandButton = true, + height = 253, + lat, + long, + onUserLocationUpdate, + children, +}: MiniMapProps) => { + const mapRef = useRef(null) + const spacing = useSpacing() + const navigation = useNavigation() + const [userLocation, setUserLocation] = useState() + + const onExpand = useCallback(() => { + navigation.navigate('Explorer') + }, [navigation]) + + const handleUserLocationUpdate = useCallback( + (location: Location) => { + setUserLocation(location) + onUserLocationUpdate?.(location) + }, + [onUserLocationUpdate], + ) + + return ( + + + + + {lat && long ? ( + + + + ) : ( + + + + + + )} + {children} + + {hasExpandButton && ( + + )} + + ) +} + +export default MiniMap diff --git a/src/components/NavBar.tsx b/src/components/NavBar.tsx index 5ac2e949b..d9ad44cd3 100644 --- a/src/components/NavBar.tsx +++ b/src/components/NavBar.tsx @@ -13,7 +13,7 @@ import Animated, { withSpring, } from 'react-native-reanimated' import { SvgProps } from 'react-native-svg' -import { useColors, useVerticalHitSlop } from '@theme/themeHooks' +import { useColors, useVerticalHitSlop } from '@config/theme/themeHooks' import Box from './Box' import TouchableOpacityBox, { TouchableOpacityBoxProps, diff --git a/src/components/Pill.tsx b/src/components/Pill.tsx index cb1c2bd60..ac0efcdd3 100644 --- a/src/components/Pill.tsx +++ b/src/components/Pill.tsx @@ -1,6 +1,6 @@ import Box from '@components/Box' import { TextProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import React, { memo } from 'react' import { SvgProps } from 'react-native-svg' import Text from './Text' diff --git a/src/components/PinDisplay.tsx b/src/components/PinDisplay.tsx index 3ddde1d3f..6f8e64b09 100644 --- a/src/components/PinDisplay.tsx +++ b/src/components/PinDisplay.tsx @@ -1,7 +1,7 @@ /* eslint-disable react/jsx-props-no-spreading */ import { BoxProps } from '@shopify/restyle' import React, { memo } from 'react' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import Box from './Box' import Dot from './Dot' diff --git a/src/components/ProgressBar.tsx b/src/components/ProgressBar.tsx index c1b84c1c8..a695f24af 100644 --- a/src/components/ProgressBar.tsx +++ b/src/components/ProgressBar.tsx @@ -1,19 +1,21 @@ import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import React, { useCallback, useEffect, useMemo, useState } from 'react' import { LayoutChangeEvent, LayoutRectangle } from 'react-native' import { useAnimatedStyle, useSharedValue, - withSpring, + withTiming, } from 'react-native-reanimated' import { ReAnimatedBox } from './AnimatedBox' import Box from './Box' +import Text from './Text' const ProgressBar = ({ progress: progressIn, + withLabel = false, ...rest -}: BoxProps & { progress: number }) => { +}: BoxProps & { progress: number; withLabel?: boolean }) => { const HEIGHT = 15 const [progressRect, setProgressRect] = useState() @@ -33,7 +35,7 @@ const ProgressBar = ({ useEffect(() => { // withRepeat to repeat the animation - width.value = withSpring((progressIn / 100) * PROGRESS_WIDTH) + width.value = withTiming((progressIn / 100) * PROGRESS_WIDTH) }, [PROGRESS_WIDTH, width, progressIn]) const progress = useAnimatedStyle(() => { @@ -48,19 +50,28 @@ const ProgressBar = ({ {...rest} borderRadius="full" width="100%" - height={HEIGHT} - backgroundColor="transparent10" - overflow="hidden" - flexDirection="row" + flexDirection="column" justifyContent="flex-start" + gap="2" > - - - + + + + + + {withLabel && ( + + {`Progress: ${progressIn}%`} + + )} ) } diff --git a/src/components/RadioButton.tsx b/src/components/RadioButton.tsx index fa9b9a4f1..bcf6e3cc8 100644 --- a/src/components/RadioButton.tsx +++ b/src/components/RadioButton.tsx @@ -27,7 +27,7 @@ const RadioButton: React.FC = ({ width={20} borderRadius="full" borderWidth={2} - borderColor="blue.light-500" + borderColor="text.quaternary-500" alignItems="center" justifyContent="center" onPress={() => onClick()} @@ -36,7 +36,7 @@ const RadioButton: React.FC = ({ width={10} height={10} borderRadius="full" - backgroundColor={selected ? 'blue.light-500' : 'transparent'} + backgroundColor={selected ? 'base.black' : 'transparent'} /> >( SafeAreaView, diff --git a/src/components/ScrollBox.tsx b/src/components/ScrollBox.tsx index 8ae28b0aa..1e4d64abf 100644 --- a/src/components/ScrollBox.tsx +++ b/src/components/ScrollBox.tsx @@ -1,6 +1,6 @@ import { createBox } from '@shopify/restyle' import { ReactNode } from 'react' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import { ScrollViewProps } from 'react-native' import { ScrollView } from 'react-native-gesture-handler' diff --git a/src/components/Search.tsx b/src/components/Search.tsx new file mode 100644 index 000000000..8d203fb6d --- /dev/null +++ b/src/components/Search.tsx @@ -0,0 +1,50 @@ +import React from 'react' +import SearchIcon from '@assets/svgs/searchIcon.svg' +import { BoxProps } from '@shopify/restyle' +import { Theme } from '@config/theme/theme' +import { useColors, useTextVariants } from '@config/theme/themeHooks' +import { TextInput } from 'react-native' +import Box from './Box' + +type SearchProps = BoxProps & { + placeholder: string + onChangeText: (text: string) => void + onEnter?: () => void +} + +export const Search = ({ + placeholder, + onChangeText, + onEnter, + ...rest +}: SearchProps) => { + const textVariants = useTextVariants() + const colors = useColors() + return ( + + + + + ) +} diff --git a/src/components/SearchInput.tsx b/src/components/SearchInput.tsx index 0fe871714..24ad2a66a 100644 --- a/src/components/SearchInput.tsx +++ b/src/components/SearchInput.tsx @@ -1,8 +1,8 @@ /* eslint-disable react/jsx-props-no-spreading */ -import Search from '@assets/images/search.svg' +import Search from '@assets/svgs/search.svg' import { BoxProps } from '@shopify/restyle' -import { BorderRadii, Spacing, Theme } from '@theme/theme' -import { useColors, useInputVariants } from '@theme/themeHooks' +import { BorderRadii, Spacing, Theme } from '@config/theme/theme' +import { useColors, useInputVariants } from '@config/theme/themeHooks' import React, { useCallback } from 'react' import { TextInputProps } from 'react-native' import Box from './Box' diff --git a/src/components/SecretKeyWarningScreen.tsx b/src/components/SecretKeyWarningScreen.tsx index b1ab78c48..b860f840e 100644 --- a/src/components/SecretKeyWarningScreen.tsx +++ b/src/components/SecretKeyWarningScreen.tsx @@ -1,6 +1,6 @@ import React, { memo, ReactNode, useCallback, useEffect, useState } from 'react' import { View } from 'react-native' -import InfoWarning from '@assets/images/customWarning.svg' +import InfoWarning from '@assets/svgs/customWarning.svg' import { useTranslation } from 'react-i18next' import Animated, { runOnJS, @@ -8,8 +8,8 @@ import Animated, { useSharedValue, withTiming, } from 'react-native-reanimated' -import globalStyles from '@theme/globalStyles' -import { useColors } from '@theme/themeHooks' +import globalStyles from '@config/theme/globalStyles' +import { useColors } from '@config/theme/themeHooks' import Text from './Text' import Box from './Box' import ButtonPressable from './ButtonPressable' diff --git a/src/components/SegmentedControl.tsx b/src/components/SegmentedControl.tsx index 162752535..4fdd8bb04 100644 --- a/src/components/SegmentedControl.tsx +++ b/src/components/SegmentedControl.tsx @@ -11,9 +11,9 @@ import React, { import { BoxProps } from '@shopify/restyle' import { GestureResponderEvent, LayoutChangeEvent } from 'react-native' import { SvgProps } from 'react-native-svg' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { useAnimatedStyle, withTiming } from 'react-native-reanimated' -import { Theme } from '../theme/theme' +import { Theme } from '../config/theme/theme' import { Box, ReAnimatedBox, Text } from '.' import TouchableOpacityBox from './TouchableOpacityBox' @@ -30,12 +30,14 @@ const SegmentedItem = ({ onSelected, onSetWidth, fullWidth, + size, }: { option: Option selected: boolean onSelected: ((event: GestureResponderEvent) => void) | undefined onSetWidth: (width: number) => void fullWidth?: boolean + size?: 'sm' | 'md' }) => { const { primaryBackground, ...colors } = useColors() const [hasTouched, setHasTouched] = useState(false) @@ -71,8 +73,8 @@ const SegmentedItem = ({ return ( void fullWidth?: boolean + size?: 'sm' | 'md' } & BoxProps const SegmentedControl = forwardRef( ( - { options, onItemSelected, fullWidth, ...boxProps }: Props, + { options, onItemSelected, fullWidth, size = 'sm', ...boxProps }: Props, ref: Ref, ) => { const [selectedIndex, setSelectedIndex] = useState(0) @@ -180,6 +183,7 @@ const SegmentedControl = forwardRef( selected={index === selectedIndex} onSelected={handleItemSelected(index)} onSetWidth={onSetWidth(index)} + size={size} /> ))} diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 7103b395e..5c3a93062 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -1,38 +1,103 @@ -import { useColors } from '@theme/themeHooks' -import ChevronDown from '@assets/images/chevronDown.svg' +import { useColors } from '@config/theme/themeHooks' +import ChevronDown from '@assets/svgs/chevronDown.svg' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' -import React, { useState } from 'react' +import { Theme } from '@config/theme/theme' +import React, { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' +import { FlatList } from 'react-native' import BlurActionSheet from './BlurActionSheet' import Box from './Box' import ListItem from './ListItem' import Text from './Text' import TouchableContainer from './TouchableContainer' +import { Search } from './Search' export type SelectProps = { - value: string - onValueChange: (value: string) => void + placeholder: string + initialValue: string | number | undefined + onValueChange: (value: string | number) => void + hasSearch?: boolean options: { label: string - value: string + value: string | number + subLabel?: string icon?: React.ReactNode }[] } & BoxProps export const Select: React.FC = ({ - value, + initialValue, onValueChange, options, + placeholder, + hasSearch, ...rest }) => { + const [value, setValue] = useState(initialValue) const [filtersOpen, setFiltersOpen] = useState(false) const { t } = useTranslation() const colors = useColors() + const selectedOption = useMemo( + () => options.find((o) => o.value === value), + [options, value], + ) + + const [filteredOptions, setFilteredOptions] = useState(options) + + const onFilterChange = useCallback( + (text: string) => { + if (text === '') { + setFilteredOptions(options) + } else { + setFilteredOptions(options.filter((o) => o.label.includes(text))) + } + }, + [options], + ) + + const renderItem = useCallback( + ({ item, index }: { item: (typeof options)[0]; index: number }) => { + const borderTopStartRadius = index === 0 ? 'xl' : 'none' + const borderTopEndRadius = index === 0 ? 'xl' : 'none' + const borderBottomStartRadius = + index === filteredOptions.length - 1 ? 'xl' : 'none' + const borderBottomEndRadius = + index === filteredOptions.length - 1 ? 'xl' : 'none' + + return ( + { + setValue(item.value) + onValueChange(item.value) + setFiltersOpen(false) + }} + selected={value === item.value} + borderTopStartRadius={borderTopStartRadius} + borderTopEndRadius={borderTopEndRadius} + borderBottomStartRadius={borderBottomStartRadius} + borderBottomEndRadius={borderBottomEndRadius} + /> + ) + }, + [onValueChange, filteredOptions, value], + ) + + const renderHeader = useCallback(() => { + return hasSearch ? ( + + ) : null + }, [hasSearch, placeholder, onFilterChange]) + return ( <> = ({ onPress={() => setFiltersOpen(true)} {...rest} > - - {options.find((o) => o.value === value)?.icon} - - {options.find((o) => o.value === value)?.label} - + + + {selectedOption?.icon} + {selectedOption ? ( + + {selectedOption?.label} + + ) : ( + + {placeholder} + + )} + + {selectedOption?.subLabel && ( + + {selectedOption?.subLabel} + + )} @@ -55,32 +133,12 @@ export const Select: React.FC = ({ open={filtersOpen} onClose={() => setFiltersOpen(false)} > - - {options.map((option, index) => { - const borderTopStartRadius = index === 0 ? 'xl' : 'none' - const borderTopEndRadius = index === 0 ? 'xl' : 'none' - const borderBottomStartRadius = - index === options.length - 1 ? 'xl' : 'none' - const borderBottomEndRadius = - index === options.length - 1 ? 'xl' : 'none' - - return ( - { - onValueChange(option.value) - setFiltersOpen(false) - }} - selected={value === option.value} - borderTopStartRadius={borderTopStartRadius} - borderTopEndRadius={borderTopEndRadius} - borderBottomStartRadius={borderBottomStartRadius} - borderBottomEndRadius={borderBottomEndRadius} - /> - ) - })} - + `${item.value}`} + ListHeaderComponent={renderHeader} + /> ) diff --git a/src/components/ServiceNavBar.tsx b/src/components/ServiceNavBar.tsx index 0f2d4abd8..ffe8abbed 100644 --- a/src/components/ServiceNavBar.tsx +++ b/src/components/ServiceNavBar.tsx @@ -13,7 +13,7 @@ import Animated, { withSpring, } from 'react-native-reanimated' import { SvgProps } from 'react-native-svg' -import { useColors, useVerticalHitSlop } from '@theme/themeHooks' +import { useColors, useVerticalHitSlop } from '@config/theme/themeHooks' import Box from './Box' import TouchableOpacityBox, { TouchableOpacityBoxProps, @@ -176,7 +176,7 @@ const NavServiceNavBar = ({ {...containerProps} paddingHorizontal="2xl" flexDirection="row" - justifyContent="center" + flex={1} shadowColor="base.black" shadowOpacity={0.3} shadowOffset={{ width: 0, height: 6 }} @@ -188,6 +188,7 @@ const NavServiceNavBar = ({ backgroundColor="primaryText" borderRadius="full" padding="md" + flex={1} gap="2" > {items} diff --git a/src/components/ServiceSheetPage.tsx b/src/components/ServiceSheetPage.tsx index 261a9471d..1462a5844 100644 --- a/src/components/ServiceSheetPage.tsx +++ b/src/components/ServiceSheetPage.tsx @@ -5,11 +5,11 @@ import { createBottomTabNavigator, } from '@react-navigation/bottom-tabs' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { Color } from '@theme/theme' +import { Color } from '@config/theme/theme' import Box from '@components/Box' import useEnrichedTransactions from '@hooks/useEnrichedTransactions' import useHaptic from '@hooks/useHaptic' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import ServiceNavBar from './ServiceNavBar' const Tab = createBottomTabNavigator() diff --git a/src/components/SplashScreen.tsx b/src/components/SplashScreen.tsx index f4258ab29..2afebb050 100644 --- a/src/components/SplashScreen.tsx +++ b/src/components/SplashScreen.tsx @@ -6,10 +6,10 @@ import Animated, { useSharedValue, withTiming, } from 'react-native-reanimated' -import globalStyles from '@theme/globalStyles' -import { useColors } from '@theme/themeHooks' -import { useAccountStorage } from '../storage/AccountStorageProvider' -import { useAppStorage } from '../storage/AppStorageProvider' +import globalStyles from '@config/theme/globalStyles' +import { useColors } from '@config/theme/themeHooks' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' import { ReAnimatedBox } from './AnimatedBox' const SplashScreen = ({ children }: { children: ReactNode }) => { diff --git a/src/components/SubmitButton.tsx b/src/components/SubmitButton.tsx index b0d8caa7c..ae780f14f 100644 --- a/src/components/SubmitButton.tsx +++ b/src/components/SubmitButton.tsx @@ -1,9 +1,10 @@ import { BoxProps } from '@shopify/restyle' import React, { memo, useMemo } from 'react' import SwipeButton from 'rn-swipe-button' -import SwipeIcon from '@assets/images/swipeIcon.svg' -import { Font, Theme } from '@theme/theme' -import { useColors } from '@theme/themeHooks' +import SwipeIcon from '@assets/svgs/swipeIcon.svg' +import { Font, Theme } from '@config/theme/theme' +import { useColors } from '@config/theme/themeHooks' +import { StyleProp, TextStyle } from 'react-native' import Box from './Box' type Props = { @@ -37,6 +38,7 @@ const SubmitButton = ({ color: disabled ? secondaryText : colorActual, fontSize: 19, paddingLeft: 30, + fontWeight: 600, }, railStyles: { backgroundColor: rest['bg.tertiary'], @@ -58,7 +60,7 @@ const SubmitButton = ({ railBackgroundColor={backgroundActual} railStyles={styles.railStyles} railBorderColor={backgroundActual} - titleStyles={styles.titleStyles} + titleStyles={styles.titleStyles as StyleProp} titleMaxFontScale={1} thumbIconBackgroundColor={backgroundActual} thumbIconBorderColor={colorActual} diff --git a/src/components/Surface.tsx b/src/components/Surface.tsx index a27d6523d..dd29b0783 100644 --- a/src/components/Surface.tsx +++ b/src/components/Surface.tsx @@ -2,8 +2,8 @@ import { BoxProps } from '@shopify/restyle' import React, { memo, useMemo } from 'react' import { StyleProp, ViewStyle } from 'react-native' -import { Color, Theme } from '@theme/theme' -import { useColorScheme, useCreateOpacity } from '@theme/themeHooks' +import { Color, Theme } from '@config/theme/theme' +import { useColorScheme, useCreateOpacity } from '@config/theme/themeHooks' import Box from './Box' type Props = BoxProps & { diff --git a/src/components/TabBar.tsx b/src/components/TabBar.tsx index f9238677d..5d5f8022a 100644 --- a/src/components/TabBar.tsx +++ b/src/components/TabBar.tsx @@ -14,8 +14,8 @@ import Animated, { } from 'react-native-reanimated' import { SvgProps } from 'react-native-svg' import useHaptic from '@hooks/useHaptic' -import { Color } from '@theme/theme' -import { useColors, useVerticalHitSlop } from '@theme/themeHooks' +import { Color } from '@config/theme/theme' +import { useColors, useVerticalHitSlop } from '@config/theme/themeHooks' import Box from './Box' import Text from './Text' import TouchableOpacityBox, { diff --git a/src/components/Text.tsx b/src/components/Text.tsx index 63309d83c..39a3bb59c 100644 --- a/src/components/Text.tsx +++ b/src/components/Text.tsx @@ -1,5 +1,5 @@ import React from 'react' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import createText from './createText' const Text = createText() diff --git a/src/components/TextInput.tsx b/src/components/TextInput.tsx index 77b2bd075..305823b6e 100644 --- a/src/components/TextInput.tsx +++ b/src/components/TextInput.tsx @@ -8,8 +8,12 @@ import { import { TextInput, TextStyle } from 'react-native' import tinycolor from 'tinycolor2' import { SvgProps } from 'react-native-svg' -import { Color, darkTheme, Theme } from '@theme/theme' -import { useColors, useInputVariants, useTextVariants } from '@theme/themeHooks' +import { Color, darkTheme, Theme } from '@config/theme/theme' +import { + useColors, + useInputVariants, + useTextVariants, +} from '@config/theme/themeHooks' import Box from './Box' import Text from './Text' import TouchableOpacityBox, { diff --git a/src/components/TextInputNew.tsx b/src/components/TextInputNew.tsx new file mode 100644 index 000000000..85d3b1ed9 --- /dev/null +++ b/src/components/TextInputNew.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import { BoxProps } from '@shopify/restyle' +import { Theme } from '@config/theme/theme' +import { useColors, useTextVariants } from '@config/theme/themeHooks' +import { TextInput, TextInputProps } from 'react-native' +import Box from './Box' +import Text from './Text' + +type SearchProps = BoxProps & { + label: string + textInputProps?: TextInputProps +} + +const TextInputNew = ({ label, textInputProps, ...rest }: SearchProps) => { + const textVariants = useTextVariants() + const colors = useColors() + return ( + + {label} + + + ) +} + +export default TextInputNew diff --git a/src/components/TextTransform.tsx b/src/components/TextTransform.tsx index 61f7b02c3..dcdb625cb 100644 --- a/src/components/TextTransform.tsx +++ b/src/components/TextTransform.tsx @@ -4,7 +4,7 @@ import React, { useMemo } from 'react' import { Trans } from 'react-i18next' import { ResponsiveValue, TextProps } from '@shopify/restyle' -import { TextVariant, Theme } from '@theme/theme' +import { TextVariant, Theme } from '@config/theme/theme' import Text from './Text' const getComponents = (variant?: ResponsiveValue) => ({ @@ -18,6 +18,7 @@ const getComponents = (variant?: ResponsiveValue) => ({ 'green.light-500': , 'blue.light-500': , 'green.400': , + quaternary: , codeHighlight: ( - camera?: React.RefObject - onUserLocationUpdate?: (userLocation: MapLibreGL.Location) => void - centerCoordinate?: Position - mapProps?: Omit, 'children'> - cameraProps?: React.ComponentProps - }> -> = ({ - children, - map, - camera, - onUserLocationUpdate, - centerCoordinate, - mapProps = {}, - cameraProps = {}, -}) => { - const mapStyle: string = useMemo( - () => - JSON.stringify({ - version: 8, - sources: { - protomaps: { - type: 'vector', - tiles: [`${Config.PMTILES_URL}/{z}/{x}/{y}.mvt`], - }, - }, - glyphs: 'https://cdn.protomaps.com/fonts/pbf/{fontstack}/{range}.pbf', - layers: mapLayers, - }), - [], - ) - - return ( - - - - {children} - - ) -} - -export default Map diff --git a/src/components/map/mapLayers.ts b/src/components/map/mapLayers.ts deleted file mode 100644 index 6b35c1002..000000000 --- a/src/components/map/mapLayers.ts +++ /dev/null @@ -1,264 +0,0 @@ -export const mapLayers: { [key: string]: unknown }[] = [ - { - id: 'land', - type: 'background', - layout: {}, - paint: { - 'background-color': '#2A2A2A', - }, - }, - { - id: 'natural_features', - type: 'fill', - source: 'protomaps', - 'source-layer': 'natural', - filter: [ - 'any', - ['==', 'natural', 'wood'], - ['==', 'leisure', 'nature_reserve'], - ['==', 'landuse', 'forest'], - ['==', 'natural', 'glacier'], - ['==', 'natural', 'sand'], - ], - paint: { - 'fill-color': '#2A2A2A', - }, - }, - { - id: 'transit_runway', - type: 'line', - source: 'protomaps', - 'source-layer': 'transit', - filter: ['has', 'aeroway'], - paint: { - 'line-color': '#2A2A2A', - 'line-width': 6, - }, - }, - { - id: 'landuse_runway', - type: 'fill', - source: 'protomaps', - 'source-layer': 'landuse', - filter: [ - 'any', - ['==', 'aeroway', 'runway'], - ['==', 'area:aeroway', 'runway'], - ['==', 'area:aeroway', 'taxiway'], - ], - paint: { - 'fill-color': '#2A2A2A', - }, - }, - { - id: 'water', - type: 'fill', - source: 'protomaps', - 'source-layer': 'water', - paint: { - 'fill-color': '#202020', - }, - }, - { - id: 'roads_other', - type: 'line', - source: 'protomaps', - 'source-layer': 'roads', - filter: ['==', 'pmap:kind', 'other'], - paint: { - 'line-color': '#3D3D3D', - 'line-dasharray': [2, 1], - 'line-width': [ - 'interpolate', - ['exponential', 1.6], - ['zoom'], - 14, - 0, - 14.5, - 0.5, - 20, - 12, - ], - }, - }, - { - id: 'roads_minor', - type: 'line', - source: 'protomaps', - 'source-layer': 'roads', - filter: ['==', 'pmap:kind', 'minor_road'], - paint: { - 'line-color': '#3D3D3D', - 'line-width': [ - 'interpolate', - ['exponential', 1.6], - ['zoom'], - 12, - 0, - 12.5, - 0.5, - 20, - 32, - ], - }, - }, - { - id: 'roads_medium', - type: 'line', - source: 'protomaps', - 'source-layer': 'roads', - filter: ['==', 'pmap:kind', 'medium_road'], - paint: { - 'line-color': '#3D3D3D', - 'line-width': [ - 'interpolate', - ['exponential', 1.6], - ['zoom'], - 7, - 0, - 7.5, - 0.5, - 20, - 32, - ], - }, - }, - { - id: 'roads_major', - type: 'line', - source: 'protomaps', - 'source-layer': 'roads', - filter: ['==', 'pmap:kind', 'major_road'], - paint: { - 'line-color': '#3D3D3D', - 'line-width': [ - 'interpolate', - ['exponential', 1.6], - ['zoom'], - 7, - 0, - 7.5, - 0.5, - 19, - 32, - ], - }, - }, - { - id: 'roads_highway', - type: 'line', - source: 'protomaps', - 'source-layer': 'roads', - filter: ['==', 'pmap:kind', 'highway'], - paint: { - 'line-color': '#3D3D3D', - 'line-width': [ - 'interpolate', - ['exponential', 1.6], - ['zoom'], - 3, - 0, - 3.5, - 0.5, - 18, - 32, - ], - }, - }, - { - id: 'boundaries_country', - type: 'line', - source: 'protomaps', - 'source-layer': 'boundaries', - filter: ['<=', 'pmap:min_admin_level', 2], - paint: { - 'line-color': '#696969', - 'line-width': 1.5, - }, - }, - { - id: 'boundaries', - type: 'line', - source: 'protomaps', - 'source-layer': 'boundaries', - filter: ['>', 'pmap:min_admin_level', 2], - paint: { - 'line-color': '#696969', - 'line-width': 1, - 'line-dasharray': [1, 2], - }, - }, - { - id: 'roads_labels', - type: 'symbol', - source: 'protomaps', - 'source-layer': 'roads', - layout: { - 'symbol-placement': 'line', - 'text-font': ['NotoSans-Regular'], - 'text-field': ['coalesce', ['get', 'name_en'], ['get', 'name']], - 'text-letter-spacing': 0.01, - 'text-size': 12, - }, - paint: { - 'text-color': '#6D6D6D', - }, - }, - { - id: 'places_city', - type: 'symbol', - source: 'protomaps', - 'source-layer': 'places', - filter: ['==', 'pmap:kind', 'city'], - layout: { - 'text-field': '{name:en}', - 'text-font': ['NotoSans-Regular'], - 'text-size': ['step', ['get', 'pmap:rank'], 0, 1, 12, 2, 10], - 'text-variable-anchor': ['bottom-left'], - 'text-radial-offset': 0.2, - }, - paint: { - 'text-color': '#6D6D6D', - 'text-halo-color': '#151515', - 'text-halo-width': 1, - }, - }, - { - id: 'places_state', - type: 'symbol', - source: 'protomaps', - 'source-layer': 'places', - filter: ['==', 'pmap:kind', 'state'], - layout: { - 'text-field': '{name:en}', - 'text-font': ['NotoSans-Regular'], - 'text-size': 14, - 'text-radial-offset': 0.2, - 'text-anchor': 'center', - 'text-transform': 'uppercase', - 'text-letter-spacing': 0.1, - }, - paint: { - 'text-color': '#6D6D6D', - 'text-halo-color': '#151515', - 'text-halo-width': 1, - }, - }, - { - id: 'places_country', - type: 'symbol', - source: 'protomaps', - 'source-layer': 'places', - filter: ['==', 'place', 'country'], - layout: { - 'text-field': '{name:en}', - 'text-font': ['NotoSans-Regular'], - 'text-size': 10, - }, - paint: { - 'text-color': '#6D6D6D', - 'text-halo-color': '#151515', - 'text-halo-width': 1, - }, - }, -] diff --git a/src/locales/en.ts b/src/config/locales/en.ts similarity index 92% rename from src/locales/en.ts rename to src/config/locales/en.ts index 628e8229c..3ecc2b7d8 100644 --- a/src/locales/en.ts +++ b/src/config/locales/en.ts @@ -25,8 +25,9 @@ export default { }, hotspotOnboarding: { scan: { - title: 'Scan for Hotspots', - start: 'Start Scan', + title: 'Choose your Hotspot', + hotspotsFound: '{{count}} Hotspots were found', + start: 'Scan Again', stop: 'Stop Scan', notEnabled: 'Bluetooth is not enabled', scanning: 'Scanning for Hotspots', @@ -42,13 +43,25 @@ export default { noneFound: 'No diagnostics found', }, wifiSettings: { - title: 'Wifi Settings', + title: 'Share Wi-Fi', + subtitle: + 'Choose the Wi-Fi network you’d like your Hotspot to connect to.', remove: 'Would you like to remove {{network}}?', available: 'Available Networks', configured: 'Configured Networks', setup: 'Setup Wifi', }, + wifiSetup: { + title: 'Enter Password', + subtitle: 'Provide password for {{ network }}', + enterPassword: 'Enter Password', + setWifi: 'Set Wi-Fi', + }, onboarding: { + hotspotConnected: 'Hotspot Connected', + hotspotConnectedBody: + 'Awesome! Your Hotspot now has an internet connection.', + confirmLocation: 'Confirm Location', title: 'Onboarding', subtitle: 'Onboard your Hotspot to the {{network}} network. After onboarding this Hotspot, you will be able to set the location and antenna details.', @@ -1529,4 +1542,119 @@ export default { manageCollectables: { title: 'Manage collectable list', }, + HotspotPage: { + metersAway: '{{meters}}m away', + amountOfHotspots: '{{amount}} Hotspots', + byDistance: 'By Distance', + byEarnings: 'By Earnings', + noHotspotsTitle: 'No Hotspots. Yet', + noHotspotsSubtitle: + 'Hotspots create wireless coverage for millions of devices.', + learnMore: 'Learn More', + add: 'Add', + filter: 'Filter Hotspots', + new: 'NEW', + nearby: 'Nearby', + distanceNotAvailable: 'Distance not available', + }, + AddHotspotPage: { + title: 'Let’s get your Hotspot connected!', + subtitle: 'Got a good spot for your Hotspot?', + locationAndMountingTips: 'Location & Mounting Tips', + addHotspot: 'Add Hotspot', + }, + SelectNetworkScreen: { + title: 'What Network?', + subtitle: 'What network does your Hotspot create coverage for?', + helpText: 'I’m not sure what I have', + }, + SelectDeviceScreen: { + title: 'What Device?', + subtitle: 'Which device to do wish to deploy?', + indoor: 'Indoor Hotspot', + outdoor: 'Outdoor Hotspot', + }, + KeepYourBoxScreen: { + title: 'Keep Your Box', + subtitle: 'You will need the QR Code on the box to deploy your Hotspot.', + }, + ConnectEthernetScreen: { + title: 'Connect Ethernet', + titleIndoor: 'Connect Ethernet\n& Power', + subtitle: 'Connect the powered ethernet cable to the rear of the Hotspot.', + subtitleIndoor: + 'Connect the powered ethernet cable to the rear of the Hotspot.', + helpText: 'The status light should turn blue.', + help: 'Help', + }, + ConnectToHotspotScreen: { + title: 'Connect to Hotspot', + subtitle: 'We’ll use your camera to scan the QR code on the Hotspot box.', + requestCameraPermissions: 'Request Camera Permissions', + perissionsGranted: 'Camera Permissions Granted', + perissionsDenied: 'Camera Permissions Denied', + manualEntry: 'Manual Entry', + }, + ScanQRCodeScreen: { + title: 'Scan QR Code', + subtitle: 'Scan the QR code on the box of the Helium Mobile Hotspot.', + manualEntry: 'Manual Entry', + validatingQRCode: 'Validating QR Code...', + tryAgain: 'There was an error, please check your network and try again.', + }, + AcquireLocationScreen: { + title: 'Acquiring Location', + subtitle: + 'Your Hotspot is waiting for a GPS signal to determine its location.', + gpsHelp: 'GPS Help', + isThisCorrect: 'Is this correct?', + locationDetermined: + 'We’ve determined the following location via GPS. Does it look correct? Rescan, if not.', + }, + SelectFloorScreen: { + title: 'What Floor?', + subtitle: 'What floor is your Hotspot on?', + selectPlaceholder: 'Select Floor', + approx: 'Approx. {{meters}}m', + floor: 'Floor {{floor}}', + }, + SetDirectionScreen: { + title: 'Rotate dial to\nset direction', + subtitle: + 'Your Hotspot should face the same direction. Point towards where you expect traffic.', + }, + AddToWalletScreen: { + title: 'WELCOME', + addressDetails: 'Floor {{floor}} | Pointing {{direction}}', + addressDetailsIndoor: 'Floor {{floor}}', + errorOnboarding: + 'There was an error onboarding your device. Please make sure your device is connected to the internet and try again.', + }, + ManualEntryScreen: { + title: 'Manual Entry', + subtitle: 'Enter the network name and password from the Hotspot’s box.', + scanQRCode: 'Scan QR Code', + tryAgain: + 'There was an error, please check your network name and password and try again.', + }, + OnboardingSheet: { + addToWallet: 'Add to wallet', + }, + ClaimTokensPage: { + title: 'Unclaimed Tokens', + subtitle: + 'Your Hotspots have earned the following tokens, that you need to claim.', + claimTokens: 'Claim Tokens', + }, + HotspotDetails: { + heliumMobileHotspot: 'Helium Mobile Hotspot Mines MOBILE.', + heliumIoTHotspot: 'Helium IoT Hotspot Mines HNT.', + deployed: 'Deployed {{date}}', + }, + ConnectViaBluetoothScreen: { + title: 'Connect via Bluetooth', + subtitle: 'All supported Hotspots use Bluetooth for initial setup.', + body: 'Follow the manufacturer’s instructions to power up your device and enter Bluetooth pairing mode.', + scanForHotspots: 'Scan for Hotspots', + }, } diff --git a/src/storage/AccountStorageProvider.tsx b/src/config/storage/AccountStorageProvider.tsx similarity index 98% rename from src/storage/AccountStorageProvider.tsx rename to src/config/storage/AccountStorageProvider.tsx index 7ab50afa9..415caf048 100644 --- a/src/storage/AccountStorageProvider.tsx +++ b/src/config/storage/AccountStorageProvider.tsx @@ -15,16 +15,16 @@ import React, { import { useAsync } from 'react-async-hook' import Config from 'react-native-config' import { cloneDeep } from 'lodash' -import { authSlice } from '../store/slices/authSlice' -import { useAppDispatch } from '../store/store' +import { authSlice } from '@store/slices/authSlice' +import { useAppDispatch } from '@store/store' import { accountNetType, AccountNetTypeOpt, heliumAddressToSolAddress, solAddressToHelium, -} from '../utils/accountUtils' -import makeApiToken from '../utils/makeApiToken' -import { getSessionKey } from '../utils/walletApiV2' +} from '@utils/accountUtils' +import makeApiToken from '@utils/makeApiToken' +import { getSessionKey } from '@utils/walletApiV2' import { useAppStorage } from './AppStorageProvider' import { CSAccount, diff --git a/src/storage/AppStorageProvider.tsx b/src/config/storage/AppStorageProvider.tsx similarity index 99% rename from src/storage/AppStorageProvider.tsx rename to src/config/storage/AppStorageProvider.tsx index 46c76eeff..01eec2160 100644 --- a/src/storage/AppStorageProvider.tsx +++ b/src/config/storage/AppStorageProvider.tsx @@ -8,7 +8,7 @@ import React, { import { useAsync } from 'react-async-hook' import AsyncStorage from '@react-native-async-storage/async-storage' import { Cluster, PublicKey } from '@solana/web3.js' -import { Intervals } from '../features/settings/useAuthIntervals' +import { Intervals } from '@features/settings/useAuthIntervals' import { getSecureItem, SecureStorageKeys, diff --git a/src/storage/GovernanceProvider.tsx b/src/config/storage/GovernanceProvider.tsx similarity index 98% rename from src/storage/GovernanceProvider.tsx rename to src/config/storage/GovernanceProvider.tsx index a3cc5a81c..b878131a4 100644 --- a/src/storage/GovernanceProvider.tsx +++ b/src/config/storage/GovernanceProvider.tsx @@ -17,8 +17,8 @@ import React, { FC, ReactNode, createContext, useContext, useMemo } from 'react' import { useAsync } from 'react-async-hook' import Config from 'react-native-config' import { useSelector } from 'react-redux' -import { useSolana } from '../solana/SolanaProvider' -import { RootState } from '../store/rootReducer' +import { useSolana } from '@features/solana/SolanaProvider' +import { RootState } from '@store/rootReducer' import { useAccountStorage } from './AccountStorageProvider' type GovNetwork = 'hnt' | 'mobile' | 'iot' diff --git a/src/storage/JupiterProvider.tsx b/src/config/storage/JupiterProvider.tsx similarity index 98% rename from src/storage/JupiterProvider.tsx rename to src/config/storage/JupiterProvider.tsx index d51c85198..6f8730f14 100644 --- a/src/storage/JupiterProvider.tsx +++ b/src/config/storage/JupiterProvider.tsx @@ -17,7 +17,7 @@ import React, { } from 'react' import { useTranslation } from 'react-i18next' import Config from 'react-native-config' -import * as Logger from '../utils/logger' +import * as Logger from '@utils/logger' interface IJupiterContextState { loading: boolean diff --git a/src/storage/LanguageProvider.tsx b/src/config/storage/LanguageProvider.tsx similarity index 92% rename from src/storage/LanguageProvider.tsx rename to src/config/storage/LanguageProvider.tsx index 4e8bca3ba..408802335 100644 --- a/src/storage/LanguageProvider.tsx +++ b/src/config/storage/LanguageProvider.tsx @@ -1,5 +1,5 @@ import React, { createContext, ReactNode, useContext } from 'react' -import { useLanguage } from '../utils/i18n' +import { useLanguage } from '@utils/i18n' const initialState = { language: 'en', changeLanguage: async () => undefined } diff --git a/src/storage/ModalsProvider.tsx b/src/config/storage/ModalsProvider.tsx similarity index 100% rename from src/storage/ModalsProvider.tsx rename to src/config/storage/ModalsProvider.tsx diff --git a/src/storage/NotificationStorageProvider.tsx b/src/config/storage/NotificationStorageProvider.tsx similarity index 93% rename from src/storage/NotificationStorageProvider.tsx rename to src/config/storage/NotificationStorageProvider.tsx index 7a56672df..df8592d67 100644 --- a/src/storage/NotificationStorageProvider.tsx +++ b/src/config/storage/NotificationStorageProvider.tsx @@ -14,13 +14,13 @@ import { orderBy, without } from 'lodash' import { HELIUM_UPDATES_ITEM, WALLET_UPDATES_ITEM, -} from '../features/notifications/notificationTypes' -import { useAppDispatch } from '../store/store' -import { getNotifications } from '../store/slices/notificationsSlice' -import usePrevious from '../hooks/usePrevious' -import { RootState } from '../store/rootReducer' +} from '@features/notifications/notificationTypes' +import { useAppDispatch } from '@store/store' +import { getNotifications } from '@store/slices/notificationsSlice' +import usePrevious from '@hooks/usePrevious' +import { RootState } from '@store/rootReducer' +import { Notification } from '@utils/walletApiV2' import { useAccountStorage } from './AccountStorageProvider' -import { Notification } from '../utils/walletApiV2' const useNotificationStorageHook = () => { const [selectedList, setSelectedList] = useState() diff --git a/src/storage/TokensProvider.tsx b/src/config/storage/TokensProvider.tsx similarity index 98% rename from src/storage/TokensProvider.tsx rename to src/config/storage/TokensProvider.tsx index cf751e3a4..d140b1afe 100644 --- a/src/storage/TokensProvider.tsx +++ b/src/config/storage/TokensProvider.tsx @@ -9,7 +9,7 @@ import React, { useState, } from 'react' import { useAsync } from 'react-async-hook' -import * as Logger from '../utils/logger' +import * as Logger from '@utils/logger' import { useAccountStorage } from './AccountStorageProvider' import { CSToken, diff --git a/src/storage/cloudStorage.ts b/src/config/storage/cloudStorage.ts similarity index 100% rename from src/storage/cloudStorage.ts rename to src/config/storage/cloudStorage.ts diff --git a/src/storage/oneSignalStorage.ts b/src/config/storage/oneSignalStorage.ts similarity index 100% rename from src/storage/oneSignalStorage.ts rename to src/config/storage/oneSignalStorage.ts diff --git a/src/storage/secureStorage.ts b/src/config/storage/secureStorage.ts similarity index 97% rename from src/storage/secureStorage.ts rename to src/config/storage/secureStorage.ts index 8753ffe70..f2158923c 100644 --- a/src/storage/secureStorage.ts +++ b/src/config/storage/secureStorage.ts @@ -10,9 +10,9 @@ import * as bip39 from 'bip39' import * as SecureStore from 'expo-secure-store' import { Alert } from 'react-native' import Config from 'react-native-config' -import { navToImportAccount } from '../navigation/NavigationHelper' -import { ellipsizeAddress } from '../utils/accountUtils' -import i18n from '../utils/i18n' +import { ellipsizeAddress } from '@utils/accountUtils' +import i18n from '@utils/i18n' +import { navToImportAccount } from '../../app/NavigationHelper' import { CSAccount } from './cloudStorage' export enum SecureStorageKeys { diff --git a/src/theme/globalStyles.ts b/src/config/theme/globalStyles.ts similarity index 100% rename from src/theme/globalStyles.ts rename to src/config/theme/globalStyles.ts diff --git a/src/theme/theme.ts b/src/config/theme/theme.ts similarity index 98% rename from src/theme/theme.ts rename to src/config/theme/theme.ts index a0b503cd6..93396c863 100644 --- a/src/theme/theme.ts +++ b/src/config/theme/theme.ts @@ -25,7 +25,7 @@ export const breakpoints = { } export const baseTheme = { - borderRadii: lightThemeTokens.borderRadii, + borderRadii: { ...lightThemeTokens.borderRadii, '6xl': 40 }, breakpoints, Font: NovaFont, inputVariants: { diff --git a/src/theme/themeHooks.ts b/src/config/theme/themeHooks.ts similarity index 98% rename from src/theme/themeHooks.ts rename to src/config/theme/themeHooks.ts index ad41624bc..fa9b25cff 100644 --- a/src/theme/themeHooks.ts +++ b/src/config/theme/themeHooks.ts @@ -3,7 +3,7 @@ import tinycolor from 'tinycolor2' import { Platform, ViewStyle } from 'react-native' import { useCallback, useMemo } from 'react' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { Color, Spacing, Theme } from '@theme/theme' +import { Color, Spacing, Theme } from 'src/config/theme/theme' import { ww } from '@utils/layout' const colorScheme = 'dark' as 'dark' | 'light' diff --git a/src/features/StatusPage/StatusBanner.tsx b/src/features/StatusPage/StatusBanner.tsx index 0fc83bb87..2bdbdc27d 100644 --- a/src/features/StatusPage/StatusBanner.tsx +++ b/src/features/StatusPage/StatusBanner.tsx @@ -7,9 +7,9 @@ import FlashMessage, { import { Linking } from 'react-native' import { formatDistanceToNow, parseISO } from 'date-fns' import { useTranslation } from 'react-i18next' -import Close from '@assets/images/closeModal.svg' +import Close from '@assets/svgs/closeModal.svg' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useColors, useHitSlop } from '@theme/themeHooks' +import { useColors, useHitSlop } from '@config/theme/themeHooks' import useStatusPage from './useStatusPage' import { HELIUM_STATUS_URL } from './statusPageTypes' import shortLocale from '../../utils/formatDistance' diff --git a/src/features/activity/ActivityDetailsScreen.tsx b/src/features/activity/ActivityDetailsScreen.tsx index 56983c6c4..007ee08b5 100644 --- a/src/features/activity/ActivityDetailsScreen.tsx +++ b/src/features/activity/ActivityDetailsScreen.tsx @@ -1,6 +1,6 @@ -import Error from '@assets/images/error.svg' -import Receive from '@assets/images/receive.svg' -import Send from '@assets/images/send.svg' +import Error from '@assets/svgs/error.svg' +import Receive from '@assets/svgs/receive.svg' +import Send from '@assets/svgs/send.svg' import BackScreen from '@components/BackScreen' import BlurActionSheet from '@components/BlurActionSheet' import Box from '@components/Box' @@ -14,14 +14,14 @@ import { useCurrentWallet } from '@hooks/useCurrentWallet' import useHaptic from '@hooks/useHaptic' import { RouteProp, useRoute } from '@react-navigation/native' import { ConfirmedSignatureInfo } from '@solana/web3.js' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import React, { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { Linking } from 'react-native' import { NavBarHeight } from '@components/ServiceNavBar' import { useSafeAreaInsets } from 'react-native-safe-area-context' import ScrollBox from '@components/ScrollBox' -import { useCreateExplorerUrl } from '../../constants/urls' +import { useCreateExplorerUrl } from '../../utils/constants/urls' import { EnrichedTransaction } from '../../types/solana' import { ellipsizeAddress, solAddressIsValid } from '../../utils/accountUtils' import AddressActivityItem from './AddressActivityItem' diff --git a/src/features/activity/ActivityListItem.tsx b/src/features/activity/ActivityListItem.tsx index 6521e347d..28e849343 100644 --- a/src/features/activity/ActivityListItem.tsx +++ b/src/features/activity/ActivityListItem.tsx @@ -1,13 +1,13 @@ -import Send from '@assets/images/send.svg' -import Receive from '@assets/images/receive.svg' -import Error from '@assets/images/error.svg' +import Send from '@assets/svgs/send.svg' +import Receive from '@assets/svgs/receive.svg' +import Error from '@assets/svgs/error.svg' import Box from '@components/Box' import Text from '@components/Text' import TouchableContainer from '@components/TouchableContainer' import { TouchableOpacityBoxProps } from '@components/TouchableOpacityBox' import { useCurrentWallet } from '@hooks/useCurrentWallet' import { ConfirmedSignatureInfo } from '@solana/web3.js' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { ellipsizeAddress, solAddressIsValid } from '@utils/accountUtils' import React, { useMemo } from 'react' import { useTranslation } from 'react-i18next' diff --git a/src/features/activity/ActivityScreen.tsx b/src/features/activity/ActivityScreen.tsx index 7846006a3..fabd8a027 100644 --- a/src/features/activity/ActivityScreen.tsx +++ b/src/features/activity/ActivityScreen.tsx @@ -11,7 +11,7 @@ import useEnrichedTransactions from '@hooks/useEnrichedTransactions' import CircleLoader from '@components/CircleLoader' import FadeInOut from '@components/FadeInOut' import useHaptic from '@hooks/useHaptic' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import { NavBarHeight } from '@components/ServiceNavBar' import ScrollBox from '@components/ScrollBox' import { ActivityNavigationProp } from './activityTypes' diff --git a/src/features/activity/AddressActivityItem.tsx b/src/features/activity/AddressActivityItem.tsx index c1bff8bf8..bf8c18635 100644 --- a/src/features/activity/AddressActivityItem.tsx +++ b/src/features/activity/AddressActivityItem.tsx @@ -2,14 +2,14 @@ import React from 'react' import { StyleSheet } from 'react-native' import { useTranslation } from 'react-i18next' import { BoxProps } from '@shopify/restyle' -import Menu from '@assets/images/menu.svg' +import Menu from '@assets/svgs/menu.svg' import Box from '@components/Box' import Text from '@components/Text' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import AccountIcon from '@components/AccountIcon' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { ellipsizeAddress } from '../../utils/accountUtils' export const LIST_ITEM_HEIGHT = 70 diff --git a/src/features/addressBook/AddressBook.tsx b/src/features/addressBook/AddressBook.tsx index 72288d816..57403a3b2 100644 --- a/src/features/addressBook/AddressBook.tsx +++ b/src/features/addressBook/AddressBook.tsx @@ -2,7 +2,7 @@ import React, { memo, useCallback } from 'react' import { useNavigation } from '@react-navigation/native' import { useTranslation } from 'react-i18next' import Box from '@components/Box' -import { CSAccount } from '@storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import BackScreen from '@components/BackScreen' import ScrollBox from '@components/ScrollBox' import ContactsList from './ContactsList' diff --git a/src/features/addressBook/AddressBookNavigator.tsx b/src/features/addressBook/AddressBookNavigator.tsx index 428d809ee..875500689 100644 --- a/src/features/addressBook/AddressBookNavigator.tsx +++ b/src/features/addressBook/AddressBookNavigator.tsx @@ -1,5 +1,5 @@ import React, { memo, useMemo } from 'react' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { createStackNavigator, StackNavigationOptions, diff --git a/src/features/addressBook/AddressExtra.tsx b/src/features/addressBook/AddressExtra.tsx index a999a8d6d..e654d3e10 100644 --- a/src/features/addressBook/AddressExtra.tsx +++ b/src/features/addressBook/AddressExtra.tsx @@ -1,8 +1,8 @@ import React, { memo } from 'react' import { ActivityIndicator } from 'react-native' -import QR from '@assets/images/qr.svg' -import Checkmark from '@assets/images/checkmark.svg' -import { useColors, useHitSlop } from '@theme/themeHooks' +import QR from '@assets/svgs/qr.svg' +import Checkmark from '@assets/svgs/checkmark.svg' +import { useColors, useHitSlop } from '@config/theme/themeHooks' import TouchableOpacityBox from '@components/TouchableOpacityBox' type AddressExtraProps = { diff --git a/src/features/addressBook/AddressQrScanner.tsx b/src/features/addressBook/AddressQrScanner.tsx index f87dda2ee..4d899940c 100644 --- a/src/features/addressBook/AddressQrScanner.tsx +++ b/src/features/addressBook/AddressQrScanner.tsx @@ -4,8 +4,8 @@ import { useNavigation } from '@react-navigation/native' import useHaptic from '@hooks/useHaptic' import useAlert from '@hooks/useAlert' import QrScanner from '@components/QrScanner' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' -import { useAppStorage } from '../../storage/AppStorageProvider' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' +import { useAppStorage } from '@config/storage/AppStorageProvider' import { parsePaymentLink } from '../../utils/linking' import { solAddressIsValid } from '../../utils/accountUtils' diff --git a/src/features/addressBook/ContactDetails.tsx b/src/features/addressBook/ContactDetails.tsx index febe41a69..f1ab9981d 100644 --- a/src/features/addressBook/ContactDetails.tsx +++ b/src/features/addressBook/ContactDetails.tsx @@ -15,10 +15,10 @@ import { TextInput as RNTextInput, Platform, } from 'react-native' -import Checkmark from '@assets/images/checkmark.svg' +import Checkmark from '@assets/svgs/checkmark.svg' import Box from '@components/Box' import Text from '@components/Text' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import TextInput from '@components/TextInput' import ButtonPressable from '@components/ButtonPressable' import AccountIcon from '@components/AccountIcon' @@ -31,15 +31,15 @@ import BackScreen from '@components/BackScreen' import { NavBarHeight } from '@components/ServiceNavBar' import { useSafeAreaInsets } from 'react-native-safe-area-context' import ScrollBox from '@components/ScrollBox' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { CSAccount } from '@config/storage/cloudStorage' +import { useSolana } from '@features/solana/SolanaProvider' +import AddressExtra from './AddressExtra' import { AddressBookNavigationProp, AddressBookStackParamList, } from './addressBookTypes' -import { useAppStorage } from '../../storage/AppStorageProvider' -import AddressExtra from './AddressExtra' -import { CSAccount } from '../../storage/cloudStorage' -import { useSolana } from '../../solana/SolanaProvider' import { solAddressToHelium } from '../../utils/accountUtils' const BUTTON_HEIGHT = 55 diff --git a/src/features/addressBook/ContactsList.tsx b/src/features/addressBook/ContactsList.tsx index 726534d2a..3b24231a3 100644 --- a/src/features/addressBook/ContactsList.tsx +++ b/src/features/addressBook/ContactsList.tsx @@ -8,14 +8,14 @@ import { sortBy, unionBy } from 'lodash' import Box from '@components/Box' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import FabButton from '@components/FabButton' import SearchInput from '@components/SearchInput' import AccountListItem from '@components/AccountListItem' -import { useSpacing } from '@theme/themeHooks' +import { useSpacing } from '@config/theme/themeHooks' import { NavBarHeight } from '@components/ServiceNavBar' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' type Props = { onAddNew: () => void diff --git a/src/features/addressBook/addressBookTypes.ts b/src/features/addressBook/addressBookTypes.ts index 99537317a..c3dbc33ba 100644 --- a/src/features/addressBook/addressBookTypes.ts +++ b/src/features/addressBook/addressBookTypes.ts @@ -1,5 +1,5 @@ import { StackNavigationProp } from '@react-navigation/stack' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' export type AddressBookStackParamList = { AddressBook: undefined diff --git a/src/features/browser/BrowserNavigator.tsx b/src/features/browser/BrowserNavigator.tsx index 83044c109..425c30b2d 100644 --- a/src/features/browser/BrowserNavigator.tsx +++ b/src/features/browser/BrowserNavigator.tsx @@ -3,11 +3,11 @@ import { createNativeStackNavigator, NativeStackNavigationOptions, } from '@react-navigation/native-stack' -import { useAppStorage } from '@storage/AppStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { useSolana } from '@features/solana/SolanaProvider' import BrowserScreen from './BrowserScreen' import { BrowserWrapper } from './BrowserWebViewScreen' import DAppTutorial from './DAppTutorial' -import { useSolana } from '../../solana/SolanaProvider' const BrowserStack = createNativeStackNavigator() diff --git a/src/features/browser/BrowserScreen.tsx b/src/features/browser/BrowserScreen.tsx index 1b25f3bb7..b98f0ef58 100644 --- a/src/features/browser/BrowserScreen.tsx +++ b/src/features/browser/BrowserScreen.tsx @@ -6,22 +6,22 @@ import { TextInput as RNTextInput, TextInputSubmitEditingEventData, } from 'react-native' -import CloseCircle from '@assets/images/CloseCircle.svg' +import CloseCircle from '@assets/svgs/CloseCircle.svg' import { useNavigation } from '@react-navigation/native' import { useTranslation } from 'react-i18next' import FadeInOut from '@components/FadeInOut' import TextInput from '@components/TextInput' import Box from '@components/Box' import { ReAnimatedBox } from '@components/AnimatedBox' -import { useColors, useOpacity, useSpacing } from '@theme/themeHooks' +import { useColors, useOpacity, useSpacing } from '@config/theme/themeHooks' import TouchableOpacityBox from '@components/TouchableOpacityBox' import Text from '@components/Text' import useBrowser from '@hooks/useBrowser' import { prependHttp } from '@utils/url' import { useAsync } from 'react-async-hook' +import { useSolana } from '@features/solana/SolanaProvider' import { BrowserNavigationProp } from './browserTypes' import BrowserListItem from './BrowserListItem' -import { useSolana } from '../../solana/SolanaProvider' import { getRecommendedDapps } from '../../utils/walletApiV2' const BrowserScreen = () => { diff --git a/src/features/browser/BrowserWebViewScreen.tsx b/src/features/browser/BrowserWebViewScreen.tsx index 697911189..fa47f69ee 100644 --- a/src/features/browser/BrowserWebViewScreen.tsx +++ b/src/features/browser/BrowserWebViewScreen.tsx @@ -1,15 +1,15 @@ -import BackArrow from '@assets/images/backArrow.svg' -import Bookmark from '@assets/images/bookmark.svg' -import BookmarkFilled from '@assets/images/bookmarkFilled.svg' -import Close from '@assets/images/close.svg' -import Refresh from '@assets/images/refresh.svg' +import BackArrow from '@assets/svgs/backArrow.svg' +import Bookmark from '@assets/svgs/bookmark.svg' +import BookmarkFilled from '@assets/svgs/bookmarkFilled.svg' +import Close from '@assets/svgs/close.svg' +import Refresh from '@assets/svgs/refresh.svg' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { SolanaSignAndSendTransactionInput, SolanaSignMessageInput, } from '@solana/wallet-standard-features' import { Transaction, VersionedTransaction } from '@solana/web3.js' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import bs58 from 'bs58' import React, { useCallback, useMemo, useRef, useState } from 'react' import { Platform, StyleSheet } from 'react-native' @@ -19,18 +19,18 @@ import { WebViewMessageEvent, WebViewNavigation, } from 'react-native-webview' +import SolanaProvider, { useSolana } from '@features/solana/SolanaProvider' +import WalletSignBottomSheet from '@features/solana/WalletSignBottomSheet' +import { + WalletSignBottomSheetRef, + WalletStandardMessageTypes, +} from '@features/solana/walletSignBottomSheetTypes' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import Box from '../../components/Box' import SafeAreaBox from '../../components/SafeAreaBox' import Text from '../../components/Text' import TouchableOpacityBox from '../../components/TouchableOpacityBox' import useBrowser from '../../hooks/useBrowser' -import SolanaProvider, { useSolana } from '../../solana/SolanaProvider' -import WalletSignBottomSheet from '../../solana/WalletSignBottomSheet' -import { - WalletSignBottomSheetRef, - WalletStandardMessageTypes, -} from '../../solana/walletSignBottomSheetTypes' -import { useAccountStorage } from '../../storage/AccountStorageProvider' import * as Logger from '../../utils/logger' import { BrowserNavigationProp, BrowserStackParamList } from './browserTypes' import injectWalletStandard from './walletStandard' diff --git a/src/features/browser/DAppTutorial.tsx b/src/features/browser/DAppTutorial.tsx index 6baf02cd7..f5aa845ce 100644 --- a/src/features/browser/DAppTutorial.tsx +++ b/src/features/browser/DAppTutorial.tsx @@ -8,16 +8,16 @@ import ImageBox from '@components/ImageBox' import SafeAreaBox from '@components/SafeAreaBox' import Text from '@components/Text' import TextTransform from '@components/TextTransform' -import { useAppStorage } from '@storage/AppStorageProvider' -import { Spacing } from '@theme/theme' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { Spacing } from '@config/theme/theme' +import { useColors, useSpacing } from '@config/theme/themeHooks' import { wp } from '@utils/layout' import ButtonPressable from '@components/ButtonPressable' import { ReAnimatedBox } from '@components/AnimatedBox' import { DelayedFadeIn } from '@components/FadeInOut' import { NativeViewGestureHandler } from 'react-native-gesture-handler' +import { useSolana } from '@features/solana/SolanaProvider' import { BrowserNavigationProp } from './browserTypes' -import { useSolana } from '../../solana/SolanaProvider' type CarouselItem = { titleKey: string diff --git a/src/features/burn/BurnScreen.tsx b/src/features/burn/BurnScreen.tsx index 3b11c1fcc..c168e761a 100644 --- a/src/features/burn/BurnScreen.tsx +++ b/src/features/burn/BurnScreen.tsx @@ -1,11 +1,6 @@ -import Close from '@assets/images/close.svg' -import QR from '@assets/images/qr.svg' -import AccountButton from '@components/AccountButton' -import AccountSelector, { - AccountSelectorRef, -} from '@components/AccountSelector' +import Close from '@assets/svgs/close.svg' +import QR from '@assets/svgs/qr.svg' import Box from '@components/Box' -import SafeAreaBox from '@components/SafeAreaBox' import SubmitButton from '@components/SubmitButton' import Text from '@components/Text' import TokenButton from '@components/TokenButton' @@ -28,7 +23,7 @@ import { useCurrentWallet } from '@hooks/useCurrentWallet' import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { PublicKey } from '@solana/web3.js' -import { useColors, useHitSlop } from '@theme/themeHooks' +import { useColors, useHitSlop, useSpacing } from '@config/theme/themeHooks' import { BN } from 'bn.js' import React, { memo as reactMemo, @@ -39,30 +34,27 @@ import React, { useState, } from 'react' import { useTranslation } from 'react-i18next' -import { Platform } from 'react-native' +import { Keyboard, Platform } from 'react-native' import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view' -import { Edge, useSafeAreaInsets } from 'react-native-safe-area-context' +import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useSelector } from 'react-redux' import { WalletNavigationProp, WalletStackParamList, -} from '@services/WalletService/pages/WalletPage/WalletPageNavigator' +} from '@services/WalletService/pages/WalletPage' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { CSAccount } from '@config/storage/cloudStorage' +import { NavBarHeight } from '@components/ServiceNavBar' +import ScrollBox from '@components/ScrollBox' import AddressBookSelector, { AddressBookRef, } from '../../components/AddressBookSelector' import HNTKeyboard, { HNTKeyboardRef } from '../../components/HNTKeyboard' import IconPressedContainer from '../../components/IconPressedContainer' import useSubmitTxn from '../../hooks/useSubmitTxn' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { CSAccount } from '../../storage/cloudStorage' import { RootState } from '../../store/rootReducer' import { useBalance } from '../../utils/Balance' -import { - accountNetType, - ellipsizeAddress, - formatAccountAlias, - solAddressIsValid, -} from '../../utils/accountUtils' +import { accountNetType, solAddressIsValid } from '../../utils/accountUtils' import { TXN_FEE_IN_SOL } from '../../utils/solanaUtils' import PaymentItem from '../payment/PaymentItem' import PaymentSubmit from '../payment/PaymentSubmit' @@ -80,12 +72,12 @@ const BurnScreen = () => { setCurrentAccount, defaultAccountAddress, } = useAccountStorage() - const { top } = useSafeAreaInsets() + const spacing = useSpacing() + const { top, bottom } = useSafeAreaInsets() const navigation = useNavigation() const { t } = useTranslation() const { primaryText } = useColors() const hitSlop = useHitSlop('6') - const accountSelectorRef = useRef(null) const { submitDelegateDataCredits } = useSubmitTxn() const addressBookRef = useRef(null) const { networkTokensToDc } = useBalance() @@ -111,8 +103,12 @@ const BurnScreen = () => { const { isDelegate } = useMemo(() => route.params, [route.params]) const containerStyle = useMemo( - () => ({ marginTop: Platform.OS === 'android' ? top : undefined }), - [top], + () => ({ + marginTop: Platform.OS === 'android' ? top : undefined, + paddingBottom: NavBarHeight + spacing['2xl'] + bottom, + flex: 1, + }), + [top, spacing, bottom], ) const networkType = useMemo( @@ -120,11 +116,6 @@ const BurnScreen = () => { [route.params.address], ) - const handleShowAccounts = useCallback(() => { - if (!accountSelectorRef?.current) return - accountSelectorRef.current.showAccountTypes(networkType)() - }, [networkType]) - const amountBalance = useMemo(() => { const amount = new BN(route.params.amount || 0) @@ -139,11 +130,15 @@ const BurnScreen = () => { }, [amountBalance, networkTokensToDc]) const onTokenItemPressed = useCallback(() => { + Keyboard.dismiss() hntKeyboardRef.current?.show({ payer: currentAccount, + payee: delegateAddress, + index: 0, balance: amountBalance, + payments: [], }) - }, [amountBalance, currentAccount]) + }, [amountBalance, currentAccount, delegateAddress]) useEffect(() => { if (currentAccount?.netType === networkType || isDelegate) return @@ -302,210 +297,178 @@ const BurnScreen = () => { return ( <> - - + - - - - - - - + - {t(isDelegate ? 'delegate.title' : 'burn.title')} - - - - + + - - - 1} - address={currentAccount?.address} - onPress={handleShowAccounts} - showBubbleArrow - marginHorizontal="6" - marginBottom="xs" - /> - - - - {isDelegate ? ( - - { - setMemo(m) - }} - onEditAddress={({ address }) => { - setDelegateAddress(address) - handleAddressError({ - address, - }) - }} - handleAddressError={handleAddressError} - mint={DC_MINT} - address={delegateAddress} - amount={amountBalance} - memo={memo} - hasError={hasError} - /> - - ) : ( - <> - - - - {t('burn.amount')} - - - {amountBalance.toString()} - - - {t('payment.fee', { - value: humanReadable(FEE, 9), - })} - - - - - - {t('burn.equivalent')} - - - {amountInDc?.toString()} - - - - - - )} - - {submitError && ( - - - {submitError} - - - )} - + - - - + + + + + + + {isDelegate ? ( + + { + setMemo(m) + }} + onEditAddress={({ address }) => { + setDelegateAddress(address) + handleAddressError({ + address, + }) + }} + handleAddressError={handleAddressError} + mint={DC_MINT} + address={delegateAddress} + account={currentAccount || undefined} + amount={amountBalance} + memo={memo} + hasError={hasError} /> + ) : ( + <> + + + {t('burn.amount')} + + + {amountBalance.toString()} + + + {t('payment.fee', { + value: humanReadable(FEE, 9), + })} + + + + + + {t('burn.equivalent')} + + + {amountInDc?.toString()} + + + + + + )} + + {submitError && ( + + + {submitError} + - + )} + + + + + + { onSuccess={navigation.popToTop} actionTitle={t('generic.ok')} /> - + { - const colors = useColors() - const screenOptions: StackNavigationOptions = useMemo( - () => ({ - headerShown: false, - cardStyle: { backgroundColor: colors.primaryBackground }, - }), - [colors], - ) - - return ( - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ) -} - -export default memo(CollectablesStackScreen) diff --git a/src/features/collectables/CollectionItem.tsx b/src/features/collectables/CollectionItem.tsx index ea338bd87..58a446fa2 100644 --- a/src/features/collectables/CollectionItem.tsx +++ b/src/features/collectables/CollectionItem.tsx @@ -1,12 +1,12 @@ import Box from '@components/Box' import Text from '@components/Text' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' -import { useColors, useSpacing } from '@theme/themeHooks' +import { Theme } from '@config/theme/theme' +import { useColors, useSpacing } from '@config/theme/themeHooks' import React, { useCallback, useState } from 'react' import { Image, Switch } from 'react-native' import { useDispatch } from 'react-redux' -import VisibilityOff from '@assets/images/visibilityOff.svg' +import VisibilityOff from '@assets/svgs/visibilityOff.svg' import { collectables as collectablesSli } from '@store/slices/collectablesSlice' export type Collection = { diff --git a/src/features/collectables/CollectionScreen.tsx b/src/features/collectables/CollectionScreen.tsx index 224588836..9b3a1ef3c 100644 --- a/src/features/collectables/CollectionScreen.tsx +++ b/src/features/collectables/CollectionScreen.tsx @@ -8,8 +8,8 @@ import TouchableOpacityBox from '@components/TouchableOpacityBox' import { DelayedFadeIn } from '@components/FadeInOut' import { ReAnimatedBox } from '@components/AnimatedBox' import useHaptic from '@hooks/useHaptic' -import globalStyles from '@theme/globalStyles' -import { useBorderRadii } from '@theme/themeHooks' +import globalStyles from '@config/theme/globalStyles' +import { useBorderRadii } from '@config/theme/themeHooks' import ScrollBox from '@components/ScrollBox' import { CollectableNavigationProp, diff --git a/src/features/collectables/HotspotCompressedListItem.tsx b/src/features/collectables/HotspotCompressedListItem.tsx deleted file mode 100644 index 8b74f0880..000000000 --- a/src/features/collectables/HotspotCompressedListItem.tsx +++ /dev/null @@ -1,251 +0,0 @@ -import IotSymbol from '@assets/images/iotSymbol.svg' -import MobileSymbol from '@assets/images/mobileSymbol.svg' -import { ReAnimatedBox } from '@components/AnimatedBox' -import Box from '@components/Box' -import ImageBox from '@components/ImageBox' -import Text from '@components/Text' -import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useMint } from '@helium/helium-react-hooks' -import { IOT_MINT, MOBILE_MINT, toNumber } from '@helium/spl-utils' -import { useHotspotAddress } from '@hooks/useHotspotAddress' -import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' -import { ellipsizeAddress, formatLargeNumber } from '@utils/accountUtils' -import BigNumber from 'bignumber.js' -import BN from 'bn.js' -import React, { useMemo } from 'react' -import { FadeIn, FadeOut } from 'react-native-reanimated' -import { useColors, useOpacity } from '@theme/themeHooks' -import { PublicKey } from '@solana/web3.js' -import { useCurrentWallet } from '@hooks/useCurrentWallet' -import { useTranslation } from 'react-i18next' -import { HotspotWithPendingRewards } from '../../types/solana' -import { Mints } from '../../utils/constants' -import { removeDashAndCapitalize } from '../../utils/hotspotNftsUtils' - -export type HotspotListItemProps = { - hotspot: HotspotWithPendingRewards - onPress: (hotspot: HotspotWithPendingRewards) => void -} & BoxProps - -const HotspotListItem = ({ - hotspot, - onPress, - ...rest -}: HotspotListItemProps) => { - const { - content: { metadata }, - } = hotspot - const { t } = useTranslation() - const colors = useColors() - const wallet = useCurrentWallet() - const { backgroundStyle: flamecoOpaque } = useOpacity('orange.500', 0.1) - const streetAddress = useHotspotAddress(hotspot) - - const { info: iotMint } = useMint(IOT_MINT) - const { info: mobileMint } = useMint(MOBILE_MINT) - - const pendingIotRewards = useMemo( - () => hotspot.pendingRewards && new BN(hotspot.pendingRewards[Mints.IOT]), - [hotspot], - ) - - const pendingIotRewardsString = useMemo(() => { - if (!hotspot.pendingRewards) return - const num = toNumber( - new BN(hotspot.pendingRewards[Mints.IOT]), - iotMint?.decimals || 6, - ) - return formatLargeNumber(new BigNumber(num)) - }, [hotspot, iotMint]) - - const pendingMobileRewards = useMemo( - () => - hotspot.pendingRewards && new BN(hotspot.pendingRewards[Mints.MOBILE]), - [hotspot.pendingRewards], - ) - - const pendingMobileRewardsString = useMemo(() => { - if (!hotspot.pendingRewards) return - const num = toNumber( - new BN(hotspot.pendingRewards[Mints.MOBILE]), - mobileMint?.decimals || 6, - ) - return formatLargeNumber(new BigNumber(num)) - }, [hotspot, mobileMint]) - - const eccCompact = useMemo(() => { - if (!metadata || !metadata?.attributes?.length) { - return undefined - } - - return metadata.attributes.find( - (attr: any) => attr?.trait_type === 'ecc_compact', - )?.value - }, [metadata]) - - const hasIotRewards = useMemo( - () => pendingIotRewards && pendingIotRewards.gt(new BN(0)), - [pendingIotRewards], - ) - const hasMobileRewards = useMemo( - () => pendingMobileRewards && pendingMobileRewards.gt(new BN(0)), - [pendingMobileRewards], - ) - - const mobileRecipient = useMemo( - () => hotspot?.rewardRecipients?.[Mints.MOBILE], - [hotspot], - ) - - const iotRecipient = useMemo( - () => hotspot?.rewardRecipients?.[Mints.IOT], - [hotspot], - ) - - const hasIotRecipient = useMemo( - () => - iotRecipient?.destination && - wallet && - !new PublicKey(iotRecipient.destination).equals(wallet) && - !new PublicKey(iotRecipient.destination).equals(PublicKey.default), - [iotRecipient, wallet], - ) - - const hasMobileRecipient = useMemo( - () => - mobileRecipient?.destination && - wallet && - !new PublicKey(mobileRecipient.destination).equals(wallet) && - !new PublicKey(mobileRecipient.destination).equals(PublicKey.default), - [mobileRecipient, wallet], - ) - - const hasRecipientSet = useMemo( - () => hasIotRecipient || hasMobileRecipient, - [hasIotRecipient, hasMobileRecipient], - ) - - return ( - - onPress(hotspot)} - > - {hasRecipientSet && ( - - - - {t('changeRewardsRecipientScreen.set')} - - - - )} - - - - {metadata?.name && ( - - {removeDashAndCapitalize(metadata.name)} - - )} - - {streetAddress && ( - - {streetAddress} - - )} - - {eccCompact ? ellipsizeAddress(eccCompact) : ''} - - - - {!!hasMobileRewards && ( - - - - {pendingMobileRewardsString} - - - )} - {!!hasIotRewards && ( - - - - {pendingIotRewardsString} - - - )} - - - - - ) -} - -export default HotspotListItem diff --git a/src/features/collectables/HotspotList.tsx b/src/features/collectables/HotspotList.tsx deleted file mode 100644 index ea79fa37d..000000000 --- a/src/features/collectables/HotspotList.tsx +++ /dev/null @@ -1,322 +0,0 @@ -import Plus from '@assets/images/plus.svg' -import Globe from '@assets/images/globe.svg' -import Box from '@components/Box' -import ButtonPressable from '@components/ButtonPressable' -import CircleLoader from '@components/CircleLoader' -import Text from '@components/Text' -import TokenIcon from '@components/TokenIcon' -import { useMint } from '@helium/helium-react-hooks' -import { IOT_MINT, MOBILE_MINT, toNumber } from '@helium/spl-utils' -import useHaptic from '@hooks/useHaptic' -import useHotspots from '@hooks/useHotspots' -import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' -import { useIsFocused, useNavigation } from '@react-navigation/native' -import { PublicKey } from '@solana/web3.js' -import { useColors, useSpacing } from '@theme/themeHooks' -import BigNumber from 'bignumber.js' -import BN from 'bn.js' -import { times } from 'lodash' -import React, { useCallback, useEffect } from 'react' -import { useTranslation } from 'react-i18next' -import { RefreshControl } from 'react-native' -import { FlatList } from 'react-native-gesture-handler' -import { useSafeAreaInsets } from 'react-native-safe-area-context' -import ScrollBox from '@components/ScrollBox' -import { CompressedNFT, HotspotWithPendingRewards } from '../../types/solana' -import { formatLargeNumber } from '../../utils/accountUtils' -import HotspotCompressedListItem from './HotspotCompressedListItem' -import { NFTSkeleton } from './NftListItem' -import { CollectableNavigationProp } from './collectablesTypes' - -export const DEFAULT_PAGE_AMOUNT = 20 - -function RewardItem({ - mint, - amount, - hasMore, -}: { - mint: PublicKey - amount: BN | undefined - hasMore: boolean -}) { - const decimals = useMint(mint)?.info?.decimals - const { json, symbol } = useMetaplexMetadata(mint) - let realAmount = '' - if (amount) { - const num = toNumber(amount, decimals || 6) - realAmount = formatLargeNumber(new BigNumber(num)) - } - - return ( - - - - {realAmount} - {hasMore ? '+' : ''} - - - {symbol} - - - ) -} - -const HotspotList = () => { - const navigation = useNavigation() - const { t } = useTranslation() - const isFocused = useIsFocused() - const { primaryText } = useColors() - const { triggerImpact } = useHaptic() - const spacing = useSpacing() - const { bottom } = useSafeAreaInsets() - - const { - hotspots, - hotspotsWithMeta, - loading: loadingHotspots, - refresh, - fetchMore, - fetchingMore, - pendingIotRewards, - pendingMobileRewards, - onEndReached, - totalHotspots, - } = useHotspots() - - const pageAmount = 20 - const handleOnEndReached = useCallback(() => { - if (!fetchingMore && isFocused && !onEndReached) { - fetchMore(pageAmount) - } - }, [fetchingMore, isFocused, fetchMore, pageAmount, onEndReached]) - - const handleNavigateToHotspot = useCallback( - (hotspot: HotspotWithPendingRewards) => { - if (hotspot.content.metadata) { - triggerImpact('light') - const { iot, mobile } = hotspot.content.metadata.hotspot_infos || {} - navigation.navigate('HotspotMapScreen', { - hotspot, - network: iot?.location - ? 'IOT' - : mobile?.location - ? 'MOBILE' - : undefined, - }) - } - }, - [navigation, triggerImpact], - ) - - const handleNavigateToClaimRewards = useCallback(() => { - navigation.navigate('ClaimAllRewardsScreen') - }, [navigation]) - - const handleNavigateToMap = useCallback(() => { - navigation.navigate('HotspotMapScreen') - }, [navigation]) - - const handleNavigateToHotspotOnboard = useCallback(() => { - navigation.navigate('OnboardingNavigator') - }, [navigation]) - - const renderHeader = useCallback(() => { - return ( - - - - } - title={t('collectablesScreen.hotspots.openMap')} - titleColor="base.white" - fontSize={14} - onPress={handleNavigateToMap} - /> - - } - title={t('collectablesScreen.hotspots.connect')} - titleColor="base.black" - fontSize={14} - onPress={handleNavigateToHotspotOnboard} - /> - - - - - - You own - - - {totalHotspots} hotspots - - - - - - - ) - }, [t, handleNavigateToMap, handleNavigateToHotspotOnboard, totalHotspots]) - - const renderCollectable = useCallback( - // eslint-disable-next-line react/no-unused-prop-types - ({ item }: { item: HotspotWithPendingRewards }) => { - return ( - - ) - }, - [handleNavigateToHotspot], - ) - - const renderEmptyComponent = useCallback(() => { - if (!loadingHotspots) return null - - if (loadingHotspots && hotspots) { - return ( - - {times(hotspots.length).map((i) => ( - - ))} - - ) - } - - return null - }, [hotspots, loadingHotspots]) - - const keyExtractor = useCallback((item: CompressedNFT) => { - return item.id - }, []) - - const Footer = useCallback( - () => ( - - {fetchingMore ? : } - - ), - [fetchingMore], - ) - - const handleRefresh = useCallback(() => { - refresh(pageAmount) - }, [pageAmount, refresh]) - - useEffect(() => { - return navigation.addListener('focus', () => { - refresh() - }) - }, [navigation, refresh]) - - return ( - <> - - } - > - - - - - - - - - - - ) -} - -export default HotspotList diff --git a/src/features/collectables/HotspotListItem.tsx b/src/features/collectables/HotspotListItem.tsx deleted file mode 100644 index 2ff84989c..000000000 --- a/src/features/collectables/HotspotListItem.tsx +++ /dev/null @@ -1,173 +0,0 @@ -import React, { useMemo } from 'react' -import { FadeIn, FadeOut } from 'react-native-reanimated' -import { BoxProps } from '@shopify/restyle' -import IotSymbol from '@assets/images/iotSymbol.svg' -import MobileSymbol from '@assets/images/mobileSymbol.svg' -import BN from 'bn.js' -import Text from '@components/Text' -import TouchableOpacityBox from '@components/TouchableOpacityBox' -import Box from '@components/Box' -import { ReAnimatedBox } from '@components/AnimatedBox' -import ImageBox from '@components/ImageBox' -import { Theme } from '@theme/theme' -import { IOT_MINT, MOBILE_MINT, toNumber } from '@helium/spl-utils' -import { useMint } from '@helium/helium-react-hooks' -import BigNumber from 'bignumber.js' -import { useColors } from '@theme/themeHooks' -import { removeDashAndCapitalize } from '../../utils/hotspotNftsUtils' -import { ww } from '../../utils/layout' -import { formatLargeNumber } from '../../utils/accountUtils' -import { Mints } from '../../utils/constants' -import { HotspotWithPendingRewards } from '../../types/solana' - -export type HotspotListItemProps = { - hotspot: HotspotWithPendingRewards - onPress: (hotspot: HotspotWithPendingRewards) => void -} & BoxProps - -const HotspotListItem = ({ - hotspot, - onPress, - ...rest -}: HotspotListItemProps) => { - const colors = useColors() - const COLLECTABLE_HEIGHT = ww / 2 - const { - content: { metadata }, - } = hotspot - - const { info: iotMint } = useMint(IOT_MINT) - const { info: mobileMint } = useMint(MOBILE_MINT) - - const pendingIotRewards = useMemo( - () => hotspot.pendingRewards && new BN(hotspot.pendingRewards[Mints.IOT]), - [hotspot.pendingRewards], - ) - const pendingIotRewardsString = useMemo(() => { - if (!hotspot.pendingRewards) return - const num = toNumber( - new BN(hotspot.pendingRewards[Mints.IOT]), - iotMint?.decimals || 6, - ) - return formatLargeNumber(new BigNumber(num)) - }, [iotMint, hotspot]) - - const pendingMobileRewards = useMemo( - () => - hotspot.pendingRewards && new BN(hotspot.pendingRewards[Mints.MOBILE]), - [hotspot.pendingRewards], - ) - - const pendingMobileRewardsString = useMemo(() => { - if (!hotspot.pendingRewards) return - const num = toNumber( - new BN(hotspot.pendingRewards[Mints.MOBILE]), - mobileMint?.decimals || 6, - ) - return formatLargeNumber(new BigNumber(num)) - }, [hotspot, mobileMint]) - - const hasIotRewards = useMemo( - () => pendingIotRewards && pendingIotRewards.gt(new BN(0)), - [pendingIotRewards], - ) - const hasMobileRewards = useMemo( - () => pendingMobileRewards && pendingMobileRewards.gt(new BN(0)), - [pendingMobileRewards], - ) - - return ( - - onPress(hotspot)} - > - - {!!hasMobileRewards && ( - - - {pendingMobileRewardsString} - - - - )} - {!!hasIotRewards && ( - - - {pendingIotRewardsString} - - - - )} - - {metadata?.name && ( - - {removeDashAndCapitalize(metadata.name)} - - )} - - ) -} - -export default HotspotListItem diff --git a/src/features/collectables/ManageCollectables.tsx b/src/features/collectables/ManageCollectables.tsx index ecc61adf1..798a5d550 100644 --- a/src/features/collectables/ManageCollectables.tsx +++ b/src/features/collectables/ManageCollectables.tsx @@ -3,7 +3,7 @@ import ScrollBox from '@components/ScrollBox' import { NavBarHeight } from '@components/ServiceNavBar' import useCollectables from '@hooks/useCollectables' import { RootState } from '@store/rootReducer' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { heliumNFTs } from '@utils/solanaUtils' import React, { useCallback } from 'react' import { useAsync } from 'react-async-hook' diff --git a/src/features/collectables/NftDetailsScreen.tsx b/src/features/collectables/NftDetailsScreen.tsx index 186914bdb..ba24b1028 100644 --- a/src/features/collectables/NftDetailsScreen.tsx +++ b/src/features/collectables/NftDetailsScreen.tsx @@ -3,24 +3,24 @@ import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { useSafeAreaInsets } from 'react-native-safe-area-context' import 'text-encoding-polyfill' import { useTranslation } from 'react-i18next' -import Face from '@assets/images/face.svg' -import ArrowRight from '@assets/images/arrowRight.svg' +import Face from '@assets/svgs/face.svg' +import ArrowRight from '@assets/svgs/arrowRight.svg' import { DelayedFadeIn } from '@components/FadeInOut' -import globalStyles from '@theme/globalStyles' +import globalStyles from '@config/theme/globalStyles' import Box from '@components/Box' import ImageBox from '@components/ImageBox' import Text from '@components/Text' import BackScreen from '@components/BackScreen' -import { useSpacing } from '@theme/themeHooks' +import { useSpacing } from '@config/theme/themeHooks' import { ReAnimatedBox } from '@components/AnimatedBox' import ScrollBox from '@components/ScrollBox' import { WalletNavigationProp, WalletStackParamList, -} from '@services/WalletService/pages/WalletPage/WalletPageNavigator' +} from '@services/WalletService/pages/WalletPage' import { NavBarHeight } from '@components/ServiceNavBar' import ButtonPressable from '@components/ButtonPressable' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import NftMetadata from './NftMetadata' import { ww } from '../../utils/layout' import { CompressedNFT } from '../../types/solana' diff --git a/src/features/collectables/NftList.tsx b/src/features/collectables/NftList.tsx index 65d1e8b17..e4ed8c853 100644 --- a/src/features/collectables/NftList.tsx +++ b/src/features/collectables/NftList.tsx @@ -4,14 +4,14 @@ import { FlatList } from 'react-native-gesture-handler' import { RefreshControl } from 'react-native' import Box from '@components/Box' import useCollectables from '@hooks/useCollectables' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import { useNavigation } from '@react-navigation/native' import { NavBarHeight } from '@components/ServiceNavBar' import { useSafeAreaInsets } from 'react-native-safe-area-context' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import Config from '@assets/images/config.svg' +import Config from '@assets/svgs/config.svg' import Text from '@components/Text' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' import ScrollBox from '@components/ScrollBox' import { useSelector } from 'react-redux' import { RootState } from '@store/rootReducer' diff --git a/src/features/collectables/NftListItem.tsx b/src/features/collectables/NftListItem.tsx index e31c9f1b7..a22b1af6c 100644 --- a/src/features/collectables/NftListItem.tsx +++ b/src/features/collectables/NftListItem.tsx @@ -8,7 +8,7 @@ import TouchableOpacityBox from '@components/TouchableOpacityBox' import CircleLoader from '@components/CircleLoader' import { ReAnimatedBox } from '@components/AnimatedBox' import useHaptic from '@hooks/useHaptic' -import { useBorderRadii } from '@theme/themeHooks' +import { useBorderRadii } from '@config/theme/themeHooks' import useLayoutWidth from '@hooks/useLayoutWidth' import { ww } from '../../utils/layout' import { Collectable } from '../../types/solana' diff --git a/src/features/collectables/NftMetadata.tsx b/src/features/collectables/NftMetadata.tsx index cad7c6a08..96353d5af 100644 --- a/src/features/collectables/NftMetadata.tsx +++ b/src/features/collectables/NftMetadata.tsx @@ -3,7 +3,7 @@ import { useTranslation } from 'react-i18next' import Box from '@components/Box' import Text from '@components/Text' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' function stringify( s: boolean | string | string[] | undefined, diff --git a/src/features/collectables/TransferCollectableScreen.tsx b/src/features/collectables/TransferCollectableScreen.tsx index 89441df32..30953b08a 100644 --- a/src/features/collectables/TransferCollectableScreen.tsx +++ b/src/features/collectables/TransferCollectableScreen.tsx @@ -1,4 +1,4 @@ -import ArrowRight from '@assets/images/arrowRight.svg' +import ArrowRight from '@assets/svgs/arrowRight.svg' import AddressBookSelector, { AddressBookRef, } from '@components/AddressBookSelector' @@ -12,7 +12,7 @@ import ImageBox from '@components/ImageBox' import Text from '@components/Text' import TextInput from '@components/TextInput' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import React, { memo, useCallback, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { @@ -27,10 +27,10 @@ import ScrollBox from '@components/ScrollBox' import { Asset } from '@helium/spl-utils' import { NavBarHeight } from '@components/ServiceNavBar' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import AddressIcon from '@assets/images/addressIcon.svg' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' +import AddressIcon from '@assets/svgs/addressIcon.svg' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' +import { CSAccount } from '@config/storage/cloudStorage' import useSubmitTxn from '../../hooks/useSubmitTxn' -import { CSAccount } from '../../storage/cloudStorage' import { solAddressIsValid } from '../../utils/accountUtils' import { ww } from '../../utils/layout' import * as Logger from '../../utils/logger' @@ -87,10 +87,6 @@ const TransferCollectableScreen = () => { [], ) - const backgroundImageUri = useMemo(() => { - return metadata.image - }, [metadata]) - const handleEditAddress = useCallback((text?: string) => { setRecipient(text || '') setRecipientName('') @@ -130,7 +126,6 @@ const TransferCollectableScreen = () => { diff --git a/src/features/collectables/TransferCompleteScreen.tsx b/src/features/collectables/TransferCompleteScreen.tsx index 80cd82703..c77da09f3 100644 --- a/src/features/collectables/TransferCompleteScreen.tsx +++ b/src/features/collectables/TransferCompleteScreen.tsx @@ -1,4 +1,4 @@ -import BackArrow from '@assets/images/backArrow.svg' +import BackArrow from '@assets/svgs/backArrow.svg' import { ReAnimatedBox } from '@components/AnimatedBox' import BackScreen from '@components/BackScreen' import Box from '@components/Box' @@ -11,7 +11,7 @@ import { useSolOwnedAmount } from '@helium/helium-react-hooks' import { useBN } from '@hooks/useBN' import { useCurrentWallet } from '@hooks/useCurrentWallet' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import { parseTransactionError } from '@utils/solanaUtils' import React, { memo, useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' @@ -22,7 +22,7 @@ import 'text-encoding-polyfill' import ScrollBox from '@components/ScrollBox' import { NavBarHeight } from '@components/ServiceNavBar' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' import { RootState } from '../../store/rootReducer' import { CompressedNFT } from '../../types/solana' import { ww } from '../../utils/layout' diff --git a/src/features/dappLogin/DappAccount.tsx b/src/features/dappLogin/DappAccount.tsx index 42f2434fb..f36ca8d16 100644 --- a/src/features/dappLogin/DappAccount.tsx +++ b/src/features/dappLogin/DappAccount.tsx @@ -1,8 +1,8 @@ import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react' import { useTranslation } from 'react-i18next' -import Crowdspot from '@assets/images/crowdspot.svg' -import AddDapp from '@assets/images/addDapp.svg' -import DappEllipsis from '@assets/images/dapp-ellipsis.svg' +import Crowdspot from '@assets/svgs/crowdspot.svg' +import AddDapp from '@assets/svgs/addDapp.svg' +import DappEllipsis from '@assets/svgs/dapp-ellipsis.svg' import { NetTypes as NetType, NetTypes } from '@helium/address' import { ActivityIndicator } from 'react-native' import AccountButton from '@components/AccountButton' @@ -12,9 +12,9 @@ import AccountSelector, { import Box from '@components/Box' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import AccountIcon from '@components/AccountIcon' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' type Props = { onLogin: () => void diff --git a/src/features/dappLogin/DappConnect.tsx b/src/features/dappLogin/DappConnect.tsx index 2d5267ad2..f512072e6 100644 --- a/src/features/dappLogin/DappConnect.tsx +++ b/src/features/dappLogin/DappConnect.tsx @@ -1,11 +1,11 @@ import React, { memo, useMemo } from 'react' import { useTranslation } from 'react-i18next' -import Crowdspot from '@assets/images/crowdspot.svg' -import AddDapp from '@assets/images/addDapp.svg' +import Crowdspot from '@assets/svgs/crowdspot.svg' +import AddDapp from '@assets/svgs/addDapp.svg' import Box from '@components/Box' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' type Props = { appName: string; onApprove: () => void; onDeny: () => void } const DappConnect = ({ appName, onApprove, onDeny }: Props) => { diff --git a/src/features/dappLogin/DappLoginScreen.tsx b/src/features/dappLogin/DappLoginScreen.tsx index 0624cfea9..fa6a37fb0 100644 --- a/src/features/dappLogin/DappLoginScreen.tsx +++ b/src/features/dappLogin/DappLoginScreen.tsx @@ -1,23 +1,20 @@ -import Close from '@assets/images/close.svg' +import Close from '@assets/svgs/close.svg' import SafeAreaBox from '@components/SafeAreaBox' import TouchableOpacityBox from '@components/TouchableOpacityBox' import Address from '@helium/address' import { TokenBurnV1 } from '@helium/transactions' import useAlert from '@hooks/useAlert' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import React, { memo, useCallback, useEffect, useMemo, useRef } from 'react' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { ActivityIndicator, Linking } from 'react-native' import { useDebouncedCallback } from 'use-debounce' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' -import { - RootNavigationProp, - RootStackParamList, -} from '../../navigation/rootTypes' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { getKeypair } from '../../storage/secureStorage' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { getKeypair } from '@config/storage/secureStorage' +import { RootNavigationProp, RootStackParamList } from '../../app/rootTypes' import DappAccount from './DappAccount' import DappConnect from './DappConnect' import { useWalletConnect } from './WalletConnectProvider' diff --git a/src/features/governance/AssignProxyScreen.tsx b/src/features/governance/AssignProxyScreen.tsx index d7d02ed07..208458404 100644 --- a/src/features/governance/AssignProxyScreen.tsx +++ b/src/features/governance/AssignProxyScreen.tsx @@ -22,7 +22,7 @@ import { usePublicKey } from '@hooks/usePublicKey' import Slider from '@react-native-community/slider' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { PublicKey, TransactionInstruction } from '@solana/web3.js' -import { useGovernance } from '@storage/GovernanceProvider' +import { useGovernance } from '@config/storage/GovernanceProvider' import { MAX_TRANSACTIONS_PER_SIGNATURE_BATCH } from '@utils/constants' import sleep from '@utils/sleep' import { getBasePriorityFee } from '@utils/walletApiV2' @@ -31,9 +31,9 @@ import React, { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { FlatList } from 'react-native' import { Edge } from 'react-native-safe-area-context' -import { useSolana } from '../../solana/SolanaProvider' -import { useWalletSign } from '../../solana/WalletSignProvider' -import { WalletStandardMessageTypes } from '../../solana/walletSignBottomSheetTypes' +import { useSolana } from '@features/solana/SolanaProvider' +import { useWalletSign } from '@features/solana/WalletSignProvider' +import { WalletStandardMessageTypes } from '@features/solana/walletSignBottomSheetTypes' import { PositionPreview } from './PositionPreview' import { ProxySearch } from './ProxySearch' import { @@ -253,8 +253,10 @@ export const AssignProxyScreen = () => { {t('gov.assignProxy.selectNetwork')} ({ label: o.charAt(0).toUpperCase() + o.slice(1), diff --git a/src/features/governance/LockTokensModal.tsx b/src/features/governance/LockTokensModal.tsx index 729c2f117..f424f3b2f 100644 --- a/src/features/governance/LockTokensModal.tsx +++ b/src/features/governance/LockTokensModal.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ -import Close from '@assets/images/close.svg' -import InfoIcon from '@assets/images/info.svg' +import Close from '@assets/svgs/close.svg' +import InfoIcon from '@assets/svgs/info.svg' import { ReAnimatedBox } from '@components/AnimatedBox' import BackScreen from '@components/BackScreen' import Box from '@components/Box' @@ -17,7 +17,7 @@ import { useMint } from '@helium/helium-react-hooks' import { HNT_MINT, toBN, toNumber } from '@helium/spl-utils' import { SubDaoWithMeta, useSubDaos } from '@helium/voter-stake-registry-hooks' import { PublicKey } from '@solana/web3.js' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { getFormattedStringFromDays, yearsToDays } from '@utils/dateTools' import { getMintMinAmountAsDecimal, precision } from '@utils/formatting' import { TXN_FEE_IN_LAMPORTS } from '@utils/solanaUtils' @@ -30,9 +30,9 @@ import { TouchableWithoutFeedback, } from 'react-native' import { Edge } from 'react-native-safe-area-context' -import HntIcon from '@assets/images/helium.svg' +import HntIcon from '@assets/svgs/helium.svg' import ScrollBox from '@components/ScrollBox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' const SOL_TXN_FEE = new BN(TXN_FEE_IN_LAMPORTS) export const defaultLockupPeriods = [ diff --git a/src/features/governance/NetworkTabs.tsx b/src/features/governance/NetworkTabs.tsx index e7a4992fb..99e64d0e9 100644 --- a/src/features/governance/NetworkTabs.tsx +++ b/src/features/governance/NetworkTabs.tsx @@ -4,9 +4,9 @@ import { PublicKey } from '@solana/web3.js' import React, { useCallback, useMemo } from 'react' import SegmentedControl from '@components/SegmentedControl' import { Mints } from '@utils/constants' -import IOT from '@assets/images/iotSymbol.svg' -import MOBILE from '@assets/images/mobileIcon.svg' -import HNT from '@assets/images/tokenHNT.svg' +import IOT from '@assets/svgs/iotSymbol.svg' +import MOBILE from '@assets/svgs/mobileIcon.svg' +import HNT from '@assets/svgs/tokenHNT.svg' import { GovernanceNavigationProp } from './governanceTypes' export const NetworkTabs: React.FC = () => { diff --git a/src/features/governance/PositionCard.tsx b/src/features/governance/PositionCard.tsx index c7e12db01..7b63ef11c 100644 --- a/src/features/governance/PositionCard.tsx +++ b/src/features/governance/PositionCard.tsx @@ -40,9 +40,9 @@ import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { useNavigation } from '@react-navigation/native' import { BoxProps } from '@shopify/restyle' import { Keypair, PublicKey, TransactionInstruction } from '@solana/web3.js' -import { useGovernance } from '@storage/GovernanceProvider' -import { Theme } from '@theme/theme' -import { useCreateOpacity } from '@theme/themeHooks' +import { useGovernance } from '@config/storage/GovernanceProvider' +import { Theme } from '@config/theme/theme' +import { useCreateOpacity } from '@config/theme/themeHooks' import { MAX_TRANSACTIONS_PER_SIGNATURE_BATCH } from '@utils/constants' import { daysToSecs, @@ -58,10 +58,10 @@ import React, { useCallback, useMemo, useRef, useState } from 'react' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { FadeIn, FadeOut } from 'react-native-reanimated' -import { MessagePreview } from '../../solana/MessagePreview' -import { useSolana } from '../../solana/SolanaProvider' -import { useWalletSign } from '../../solana/WalletSignProvider' -import { WalletStandardMessageTypes } from '../../solana/walletSignBottomSheetTypes' +import { MessagePreview } from '@features/solana/MessagePreview' +import { useSolana } from '@features/solana/SolanaProvider' +import { useWalletSign } from '@features/solana/WalletSignProvider' +import { WalletStandardMessageTypes } from '@features/solana/walletSignBottomSheetTypes' import { DelegateTokensModal } from './DelegateTokensModal' import LockTokensModal, { LockTokensModalFormValues } from './LockTokensModal' import { TransferTokensModal } from './TransferTokensModal' diff --git a/src/features/governance/PositionPreview.tsx b/src/features/governance/PositionPreview.tsx index c0593de0a..46843de6c 100644 --- a/src/features/governance/PositionPreview.tsx +++ b/src/features/governance/PositionPreview.tsx @@ -1,13 +1,13 @@ -import Hnt from '@assets/images/hnt.svg' -import Iot from '@assets/images/iot.svg' -import Mobile from '@assets/images/mobile.svg' +import Hnt from '@assets/svgs/hnt.svg' +import Iot from '@assets/svgs/iot.svg' +import Mobile from '@assets/svgs/mobile.svg' import Box from '@components/Box' import Text from '@components/Text' import TouchableContainer, { ButtonPressAnimationProps, } from '@components/TouchableContainer' import { PositionWithMeta } from '@helium/voter-stake-registry-hooks' -import { useGovernance } from '@storage/GovernanceProvider' +import { useGovernance } from '@config/storage/GovernanceProvider' import { getMinDurationFmt } from '@utils/dateTools' import { humanReadable } from '@utils/formatting' import BN from 'bn.js' diff --git a/src/features/governance/PositionsList.tsx b/src/features/governance/PositionsList.tsx index 79faec187..28699f9c6 100644 --- a/src/features/governance/PositionsList.tsx +++ b/src/features/governance/PositionsList.tsx @@ -1,4 +1,4 @@ -import LightningBolt from '@assets/images/transactions.svg' +import LightningBolt from '@assets/svgs/transactions.svg' import Box from '@components/Box' import { CardSkeleton } from '@components/CardSkeleton' import Text from '@components/Text' @@ -7,9 +7,9 @@ import { useSubDaos, } from '@helium/voter-stake-registry-hooks' import { BoxProps } from '@shopify/restyle' -import { useGovernance } from '@storage/GovernanceProvider' -import { Theme } from '@theme/theme' -import { useColors } from '@theme/themeHooks' +import { useGovernance } from '@config/storage/GovernanceProvider' +import { Theme } from '@config/theme/theme' +import { useColors } from '@config/theme/themeHooks' import { times } from 'lodash' import React, { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' diff --git a/src/features/governance/PositionsScreen.tsx b/src/features/governance/PositionsScreen.tsx index 02019c3c6..313072c1b 100644 --- a/src/features/governance/PositionsScreen.tsx +++ b/src/features/governance/PositionsScreen.tsx @@ -23,7 +23,7 @@ import { import { useCurrentWallet } from '@hooks/useCurrentWallet' import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { Keypair, TransactionInstruction } from '@solana/web3.js' -import { useGovernance } from '@storage/GovernanceProvider' +import { useGovernance } from '@config/storage/GovernanceProvider' import { MAX_TRANSACTIONS_PER_SIGNATURE_BATCH } from '@utils/constants' import { daysToSecs, getFormattedStringFromDays } from '@utils/dateTools' import { getBasePriorityFee } from '@utils/walletApiV2' @@ -31,12 +31,12 @@ import BN from 'bn.js' import React, { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import { useSpacing } from '@theme/themeHooks' +import { useSpacing } from '@config/theme/themeHooks' import ScrollBox from '@components/ScrollBox' -import { MessagePreview } from '../../solana/MessagePreview' -import { useSolana } from '../../solana/SolanaProvider' -import { useWalletSign } from '../../solana/WalletSignProvider' -import { WalletStandardMessageTypes } from '../../solana/walletSignBottomSheetTypes' +import { MessagePreview } from '@features/solana/MessagePreview' +import { useSolana } from '@features/solana/SolanaProvider' +import { useWalletSign } from '@features/solana/WalletSignProvider' +import { WalletStandardMessageTypes } from '@features/solana/walletSignBottomSheetTypes' import { ClaimingRewardsModal } from './ClaimingRewardsModal' import GovernanceWrapper from './GovernanceWrapper' import LockTokensModal, { LockTokensModalFormValues } from './LockTokensModal' diff --git a/src/features/governance/ProposalCard.tsx b/src/features/governance/ProposalCard.tsx index 3c42dea4d..e8e3ce40c 100644 --- a/src/features/governance/ProposalCard.tsx +++ b/src/features/governance/ProposalCard.tsx @@ -9,8 +9,8 @@ import { } from '@helium/modular-governance-hooks' import { BoxProps } from '@shopify/restyle' import { PublicKey } from '@solana/web3.js' -import { useGovernance } from '@storage/GovernanceProvider' -import { Theme } from '@theme/theme' +import { useGovernance } from '@config/storage/GovernanceProvider' +import { Theme } from '@config/theme/theme' import { humanReadable } from '@utils/formatting' import axios from 'axios' import BN from 'bn.js' @@ -20,7 +20,7 @@ import { useAsync } from 'react-async-hook' import { FadeIn, FadeOut } from 'react-native-reanimated' import { useTranslation } from 'react-i18next' import { getTimeFromNowFmt } from '@utils/dateTools' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { getDerivedProposalState } from '@utils/governanceUtils' import { ProposalFilter, ProposalV0 } from './governanceTypes' import { ProposalTags } from './ProposalTags' diff --git a/src/features/governance/ProposalScreen.tsx b/src/features/governance/ProposalScreen.tsx index c164967e7..7dbde690d 100644 --- a/src/features/governance/ProposalScreen.tsx +++ b/src/features/governance/ProposalScreen.tsx @@ -1,4 +1,4 @@ -import BrowseVoters from '@assets/images/browseVoters.svg' +import BrowseVoters from '@assets/svgs/browseVoters.svg' import { ReAnimatedBox } from '@components/AnimatedBox' import BackScreen from '@components/BackScreen' import Box from '@components/Box' @@ -27,9 +27,9 @@ import { } from '@helium/voter-stake-registry-hooks' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { PublicKey, TransactionInstruction } from '@solana/web3.js' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { useGovernance } from '@storage/GovernanceProvider' -import globalStyles from '@theme/globalStyles' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useGovernance } from '@config/storage/GovernanceProvider' +import globalStyles from '@config/theme/globalStyles' import { MAX_TRANSACTIONS_PER_SIGNATURE_BATCH } from '@utils/constants' import { getTimeFromNowFmt } from '@utils/dateTools' import { humanReadable } from '@utils/formatting' @@ -42,10 +42,11 @@ import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { Edge } from 'react-native-safe-area-context' import ScrollBox from '@components/ScrollBox' -import { MessagePreview } from '../../solana/MessagePreview' -import { useSolana } from '../../solana/SolanaProvider' -import { useWalletSign } from '../../solana/WalletSignProvider' -import { WalletStandardMessageTypes } from '../../solana/walletSignBottomSheetTypes' +import { useColors } from '@config/theme/themeHooks' +import { MessagePreview } from '@features/solana/MessagePreview' +import { useSolana } from '@features/solana/SolanaProvider' +import { useWalletSign } from '@features/solana/WalletSignProvider' +import { WalletStandardMessageTypes } from '@features/solana/walletSignBottomSheetTypes' import { VoteOption } from './VoteOption' import { GovernanceNavigationProp, @@ -58,6 +59,7 @@ import { type Route = RouteProp export const ProposalScreen = () => { const { t } = useTranslation() + const colors = useColors() const route = useRoute() const navigation = useNavigation() const { upsertAccount, currentAccount } = useAccountStorage() @@ -521,8 +523,15 @@ export const ProposalScreen = () => { } + backgroundColor="primaryText" + titleColor="primaryBackground" + LeadingComponent={ + + } borderRadius="full" mt="4" onPress={handleBrowseVoters} diff --git a/src/features/governance/ProposalsList.tsx b/src/features/governance/ProposalsList.tsx index fb9a41abd..1018f71c5 100644 --- a/src/features/governance/ProposalsList.tsx +++ b/src/features/governance/ProposalsList.tsx @@ -7,9 +7,9 @@ import TouchableOpacityBox from '@components/TouchableOpacityBox' import { useOrganizationProposals } from '@helium/modular-governance-hooks' import { useNavigation } from '@react-navigation/native' import { BoxProps } from '@shopify/restyle' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { useGovernance } from '@storage/GovernanceProvider' -import { Theme } from '@theme/theme' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useGovernance } from '@config/storage/GovernanceProvider' +import { Theme } from '@config/theme/theme' import { getDerivedProposalState } from '@utils/governanceUtils' import React, { useCallback, useMemo, useState } from 'react' import { useAsync } from 'react-async-hook' diff --git a/src/features/governance/ProxySearch.tsx b/src/features/governance/ProxySearch.tsx index d7876431a..a8af52514 100644 --- a/src/features/governance/ProxySearch.tsx +++ b/src/features/governance/ProxySearch.tsx @@ -1,4 +1,4 @@ -import BrowseVoters from '@assets/images/browseVoters.svg' +import BrowseVoters from '@assets/svgs/browseVoters.svg' import Box from '@components/Box' import ButtonPressable from '@components/ButtonPressable' import CircleLoader from '@components/CircleLoader' @@ -9,13 +9,14 @@ import { proxiesQuery } from '@helium/voter-stake-registry-hooks' import { EnhancedProxy } from '@helium/voter-stake-registry-sdk' import { useNavigation } from '@react-navigation/native' import { PublicKey } from '@solana/web3.js' -import { useGovernance } from '@storage/GovernanceProvider' +import { useGovernance } from '@config/storage/GovernanceProvider' import { useInfiniteQuery } from '@tanstack/react-query' import { shortenAddress } from '@utils/formatting' import React, { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { FlatList } from 'react-native' import { useDebounce } from 'use-debounce' +import { useColors } from '@config/theme/themeHooks' import { GovernanceNavigationProp } from './governanceTypes' export const ProxySearch: React.FC<{ @@ -27,6 +28,7 @@ export const ProxySearch: React.FC<{ const [focused, setFocused] = useState(false) const [debouncedInput] = useDebounce(input, 300) const { voteService, mint } = useGovernance() + const colors = useColors() const { data: resultPaged, isLoading: loading, @@ -131,8 +133,10 @@ export const ProxySearch: React.FC<{ }} /> { {t('gov.assignProxy.selectNetwork')} + {height ? : null} + + ) +} + +export default SelectFloorScreen diff --git a/src/features/hotspot-onboarding/screens/SelectLocationScreen.tsx b/src/features/hotspot-onboarding/screens/SelectLocationScreen.tsx new file mode 100644 index 000000000..9a9c0cf85 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/SelectLocationScreen.tsx @@ -0,0 +1,287 @@ +import MapPin from '@assets/svgs/mapPin.svg' +import { Box, DelayedFadeIn, FadeInOut, ReAnimatedBox, Text } from '@components' +import useAlert from '@hooks/useAlert' +import { useForwardGeo } from '@hooks/useForwardGeo' +import { useReverseGeo } from '@hooks/useReverseGeo' +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import { useTranslation } from 'react-i18next' +import { KeyboardAvoidingView } from 'react-native' +import 'text-encoding-polyfill' +import { useDebounce } from 'use-debounce' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import Map from '@components/Map' +import { + Camera, + Location, + MapState, + MapView, + UserLocation, +} from '@rnmapbox/maps' +import { INITIAL_MAP_VIEW_STATE, MAX_MAP_ZOOM } from '@utils/mapUtils' +import { Search } from '@components/Search' +import CheckButton from '../components/CheckButton' +import { useHotspotOnboarding } from '../OnboardingSheet' + +const SelectLocationScreen = () => { + const { t } = useTranslation() + const mapRef = useRef(null) + const cameraRef = useRef(null) + const { showOKAlert } = useAlert() + const colors = useColors() + const spacing = useSpacing() + const { carouselRef, setOnboardDetails } = useHotspotOnboarding() + const [mapCenter, setMapCenter] = useState() + const [searchValue, setSearchValue] = useState() + const reverseGeo = useReverseGeo(mapCenter) + const forwardGeo = useForwardGeo() + const [darkCheckMode, setDarkCheckMode] = useState(true) + + const [initialUserLocation, setInitialUserLocation] = useState() + const [initialCenterSet, setInitalCenter] = useState(false) + + const [userLocation, setUserLocation] = useState() + const onUserLocationUpdate = useCallback( + (loc: Location) => { + setUserLocation(loc) + }, + [setUserLocation], + ) + + const handleCameraChanged = useCallback((state: MapState) => { + setDarkCheckMode(state.properties.zoom < 3) + }, []) + + useEffect(() => { + const coords = userLocation?.coords + if (!initialUserLocation && coords) { + setInitialUserLocation([coords.longitude, coords.latitude]) + } + }, [initialUserLocation, setInitialUserLocation, userLocation?.coords]) + + const initialCenter = useMemo(() => { + return initialUserLocation || INITIAL_MAP_VIEW_STATE.centerCoordinate + }, [initialUserLocation]) + + useEffect(() => { + if ( + initialCenter && + JSON.stringify(initialCenter) !== + JSON.stringify(INITIAL_MAP_VIEW_STATE.centerCoordinate) && + !initialCenterSet + ) { + setInitalCenter(true) + cameraRef.current?.setCamera({ + centerCoordinate: initialCenter, + animationDuration: 0, + }) + } + }, [initialCenter, cameraRef, initialCenterSet, setInitalCenter]) + + const handleOnSearch = useCallback(async () => { + if (searchValue) { + try { + const coords = await forwardGeo.execute(searchValue) + + if (cameraRef?.current && coords) { + cameraRef.current.setCamera({ + animationDuration: 500, + centerCoordinate: coords, + zoomLevel: MAX_MAP_ZOOM / 1.2, + }) + } + } catch (error) { + const { message = '' } = error as Error + if (message === t('noData')) { + await showOKAlert({ + title: t('generic.error'), + message: t('assertLocationScreen.locationNotFound'), + }) + } + } + } + }, [cameraRef, t, searchValue, forwardGeo, showOKAlert]) + + const handleRegionChanged = useCallback(async () => { + if (mapRef?.current) { + const center = await mapRef?.current.getCenter() + if (JSON.stringify(center) !== JSON.stringify(mapCenter)) { + setMapCenter(center) + } + } + }, [mapRef, mapCenter, setMapCenter]) + + const onConfirmLocation = useCallback(() => { + const long = mapCenter?.[0] + const lat = mapCenter?.[1] + + setOnboardDetails((o) => ({ + ...o, + latitude: lat || 0, + longitude: long || 0, + })) + carouselRef?.current?.snapToNext() + }, [mapCenter, carouselRef, setOnboardDetails]) + + const [reverseGeoLoading] = useDebounce(reverseGeo.loading, 300) + + return ( + + + + <> + + + {/* {(sameLocation ? [iotLocation] : [iotLocation, mobileLocation]) + .map((location, i) => { + if (!location || location.length < 2) return null + + return ( + + {sameLocation ? ( + + + + + + + + + + + + + ) : ( + + )} + + ) + }) + .filter(Boolean)} */} + + + + + + + + + + + + + + + {!reverseGeoLoading && reverseGeo.result && ( + + + + {reverseGeo.result} + + + + )} + + + + + ) +} + +export default SelectLocationScreen diff --git a/src/features/hotspot-onboarding/screens/SelectNetworkScreen.tsx b/src/features/hotspot-onboarding/screens/SelectNetworkScreen.tsx new file mode 100644 index 000000000..15bea522c --- /dev/null +++ b/src/features/hotspot-onboarding/screens/SelectNetworkScreen.tsx @@ -0,0 +1,111 @@ +import Box from '@components/Box' +import Text from '@components/Text' +import TouchableContainer from '@components/TouchableContainer' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import MobileIcon from '@assets/svgs/mobileIconNew.svg' +import IotIcon from '@assets/svgs/iotIconNew.svg' +import CarotRight from '@assets/svgs/carot-right.svg' +import { useColors } from '@config/theme/themeHooks' +import RightArrow from '@assets/svgs/rightArrow.svg' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import { HOTSPOT_HELP } from '@utils/constants/urls' +import { Linking } from 'react-native' +import { useHotspotOnboarding, OnboardDetails } from '../OnboardingSheet' + +const SelectNetworkScreen = () => { + const { t } = useTranslation() + const colors = useColors() + const { setOnboardDetails, carouselRef } = useHotspotOnboarding() + + const onMobileSelected = useCallback(() => { + setOnboardDetails((o: OnboardDetails) => ({ ...o, network: 'mobile' })) + carouselRef?.current?.snapToNext() + }, [setOnboardDetails, carouselRef]) + + const onIotSelected = useCallback(() => { + setOnboardDetails((o: OnboardDetails) => ({ ...o, network: 'iot' })) + carouselRef?.current?.snapToNext() + }, [setOnboardDetails, carouselRef]) + + const onOpenHelp = useCallback(() => { + Linking.openURL(HOTSPOT_HELP) + }, []) + + return ( + + + {t('SelectNetworkScreen.title')} + + + {t('SelectNetworkScreen.subtitle')} + + + + + MOBILE + + + + + + + IOT + + + + + + {t('SelectNetworkScreen.helpText')} + + + + + ) +} + +export default SelectNetworkScreen diff --git a/src/features/hotspot-onboarding/iot-ble/AddGatewayBle.tsx b/src/features/hotspot-onboarding/screens/iot/AddToWalletScreen.tsx similarity index 58% rename from src/features/hotspot-onboarding/iot-ble/AddGatewayBle.tsx rename to src/features/hotspot-onboarding/screens/iot/AddToWalletScreen.tsx index 6e874be77..46505ffb7 100644 --- a/src/features/hotspot-onboarding/iot-ble/AddGatewayBle.tsx +++ b/src/features/hotspot-onboarding/screens/iot/AddToWalletScreen.tsx @@ -1,21 +1,15 @@ -import BackScreen from '@components/BackScreen' import Box from '@components/Box' import ButtonPressable from '@components/ButtonPressable' -import CircleLoader from '@components/CircleLoader' import RadioButton from '@components/RadioButton' import Text from '@components/Text' import { init, iotInfoKey, keyToAssetKey, - mobileInfoKey, } from '@helium/helium-entity-manager-sdk' -import { daoKey } from '@helium/helium-sub-daos-sdk' -import { useOnboarding } from '@helium/react-native-sdk' +import { useHotspotBle, useOnboarding } from '@helium/react-native-sdk' import { - HNT_MINT, IOT_MINT, - MOBILE_MINT, bufferToTransaction, getAsset, sendAndConfirmWithRetry, @@ -25,10 +19,9 @@ import { useCurrentWallet } from '@hooks/useCurrentWallet' import { useImplicitBurn } from '@hooks/useImplicitBurn' import { useKeyToAsset } from '@hooks/useKeyToAsset' import { useOnboardingBalnces } from '@hooks/useOnboardingBalances' -import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { LAMPORTS_PER_SOL, Transaction } from '@solana/web3.js' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { IOT_CONFIG_KEY, MOBILE_CONFIG_KEY } from '@utils/constants' +import { LAMPORTS_PER_SOL, PublicKey, Transaction } from '@solana/web3.js' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { IOT_CONFIG_KEY, DAO_KEY } from '@utils/constants' import sleep from '@utils/sleep' import { getHotspotWithRewards, isInsufficientBal } from '@utils/solanaUtils' import BN from 'bn.js' @@ -36,23 +29,91 @@ import { Buffer } from 'buffer' import React, { useMemo, useState } from 'react' import { useAsync, useAsyncCallback } from 'react-async-hook' import { useTranslation } from 'react-i18next' -import { Alert, Linking, ScrollView } from 'react-native' -import { useSolana } from '../../../solana/SolanaProvider' -import { CollectableNavigationProp } from '../../collectables/collectablesTypes' -import { HotspotBLEStackParamList } from './navTypes' - -type Route = RouteProp +import { Alert, Linking } from 'react-native' +import ScrollBox from '@components/ScrollBox' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import Map from '@components/Map' +import { Camera } from '@rnmapbox/maps' +import ImageBox from '@components/ImageBox' +import { getAddressFromLatLng } from '@utils/location' +import { FadeIn, FadeOut } from 'react-native-reanimated' +import { ReAnimatedBox } from '@components/AnimatedBox' +import TouchableContainer from '@components/TouchableContainer' +import RightArrow from '@assets/svgs/rightArrow.svg' +import AccountIcon from '@components/AccountIcon' +import { useBottomSheet } from '@gorhom/bottom-sheet' +import { useNavigation } from '@react-navigation/native' +import { HotspotServiceNavigationProp } from 'src/app/services/HotspotService' +import { useSolana } from '@features/solana/SolanaProvider' +import Loading from '../../components/Loading' +import { useHotspotOnboarding } from '../../OnboardingSheet' const REQUIRED_SOL = new BN((0.00089088 + 0.00001) * LAMPORTS_PER_SOL) -const AddGatewayBle = () => { - const route = useRoute() - const { createGatewayTx, onboardingAddress, network } = route.params +const AddToWalletScreen = () => { const { onboardingClient, getOnboardTransactions } = useOnboarding() const { currentAccount } = useAccountStorage() const { anchorProvider } = useSolana() const { t } = useTranslation() - const collectNav = useNavigation() const wallet = useCurrentWallet() + const spacing = useSpacing() + const colors = useColors() + const { close } = useBottomSheet() + const navigation = useNavigation() + + const { + onboardDetails: { + iotDetails: { animalName }, + latitude, + longitude, + height, + }, + } = useHotspotOnboarding() + + const { + isConnected, + getOnboardingAddress, + createGatewayTxn: getCreateGatewayTxn, + } = useHotspotBle() + + const { result: connected } = useAsync(isConnected, []) + + const { + result: { + address: onboardingAddress, + keyToAssetK, + createGatewayTx, + } = {} as { + address?: string + keyToAssetK?: PublicKey + createGatewayTx?: string + }, + } = useAsync( + async ( + c: boolean | undefined, + accountAddress?: string, + ): Promise<{ + address?: string + keyToAssetK?: PublicKey + createGatewayTx?: string + }> => { + if (c && accountAddress) { + const addr = await getOnboardingAddress() + const tx = await getCreateGatewayTxn({ + ownerAddress: accountAddress, + payerAddress: accountAddress, + }) + // For testing + // const addr = TEST_HOTSPOT.address.b58 + return { + address: addr, + keyToAssetK: keyToAssetKey(DAO_KEY, addr, 'b58')[0], + createGatewayTx: tx, + } + } + return {} + }, + [connected, currentAccount?.address], + ) const { error: onboardBalError, @@ -70,10 +131,8 @@ const AddGatewayBle = () => { locationAssertDcRequirements, loadingOnboardingDcRequirements, } = useOnboardingBalnces(onboardingAddress) - const keyToAssetK = useMemo(() => { - return keyToAssetKey(daoKey(HNT_MINT)[0], onboardingAddress)[0].toBase58() - }, [onboardingAddress]) - const { info: keyToAsset } = useKeyToAsset(keyToAssetK) + + const { info: keyToAsset } = useKeyToAsset(keyToAssetK?.toBase58()) const { result: asset } = useAsync(async () => { if (anchorProvider && keyToAsset) { return getAsset(anchorProvider.connection.rpcEndpoint, keyToAsset.asset) @@ -81,7 +140,7 @@ const AddGatewayBle = () => { return undefined }, [anchorProvider, keyToAsset]) const wrongOwner = asset && wallet && !asset.ownership.owner.equals(wallet) - const mint = network === 'IOT' ? IOT_MINT : MOBILE_MINT + const mint = IOT_MINT const requiredDc = onboardingDcRequirements[mint.toBase58()] || new BN(0) const assertRequiredDc = locationAssertDcRequirements[mint.toBase58()] || new BN(0) @@ -203,15 +262,10 @@ const AddGatewayBle = () => { wrapProgramError(e) } - const configKey = network === 'IOT' ? IOT_CONFIG_KEY : MOBILE_CONFIG_KEY - const fetcher = - network === 'IOT' - ? hemProgram.account.iotHotspotInfoV0 - : hemProgram.account.mobileHotspotInfoV0 - const networkInfoK = - network === 'IOT' - ? iotInfoKey(configKey, onboardingAddress)[0] - : mobileInfoKey(configKey, onboardingAddress)[0] + const configKey = IOT_CONFIG_KEY + const fetcher = hemProgram.account.iotHotspotInfoV0 + const networkInfoK = iotInfoKey(configKey, onboardingAddress || '')[0] + const networkInfo = await fetcher.fetchNullable(networkInfoK) if (!networkInfo && onboardingAddress) { // Implicit burn to DC if needed @@ -223,7 +277,14 @@ const AddGatewayBle = () => { const { solanaTransactions } = await getOnboardTransactions({ hotspotAddress: onboardingAddress, payer, - networkDetails: [{ hotspotType: network }], + networkDetails: [ + { + hotspotType: 'IOT', + lat: latitude, + lng: longitude, + elevation: height, + }, + ], }) let solanaSignedTransactions: Transaction[] | undefined @@ -267,7 +328,9 @@ const AddGatewayBle = () => { totalTime += 2000 // eslint-disable-next-line no-await-in-loop keyToAssetPostOnboard = - await hemProgram.account.keyToAssetV0.fetchNullable(keyToAssetK) + await hemProgram.account.keyToAssetV0.fetchNullable( + keyToAssetK?.toBase58() || '', + ) } if (!keyToAssetPostOnboard) { throw new Error(t('hotspotOnboarding.onboarding.failedToFind')) @@ -278,11 +341,10 @@ const AddGatewayBle = () => { anchorProvider, ) - if (networkInfo) { - collectNav.navigate('HotspotMapScreen', { hotspot: collectable, network }) - } else { - collectNav.navigate('AssertLocationScreen', { collectable }) - } + close() + navigation.navigate('Hotspot', { + newHotspot: collectable, + }) }) const error = onboardBalError || @@ -310,32 +372,117 @@ const AddGatewayBle = () => { const usd = requiredDc.toNumber() / 100000 const assertUsd = assertRequiredDc.toNumber() / 100000 + const { result: location } = useAsync(async () => { + const address = await getAddressFromLatLng(latitude, longitude) + + return `~${address?.street ? `${address?.street}, ` : ''}${address.city}, ${ + address.state + }` + }, [latitude, longitude]) + + const floor = useMemo(() => height / 5, [height]) + + const contentContainerStyle = useMemo( + () => ({ + flexGrow: 1, + padding: spacing['2xl'], + paddingBottom: spacing['10xl'], + }), + [spacing], + ) + return ( - - + <> + + + + + + + + + + + + + {t('AddToWalletScreen.title')} + - {t('hotspotOnboarding.onboarding.subtitle', { - network, - })} + {animalName} + + + {location} + + + {t('AddToWalletScreen.addressDetailsIndoor', { + floor, + })} + + {error && ( - + {error.message ? error.message.toString() : error.toString()} )} {!wrongOwner && balError && ( <> - + {t('hotspotOnboarding.onboarding.responsible')} - + {t('hotspotOnboarding.onboarding.manufacturerMissing', { name: maker?.name, tokens: `${[ @@ -346,7 +493,12 @@ const AddGatewayBle = () => { .join(' and ')}`, })} - + {t('hotspotOnboarding.onboarding.twoSolutions')} { { const url = `https://docs.helium.com/hotspot-makers/#${maker?.name.toLowerCase()}` @@ -393,12 +545,24 @@ const AddGatewayBle = () => { {selectedOption === 'pay' && ( <> {!callbackLoading && insufficientMySolBal && ( - + {t('hotspotOnboarding.onboarding.notEnoughSol')} )} {!callbackLoading && insufficientMyDcBal && ( - + {t('hotspotOnboarding.onboarding.notEnoughDc')} )} @@ -410,51 +574,65 @@ const AddGatewayBle = () => { mt="2" variant="textMdMedium" color="error.500" + marginHorizontal="2xl" + textAlign="center" > {t('hotspotOnboarding.onboarding.pay', { usd, assertUsd, })} - : undefined} - /> )} )} )} - {!wrongOwner && !balError ? ( - + + {loading ? ( + + ) : ( + : undefined} - /> - ) : null} - - + pressableStyles={{ flex: undefined }} + > + + {t('OnboardingSheet.addToWallet')} + + + + + + + )} + + ) } -export default AddGatewayBle +export default AddToWalletScreen diff --git a/src/features/hotspot-onboarding/screens/iot/ConnectViaBluetoothScreen.tsx b/src/features/hotspot-onboarding/screens/iot/ConnectViaBluetoothScreen.tsx new file mode 100644 index 000000000..93d57a848 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/iot/ConnectViaBluetoothScreen.tsx @@ -0,0 +1,105 @@ +import Box from '@components/Box' +import ScrollBox from '@components/ScrollBox' +import Text from '@components/Text' +import TouchableContainer from '@components/TouchableContainer' +import { useHotspotOnboarding } from '@features/hotspot-onboarding/OnboardingSheet' +import React, { useCallback, useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import RightArrow from '@assets/svgs/rightArrow.svg' +import BluetoothIcon from '@assets/svgs/bluetooth.svg' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import { FadeIn, FadeOut } from 'react-native-reanimated' +import { ReAnimatedBox } from '@components/AnimatedBox' +import { ViewStyle, StyleProp } from 'react-native' + +const ConnectViaBluetoothScreen = () => { + const { t } = useTranslation() + const colors = useColors() + const spacing = useSpacing() + const { carouselRef } = useHotspotOnboarding() + + const onScanForHotspots = useCallback(() => { + carouselRef?.current?.snapToNext() + }, [carouselRef]) + + const contentContainerStyle = useMemo(() => { + return { + padding: spacing['2xl'], + paddingBottom: spacing['4xl'], + flex: 1, + justifyContent: 'center', + alignItems: 'center', + gap: spacing['2.5'], + } + }, [spacing]) + + return ( + <> + } + > + + + {t('ConnectViaBluetoothScreen.title')} + + + {t('ConnectViaBluetoothScreen.subtitle')} + + + {t('ConnectViaBluetoothScreen.body')} + + + + + + {t('ConnectViaBluetoothScreen.scanForHotspots')} + + + + + + + + ) +} + +export default ConnectViaBluetoothScreen diff --git a/src/features/hotspot-onboarding/screens/iot/HotspotConnected.tsx b/src/features/hotspot-onboarding/screens/iot/HotspotConnected.tsx new file mode 100644 index 000000000..6afb0851c --- /dev/null +++ b/src/features/hotspot-onboarding/screens/iot/HotspotConnected.tsx @@ -0,0 +1,86 @@ +import React, { useCallback, useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import ScrollBox from '@components/ScrollBox' +import CheckmarkCircle from '@assets/svgs/checkmarkCircle.svg' +import Text from '@components/Text' +import { ReAnimatedBox } from '@components/AnimatedBox' +import { FadeIn, FadeOut } from 'react-native-reanimated' +import TouchableContainer from '@components/TouchableContainer' +import RightArrow from '@assets/svgs/rightArrow.svg' +import Box from '@components/Box' +import { useSpacing } from '@config/theme/themeHooks' +import { StyleProp, ViewStyle } from 'react-native' +import { useHotspotOnboarding } from '../../OnboardingSheet' + +export default function HotspotConnected() { + const { t } = useTranslation() + const spacing = useSpacing() + const { carouselRef } = useHotspotOnboarding() + + const onConfirmLocation = useCallback(() => { + carouselRef?.current?.snapToNext() + }, [carouselRef]) + + const contentContainerStyle = useMemo(() => { + return { + padding: spacing['2xl'], + flex: 1, + justifyContent: 'center', + } + }, [spacing]) + + return ( + } + > + + + + {t('hotspotOnboarding.onboarding.hotspotConnected')} + + + {t('hotspotOnboarding.onboarding.hotspotConnectedBody')} + + + + + + {t('hotspotOnboarding.onboarding.confirmLocation')} + + + + + + ) +} diff --git a/src/features/hotspot-onboarding/screens/iot/ScanHotspots.tsx b/src/features/hotspot-onboarding/screens/iot/ScanHotspots.tsx new file mode 100644 index 000000000..ab862e7a7 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/iot/ScanHotspots.tsx @@ -0,0 +1,336 @@ +import Text from '@components/Text' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import { Device, useHotspotBle } from '@helium/react-native-sdk' +import React, { useCallback, useEffect, useMemo, useState } from 'react' +import { useTranslation } from 'react-i18next' +import RightArrow from '@assets/svgs/rightArrow.svg' +import { + FlatList, + Platform, + PermissionsAndroid, + RefreshControl, + StyleProp, + ViewStyle, +} from 'react-native' +import { + PERMISSIONS, + PermissionStatus, + RESULTS, + check, + request, +} from 'react-native-permissions' +import ScrollBox from '@components/ScrollBox' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import Box from '@components/Box' +import TouchableContainer from '@components/TouchableContainer' +import CarotRight from '@assets/svgs/carot-right.svg' +import Config from 'react-native-config' +import * as Logger from '@utils/logger' +import { useHotspotOnboarding } from '../../OnboardingSheet' + +const MOCK = Config.MOCK_IOT === 'true' +const MOCK_DEVICES = [ + { id: '1', name: 'RAK-78908' }, + { id: '2', name: 'Helium-Hotspot-775' }, +] as Device[] + +const ScanHotspots = () => { + const { startScan, stopScan, connect, scannedDevices } = useHotspotBle() + const [scanning, setScanning] = useState(false) + const colors = useColors() + const { carouselRef } = useHotspotOnboarding() + const [canScan, setCanScan] = useState(undefined) + const spacing = useSpacing() + const { t } = useTranslation() + const [error, setError] = useState(undefined) + + const bluetoothDevices = useMemo(() => { + if (MOCK) { + return MOCK_DEVICES + } + return scannedDevices + }, [scannedDevices]) + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const showError = (e: any) => { + Logger.error(e) + setError(e.toString()) + } + + const updateCanScan = useCallback((result: PermissionStatus) => { + switch (result) { + case RESULTS.UNAVAILABLE: + case RESULTS.BLOCKED: + case RESULTS.DENIED: + case RESULTS.LIMITED: + setCanScan(false) + break + case RESULTS.GRANTED: + setCanScan(true) + break + } + }, []) + + useEffect(() => { + if (Platform.OS === 'ios') { + setCanScan(true) + return + } + + check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION) + .then(updateCanScan) + .catch(showError) + }, [updateCanScan]) + + useEffect(() => { + if (canScan !== false) return + + request(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION) + .then(updateCanScan) + .catch(showError) + }, [canScan, updateCanScan]) + + const checkPermission = async () => { + if (Platform.OS === 'ios') { + return true + } + + const perms = [ + PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, + PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, + ] + + const results = await Promise.all( + perms.map((p) => PermissionsAndroid.check(p)), + ) + + if (results.findIndex((r) => r === false) === -1) { + return true + } + + const granted = await PermissionsAndroid.requestMultiple([ + PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, + PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, + ]) + + perms.forEach((p) => { + if (!granted[p]) { + return false + } + }) + + return true + } + + const handleScanPress = useCallback(async () => { + setError(undefined) + const shouldScan = !scanning + setScanning(shouldScan) + await checkPermission() + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let timeout: any | undefined + if (shouldScan) { + setError(undefined) + timeout = setTimeout(() => { + stopScan() + setScanning(false) + if (scannedDevices.length === 0) { + setError( + 'No hotspots found. Please ensure bluetooth pairing is enabled', + ) + } + }, 30 * 1000) + } + + if (shouldScan) { + startScan((e) => { + if (e) { + showError(e) + } + }) + } else { + stopScan() + } + return () => { + if (timeout) { + clearTimeout(timeout) + stopScan() + } + } + }, [scannedDevices.length, scanning, startScan, stopScan]) + + useEffect(() => { + // eslint-disable-next-line no-underscore-dangle + if (carouselRef?.current?._activeItem === 1) { + handleScanPress() + } + // eslint-disable-next-line react-hooks/exhaustive-deps, no-underscore-dangle + }, [carouselRef?.current?._activeItem]) + + const navNext = useCallback( + () => carouselRef?.current?.snapToNext(), + [carouselRef], + ) + + const [connecting, setConnecting] = useState(false) + const connectDevice = useCallback( + (d: Device) => async () => { + if (MOCK) { + navNext() + return + } + + try { + setConnecting(true) + await connect(d) + if (scanning) { + stopScan() + setScanning(false) + } + setConnecting(false) + navNext() + } catch (e) { + showError(e) + } finally { + setConnecting(false) + } + }, + [connect, navNext, scanning, stopScan], + ) + + const renderItem = React.useCallback( + // eslint-disable-next-line react/no-unused-prop-types + ({ item }: { item: Device }) => { + const first = item.id === bluetoothDevices[0].id + const last = item.id === bluetoothDevices[bluetoothDevices.length - 1].id + const borderTopStartRadius = first ? '2xl' : 'none' + const borderTopEndRadius = first ? '2xl' : 'none' + const borderBottomStartRadius = last ? '2xl' : 'none' + const borderBottomEndRadius = last ? '2xl' : 'none' + return ( + + + {item.name} + + + + ) + }, + [connectDevice, connecting, bluetoothDevices, colors], + ) + + const renderHeader = useCallback(() => { + return ( + + + {t('hotspotOnboarding.scan.title')} + + {bluetoothDevices.length > 0 && ( + + {t('hotspotOnboarding.scan.hotspotsFound', { + count: bluetoothDevices.length, + })} + + )} + {error && ( + + {error} + + )} + + ) + }, [t, bluetoothDevices, error]) + + const renderFooter = useCallback(() => { + return ( + + + {canScan + ? scanning + ? t('hotspotOnboarding.scan.stop') + : t('hotspotOnboarding.scan.start') + : t('hotspotOnboarding.scan.notEnabled')} + + + + ) + }, [canScan, handleScanPress, scanning, t, colors]) + + const contentContainerStyle = useMemo( + () => ({ + padding: spacing['2xl'], + flex: 1, + justifyContent: 'center', + }), + [spacing], + ) + + const keyExtractor = React.useCallback(({ id }: Device) => id, []) + + return ( + + } + contentContainerStyle={{ + flex: 1, + }} + > + } + ListHeaderComponent={renderHeader} + data={bluetoothDevices} + renderItem={renderItem} + keyExtractor={keyExtractor} + ListFooterComponent={renderFooter} + /> + + ) +} + +export default ScanHotspots diff --git a/src/features/hotspot-onboarding/screens/iot/WifiSettings.tsx b/src/features/hotspot-onboarding/screens/iot/WifiSettings.tsx new file mode 100644 index 000000000..fb2fb0e08 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/iot/WifiSettings.tsx @@ -0,0 +1,253 @@ +import Text from '@components/Text' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import { useHotspotBle } from '@helium/react-native-sdk' +import { Keypair } from '@solana/web3.js' +import React, { useCallback, useEffect, useMemo, useState } from 'react' +import { useAsyncCallback } from 'react-async-hook' +import { useTranslation } from 'react-i18next' +import { FlatList, RefreshControl, StyleProp, ViewStyle } from 'react-native' +import ScrollBox from '@components/ScrollBox' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import Box from '@components/Box' +import RightArrow from '@assets/svgs/rightArrow.svg' +import Checkmark from '@assets/svgs/checkmark.svg' +import TouchableContainer from '@components/TouchableContainer' +import CarotRight from '@assets/svgs/carot-right.svg' +import Config from 'react-native-config' +import animalName from 'angry-purple-tiger' +import { useHotspotOnboarding } from '../../OnboardingSheet' + +const MOCK = Config.MOCK_IOT === 'true' + +const WifiSettings = () => { + const { t } = useTranslation() + const spacing = useSpacing() + const colors = useColors() + const [networks, setNetworks] = useState() + const [configuredNetworks, setConfiguredNetworks] = useState() + const [connected, setConnected] = useState(false) + + const { isConnected, readWifiNetworks, getOnboardingAddress } = + useHotspotBle() + const { carouselRef, setOnboardDetails } = useHotspotOnboarding() + + useEffect(() => { + isConnected().then(setConnected) + }, [isConnected]) + + const { + execute: handleRefresh, + loading: refreshing, + error, + } = useAsyncCallback(async () => { + if (MOCK) { + setConfiguredNetworks(['Solana-House-5678']) + setNetworks(['Helium-House-1234']) + return + } + + if (!connected) return + + const configured = await readWifiNetworks(true) + setConfiguredNetworks(configured) + const available = await readWifiNetworks(false) + setNetworks(available) + }) + + // Refresh on network change or on load + useEffect(() => { + handleRefresh() + }, [handleRefresh, connected]) + + const handleNetworkSelected = useCallback( + ({ + network, + type, + }: { + network: string + type: 'configured' | 'available' + }) => + async () => { + if (type === 'available') { + setOnboardDetails((o) => ({ + ...o, + iotDetails: { + ...o.iotDetails, + network, + }, + })) + carouselRef?.current?.snapToNext() + } else { + // DO something + const onboardingAddress = MOCK + ? Keypair.generate().publicKey.toBase58() + : await getOnboardingAddress() + setOnboardDetails((o) => ({ + ...o, + iotDetails: { + ...o.iotDetails, + onboardingAddress, + network, + animalName: animalName(onboardingAddress), + }, + })) + carouselRef?.current?.snapToItem(5) + } + }, + [carouselRef, setOnboardDetails, getOnboardingAddress], + ) + + const data = useMemo( + () => [...(configuredNetworks || []), ...(networks || [])], + [configuredNetworks, networks], + ) + + const renderItem = useCallback( + ({ + item: network, + }: { + // eslint-disable-next-line react/no-unused-prop-types + item: string + // eslint-disable-next-line react/no-unused-prop-types + }) => { + const first = data[0] === network + const last = data[data.length - 1] === network + const borderTopStartRadius = first ? '2xl' : 'none' + const borderBottomStartRadius = last ? '2xl' : 'none' + const borderBottomEndRadius = last ? '2xl' : 'none' + const borderTopEndRadius = first ? '2xl' : 'none' + + const isConfigured = configuredNetworks?.includes(network) + + return ( + + + {network} + + {!isConfigured && ( + + )} + {isConfigured && } + + ) + }, + [handleNetworkSelected, data, colors, configuredNetworks], + ) + + const keyExtractor = useCallback((name: string) => name, []) + + const renderHeader = useCallback( + () => ( + + + {t('hotspotOnboarding.wifiSettings.title')} + + + {t('hotspotOnboarding.wifiSettings.subtitle')} + + {error && ( + + {error.message ? error.message.toString() : error.toString()} + + )} + + ), + [error, t], + ) + + const renderFooter = useCallback( + () => ( + + + {refreshing + ? t('hotspotOnboarding.scan.stop') + : t('hotspotOnboarding.scan.start')} + + + + ), + [colors, handleRefresh, refreshing, t], + ) + + const contentContainerStyle = useMemo( + () => ({ + padding: spacing['2xl'], + flex: 1, + }), + [spacing], + ) + + const flatListContentContainerStyle = useMemo( + () => ({ + padding: spacing['2xl'], + flex: 1, + justifyContent: 'center', + }), + [spacing], + ) + + return ( + + } + > + + } + /> + + ) +} + +export default WifiSettings diff --git a/src/features/hotspot-onboarding/screens/iot/WifiSetup.tsx b/src/features/hotspot-onboarding/screens/iot/WifiSetup.tsx new file mode 100644 index 000000000..a67a1e7a5 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/iot/WifiSetup.tsx @@ -0,0 +1,168 @@ +import Box from '@components/Box' +import Text from '@components/Text' +import TextInput from '@components/TextInput' +import { BleError, useHotspotBle } from '@helium/react-native-sdk' +import React, { useCallback, useMemo, useState } from 'react' +import { useTranslation } from 'react-i18next' +import ScrollBox from '@components/ScrollBox' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import { ViewStyle, StyleProp, KeyboardAvoidingView } from 'react-native' +import Visibility from '@assets/svgs/visibility.svg' +import VisibilityOff from '@assets/svgs/visibilityOff.svg' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import ImageBox from '@components/ImageBox' +import { Keypair } from '@solana/web3.js' +import animalName from 'angry-purple-tiger' +import Config from 'react-native-config' +import { useHotspotOnboarding } from '../../OnboardingSheet' +import CheckButton from '../../components/CheckButton' +import Loading from '../../components/Loading' + +const MOCK = Config.MOCK_IOT === 'true' + +const WifiSetup = () => { + const [secureTextEntry, setSecureTextEntry] = useState(true) + const [error, setError] = useState('') + const [loading, setLoading] = useState(false) + const [password, setPassword] = useState('') + const { setWifi, getOnboardingAddress } = useHotspotBle() + const { t } = useTranslation() + const spacing = useSpacing() + const colors = useColors() + const { carouselRef, setOnboardDetails } = useHotspotOnboarding() + + const { + onboardDetails: { + iotDetails: { network }, + }, + } = useHotspotOnboarding() + + const toggleSecureEntry = useCallback(() => { + setSecureTextEntry(!secureTextEntry) + }, [secureTextEntry]) + + const handleSetWifi = useCallback(async () => { + if (MOCK) { + setLoading(true) + + // wait 2 seconds + setTimeout(() => { + setLoading(false) + }, 2000) + + const onboardingAddress = Keypair.generate().publicKey.toBase58() + setOnboardDetails((o) => ({ + ...o, + iotDetails: { ...o.iotDetails, onboardingAddress }, + })) + carouselRef?.current?.snapToNext() + return + } + + setLoading(true) + try { + await setWifi(network, password) + const onboardingAddress = await getOnboardingAddress() + setOnboardDetails((o) => ({ + ...o, + iotDetails: { + ...o.iotDetails, + onboardingAddress, + animalName: animalName(onboardingAddress), + }, + })) + carouselRef?.current?.snapToNext() + } catch (e) { + if (typeof e === 'string') { + setError(e) + } else { + setError((e as BleError).toString()) + } + } + setLoading(false) + }, [ + password, + setWifi, + network, + carouselRef, + getOnboardingAddress, + setOnboardDetails, + ]) + + const contentContainer = useMemo( + () => ({ + padding: spacing['2xl'], + flex: 1, + justifyContent: 'center', + }), + [spacing], + ) + + return ( + }> + + + + + {t('hotspotOnboarding.wifiSetup.title')} + + + {t('hotspotOnboarding.wifiSetup.subtitle', { network })} + + {error && ( + + {error} + + )} + + + + + {secureTextEntry ? ( + + ) : ( + + )} + + + + {!loading && } + {loading && } + + ) +} + +export default WifiSetup diff --git a/src/features/hotspot-onboarding/iot-ble/navTypes.tsx b/src/features/hotspot-onboarding/screens/iot/navTypes.tsx similarity index 88% rename from src/features/hotspot-onboarding/iot-ble/navTypes.tsx rename to src/features/hotspot-onboarding/screens/iot/navTypes.tsx index d702ccf8b..c8eaf1354 100644 --- a/src/features/hotspot-onboarding/iot-ble/navTypes.tsx +++ b/src/features/hotspot-onboarding/screens/iot/navTypes.tsx @@ -1,5 +1,8 @@ import { NativeStackNavigationProp } from '@react-navigation/native-stack' -import { IotBleOptions } from '../navTypes' + +export type IotBleOptions = { + bleInstructions?: string +} export type HotspotBLEStackParamList = { ScanHotspots: IotBleOptions diff --git a/src/features/hotspot-onboarding/iot-ble/optionsContext.tsx b/src/features/hotspot-onboarding/screens/iot/optionsContext.tsx similarity index 90% rename from src/features/hotspot-onboarding/iot-ble/optionsContext.tsx rename to src/features/hotspot-onboarding/screens/iot/optionsContext.tsx index 8f56b8832..7b7f88944 100644 --- a/src/features/hotspot-onboarding/iot-ble/optionsContext.tsx +++ b/src/features/hotspot-onboarding/screens/iot/optionsContext.tsx @@ -1,5 +1,5 @@ import React, { useContext } from 'react' -import { IotBleOptions } from '../navTypes' +import { IotBleOptions } from './navTypes' const IotBleOptionsContext = React.createContext({}) diff --git a/src/features/hotspot-onboarding/screens/mobile/AcquireLocationScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/AcquireLocationScreen.tsx new file mode 100644 index 000000000..77127a03c --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/AcquireLocationScreen.tsx @@ -0,0 +1,149 @@ +import Box from '@components/Box' +import Text from '@components/Text' +import TouchableContainer from '@components/TouchableContainer' +import React, { useCallback, useState } from 'react' +import { useTranslation } from 'react-i18next' +import InfoIcon from '@assets/svgs/infoIcon.svg' +import ImageBox from '@components/ImageBox' +import MiniMap from '@components/MiniMap' +import { getAddressFromLatLng } from '@utils/location' +import { useAsync } from 'react-async-hook' +import * as Location from 'expo-location' +import { useHotspotOnboarding } from '../../OnboardingSheet' +import CheckButton from '../../components/CheckButton' + +export const AcquireLocationScreen = () => { + const [lat, setLat] = useState(null) + const [lng, setLng] = useState(null) + const { t } = useTranslation() + const { carouselRef, setOnboardDetails } = useHotspotOnboarding() + + const onNext = useCallback(() => { + if (!lat || !lng) { + // TODO: show error. Show retry button + return + } + + carouselRef?.current?.snapToNext() + setOnboardDetails((o) => ({ + ...o, + latitude: lat, + longitude: lng, + })) + }, [carouselRef, setOnboardDetails, lat, lng]) + + const DeterminingLocation = useCallback(() => { + return ( + <> + + + {t('AcquireLocationScreen.title')} + + + {t('AcquireLocationScreen.subtitle')} + + + + + {t('AcquireLocationScreen.gpsHelp')} + + + + ) + }, [t]) + + const { result: location, loading: loadingLocation } = useAsync(async () => { + const loc = await Location.getCurrentPositionAsync({ + accuracy: Location.LocationAccuracy.Highest, + }) + + const newLat = loc?.coords.latitude + const newLng = loc?.coords.longitude + setLat(newLat) + setLng(newLng) + + if (!newLat || !newLng) { + return null + } + + const address = await getAddressFromLatLng(newLat, newLng) + + return `~${address.street}, ${address.city}, ${address.state}` + }, []) + + const DeterminedLocation = useCallback(() => { + return ( + + + + + + {location} + + + + + {t('AcquireLocationScreen.isThisCorrect')} + + + {t('AcquireLocationScreen.locationDetermined')} + + + ) + }, [t, location]) + + return ( + + {!loadingLocation && location ? ( + + ) : ( + + )} + {location && } + + ) +} + +export default AcquireLocationScreen diff --git a/src/features/hotspot-onboarding/screens/mobile/AddToWalletScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/AddToWalletScreen.tsx new file mode 100644 index 000000000..11536fe8c --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/AddToWalletScreen.tsx @@ -0,0 +1,132 @@ +import Box from '@components/Box' +import Text from '@components/Text' +import React, { useMemo } from 'react' +import { useTranslation } from 'react-i18next' +import ImageBox from '@components/ImageBox' +import Map from '@components/Map' +import { Camera } from '@rnmapbox/maps' +import { getAddressFromLatLng } from '@utils/location' +import { useAsync } from 'react-async-hook' +import AddToWalletButton from '../../components/WalletButton' +import { useHotspotOnboarding } from '../../OnboardingSheet' + +export const AddToWalletScreen = () => { + const { t } = useTranslation() + + const { + onboardDetails: { + deviceInfo: { deviceType, animalName }, + latitude, + longitude, + height, + azimuth, + }, + onboardDeviceError, + } = useHotspotOnboarding() + + const { result: location } = useAsync(async () => { + const address = await getAddressFromLatLng(latitude, longitude) + + return `~${address?.street ? `${address?.street}, ` : ''}${address.city}, ${ + address.state + }` + }, [latitude, longitude]) + + const floor = useMemo(() => height / 5, [height]) + + return ( + + + + + + + + + {deviceType === 'WifiOutdoor' && ( + + + + )} + + {deviceType === 'WifiIndoor' && ( + + + + )} + + + {t('AddToWalletScreen.title')} + + + {animalName} + + + + {location} + + + {deviceType === 'WifiIndoor' + ? t('AddToWalletScreen.addressDetailsIndoor', { + floor, + }) + : t('AddToWalletScreen.addressDetails', { + floor, + direction: `${azimuth}°`, + })} + + + {onboardDeviceError && ( + + {t('AddToWalletScreen.errorOnboarding')} + + )} + + + ) +} + +export default AddToWalletScreen diff --git a/src/features/hotspot-onboarding/screens/mobile/ConnectEthernetScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/ConnectEthernetScreen.tsx new file mode 100644 index 000000000..f4ed05a41 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/ConnectEthernetScreen.tsx @@ -0,0 +1,94 @@ +import Box from '@components/Box' +import React, { useCallback } from 'react' +import Text from '@components/Text' +import { useTranslation } from 'react-i18next' +import ImageBox from '@components/ImageBox' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import InfoIcon from '@assets/svgs/infoIcon.svg' +import { Linking } from 'react-native' +import { HOTSPOT_HELP } from '@utils/constants/urls' +import CheckButton from '../../components/CheckButton' +import { useHotspotOnboarding } from '../../OnboardingSheet' + +export const ConnectEthernetScreen = () => { + const { t } = useTranslation() + + const { + carouselRef, + onboardDetails: { + deviceInfo: { deviceType }, + }, + } = useHotspotOnboarding() + + const onNext = useCallback(() => { + carouselRef?.current?.snapToNext() + }, [carouselRef]) + + const onOpenHelp = useCallback(() => { + Linking.openURL(HOTSPOT_HELP) + }, []) + + return ( + + {deviceType === 'WifiOutdoor' && ( + + )} + {deviceType === 'WifiIndoor' && ( + + )} + + {t( + deviceType === 'WifiOutdoor' + ? 'ConnectEthernetScreen.title' + : 'ConnectEthernetScreen.titleIndoor', + )} + + + {deviceType === 'WifiOutdoor' + ? t('ConnectEthernetScreen.subtitle') + : t('ConnectEthernetScreen.subtitleIndoor')} + + + {t('ConnectEthernetScreen.helpText')} + + + + + {t('ConnectEthernetScreen.help')} + + + + + ) +} + +export default ConnectEthernetScreen diff --git a/src/features/hotspot-onboarding/screens/mobile/ConnectToHotspotScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/ConnectToHotspotScreen.tsx new file mode 100644 index 000000000..560e03049 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/ConnectToHotspotScreen.tsx @@ -0,0 +1,140 @@ +import Box from '@components/Box' +import React, { useCallback, useEffect, useState } from 'react' +import { useTranslation } from 'react-i18next' +import ImageBox from '@components/ImageBox' +import Text from '@components/Text' +import TouchableContainer from '@components/TouchableContainer' +import CameraCheck from '@assets/svgs/cameraCheck.svg' +import NoCamera from '@assets/svgs/noCamera.svg' +import RightArrow from '@assets/svgs/rightArrow.svg' +import { useColors } from '@config/theme/themeHooks' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import { requestCameraPermission } from '@utils/camera' +import { PermissionStatus } from 'react-native-permissions' +import { Color } from '@config/theme/theme' +import { useHotspotOnboarding } from '../../OnboardingSheet' +import CheckButton from '../../components/CheckButton' + +export const ConnectToHotspotScreen = () => { + const { + manualEntry, + setManualEntry, + carouselRef, + onboardDetails: { + deviceInfo: { deviceType }, + }, + } = useHotspotOnboarding() + const { t } = useTranslation() + const colors = useColors() + const [cameraPermission, setCameraPermission] = useState() + + const onRequest = useCallback(async () => { + const status = __DEV__ ? 'granted' : await requestCameraPermission() + + setCameraPermission(status) + + if (status === 'granted') { + setManualEntry(false) + } + }, [setManualEntry]) + + useEffect(() => { + if (manualEntry) { + setCameraPermission(undefined) + } + }, [cameraPermission, manualEntry]) + + const onNext = useCallback(() => { + carouselRef?.current?.snapToNext() + }, [carouselRef]) + + const onManualEntry = useCallback(() => { + setManualEntry(true) + setCameraPermission(undefined) + carouselRef?.current?.snapToNext() + }, [setManualEntry, carouselRef]) + + const CameraCheckButton = useCallback(() => { + let backgroundColor: Color = 'primaryText' + let backgroundColorPressed: Color = 'base.black' + + if (cameraPermission === 'granted') { + backgroundColor = 'success.500' + backgroundColorPressed = 'success.600' + } + + if (cameraPermission === 'denied') { + backgroundColor = 'error.500' + backgroundColorPressed = 'error.600' + } + + return ( + + {cameraPermission === 'denied' && } + {cameraPermission === 'granted' && } + + {t('ConnectToHotspotScreen.requestCameraPermissions')} + + + ) + }, [t, onRequest, cameraPermission]) + + return ( + + {deviceType === 'WifiOutdoor' && ( + + )} + {deviceType === 'WifiIndoor' && ( + + )} + + {t('ConnectToHotspotScreen.title')} + + + {t('ConnectToHotspotScreen.subtitle')} + + + + + {t('ConnectToHotspotScreen.manualEntry')} + + + + {cameraPermission === 'granted' && } + + ) +} + +export default ConnectToHotspotScreen diff --git a/src/features/hotspot-onboarding/screens/mobile/KeepYourBoxScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/KeepYourBoxScreen.tsx new file mode 100644 index 000000000..2b1cd6874 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/KeepYourBoxScreen.tsx @@ -0,0 +1,46 @@ +import Box from '@components/Box' +import React, { useCallback } from 'react' +import Text from '@components/Text' +import { useTranslation } from 'react-i18next' +import ImageBox from '@components/ImageBox' + +import { useHotspotOnboarding } from '../../OnboardingSheet' +import ForwardButton from '../../components/ForwardButton' + +export const KeepYourBoxScreen = () => { + const { t } = useTranslation() + const { + onboardDetails: { + deviceInfo: { deviceType }, + }, + carouselRef, + } = useHotspotOnboarding() + + const onNext = useCallback(() => { + carouselRef?.current?.snapToNext() + }, [carouselRef]) + + return ( + + {deviceType === 'WifiOutdoor' && ( + + )} + {deviceType === 'WifiIndoor' && ( + + )} + + {t('KeepYourBoxScreen.title')} + + + {t('KeepYourBoxScreen.subtitle')} + + + + ) +} + +export default KeepYourBoxScreen diff --git a/src/features/hotspot-onboarding/screens/mobile/ManualEntryScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/ManualEntryScreen.tsx new file mode 100644 index 000000000..fffd305f6 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/ManualEntryScreen.tsx @@ -0,0 +1,107 @@ +import React, { useCallback, useMemo, useState } from 'react' +import Text from '@components/Text' +import Box from '@components/Box' +import { useTranslation } from 'react-i18next' +import TextInputNew from '@components/TextInputNew' +import CheckButton from '../../components/CheckButton' +import { useHotspotOnboarding } from '../../OnboardingSheet' +import Loading from '../../components/Loading' + +const ManualEntryScreen = () => { + const { t } = useTranslation() + const [validNetworkName, setValidNetworkName] = useState(false) + const [validNetworkPassword, setValidNetworkPassword] = useState(false) + const [ssid, setSsid] = useState('') + const [password, setPassword] = useState('') + + const { + carouselRef, + getDeviceInfo, + getDeviceInfoError, + getDeviceInfoLoading, + } = useHotspotOnboarding() + + const onChangeNetworkName = useCallback((text: string) => { + // Regex to validate network name looks like Helium-XXXX + setValidNetworkName(text.length > 8 && text.includes('Helium-')) + setSsid(text) + }, []) + + const onChangeNetworkPassword = useCallback((text: string) => { + setValidNetworkPassword(text.length > 7) + setPassword(text) + }, []) + + const wifiDataB64 = useMemo(() => { + if (!validNetworkName || !validNetworkPassword) return + + const wifiData = `WIFI:S:${ssid};T:WPA;P:${password};H:false;` + return Buffer.from(wifiData).toString('base64') + }, [password, ssid, validNetworkName, validNetworkPassword]) + + const onNext = useCallback(async () => { + if (!wifiDataB64) { + // TODO: Show generic error + return + } + const deviceInfo = await getDeviceInfo(wifiDataB64) + + if (deviceInfo) { + carouselRef?.current?.snapToNext() + } + }, [carouselRef, getDeviceInfo, wifiDataB64]) + + return ( + + + {t('ManualEntryScreen.title')} + + + {t('ManualEntryScreen.subtitle')} + + + + + + + + {getDeviceInfoError && ( + + {t('ManualEntryScreen.tryAgain')} + + )} + {validNetworkName && validNetworkPassword && !getDeviceInfoLoading && ( + + )} + {getDeviceInfoLoading && } + + ) +} + +export default ManualEntryScreen diff --git a/src/features/hotspot-onboarding/screens/mobile/ScanQRCodeScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/ScanQRCodeScreen.tsx new file mode 100644 index 000000000..8c5885664 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/ScanQRCodeScreen.tsx @@ -0,0 +1,157 @@ +import Box from '@components/Box' +import React, { useCallback, useState } from 'react' +import { StyleSheet } from 'react-native' +import Text from '@components/Text' +import { useTranslation } from 'react-i18next' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import { useColors } from '@config/theme/themeHooks' +import RightArrow from '@assets/svgs/rightArrow.svg' +import { + Camera, + useCameraDevice, + useCodeScanner, +} from 'react-native-vision-camera' +import useAppear from '@hooks/useAppear' +import useDisappear from '@hooks/useDisappear' +import useHaptic from '@hooks/useHaptic' +import { useAsync } from 'react-async-hook' +import { useHotspotOnboarding } from '../../OnboardingSheet' +import CheckButton from '../../components/CheckButton' +import Loading from '../../components/Loading' + +const ScanQRCodeScreen = () => { + const { t } = useTranslation() + const colors = useColors() + const [isActive, setIsActive] = useState(false) + const { triggerImpact } = useHaptic() + const [qrCode, setQrCode] = useState(null) + + const { + carouselRef, + setManualEntry, + getDeviceInfo, + getDeviceInfoLoading, + getDeviceInfoError, + onboardDetails, + } = useHotspotOnboarding() + + const onManualEntry = useCallback(() => { + setManualEntry(true) + }, [setManualEntry]) + + const device = useCameraDevice('back', { + physicalDevices: ['ultra-wide-angle-camera'], + }) + + useAppear(() => { + setIsActive(true) + }) + + useDisappear(() => { + setIsActive(false) + }) + const onNext = useCallback(async () => { + if (__DEV__) { + // Make sure MOCK_HMH is set to true in .env + await getDeviceInfo('MOCK_QR') + carouselRef?.current?.snapToNext() + return + } + + if (!qrCode) return + + const deviceInfo = await getDeviceInfo(qrCode) + + if (deviceInfo) { + carouselRef?.current?.snapToNext() + } + }, [carouselRef, getDeviceInfo, qrCode]) + + const codeScanner = useCodeScanner({ + codeTypes: ['qr'], + onCodeScanned: (codes) => { + if (!codes.length || !codes[0].value || onboardDetails.qrCode) return + + setQrCode(codes[0].value) + }, + }) + + useAsync(async () => { + if (!qrCode) return + triggerImpact('heavy') + onNext() + }, [qrCode, getDeviceInfo, onNext]) + + return ( + + + + {device ? ( + + ) : ( + + )} + + + + {t('ScanQRCodeScreen.title')} + + + {t('ScanQRCodeScreen.subtitle')} + + + + {t('ScanQRCodeScreen.manualEntry')} + + + + {getDeviceInfoError && ( + + {t('ScanQRCodeScreen.tryAgain')} + + )} + {__DEV__ && !getDeviceInfoLoading && } + {getDeviceInfoLoading && } + + ) +} + +export default ScanQRCodeScreen diff --git a/src/features/hotspot-onboarding/screens/mobile/SelectDeviceScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/SelectDeviceScreen.tsx new file mode 100644 index 000000000..2d669e7bc --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/SelectDeviceScreen.tsx @@ -0,0 +1,102 @@ +import Box from '@components/Box' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import Text from '@components/Text' +import TouchableContainer from '@components/TouchableContainer' +import MobileTextLogo from '@assets/svgs/mobileTextLogo.svg' +import ImageBox from '@components/ImageBox' +import TextTransform from '@components/TextTransform' +import { DeviceType, useHotspotOnboarding } from '../../OnboardingSheet' + +const SelectDeviceScreen = () => { + const { t } = useTranslation() + const { carouselRef, setOnboardDetails } = useHotspotOnboarding() + + const onSelectHotspot = useCallback( + (deviceType: DeviceType) => () => { + setOnboardDetails((o) => ({ + ...o, + deviceInfo: { + ...o.deviceInfo, + deviceType, + }, + })) + carouselRef?.current?.snapToNext() + }, + [carouselRef, setOnboardDetails], + ) + + return ( + + + {t('SelectDeviceScreen.title')} + + + {t('SelectDeviceScreen.subtitle')} + + + + + + + + + {t('SelectDeviceScreen.indoor')} + + + + + + + + + + + + + ) +} + +export default SelectDeviceScreen diff --git a/src/features/hotspot-onboarding/screens/mobile/SetDirectionScreen.tsx b/src/features/hotspot-onboarding/screens/mobile/SetDirectionScreen.tsx new file mode 100644 index 000000000..efbb7f484 --- /dev/null +++ b/src/features/hotspot-onboarding/screens/mobile/SetDirectionScreen.tsx @@ -0,0 +1,96 @@ +import Box from '@components/Box' +import React, { useCallback } from 'react' +import Text from '@components/Text' +import { useTranslation } from 'react-i18next' +import RotateIcon from '@assets/svgs/rotateIcon.svg' +import Map from '@components/Map' +import { Camera } from '@rnmapbox/maps' +import ImageBox from '@components/ImageBox' +import useHeading from '@hooks/useHeading' +import { degToCompass } from '@utils/degree' +import { ReAnimatedBox } from '@components/AnimatedBox' +import { useAnimatedStyle, withSpring } from 'react-native-reanimated' +import { HELIUM_WORLD_POI } from '@utils/constants' +import CheckButton from '../../components/CheckButton' +import { useHotspotOnboarding } from '../../OnboardingSheet' + +const SetDirectionScreen = () => { + const { t } = useTranslation() + const { heading } = useHeading() + const { carouselRef, setOnboardDetails } = useHotspotOnboarding() + + const onNext = useCallback(() => { + setOnboardDetails((o) => ({ + ...o, + azimuth: heading, + })) + carouselRef?.current?.snapToNext() + }, [carouselRef, setOnboardDetails, heading]) + + const rotationStyle = useAnimatedStyle(() => { + return { + transform: [{ rotate: withSpring(`-${heading}deg`) }], + } + }) + + return ( + + + + + {t('SetDirectionScreen.title')} + + + {t('SetDirectionScreen.subtitle')} + + + {`${heading}° | ${degToCompass(heading)}`} + + + + + + + + + + + + + ) +} + +export default SetDirectionScreen diff --git a/src/features/collectables/AntennaSetupScreen.tsx b/src/features/hotspots/AntennaSetupScreen.tsx similarity index 99% rename from src/features/collectables/AntennaSetupScreen.tsx rename to src/features/hotspots/AntennaSetupScreen.tsx index 24d33278f..9a65758f0 100644 --- a/src/features/collectables/AntennaSetupScreen.tsx +++ b/src/features/hotspots/AntennaSetupScreen.tsx @@ -22,7 +22,7 @@ import { DelayedFadeIn } from '@components/FadeInOut' import { CollectableNavigationProp, CollectableStackParamList, -} from './collectablesTypes' +} from './hotspotTypes' import { parseH3BNLocation } from '../../utils/h3' import * as Logger from '../../utils/logger' diff --git a/src/features/collectables/AssertLocationScreen.tsx b/src/features/hotspots/AssertLocationScreen.tsx similarity index 80% rename from src/features/collectables/AssertLocationScreen.tsx rename to src/features/hotspots/AssertLocationScreen.tsx index 3970d37dd..9097c8082 100644 --- a/src/features/collectables/AssertLocationScreen.tsx +++ b/src/features/hotspots/AssertLocationScreen.tsx @@ -1,6 +1,5 @@ -import BackArrow from '@assets/images/backArrow.svg' -import Hex from '@assets/images/hex.svg' -import MapPin from '@assets/images/mapPin.svg' +import Hex from '@assets/svgs/hex.svg' +import MapPin from '@assets/svgs/mapPin.svg' import { Box, ButtonPressable, @@ -12,12 +11,9 @@ import { ImageBox, ReAnimatedBlurBox, ReAnimatedBox, - SearchInput, Text, TextInput, } from '@components' -import Map from '@components/map/Map' -import { INITIAL_MAP_VIEW_STATE, MAX_MAP_ZOOM } from '@components/map/utils' import TouchableOpacityBox from '@components/TouchableOpacityBox' import { NetworkType } from '@helium/onboarding' import { IOT_MINT, MOBILE_MINT } from '@helium/spl-utils' @@ -31,7 +27,6 @@ import { useMobileInfo } from '@hooks/useMobileInfo' import { useOnboardingBalnces } from '@hooks/useOnboardingBalances' import { useReverseGeo } from '@hooks/useReverseGeo' import useSubmitTxn from '@hooks/useSubmitTxn' -import MapLibreGL from '@maplibre/maplibre-react-native' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { parseH3BNLocation } from '@utils/h3' import { removeDashAndCapitalize } from '@utils/hotspotNftsUtils' @@ -54,28 +49,41 @@ import { } from 'react-native' import 'text-encoding-polyfill' import { useDebounce } from 'use-debounce' -import { useColors, useCreateOpacity, useSpacing } from '@theme/themeHooks' +import { useColors, useCreateOpacity } from '@config/theme/themeHooks' import { useSafeAreaInsets } from 'react-native-safe-area-context' -import CloseButton from '@components/CloseButton' +import Map from '@components/Map' +import { + Camera, + Location, + MapView, + MarkerView, + UserLocation, +} from '@rnmapbox/maps' +import { + MIN_MAP_ZOOM, + INITIAL_MAP_VIEW_STATE, + MAX_MAP_ZOOM, +} from '@utils/mapUtils' +import { NavBarHeight } from '@components/ServiceNavBar' +import { Search } from '@components/Search' import { CollectableNavigationProp, CollectableStackParamList, -} from './collectablesTypes' +} from './hotspotTypes' type Route = RouteProp const AssertLocationScreen = () => { const { t } = useTranslation() const { bottom } = useSafeAreaInsets() - const spacing = useSpacing() const route = useRoute() const { backgroundStyle } = useCreateOpacity() const { collectable } = route.params const entityKey = useEntityKey(collectable) const { info: iotInfoAcc } = useIotInfo(entityKey) const { info: mobileInfoAcc } = useMobileInfo(entityKey) - const mapRef = useRef(null) - const cameraRef = useRef(null) + const mapRef = useRef(null) + const cameraRef = useRef(null) const { showOKAlert } = useAlert() const colors = useColors() const [mapCenter, setMapCenter] = useState() @@ -90,6 +98,7 @@ const AssertLocationScreen = () => { const forwardGeo = useForwardGeo() const { submitUpdateEntityInfo } = useSubmitTxn() const navigation = useNavigation() + const { maker, makerDc, @@ -131,9 +140,9 @@ const AssertLocationScreen = () => { const [initialUserLocation, setInitialUserLocation] = useState() const [initialCenterSet, setInitalCenter] = useState(false) - const [userLocation, setUserLocation] = useState() + const [userLocation, setUserLocation] = useState() const onUserLocationUpdate = useCallback( - (loc: MapLibreGL.Location) => { + (loc: Location) => { setUserLocation(loc) }, [setUserLocation], @@ -252,7 +261,10 @@ const AssertLocationScreen = () => { cameraRef.current.setCamera({ animationDuration: 500, zoomLevel: MAX_MAP_ZOOM, - centerCoordinate: userLocation?.coords, + centerCoordinate: [ + userLocation?.coords.longitude, + userLocation?.coords.latitude, + ], }) } }, [cameraRef, userLocation?.coords]) @@ -407,6 +419,10 @@ const AssertLocationScreen = () => { [loadingMyDc, loadingMakerDc, loadingLocationAssertDcRequirements], ) + const onBack = useCallback(() => { + navigation.goBack() + }, [navigation]) + const [debouncedDisabled] = useDebounce(disabled, 300) const [reverseGeoLoading] = useDebounce(reverseGeo.loading, 300) @@ -417,7 +433,7 @@ const AssertLocationScreen = () => { flexGrow={1} justifyContent="center" alignItems="center" - backgroundColor="bg.tertiary" + backgroundColor="primaryBackground" overflow="hidden" position="relative" > @@ -435,73 +451,86 @@ const AssertLocationScreen = () => { - {(sameLocation ? [iotLocation] : [iotLocation, mobileLocation]) - .map((location, i) => { - if (!location || location.length < 2) return null - - return ( - - {sameLocation ? ( - - - - + <> + + + {(sameLocation ? [iotLocation] : [iotLocation, mobileLocation]) + .map((location, i) => { + if (!location || location.length < 2) return null + + return ( + + {sameLocation ? ( + + + + + - - - - + + + + - - ) : ( - - )} - - ) - }) - .filter(Boolean)} + ) : ( + + )} + + ) + }) + .filter(Boolean)} + { paddingLeft="5" top={0} > - navigation.goBack()} - > - - - Back - - + { { { { ) : ( - + + + )} {!searchVisible && ( - + { justifyContent="center" onPress={handleAssertLocationPress} style={{ - marginBottom: bottom + spacing['0.5'], + marginBottom: bottom + NavBarHeight, }} > {debouncedDisabled || asserting ? ( @@ -742,17 +764,19 @@ const AssertLocationScreen = () => { bottom={0} height="100%" width="100%" + paddingHorizontal="xl" > Keyboard.dismiss()}> - - - + setElevGainVisible(false)} /> + { @@ -798,9 +822,9 @@ const AssertLocationScreen = () => { }} /> { - + { const { t } = useTranslation() diff --git a/src/features/collectables/ClaimRewardsScreen.tsx b/src/features/hotspots/ClaimRewardsScreen.tsx similarity index 99% rename from src/features/collectables/ClaimRewardsScreen.tsx rename to src/features/hotspots/ClaimRewardsScreen.tsx index 5b9e729f5..046ac8403 100644 --- a/src/features/collectables/ClaimRewardsScreen.tsx +++ b/src/features/hotspots/ClaimRewardsScreen.tsx @@ -19,7 +19,7 @@ import { Mints } from '../../utils/constants' import { CollectableNavigationProp, CollectableStackParamList, -} from './collectablesTypes' +} from './hotspotTypes' type Route = RouteProp diff --git a/src/features/collectables/ClaimingRewardsScreen.tsx b/src/features/hotspots/ClaimingRewardsScreen.tsx similarity index 96% rename from src/features/collectables/ClaimingRewardsScreen.tsx rename to src/features/hotspots/ClaimingRewardsScreen.tsx index 94f7759d5..5bbaae094 100644 --- a/src/features/collectables/ClaimingRewardsScreen.tsx +++ b/src/features/hotspots/ClaimingRewardsScreen.tsx @@ -1,4 +1,4 @@ -import BackArrow from '@assets/images/backArrow.svg' +import BackArrow from '@assets/svgs/backArrow.svg' import AccountIcon from '@components/AccountIcon' import { ReAnimatedBox } from '@components/AnimatedBox' import Box from '@components/Box' @@ -13,7 +13,7 @@ import { useBN } from '@hooks/useBN' import { useCurrentWallet } from '@hooks/useCurrentWallet' import useHotspots from '@hooks/useHotspots' import { useNavigation } from '@react-navigation/native' -import globalStyles from '@theme/globalStyles' +import globalStyles from '@config/theme/globalStyles' import { parseTransactionError } from '@utils/solanaUtils' import LottieView from 'lottie-react-native' import React, { memo, useCallback, useEffect, useRef, useState } from 'react' @@ -22,9 +22,9 @@ import Animated, { FadeIn, FadeOut } from 'react-native-reanimated' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useSelector } from 'react-redux' import 'text-encoding-polyfill' -import { useColors } from '@theme/themeHooks' -import { HotspotServiceNavigationProp } from '@services/HotspotService' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { useColors } from '@config/theme/themeHooks' +import { HotspotServiceNavigationProp } from 'src/app/services/HotspotService' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { RootState } from '../../store/rootReducer' import iotMobileTokens from './animations/iot-mobile-tokens.json' import iotTokens from './animations/iot-tokens.json' diff --git a/src/features/hotspot-onboarding/iot-ble/Diagnostics.tsx b/src/features/hotspots/Diagnostics.tsx similarity index 96% rename from src/features/hotspot-onboarding/iot-ble/Diagnostics.tsx rename to src/features/hotspots/Diagnostics.tsx index a4b50c5a5..1a7ebacac 100644 --- a/src/features/hotspot-onboarding/iot-ble/Diagnostics.tsx +++ b/src/features/hotspots/Diagnostics.tsx @@ -9,10 +9,9 @@ import React, { useCallback, useState } from 'react' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { ScrollView } from 'react-native' -import type { HotspotBleNavProp } from './navTypes' const Diagnostics = () => { - const navigation = useNavigation() + const navigation = useNavigation() const navNext = useCallback(() => navigation.goBack(), [navigation]) const { getDiagnosticInfo } = useHotspotBle() diff --git a/src/features/hotspots/EmptyState.tsx b/src/features/hotspots/EmptyState.tsx new file mode 100644 index 000000000..9544f3ceb --- /dev/null +++ b/src/features/hotspots/EmptyState.tsx @@ -0,0 +1,92 @@ +import Box from '@components/Box' +import { NavBarHeight } from '@components/ServiceNavBar' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import React, { useCallback } from 'react' +import { useTranslation } from 'react-i18next' +import { useSafeAreaInsets } from 'react-native-safe-area-context' +import Text from '@components/Text' +import ButtonPressable from '@components/ButtonPressable' +import AddIcon from '@assets/svgs/add.svg' +import { Image, Linking } from 'react-native' +import { useNavigation } from '@react-navigation/native' +import { HotspotServiceNavigationProp } from 'src/app/services/HotspotService' + +const EmptyState = () => { + const spacing = useSpacing() + const colors = useColors() + const { t } = useTranslation() + const { bottom } = useSafeAreaInsets() + const navigation = useNavigation() + + const onLearnMore = useCallback(() => { + Linking.openURL('https://hellohelium.com/hotspot') + }, []) + + const onAddHotspot = useCallback(() => { + navigation.navigate('AddHotspot') + }, [navigation]) + + return ( + + + + + {t('HotspotPage.noHotspotsTitle')} + + + {t('HotspotPage.noHotspotsSubtitle')} + + + + + } + /> + + + + ) +} + +export default EmptyState diff --git a/src/features/hotspots/HotspotConfig.tsx b/src/features/hotspots/HotspotConfig.tsx new file mode 100644 index 000000000..7aa75e43d --- /dev/null +++ b/src/features/hotspots/HotspotConfig.tsx @@ -0,0 +1,206 @@ +import Box from '@components/Box' +import FabButton from '@components/FabButton' +import Text from '@components/Text' +import { useNavigation, useRoute } from '@react-navigation/native' +import React, { useCallback, useMemo } from 'react' +import ScrollBox from '@components/ScrollBox' +import { useColors, useSpacing } from '@config/theme/themeHooks' +import { FlatList } from 'react-native' +import TouchableContainer from '@components/TouchableContainer' +import useCopyText from '@hooks/useCopyText' +import useHaptic from '@hooks/useHaptic' +import { ellipsizeAddress } from '@utils/accountUtils' +import CarotRight from '@assets/svgs/carot-right.svg' +import { HotspotNavigationProp } from '@services/HotspotService/pages/HotspotPage' +import { HotspotWithPendingRewards } from '../../types/solana' + +type HotspotConfigItem = { + title: string + subtitle?: string + onPress: () => void +} + +export const HotspotConfig = () => { + const { hotspot, hotspotAddress } = useRoute().params as { + hotspot: HotspotWithPendingRewards + hotspotAddress: string + } + + const isIotHotspot = useMemo(() => { + return ( + hotspot?.content?.metadata?.hotspot_infos?.iot?.device_type || + !hotspot?.content?.metadata?.hotspot_infos?.mobile?.device_type + ) + }, [hotspot]) + + const spacing = useSpacing() + const colors = useColors() + const navigation = useNavigation() + const copyText = useCopyText() + const { triggerImpact } = useHaptic() + + const data = useMemo(() => { + return [ + { + title: 'Update Location', + subtitle: hotspotAddress, + Icon: undefined, + onPress: () => { + navigation.navigate('AssertLocationScreen', { + collectable: hotspot, + }) + }, + }, + { + title: 'Update Rewards Recipient', + subtitle: undefined, + Icon: undefined, + onPress: () => { + navigation.navigate('ChangeRewardsRecipientScreen', { + hotspot, + }) + }, + }, + { + title: 'Antenna Setup', + subtitle: undefined, + Icon: undefined, + onPress: () => { + navigation.navigate('AntennaSetupScreen', { + collectable: hotspot, + }) + }, + }, + { + title: 'Transfer ownership', + subtitle: undefined, + onPress: () => { + navigation.navigate('TransferCollectableScreen', { + collectable: hotspot, + }) + }, + }, + { + title: 'Copy address', + subtitle: undefined, + onPress: () => { + triggerImpact('light') + copyText({ + message: ellipsizeAddress(hotspot?.id), + copyText: hotspot?.id, + }) + }, + }, + !isIotHotspot && { + title: 'Reboot', + subtitle: undefined, + Icon: undefined, + onPress: () => {}, + }, + isIotHotspot && { + title: 'Diagnostics', + subtitle: undefined, + onPress: () => { + navigation.navigate('DiagnosticsScreen', { + collectable: hotspot, + }) + }, + }, + isIotHotspot && { + title: 'Setup Wifi', + subtitle: undefined, + onPress: () => { + navigation.navigate('ModifyWifiScreen', { + collectable: hotspot, + }) + }, + }, + ].filter(Boolean) as HotspotConfigItem[] + }, [ + copyText, + hotspot, + triggerImpact, + navigation, + hotspotAddress, + isIotHotspot, + ]) + + const onBack = useCallback(() => { + navigation.goBack() + }, [navigation]) + + const keyExtractor = useCallback((item: HotspotConfigItem) => item.title, []) + + const renderItem = useCallback( + // eslint-disable-next-line react/no-unused-prop-types + ({ item }: { item: HotspotConfigItem }) => { + const isFirst = item.title === data[0].title + const isLast = item.title === data[data.length - 1].title + const borderTopStartRadius = isFirst ? '3xl' : undefined + const borderTopEndRadius = isFirst ? '3xl' : undefined + const borderBottomStartRadius = isLast ? '3xl' : undefined + const borderBottomEndRadius = isLast ? '3xl' : undefined + + return ( + + + + {item.title} + {item.subtitle && ( + + {item.subtitle} + + )} + + + + + + + + ) + }, + [data, colors], + ) + + const contentContainerStyle = useMemo(() => { + return { + // paddingBottom: spacing['2xl'], + } + }, []) + + const renderHeader = useCallback(() => { + return ( + + + + ) + }, [onBack]) + + return ( + + + + ) +} + +export default HotspotConfig diff --git a/src/features/hotspots/HotspotDetails.tsx b/src/features/hotspots/HotspotDetails.tsx new file mode 100644 index 000000000..a5413519f --- /dev/null +++ b/src/features/hotspots/HotspotDetails.tsx @@ -0,0 +1,258 @@ +import Box from '@components/Box' +import ScrollBox from '@components/ScrollBox' +import React, { useCallback, useMemo } from 'react' +import { useBorderRadii, useColors, useSpacing } from '@config/theme/themeHooks' +import Crown from '@assets/svgs/crown.svg' +import Text from '@components/Text' +import MapPin from '@assets/svgs/mapPin.svg' +import Hex from '@assets/svgs/hex.svg' +import Clock from '@assets/svgs/clock.svg' +import Person from '@assets/svgs/person.svg' +import Electricity from '@assets/svgs/electricity.svg' +import FabButton from '@components/FabButton' +import { useNavigation, useRoute } from '@react-navigation/native' +import { PublicKey } from '@solana/web3.js' +import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' +import { useMaker } from '@hooks/useMaker' +import MakerHotspotImage from '@components/MakerHotspotImage' +import { getAddressFromLatLng } from '@utils/location' +import { useAsync } from 'react-async-hook' +import SkeletonPlaceholder from 'react-native-skeleton-placeholder' +import { useTranslation } from 'react-i18next' +import { formatDistanceToNow } from 'date-fns' +import MiniMap from '@components/MiniMap' +import { HotspotNavigationProp } from '@services/HotspotService/pages/HotspotPage' +import { HotspotWithPendingRewards } from '../../types/solana' + +const MINI_MAP_HEIGHT = 310 + +const HotspotDetails = () => { + const { t } = useTranslation() + const { hotspot } = useRoute().params as { + hotspot: HotspotWithPendingRewards + } + const spacing = useSpacing() + const navigation = useNavigation() + + const colors = useColors() + const borderRadii = useBorderRadii() + + const onBack = useCallback(() => { + navigation.goBack() + }, [navigation]) + + const collectionKey = useMemo(() => { + return new PublicKey( + hotspot.grouping.find((g) => g.group_key === 'collection')?.group_value, + ) + }, [hotspot]) + + const subDao = useMemo(() => { + if (hotspot?.content?.metadata?.hotspot_infos?.iot?.device_type) { + return 'iot' + } + + if (hotspot?.content?.metadata?.hotspot_infos?.mobile?.device_type) { + return 'mobile' + } + + return 'iot' + }, [hotspot]) + + const { result: hotspotAddress } = useAsync(async () => { + const subDaoInfo = hotspot?.content?.metadata?.hotspot_infos[subDao] + + const lat = subDaoInfo?.lat + const long = subDaoInfo?.long + + const address = await getAddressFromLatLng(lat, long) + + return `${address.street}, ${address.city}, ${address.state}` + }, [hotspot, subDao]) + + const onConfig = useCallback(() => { + if (!hotspotAddress) return + navigation.push('HotspotConfig', { hotspot, hotspotAddress }) + }, [navigation, hotspot, hotspotAddress]) + + const deviceType = useMemo(() => { + return hotspot?.content?.metadata?.hotspot_infos?.iot?.device_type + }, [hotspot]) + + const { metadata: mplxMetadata } = useMetaplexMetadata(collectionKey) + + const { info: makerAcc } = useMaker(mplxMetadata?.updateAuthority.toBase58()) + + const HeaderButtons = useCallback(() => { + return ( + + + + + ) + }, [onBack, spacing, onConfig]) + + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const LevelBadge = useCallback(() => { + return ( + + + + Level 15 + + + ) + }, []) + + const deployedDate = useMemo(() => { + const subDaoInfo = hotspot?.content?.metadata?.hotspot_infos[subDao] + + const date = new Date(subDaoInfo?.created_at) + + return t('HotspotDetails.deployed', { + date: formatDistanceToNow(date, { addSuffix: true }), + }) + }, [hotspot, subDao, t]) + + const coordinates = useMemo(() => { + const subDaoInfo = hotspot?.content?.metadata?.hotspot_infos[subDao] + + return [subDaoInfo?.lat, subDaoInfo?.long] + }, [hotspot, subDao]) + + const HotspotMetaLineItem = useCallback( + // eslint-disable-next-line react/no-unused-prop-types + ({ type, label }: { type: string; label: string | undefined }) => { + let Icon = MapPin + switch (type) { + default: + case 'mapPin': + Icon = MapPin + break + case 'hex': + Icon = Hex + break + case 'clock': + Icon = Clock + break + case 'person': + Icon = Person + break + case 'electricity': + Icon = Electricity + break + } + + const iconColor = colors['blue.dark-500'] + + return ( + + + {label ? ( + + {label} + + ) : ( + + + + )} + + ) + }, + [colors, borderRadii], + ) + + return ( + + + + + + + + {/* + TODO: Add level badge + */} + + + {hotspot?.content?.metadata?.name} + + + + + + + {/* + */} + + + ) +} + +export default HotspotDetails diff --git a/src/features/collectables/HotspotMapHotspotDetails.tsx b/src/features/hotspots/HotspotMapHotspotDetails.tsx similarity index 98% rename from src/features/collectables/HotspotMapHotspotDetails.tsx rename to src/features/hotspots/HotspotMapHotspotDetails.tsx index e3521c8f2..a72270599 100644 --- a/src/features/collectables/HotspotMapHotspotDetails.tsx +++ b/src/features/hotspots/HotspotMapHotspotDetails.tsx @@ -1,7 +1,7 @@ -import CopyAddress from '@assets/images/copyAddress.svg' -import Hex from '@assets/images/hex.svg' -import IotSymbol from '@assets/images/iotSymbol.svg' -import MobileSymbol from '@assets/images/mobileSymbol.svg' +import CopyAddress from '@assets/svgs/copyAddress.svg' +import Hex from '@assets/svgs/hex.svg' +import IotSymbol from '@assets/svgs/iotSymbol.svg' +import MobileSymbol from '@assets/svgs/mobileSymbol.svg' import { ReAnimatedBlurBox } from '@components/AnimatedBox' import Box from '@components/Box' import CircleLoader from '@components/CircleLoader' @@ -29,7 +29,7 @@ import { MobileHotspotInfoV0, useMobileInfo } from '@hooks/useMobileInfo' import { usePublicKey } from '@hooks/usePublicKey' import { useNavigation } from '@react-navigation/native' import { PublicKey } from '@solana/web3.js' -import { useColors, useOpacity } from '@theme/themeHooks' +import { useColors, useOpacity } from '@config/theme/themeHooks' import { ellipsizeAddress, formatLargeNumber } from '@utils/accountUtils' import { removeDashAndCapitalize } from '@utils/hotspotNftsUtils' import { Explorer } from '@utils/walletApiV2' @@ -41,10 +41,10 @@ import { useTranslation } from 'react-i18next' import { Alert, AlertButton, Linking } from 'react-native' import { SvgUri } from 'react-native-svg' import SafeAreaBox from '@components/SafeAreaBox' -import { useSolana } from '../../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { CompressedNFT } from '../../types/solana' import { IOT_CONFIG_KEY, MOBILE_CONFIG_KEY, Mints } from '../../utils/constants' -import { CollectableNavigationProp } from './collectablesTypes' +import { CollectableNavigationProp } from '../collectables/collectablesTypes' const IotMapDetails = ({ maker, diff --git a/src/features/collectables/HotspotMapLegend.tsx b/src/features/hotspots/HotspotMapLegend.tsx similarity index 97% rename from src/features/collectables/HotspotMapLegend.tsx rename to src/features/hotspots/HotspotMapLegend.tsx index ca5153009..70a4a2440 100644 --- a/src/features/collectables/HotspotMapLegend.tsx +++ b/src/features/hotspots/HotspotMapLegend.tsx @@ -1,7 +1,7 @@ -import Hex from '@assets/images/hex.svg' +import Hex from '@assets/svgs/hex.svg' import Box from '@components/Box' import Text from '@components/Text' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import React from 'react' export const HotspotMapLegend = ({ diff --git a/src/features/collectables/HotspotMapScreen.tsx b/src/features/hotspots/HotspotMapScreen.tsx similarity index 65% rename from src/features/collectables/HotspotMapScreen.tsx rename to src/features/hotspots/HotspotMapScreen.tsx index c8033b0b5..4200b77c2 100644 --- a/src/features/collectables/HotspotMapScreen.tsx +++ b/src/features/hotspots/HotspotMapScreen.tsx @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-non-null-assertion */ /* eslint-disable no-restricted-properties */ -import BackArrow from '@assets/images/backArrow.svg' -import Hex from '@assets/images/hex.svg' +import BackArrow from '@assets/svgs/backArrow.svg' +import Hex from '@assets/svgs/hex.svg' import { ReAnimatedBlurBox } from '@components/AnimatedBox' import Box from '@components/Box' import CircleLoader from '@components/CircleLoader' @@ -9,8 +9,6 @@ import FabButton from '@components/FabButton' import { DelayedFadeIn } from '@components/FadeInOut' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import Map from '@components/map/Map' -import { INITIAL_MAP_VIEW_STATE, MAX_MAP_ZOOM } from '@components/map/utils' import { BottomSheetModal, BottomSheetModalProvider, @@ -27,36 +25,31 @@ import { chunks, truthy } from '@helium/spl-utils' import useHotspots from '@hooks/useHotspots' import { IotHotspotInfoV0 } from '@hooks/useIotInfo' import { MobileHotspotInfoV0 } from '@hooks/useMobileInfo' -import MapLibreGL, { OnPressEvent } from '@maplibre/maplibre-react-native' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { useBackgroundStyle, useColors } from '@theme/themeHooks' -import { Polygon, feature, featureCollection } from '@turf/helpers' +import { useBackgroundStyle, useColors } from '@config/theme/themeHooks' import { IOT_CONFIG_KEY, MOBILE_CONFIG_KEY } from '@utils/constants' -import { parseH3BNLocation } from '@utils/h3' import { getCachedIotInfos, getCachedKeyToAssets, getCachedMobileInfos, toAsset, } from '@utils/solanaUtils' -import { BN } from 'bn.js' -import { cellToBoundary, latLngToCell } from 'h3-js' import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' -import { Alert } from 'react-native' -import { useSolana } from '../../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { HotspotWithPendingRewards } from '../../types/solana' import { HotspotMapHotspotDetails } from './HotspotMapHotspotDetails' import { HotspotMapLegend } from './HotspotMapLegend' import { CollectableNavigationProp, CollectableStackParamList, -} from './collectablesTypes' +} from '../collectables/collectablesTypes' type Route = RouteProp const DEFAULT_HEX = '631210968843200500' // used for when a hotspot has no iotInfo or mobileInfo + const HotspotMapScreen = () => { const { t } = useTranslation() const { anchorProvider } = useSolana() @@ -64,12 +57,11 @@ const HotspotMapScreen = () => { const bottomSheetStyle = useBackgroundStyle('bg.tertiary') const navigation = useNavigation() const colors = useColors() - const mapRef = useRef(null) - const cameraRef = useRef(null) + // const mapRef = useRef(null) + // const cameraRef = useRef(null) const bottomSheetRef = useRef(null) - const [bottomSheetHeight, setBottomSheetHeight] = useState(0) const [bottomSheetSnapIndex, setBottomSheetSnapIndex] = useState(-1) - const [zoomLevel, setZoomLevel] = useState(INITIAL_MAP_VIEW_STATE.zoomLevel) + // const [zoomLevel, setZoomLevel] = useState(INITIAL_MAP_VIEW_STATE.zoomLevel) const [hotspot, setHotspot] = useState(route.params?.hotspot) const [networkType, setNetworkType] = useState<'IOT' | 'MOBILE'>( route.params?.network || 'IOT', @@ -82,41 +74,41 @@ const HotspotMapScreen = () => { const [activeHotspotIndex, setActiveHotspotIndex] = useState(0) const [legendVisible, setLegendVisible] = useState(false) const { hotspots, fetchAll, loading, onEndReached } = useHotspots() - const [initialUserLocation, setInitialUserLocation] = useState() - const [initialCenterSet, setInitalCenter] = useState(false) - const [userLocation, setUserLocation] = useState() - const onUserLocationUpdate = useCallback( - (loc: MapLibreGL.Location) => { - setUserLocation(loc) - }, - [setUserLocation], - ) - - useEffect(() => { - const coords = userLocation?.coords - if (!initialUserLocation && coords) { - setInitialUserLocation([coords.longitude, coords.latitude]) - } - }, [initialUserLocation, setInitialUserLocation, userLocation?.coords]) - - const initialCenter = useMemo(() => { - return initialUserLocation || INITIAL_MAP_VIEW_STATE.centerCoordinate - }, [initialUserLocation]) - - useEffect(() => { - if ( - initialCenter && - JSON.stringify(initialCenter) !== - JSON.stringify(INITIAL_MAP_VIEW_STATE.centerCoordinate) && - !initialCenterSet - ) { - setInitalCenter(true) - cameraRef.current?.setCamera({ - centerCoordinate: initialCenter, - animationDuration: 0, - }) - } - }, [initialCenter, cameraRef, initialCenterSet, setInitalCenter]) + // const [initialUserLocation, setInitialUserLocation] = useState() + // const [initialCenterSet, setInitalCenter] = useState(false) + // const [userLocation, setUserLocation] = useState() + // const onUserLocationUpdate = useCallback( + // (loc: MapLibreGL.Location) => { + // setUserLocation(loc) + // }, + // [setUserLocation], + // ) + + // useEffect(() => { + // const coords = userLocation?.coords + // if (!initialUserLocation && coords) { + // setInitialUserLocation([coords.longitude, coords.latitude]) + // } + // }, [initialUserLocation, setInitialUserLocation, userLocation?.coords]) + + // const initialCenter = useMemo(() => { + // return initialUserLocation || INITIAL_MAP_VIEW_STATE.centerCoordinate + // }, [initialUserLocation]) + + // useEffect(() => { + // if ( + // initialCenter && + // JSON.stringify(initialCenter) !== + // JSON.stringify(INITIAL_MAP_VIEW_STATE.centerCoordinate) && + // !initialCenterSet + // ) { + // setInitalCenter(true) + // cameraRef.current?.setCamera({ + // centerCoordinate: initialCenter, + // animationDuration: 0, + // }) + // } + // }, [initialCenter, cameraRef, initialCenterSet, setInitalCenter]) // - fetch all hotspots useEffect(() => { @@ -233,82 +225,82 @@ const HotspotMapScreen = () => { }, [loadingInfos, activeHex, hotspot, legendVisible, bottomSheetRef]) // - center the map on the active hex - useAsync(async () => { - if ( - activeHex && - activeHex !== DEFAULT_HEX && - mapRef?.current && - bottomSheetHeight - ) { - const cords = parseH3BNLocation(new BN(activeHex)).reverse() - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore - const mapHeight = mapRef.current.state.height - - if (mapHeight - bottomSheetHeight > 0) { - // eslint-disable-next-line @typescript-eslint/no-shadow - const zoomLevel = await mapRef.current.getZoom() - - // Define the shift needed to adjust the map's center. This is set to a quarter of the bottom sheet's height. - // This means the hexagon will be centered in the upper 3/4 of the map's viewable area. - const centeringShift = bottomSheetHeight / 4 - - // Convert the latitude to radians for more accurate calculations - const latitudeRadians = (cords[1] * Math.PI) / 180 - - // Calculate the number of meters per pixel at the current latitude and zoom level. This uses the Earth's - // radius in meters and accounts for the zoom level to approximate how much geographic space each pixel covers. - const metersPerPixel = - (Math.cos(latitudeRadians) * 2 * Math.PI * 6378137) / - (256 * 2 ** zoomLevel) - - // Calculate the shift in pixels needed to adjust the map's center based on the bottom sheet's height - const pixelShift = centeringShift - - // Convert the pixel shift into a latitude degree shift, using the average meter per degree at the equator. - const degreeShift = (pixelShift * metersPerPixel) / 111319.9 - - // Adjust the map's center coordinate by subtracting the degree shift from the latitude. This effectively - // moves the map's center up to account for the bottom sheet, ensuring the hexagon is centered in the - // viewable area above the bottom sheet. - cameraRef.current?.setCamera({ - centerCoordinate: [cords[0], cords[1] - degreeShift], - animationDuration: 200, - }) - } - } - }, [activeHex, mapRef, bottomSheetHeight, cameraRef]) - - const iconSize = useMemo(() => 0.17 * (zoomLevel / MAX_MAP_ZOOM), [zoomLevel]) - - const hexsFeature = useMemo( - () => - featureCollection( - Object.keys(hexInfoBuckets).map((h) => { - const center = parseH3BNLocation(new BN(h)) - return feature( - { - type: 'Polygon', - coordinates: [ - cellToBoundary( - latLngToCell( - center[0], - center[1], - networkType === 'MOBILE' ? (zoomLevel > 16 ? 12 : 10) : 8, - ), - ).map((p) => p.reverse()), - ], - } as Polygon, - { - id: h, - color: networkType === 'MOBILE' ? '#009EF8' : '#26ED75', - opacity: h === activeHex ? 1 : 0.3, - }, - ) - }), - ), - [activeHex, hexInfoBuckets, networkType, zoomLevel], - ) + // useAsync(async () => { + // if ( + // activeHex && + // activeHex !== DEFAULT_HEX && + // mapRef?.current && + // bottomSheetHeight + // ) { + // const cords = parseH3BNLocation(new BN(activeHex)).reverse() + // // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // // @ts-ignore + // const mapHeight = mapRef.current.state.height + + // if (mapHeight - bottomSheetHeight > 0) { + // // eslint-disable-next-line @typescript-eslint/no-shadow + // const zoomLevel = await mapRef.current.getZoom() + + // // Define the shift needed to adjust the map's center. This is set to a quarter of the bottom sheet's height. + // // This means the hexagon will be centered in the upper 3/4 of the map's viewable area. + // const centeringShift = bottomSheetHeight / 4 + + // // Convert the latitude to radians for more accurate calculations + // const latitudeRadians = (cords[1] * Math.PI) / 180 + + // // Calculate the number of meters per pixel at the current latitude and zoom level. This uses the Earth's + // // radius in meters and accounts for the zoom level to approximate how much geographic space each pixel covers. + // const metersPerPixel = + // (Math.cos(latitudeRadians) * 2 * Math.PI * 6378137) / + // (256 * 2 ** zoomLevel) + + // // Calculate the shift in pixels needed to adjust the map's center based on the bottom sheet's height + // const pixelShift = centeringShift + + // // Convert the pixel shift into a latitude degree shift, using the average meter per degree at the equator. + // const degreeShift = (pixelShift * metersPerPixel) / 111319.9 + + // // Adjust the map's center coordinate by subtracting the degree shift from the latitude. This effectively + // // moves the map's center up to account for the bottom sheet, ensuring the hexagon is centered in the + // // viewable area above the bottom sheet. + // cameraRef.current?.setCamera({ + // centerCoordinate: [cords[0], cords[1] - degreeShift], + // animationDuration: 200, + // }) + // } + // } + // }, [activeHex, mapRef, bottomSheetHeight, cameraRef]) + + // const iconSize = useMemo(() => 0.17 * (zoomLevel / MAX_MAP_ZOOM), [zoomLevel]) + + // const hexsFeature = useMemo( + // () => + // featureCollection( + // Object.keys(hexInfoBuckets).map((h) => { + // const center = parseH3BNLocation(new BN(h)) + // return feature( + // { + // type: 'Polygon', + // coordinates: [ + // cellToBoundary( + // latLngToCell( + // center[0], + // center[1], + // networkType === 'MOBILE' ? (zoomLevel > 16 ? 12 : 10) : 8, + // ), + // ).map((p) => p.reverse()), + // ], + // } as Polygon, + // { + // id: h, + // color: networkType === 'MOBILE' ? '#009EF8' : '#26ED75', + // opacity: h === activeHex ? 1 : 0.3, + // }, + // ) + // }), + // ), + // [activeHex, hexInfoBuckets, networkType, zoomLevel], + // ) const activeHexItem = useMemo(() => { if (!loadingInfos && activeHex) { @@ -343,24 +335,24 @@ const HotspotMapScreen = () => { [loading, onEndReached, loadingInfos], ) - const handleUserLocationPress = useCallback(() => { - if (cameraRef?.current && userLocation?.coords) { - cameraRef.current.setCamera({ - animationDuration: 500, - zoomLevel: MAX_MAP_ZOOM, - centerCoordinate: userLocation.coords, - }) - } - }, [userLocation, cameraRef]) - - const handleRegionChanged = useCallback(async () => { - if (mapRef?.current) { - const zoom = await mapRef.current.getZoom() - if (zoomLevel !== zoom) { - setZoomLevel(zoom) - } - } - }, [mapRef, zoomLevel, setZoomLevel]) + // const handleUserLocationPress = useCallback(() => { + // if (cameraRef?.current && userLocation?.coords) { + // cameraRef.current.setCamera({ + // animationDuration: 500, + // zoomLevel: MAX_MAP_ZOOM, + // centerCoordinate: userLocation.coords, + // }) + // } + // }, [userLocation, cameraRef]) + + // const handleRegionChanged = useCallback(async () => { + // if (mapRef?.current) { + // const zoom = await mapRef.current.getZoom() + // if (zoomLevel !== zoom) { + // setZoomLevel(zoom) + // } + // } + // }, [mapRef, zoomLevel, setZoomLevel]) const handleLegendPress = useCallback(() => { setLegendVisible(true) @@ -371,28 +363,28 @@ const HotspotMapScreen = () => { setHotspot(undefined) }, [networkType, setNetworkType]) - const handleHexClick = useCallback( - (event: OnPressEvent) => { - const hex = event.features[0] - setLegendVisible(false) - const id = hex.properties?.id - setActiveHex(id) - if (id && (hexInfoBuckets[id]?.length || 0) > 1) { - Alert.alert( - t('collectablesScreen.hotspots.selectActive.title'), - t('collectablesScreen.hotspots.selectActive.which'), - hexInfoBuckets[id].map((info, index) => ({ - text: hotspots.find((h) => h.id === info.asset.toBase58())?.content - ?.metadata?.name, - onPress: () => { - setActiveHotspotIndex(index) - }, - })), - ) - } - }, - [hexInfoBuckets, hotspots, t], - ) + // const handleHexClick = useCallback( + // (event: OnPressEvent) => { + // const hex = event.features[0] + // setLegendVisible(false) + // const id = hex.properties?.id + // setActiveHex(id) + // if (id && (hexInfoBuckets[id]?.length || 0) > 1) { + // Alert.alert( + // t('collectablesScreen.hotspots.selectActive.title'), + // t('collectablesScreen.hotspots.selectActive.which'), + // hexInfoBuckets[id].map((info, index) => ({ + // text: hotspots.find((h) => h.id === info.asset.toBase58())?.content + // ?.metadata?.name, + // onPress: () => { + // setActiveHotspotIndex(index) + // }, + // })), + // ) + // } + // }, + // [hexInfoBuckets, hotspots, t], + // ) return ( @@ -417,9 +409,9 @@ const HotspotMapScreen = () => { - { setLegendVisible(false) }, }} - > - {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */} - {/* @ts-ignore */} - */} + {/* eslint-disable-next-line @typescript-eslint/ban-ts-comment */} + {/* @ts-ignore */} + {/* - */} + {/* { fillOpacity: ['get', 'opacity'], }} /> - - + */} + {/* */} { width={36} height={36} justifyContent="center" - onPress={handleUserLocationPress} + // onPress={handleUserLocationPress} /> @@ -564,11 +556,7 @@ const HotspotMapScreen = () => { onChange={(idx) => setBottomSheetSnapIndex(idx)} > - - setBottomSheetHeight(e.nativeEvent.layout.height) - } - > + {legendVisible && } {activeHexItem && ( { + const { + hotspotsWithMeta, + loading: loadingHotspots, + refresh, + fetchMore, + fetchingMore, + onEndReached, + } = useHotspots() + + const isFocused = useIsFocused() + const colors = useColors() + const { t } = useTranslation() + const spacing = useSpacing() + const { bottom } = useSafeAreaInsets() + const navigation = useNavigation() + const [filterText, setFilterText] = useState('') + const [userLocation, setUserLocation] = useState() + const [filter, setFilter] = useState<'distance' | 'earnings'>('distance') + const route = useRoute<{ + params: { + newHotspot?: HotspotWithPendingRewards | undefined + } + key: string + name: string + }>() + + const newHotspot = useMemo(() => route?.params?.newHotspot, [route]) + + const onUserLocationUpdate = useCallback((location: Location) => { + setUserLocation(location) + }, []) + + const onItemSelected = useCallback((value: number) => { + setFilter(value === 0 ? 'distance' : 'earnings') + }, []) + + const options = useMemo( + () => [ + { + label: t('HotspotPage.byDistance'), + value: 'distance', + }, + { + label: t('HotspotPage.byEarnings'), + value: 'earnings', + }, + ], + [t], + ) + + const onHotspotDetails = useCallback( + (hotspot: HotspotWithPendingRewards) => () => { + navigation.navigate('HotspotDetails', { hotspot }) + }, + [navigation], + ) + + const hotspotsWithDistance = useMemo(() => { + let hotspots = hotspotsWithMeta + + if (newHotspot) { + // we push the new hotspot to the top of the list and remove it from the array + hotspots = [ + newHotspot, + ...hotspots.filter((hotspot) => hotspot.id !== newHotspot.id), + ] + } + + return hotspots.map((hotspot) => { + const subDao = hotspot?.content?.metadata?.hotspot_infos?.iot?.device_type + ? 'iot' + : 'mobile' + const { long, lat } = hotspot.content.metadata.hotspot_infos[subDao] + + if (!long || !lat) + return { + ...hotspot, + distance: undefined, + } + + const distance = userLocation + ? getDistance( + { + latitude: userLocation?.coords.latitude, + longitude: userLocation?.coords.longitude, + }, + { + latitude: toNumber(lat), + longitude: toNumber(long), + }, + ) + : undefined + + return { + ...hotspot, + distance, + } + }) + }, [hotspotsWithMeta, userLocation, newHotspot]) + + const filteredHotspots = useMemo(() => { + const sortedHotspots = hotspotsWithDistance.sort((a, b) => { + if (filter === 'distance') { + // if distance is undefined, sort it to the end + return (a?.distance ?? Infinity) - (b?.distance ?? Infinity) + } + return ( + (heliumToNumber( + new BN(b?.pendingRewards?.[MOBILE_MINT?.toBase58()] ?? 0), + 6, + ) ?? 0) - + (heliumToNumber( + new BN(a?.pendingRewards?.[MOBILE_MINT?.toBase58()] ?? 0), + 6, + ) ?? 0) + ) + }) + + if (!filterText || filterText === '') { + return sortedHotspots as (HotspotWithPendingRewards & { + distance: number + })[] + } + + return sortedHotspots.filter((hotspot) => { + return hotspot.content.metadata.name + .toLowerCase() + .includes(filterText.toLowerCase()) + }) as (HotspotWithPendingRewards & { distance: number })[] + }, [hotspotsWithDistance, filterText, filter]) + + const renderHeader = useCallback(() => { + return ( + + + {hotspotsWithMeta.map((hotspot) => { + const subDao = hotspot?.content?.metadata?.hotspot_infos?.iot + ?.device_type + ? 'iot' + : 'mobile' + const { long, lat } = hotspot.content.metadata.hotspot_infos[subDao] + + if (!long || !lat) return null + + return ( + + + + ) + })} + + + {t('HotspotPage.amountOfHotspots', { + amount: hotspotsWithMeta?.length, + })} + + + + + + + ) + }, [onUserLocationUpdate, hotspotsWithMeta, t, options, onItemSelected]) + + const renderItem = useCallback( + // eslint-disable-next-line react/no-unused-prop-types + ({ item }: { item: HotspotWithPendingRewards & { distance: number } }) => { + const isFirst = item.id === filteredHotspots[0].id + const isLast = + item.id === filteredHotspots[filteredHotspots.length - 1].id + const borderTopStartRadius = isFirst ? '3xl' : undefined + const borderTopEndRadius = isFirst ? '3xl' : undefined + const borderBottomStartRadius = isLast ? '3xl' : undefined + const borderBottomEndRadius = isLast ? '3xl' : undefined + + const { name } = item.content.metadata + + const isActive = item?.content?.metadata?.hotspot_infos?.iot?.is_active + + const isNewHotspot = item.id === newHotspot?.id + + const distance = item?.distance + + // if distance is less than 5 meters, show 'Nearby' + let distanceText = t('HotspotPage.distanceNotAvailable') + + if (distance && distance < 5) { + distanceText = t('HotspotPage.nearby') + } else if (distance) { + distanceText = t('HotspotPage.metersAway', { + meters: distance, + }) + } + + return ( + + + + + + {name} + + + + {distanceText} + + + + {isNewHotspot && ( + + + {t('HotspotPage.new')} + + + )} + + + + ) + }, + [filteredHotspots, onHotspotDetails, newHotspot, t, colors], + ) + + const pageAmount = 20 + const handleOnEndReached = useCallback(() => { + if (!fetchingMore && isFocused && !onEndReached) { + fetchMore(pageAmount) + } + }, [fetchingMore, isFocused, fetchMore, pageAmount, onEndReached]) + + const handleRefresh = useCallback(() => { + refresh(pageAmount) + }, [pageAmount, refresh]) + + const keyExtractor = useCallback( + (item: HotspotWithPendingRewards & { distance: number }) => { + return item.id + }, + [], + ) + + const contentContainerStyle = useMemo(() => { + return { + paddingHorizontal: spacing['2xl'], + paddingBottom: bottom + NavBarHeight + spacing.xl, + } + }, [spacing, bottom]) + + return ( + <> + {hotspotsWithMeta.length === 0 ? : null} + + + } + > + + + + ) +} + +export default HotspotPage diff --git a/src/features/hotspots/ModifyWifiScreen.tsx b/src/features/hotspots/ModifyWifiScreen.tsx new file mode 100644 index 000000000..d1abc1be6 --- /dev/null +++ b/src/features/hotspots/ModifyWifiScreen.tsx @@ -0,0 +1,750 @@ +import BackScreen from '@components/BackScreen' +import Box from '@components/Box' +import { useSpacing, useColors } from '@config/theme/themeHooks' +import { BleError, Device, useHotspotBle } from '@helium/react-native-sdk' +import { wp } from '@utils/layout' +import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' +import Carousel from 'react-native-snap-carousel' +import { useTranslation } from 'react-i18next' +import TouchableContainer from '@components/TouchableContainer' +import Text from '@components/Text' +import CarotRight from '@assets/svgs/carot-right.svg' +import { + Alert, + FlatList, + PermissionsAndroid, + Platform, + RefreshControl, + StyleProp, + ViewStyle, +} from 'react-native' +import ScrollBox from '@components/ScrollBox' +import TouchableOpacityBox from '@components/TouchableOpacityBox' +import RightArrow from '@assets/svgs/rightArrow.svg' +import { + check, + PERMISSIONS, + request, + RESULTS, + PermissionStatus, +} from 'react-native-permissions' +import * as Logger from '@utils/logger' +import { useAsyncCallback } from 'react-async-hook' +import { ButtonPressable, ImageBox, TextInput } from '@components/index' +import Visibility from '@assets/svgs/visibility.svg' +import VisibilityOff from '@assets/svgs/visibilityOff.svg' +import { useNavigation } from '@react-navigation/native' +import Config from 'react-native-config' +import Checkmark from '@assets/svgs/checkmark.svg' + +const MOCK = Config.MOCK_IOT === 'true' +const MOCK_DEVICES = [ + { id: '1', name: 'RAK-78908' }, + { id: '2', name: 'Helium-Hotspot-775' }, +] as Device[] + +type CarouselItem = { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + Screen: (ScreenProps) => React.JSX.Element +} + +const ModifyWifiScreen = () => { + const carouselRef = useRef>(null) + const [network, setNetwork] = useState(undefined) + + const slides = useMemo(() => { + return [ + { + Screen: ScanHotspots, + }, + { + Screen: WifiSettings, + }, + { + Screen: WifiSetup, + }, + ] + }, []) + + const renderCarouselItem = useCallback( + // eslint-disable-next-line react/no-unused-prop-types + ({ item }: { item: CarouselItem }) => { + return ( + + ) + }, + [network], + ) + + return ( + + + + ) +} + +const ScanHotspots = ({ + carouselRef, +}: { + carouselRef: React.RefObject> +}) => { + const { startScan, stopScan, connect, scannedDevices } = useHotspotBle() + const [scanning, setScanning] = useState(false) + const colors = useColors() + const [canScan, setCanScan] = useState(undefined) + const spacing = useSpacing() + const { t } = useTranslation() + const [error, setError] = useState(undefined) + + const bluetoothDevices = useMemo(() => { + if (MOCK) { + return MOCK_DEVICES + } + return scannedDevices + }, [scannedDevices]) + + // eslint-disable-next-line @typescript-eslint/no-explicit-any + const showError = (e: any) => { + Logger.error(e) + setError(e.toString()) + } + + const updateCanScan = useCallback((result: PermissionStatus) => { + switch (result) { + case RESULTS.UNAVAILABLE: + case RESULTS.BLOCKED: + case RESULTS.DENIED: + case RESULTS.LIMITED: + setCanScan(false) + break + case RESULTS.GRANTED: + setCanScan(true) + break + } + }, []) + + useEffect(() => { + if (Platform.OS === 'ios') { + setCanScan(true) + return + } + + check(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION) + .then(updateCanScan) + .catch(showError) + }, [updateCanScan]) + + useEffect(() => { + if (canScan !== false) return + + request(PERMISSIONS.ANDROID.ACCESS_FINE_LOCATION) + .then(updateCanScan) + .catch(showError) + }, [canScan, updateCanScan]) + + const checkPermission = async () => { + if (Platform.OS === 'ios') { + return true + } + + const perms = [ + PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, + PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, + ] + + const results = await Promise.all( + perms.map((p) => PermissionsAndroid.check(p)), + ) + + if (results.findIndex((r) => r === false) === -1) { + return true + } + + const granted = await PermissionsAndroid.requestMultiple([ + PermissionsAndroid.PERMISSIONS.BLUETOOTH_SCAN, + PermissionsAndroid.PERMISSIONS.BLUETOOTH_CONNECT, + ]) + + perms.forEach((p) => { + if (!granted[p]) { + return false + } + }) + + return true + } + + const navNext = useCallback( + () => carouselRef?.current?.snapToNext(), + [carouselRef], + ) + + const handleScanPress = useCallback(async () => { + const shouldScan = !scanning + setScanning(shouldScan) + await checkPermission() + // eslint-disable-next-line @typescript-eslint/no-explicit-any + let timeout: any | undefined + if (shouldScan) { + setError(undefined) + timeout = setTimeout(() => { + stopScan() + setScanning(false) + if (scannedDevices.length === 0) { + setError( + 'No hotspots found. Please ensure bluetooth pairing is enabled', + ) + } + }, 30 * 1000) + } + + if (shouldScan) { + startScan((e) => { + if (e) { + showError(e) + } + }) + } else { + stopScan() + } + return () => { + if (timeout) { + clearTimeout(timeout) + stopScan() + } + } + }, [scannedDevices, scanning, startScan, stopScan]) + + const [connecting, setConnecting] = useState(false) + const connectDevice = useCallback( + (d: Device) => async () => { + if (MOCK) { + navNext() + return + } + + try { + setConnecting(true) + await connect(d) + if (scanning) { + stopScan() + setScanning(false) + } + setConnecting(false) + navNext() + } catch (e) { + showError(e) + } finally { + setConnecting(false) + } + }, + [connect, navNext, scanning, stopScan], + ) + + const renderItem = React.useCallback( + // eslint-disable-next-line react/no-unused-prop-types + ({ item }: { item: Device }) => { + const first = item.id === bluetoothDevices[0].id + const last = item.id === bluetoothDevices[bluetoothDevices.length - 1].id + const borderTopStartRadius = first ? '2xl' : 'none' + const borderTopEndRadius = first ? '2xl' : 'none' + const borderBottomStartRadius = last ? '2xl' : 'none' + const borderBottomEndRadius = last ? '2xl' : 'none' + + return ( + + + {item.name} + + + + ) + }, + [connectDevice, connecting, bluetoothDevices, colors], + ) + + const renderHeader = useCallback(() => { + return ( + + + {t('hotspotOnboarding.scan.title')} + + {bluetoothDevices.length > 0 && ( + + {t('hotspotOnboarding.scan.hotspotsFound', { + count: bluetoothDevices.length, + })} + + )} + {error && ( + + {error} + + )} + + ) + }, [t, bluetoothDevices, error]) + + const renderFooter = useCallback(() => { + return ( + + + {canScan + ? scanning + ? t('hotspotOnboarding.scan.stop') + : t('hotspotOnboarding.scan.start') + : t('hotspotOnboarding.scan.notEnabled')} + + + + ) + }, [canScan, handleScanPress, scanning, t, colors]) + + const contentContainerStyle = useMemo( + () => ({ + padding: spacing['2xl'], + flex: 1, + justifyContent: 'center', + }), + [spacing], + ) + + const keyExtractor = React.useCallback(({ id }: Device) => id, []) + + return ( + + } + contentContainerStyle={{ + flex: 1, + }} + > + } + ListHeaderComponent={renderHeader} + data={bluetoothDevices} + renderItem={renderItem} + keyExtractor={keyExtractor} + ListFooterComponent={renderFooter} + /> + + ) +} + +const WifiSettings = ({ + carouselRef, + onNetworkSelected, +}: { + carouselRef: React.RefObject> + onNetworkSelected: (network: string) => void +}) => { + const { t } = useTranslation() + const spacing = useSpacing() + const colors = useColors() + const [networks, setNetworks] = useState() + const [configuredNetworks, setConfiguredNetworks] = useState() + const [connected, setConnected] = useState(false) + + const { isConnected, readWifiNetworks, removeConfiguredWifi } = + useHotspotBle() + + useEffect(() => { + isConnected().then(setConnected) + }, [isConnected]) + + const { + execute: handleRefresh, + loading: refreshing, + error, + } = useAsyncCallback(async () => { + if (MOCK) { + setConfiguredNetworks(['Solana-House-5678']) + setNetworks(['Helium-House-1234']) + return + } + + if (!connected) return + + const configured = await readWifiNetworks(true) + setConfiguredNetworks(configured) + const available = await readWifiNetworks(false) + setNetworks(available) + }) + + // Refresh on network change or on load + useEffect(() => { + handleRefresh() + }, [handleRefresh, connected]) + + const handleNetworkSelected = useCallback( + ({ + network, + type, + }: { + network: string + type: 'configured' | 'available' + }) => + async () => { + if (type === 'available') { + onNetworkSelected(network) + carouselRef?.current?.snapToNext() + } else { + Alert.alert( + t('hotspotOnboarding.wifiSettings.title'), + t('hotspotOnboarding.wifiSettings.remove', { network }), + [ + { + text: t('generic.cancel'), + style: 'default', + }, + { + text: t('generic.remove'), + style: 'destructive', + onPress: async () => { + setConfiguredNetworks( + configuredNetworks?.filter((n) => n !== network), + ) + await removeConfiguredWifi(network) + readWifiNetworks(true).then(setConfiguredNetworks) + readWifiNetworks(false).then(setNetworks) + }, + }, + ], + ) + } + }, + [ + onNetworkSelected, + carouselRef, + t, + configuredNetworks, + removeConfiguredWifi, + readWifiNetworks, + ], + ) + + const data = useMemo( + () => [...(configuredNetworks || []), ...(networks || [])], + [configuredNetworks, networks], + ) + + const renderItem = useCallback( + ({ + item: network, + }: { + // eslint-disable-next-line react/no-unused-prop-types + item: string + // eslint-disable-next-line react/no-unused-prop-types + }) => { + const first = data[0] === network + const last = data[data.length - 1] === network + const borderTopStartRadius = first ? '2xl' : 'none' + const borderBottomStartRadius = last ? '2xl' : 'none' + const borderBottomEndRadius = last ? '2xl' : 'none' + const borderTopEndRadius = first ? '2xl' : 'none' + + const isConfigured = configuredNetworks?.includes(network) + + return ( + + + {network} + + {!isConfigured && ( + + )} + {isConfigured && } + + ) + }, + [handleNetworkSelected, data, colors, configuredNetworks], + ) + + const keyExtractor = useCallback((name: string) => name, []) + + const renderHeader = useCallback( + () => ( + + + {t('hotspotOnboarding.wifiSettings.title')} + + + {t('hotspotOnboarding.wifiSettings.subtitle')} + + {error && ( + + {error.message ? error.message.toString() : error.toString()} + + )} + + ), + [error, t], + ) + + const renderFooter = useCallback( + () => ( + + + {refreshing + ? t('hotspotOnboarding.scan.stop') + : t('hotspotOnboarding.scan.start')} + + + + ), + [colors, handleRefresh, refreshing, t], + ) + + const contentContainerStyle = useMemo( + () => ({ + padding: spacing['2xl'], + flex: 1, + }), + [spacing], + ) + + const flatListContentContainerStyle = useMemo( + () => ({ + padding: spacing['2xl'], + flex: 1, + justifyContent: 'center', + }), + [spacing], + ) + + return ( + + } + > + + } + /> + + ) +} + +const WifiSetup = ({ network }: { network: string }) => { + const [secureTextEntry, setSecureTextEntry] = useState(true) + const [error, setError] = useState('') + const [loading, setLoading] = useState(false) + const [password, setPassword] = useState('') + const { setWifi } = useHotspotBle() + const { t } = useTranslation() + const spacing = useSpacing() + const colors = useColors() + const navigation = useNavigation() + + const toggleSecureEntry = useCallback(() => { + setSecureTextEntry(!secureTextEntry) + }, [secureTextEntry]) + + const handleSetWifi = useCallback(async () => { + setLoading(true) + try { + await setWifi(network, password) + navigation.goBack() + } catch (e) { + if (typeof e === 'string') { + setError(e) + } else { + setError((e as BleError).toString()) + } + } + setLoading(false) + }, [password, setWifi, network, navigation]) + + const contentContainer = useMemo( + () => ({ + paddingHorizontal: spacing['2xl'], + flex: 1, + justifyContent: 'center', + }), + [spacing], + ) + + return ( + }> + + + + {t('hotspotOnboarding.wifiSetup.title')} + + + {t('hotspotOnboarding.wifiSetup.subtitle', { network })} + + {error && ( + + {error} + + )} + + + + + {secureTextEntry ? ( + + ) : ( + + )} + + + + + + ) +} + +export default ModifyWifiScreen diff --git a/src/features/collectables/SettingUpAntennaScreen.tsx b/src/features/hotspots/SettingUpAntennaScreen.tsx similarity index 96% rename from src/features/collectables/SettingUpAntennaScreen.tsx rename to src/features/hotspots/SettingUpAntennaScreen.tsx index e2a33de88..82844980d 100644 --- a/src/features/collectables/SettingUpAntennaScreen.tsx +++ b/src/features/hotspots/SettingUpAntennaScreen.tsx @@ -1,11 +1,11 @@ import React, { memo, useCallback } from 'react' import Box from '@components/Box' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { useNavigation } from '@react-navigation/native' -import { TabBarNavigationProp } from 'src/navigation/rootTypes' +import { TabBarNavigationProp } from 'src/app/rootTypes' import { ReAnimatedBox } from '@components/AnimatedBox' import { DelayedFadeIn } from '@components/FadeInOut' -import BackArrow from '@assets/images/backArrow.svg' +import BackArrow from '@assets/svgs/backArrow.svg' import AccountIcon from '@components/AccountIcon' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useTranslation } from 'react-i18next' diff --git a/src/features/collectables/animations/iot-mobile-tokens.json b/src/features/hotspots/animations/iot-mobile-tokens.json similarity index 100% rename from src/features/collectables/animations/iot-mobile-tokens.json rename to src/features/hotspots/animations/iot-mobile-tokens.json diff --git a/src/features/collectables/animations/iot-tokens.json b/src/features/hotspots/animations/iot-tokens.json similarity index 100% rename from src/features/collectables/animations/iot-tokens.json rename to src/features/hotspots/animations/iot-tokens.json diff --git a/src/features/collectables/animations/mobile-tokens.json b/src/features/hotspots/animations/mobile-tokens.json similarity index 100% rename from src/features/collectables/animations/mobile-tokens.json rename to src/features/hotspots/animations/mobile-tokens.json diff --git a/src/features/hotspots/hotspotTypes.ts b/src/features/hotspots/hotspotTypes.ts new file mode 100644 index 000000000..0c379b575 --- /dev/null +++ b/src/features/hotspots/hotspotTypes.ts @@ -0,0 +1,60 @@ +import { StackNavigationProp } from '@react-navigation/stack' +import { + Collectable, + CompressedNFT, + HotspotWithPendingRewards, +} from '../../types/solana' + +export type PaymentRouteParam = { + collectable?: CompressedNFT +} + +export type CollectableStackParamList = { + HotspotList: undefined + HotspotMapScreen: + | undefined + | { + hotspot?: HotspotWithPendingRewards + network?: 'IOT' | 'MOBILE' + } + AssertLocationScreen: { + collectable: HotspotWithPendingRewards + } + AntennaSetupScreen: { + collectable: HotspotWithPendingRewards + } + SettingUpAntennaScreen: undefined + PaymentScreen: undefined | PaymentRouteParam + ClaimRewardsScreen: { + hotspot: HotspotWithPendingRewards + } + ClaimAllRewardsScreen: undefined + ClaimingRewardsScreen: undefined + ChangeRewardsRecipientScreen: { + hotspot: HotspotWithPendingRewards + } + CollectionScreen: { + collection: Collectable[] + } + NftDetailsScreen: { + collectable: Collectable + } + NftMetadataScreen: { + // eslint-disable-next-line @typescript-eslint/no-explicit-any + metadata: any + } + TransferCollectableScreen: { + collectable: CompressedNFT | Collectable + } + TransferCompleteScreen: { + collectable: CompressedNFT | Collectable + } + AddNewContact: undefined + PaymentQrScanner: undefined + AddressBookNavigator: undefined + ScanAddress: undefined + OnboardingNavigator: undefined +} + +export type CollectableNavigationProp = + StackNavigationProp diff --git a/src/features/keystone/ConnectKeystoneStartScreen.tsx b/src/features/keystone/ConnectKeystoneStartScreen.tsx index 12012f174..687c74bdc 100644 --- a/src/features/keystone/ConnectKeystoneStartScreen.tsx +++ b/src/features/keystone/ConnectKeystoneStartScreen.tsx @@ -4,7 +4,7 @@ import ButtonPressable from '@components/ButtonPressable' import SafeAreaBox from '@components/SafeAreaBox' import Text from '@components/Text' import { useNavigation } from '@react-navigation/native' -import WarningKeystone from '@assets/images/warningKeystone.svg' +import WarningKeystone from '@assets/svgs/warningKeystone.svg' import React, { forwardRef, ReactNode, @@ -16,11 +16,11 @@ import React, { } from 'react' import useCamera from '@hooks/useCamera' import { BottomSheetBackdrop, BottomSheetModal } from '@gorhom/bottom-sheet' -import { useOpacity, useSpacing } from '@theme/themeHooks' +import { useOpacity, useSpacing } from '@config/theme/themeHooks' import useBackHandler from '@hooks/useBackHandler' import { useTheme } from '@shopify/restyle' import { t } from 'i18next' -import { RootNavigationProp } from 'src/navigation/rootTypes' +import { RootNavigationProp } from 'src/app/rootTypes' import { Image, Linking, Platform } from 'react-native' type CameraPermissionBottomSheetAlertRef = { diff --git a/src/features/keystone/KeystoneAccountAssignScreen.tsx b/src/features/keystone/KeystoneAccountAssignScreen.tsx index 79c0ae8c9..6ae394992 100644 --- a/src/features/keystone/KeystoneAccountAssignScreen.tsx +++ b/src/features/keystone/KeystoneAccountAssignScreen.tsx @@ -7,20 +7,20 @@ import Text from '@components/Text' import TextInput from '@components/TextInput' import CheckBox from '@react-native-community/checkbox' import { useNavigation } from '@react-navigation/native' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import React, { memo, useCallback, useMemo, useState } from 'react' import { useAsyncCallback } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { KeyboardAvoidingView, Platform, StyleSheet } from 'react-native' import { useSafeAreaInsets } from 'react-native-safe-area-context' import base58 from 'bs58' -import { CSAccountVersion } from '@storage/cloudStorage' +import { CSAccountVersion } from '@config/storage/cloudStorage' import { hex } from '@coral-xyz/anchor/dist/cjs/utils/bytes' import { PublicKey } from '@solana/web3.js' import Address from '@helium/address' import { ED25519_KEY_TYPE } from '@helium/address/build/KeyTypes' -import { RootNavigationProp } from '../../navigation/rootTypes' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { RootNavigationProp } from '../../app/rootTypes' import { ImportAccountNavigationProp } from '../onboarding/import/importAccountNavTypes' import { CreateAccountNavigationProp } from '../onboarding/create/createAccountNavTypes' import { useKeystoneOnboarding } from './KeystoneOnboardingProvider' diff --git a/src/features/keystone/KeystoneModal.tsx b/src/features/keystone/KeystoneModal.tsx index 0236523d2..b3ba7864d 100644 --- a/src/features/keystone/KeystoneModal.tsx +++ b/src/features/keystone/KeystoneModal.tsx @@ -6,7 +6,7 @@ import { } from '@gorhom/bottom-sheet' import useBackHandler from '@hooks/useBackHandler' import { useTheme } from '@shopify/restyle' -import { useOpacity, useSpacing } from '@theme/themeHooks' +import { useOpacity, useSpacing } from '@config/theme/themeHooks' import React, { ReactNode, Ref, @@ -19,7 +19,7 @@ import React, { useState, } from 'react' import EventEmitter from 'events' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { KeystoneSolanaSDK } from '@keystonehq/keystone-sdk' import { uuid } from '@keystonehq/keystone-sdk/dist/utils' import SignTxModal from './SignTx/SignTxModal' diff --git a/src/features/keystone/ScanQrCodeScreen.tsx b/src/features/keystone/ScanQrCodeScreen.tsx index c51e51cf7..1295e8900 100644 --- a/src/features/keystone/ScanQrCodeScreen.tsx +++ b/src/features/keystone/ScanQrCodeScreen.tsx @@ -3,7 +3,7 @@ import DynamicQrScanner from '@components/DynamicQrScanner' import SafeAreaBox from '@components/SafeAreaBox' import { URDecoder } from '@ngraveio/bc-ur' import KeystoneSDK, { MultiAccounts, UR } from '@keystonehq/keystone-sdk' -import { RootNavigationProp } from 'src/navigation/rootTypes' +import { RootNavigationProp } from 'src/app/rootTypes' import { useNavigation } from '@react-navigation/native' import { Alert } from 'react-native' import { useTranslation } from 'react-i18next' diff --git a/src/features/keystone/SelectKeystoneAccountsScreen.tsx b/src/features/keystone/SelectKeystoneAccountsScreen.tsx index 1de99393e..5cc09a8fd 100644 --- a/src/features/keystone/SelectKeystoneAccountsScreen.tsx +++ b/src/features/keystone/SelectKeystoneAccountsScreen.tsx @@ -6,23 +6,19 @@ import SafeAreaBox from '@components/SafeAreaBox' import Text from '@components/Text' import ButtonPressable from '@components/ButtonPressable' import { FlatList, RefreshControl } from 'react-native' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import CheckBox from '@react-native-community/checkbox' import TouchableContainer from '@components/TouchableContainer' import { humanReadable } from '@helium/spl-utils' import BN from 'bn.js' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { - RootNavigationProp, - RootStackParamList, -} from 'src/navigation/rootTypes' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { RootNavigationProp, RootStackParamList } from 'src/app/rootTypes' import { ellipsizeAddress } from '@utils/accountUtils' import base58 from 'bs58' import { retryWithBackoff } from '@utils/retryWithBackoff' import { PublicKey } from '@solana/web3.js' import { useTranslation } from 'react-i18next' -import { useSolana } from '../../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { useKeystoneOnboarding } from './KeystoneOnboardingProvider' export type KeystoneAccountType = { @@ -42,7 +38,6 @@ const SelectKeystoneAccountsScreen = () => { const colors = useColors() const route = useRoute() const { setKeystoneOnboardingData } = useKeystoneOnboarding() - const { hasAccounts } = useAccountStorage() const { derivationAccounts } = route.params const [selected, setSelected] = React.useState>( new Set(derivationAccounts.map((item) => item.path)), diff --git a/src/features/keystone/SignTx/SignTxModal.tsx b/src/features/keystone/SignTx/SignTxModal.tsx index 97dc4bb2a..47e194f4c 100644 --- a/src/features/keystone/SignTx/SignTxModal.tsx +++ b/src/features/keystone/SignTx/SignTxModal.tsx @@ -1,6 +1,6 @@ import SafeAreaBox from '@components/SafeAreaBox' import React, { useEffect, useMemo, useState } from 'react' -import Keystone from '@assets/images/keystoneLogo.svg' +import Keystone from '@assets/svgs/keystoneLogo.svg' import Box from '@components/Box' import Text from '@components/Text' import ButtonPressable from '@components/ButtonPressable' @@ -19,7 +19,7 @@ import { useAsync } from 'react-async-hook' import EventEmitter from 'events' import CloseButton from '@components/CloseButton' -import { useHitSlop } from '@theme/themeHooks' +import { useHitSlop } from '@config/theme/themeHooks' import { CameraScannerLayout } from '../../../components/CameraScannerLayout' import { KeystoneSolSignRequest } from '../types/keystoneSolanaTxType' diff --git a/src/features/ledger/DeviceChooseType.tsx b/src/features/ledger/DeviceChooseType.tsx index 49508e121..792b9e013 100644 --- a/src/features/ledger/DeviceChooseType.tsx +++ b/src/features/ledger/DeviceChooseType.tsx @@ -1,11 +1,11 @@ import React, { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { useNavigation } from '@react-navigation/native' -import Ledger from '@assets/images/ledger.svg' +import Ledger from '@assets/svgs/ledger.svg' import Text from '@components/Text' import Box from '@components/Box' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import SafeAreaBox from '@components/SafeAreaBox' import { LedgerNavigatorNavigationProp } from './ledgerNavigatorTypes' diff --git a/src/features/ledger/DeviceScan.tsx b/src/features/ledger/DeviceScan.tsx index 270861023..2e44b9728 100644 --- a/src/features/ledger/DeviceScan.tsx +++ b/src/features/ledger/DeviceScan.tsx @@ -3,9 +3,9 @@ import { useTranslation } from 'react-i18next' import { FlatList, LayoutChangeEvent } from 'react-native' import { Device } from 'react-native-ble-plx' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import CarotRight from '@assets/images/carot-right.svg' -import LedgerCircle from '@assets/images/ledger-circle.svg' -import Ledger from '@assets/images/ledger.svg' +import CarotRight from '@assets/svgs/carot-right.svg' +import LedgerCircle from '@assets/svgs/ledger-circle.svg' +import Ledger from '@assets/svgs/ledger.svg' import { BottomSheetBackdrop, BottomSheetModal, @@ -16,7 +16,7 @@ import BackButton from '@components/BackButton' import Text from '@components/Text' import Box from '@components/Box' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useColors, useOpacity } from '@theme/themeHooks' +import { useColors, useOpacity } from '@config/theme/themeHooks' import useBackHandler from '@hooks/useBackHandler' import useLedgerDeviceScan from '@hooks/useLedgerDeviceScan' import LedgerConnectSteps from './LedgerConnectSteps' diff --git a/src/features/ledger/DeviceScanUsb.tsx b/src/features/ledger/DeviceScanUsb.tsx index d82f509a1..0bd2ab1a3 100644 --- a/src/features/ledger/DeviceScanUsb.tsx +++ b/src/features/ledger/DeviceScanUsb.tsx @@ -3,13 +3,13 @@ import TransportHID from '@ledgerhq/react-native-hid' import { useTranslation } from 'react-i18next' import { FlatList } from 'react-native' import { useNavigation } from '@react-navigation/native' -import CarotRight from '@assets/images/carot-right.svg' -import LedgerCircle from '@assets/images/ledger-circle.svg' -import Ledger from '@assets/images/ledger.svg' +import CarotRight from '@assets/svgs/carot-right.svg' +import LedgerCircle from '@assets/svgs/ledger-circle.svg' +import Ledger from '@assets/svgs/ledger.svg' import Text from '@components/Text' import Box from '@components/Box' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import SafeAreaBox from '@components/SafeAreaBox' import { LedgerNavigatorNavigationProp } from './ledgerNavigatorTypes' diff --git a/src/features/ledger/DeviceShow.tsx b/src/features/ledger/DeviceShow.tsx index a97621679..865e71e4f 100644 --- a/src/features/ledger/DeviceShow.tsx +++ b/src/features/ledger/DeviceShow.tsx @@ -3,25 +3,25 @@ import { ActivityIndicator, Image, SectionList } from 'react-native' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { useTranslation } from 'react-i18next' import { useAsync } from 'react-async-hook' -import Ledger from '@assets/images/ledger.svg' -import ArrowRight from '@assets/images/arrowRight.svg' +import Ledger from '@assets/svgs/ledger.svg' +import ArrowRight from '@assets/svgs/arrowRight.svg' import { TouchableOpacity } from 'react-native-gesture-handler' import Box from '@components/Box' import Text from '@components/Text' import ButtonPressable from '@components/ButtonPressable' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import BackButton from '@components/BackButton' -import { CSAccountVersion, CSAccounts } from '@storage/cloudStorage' +import { CSAccountVersion, CSAccounts } from '@config/storage/cloudStorage' import useLedger, { LedgerAccount } from '@hooks/useLedger' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' +import { + useAccountStorage, + MAX_ACCOUNTS, +} from '@config/storage/AccountStorageProvider' import { LedgerNavigatorNavigationProp, LedgerNavigatorStackParamList, } from './ledgerNavigatorTypes' -import { - useAccountStorage, - MAX_ACCOUNTS, -} from '../../storage/AccountStorageProvider' import LedgerAccountListItem, { Section } from './LedgerAccountListItem' type Route = RouteProp diff --git a/src/features/ledger/LedgerAccountListItem.tsx b/src/features/ledger/LedgerAccountListItem.tsx index 47b7dbce7..d4489f2e3 100644 --- a/src/features/ledger/LedgerAccountListItem.tsx +++ b/src/features/ledger/LedgerAccountListItem.tsx @@ -5,7 +5,7 @@ import Text from '@components/Text' import { toBN } from '@helium/spl-utils' import { LedgerAccount } from '@hooks/useLedger' import CheckBox from '@react-native-community/checkbox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { humanReadable } from '@utils/solanaUtils' import React, { memo, useCallback, useMemo } from 'react' import { ellipsizeAddress } from '../../utils/accountUtils' diff --git a/src/features/ledger/LedgerConnectSteps.tsx b/src/features/ledger/LedgerConnectSteps.tsx index 6ece8dd74..55526d5d8 100644 --- a/src/features/ledger/LedgerConnectSteps.tsx +++ b/src/features/ledger/LedgerConnectSteps.tsx @@ -1,11 +1,11 @@ import React, { memo } from 'react' import { useTranslation } from 'react-i18next' -import Check from '@assets/images/checkmark.svg' +import Check from '@assets/svgs/checkmark.svg' import { LayoutChangeEvent } from 'react-native' -import InfoError from '@assets/images/infoError.svg' +import InfoError from '@assets/svgs/infoError.svg' import Box from '@components/Box' import Text from '@components/Text' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import TouchableOpacityBox from '@components/TouchableOpacityBox' type Props = { diff --git a/src/features/ledger/LedgerModal.tsx b/src/features/ledger/LedgerModal.tsx index c89b42f4a..7d2cf9a9c 100644 --- a/src/features/ledger/LedgerModal.tsx +++ b/src/features/ledger/LedgerModal.tsx @@ -13,9 +13,9 @@ import useBackHandler from '@hooks/useBackHandler' import useLedger from '@hooks/useLedger' import { DeviceModelId } from '@ledgerhq/types-devices' import { BoxProps } from '@shopify/restyle' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { Theme } from '@theme/theme' -import { useColors, useOpacity } from '@theme/themeHooks' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { Theme } from '@config/theme/theme' +import { useColors, useOpacity } from '@config/theme/themeHooks' import { signLedgerMessage, signLedgerTransaction } from '@utils/heliumLedger' import React, { ReactNode, @@ -29,7 +29,6 @@ import React, { useState, } from 'react' import { useTranslation } from 'react-i18next' -import { useSharedValue } from 'react-native-reanimated' import Animation from './Animation' import LedgerConnectSteps from './LedgerConnectSteps' import { getDeviceAnimation } from './getDeviceAnimation' @@ -71,8 +70,6 @@ const LedgerModal = forwardRef( | 'enableBlindSign' >('loading') - const animatedContentHeight = useSharedValue(0) - const openAppAndSign = useCallback( async ({ transactionBuffer: tBuffer, @@ -341,7 +338,6 @@ const LedgerModal = forwardRef( backgroundStyle={backgroundStyle} backdropComponent={renderBackdrop} handleIndicatorStyle={handleIndicatorStyle} - contentHeight={animatedContentHeight} enableDynamicSizing > diff --git a/src/features/ledger/PairStart.tsx b/src/features/ledger/PairStart.tsx index b52a77b57..a3b41249f 100644 --- a/src/features/ledger/PairStart.tsx +++ b/src/features/ledger/PairStart.tsx @@ -1,13 +1,13 @@ import React, { memo, useCallback } from 'react' -import Ledger from '@assets/images/ledger.svg' +import Ledger from '@assets/svgs/ledger.svg' import { useTranslation } from 'react-i18next' import { useNavigation } from '@react-navigation/native' import Box from '@components/Box' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import Text from '@components/Text' import SafeAreaBox from '@components/SafeAreaBox' import ButtonPressable from '@components/ButtonPressable' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { AddNewAccountNavigationProp } from '../home/addNewAccount/addNewAccountTypes' const PairStart = () => { diff --git a/src/features/ledger/PairSuccess.tsx b/src/features/ledger/PairSuccess.tsx index 41a3251c3..d8b0848a4 100644 --- a/src/features/ledger/PairSuccess.tsx +++ b/src/features/ledger/PairSuccess.tsx @@ -1,14 +1,14 @@ import { useNavigation } from '@react-navigation/native' import React, { useCallback } from 'react' import { useTranslation } from 'react-i18next' -import Ledger from '@assets/images/ledger.svg' +import Ledger from '@assets/svgs/ledger.svg' import Box from '@components/Box' import Text from '@components/Text' import ButtonPressable from '@components/ButtonPressable' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { LedgerNavigatorNavigationProp } from './ledgerNavigatorTypes' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { RootNavigationProp } from '../../navigation/rootTypes' +import { RootNavigationProp } from '../../app/rootTypes' const PairSuccess = () => { const { t } = useTranslation() diff --git a/src/features/ledger/ledgerNavigatorTypes.tsx b/src/features/ledger/ledgerNavigatorTypes.tsx index 070bdbaf0..6146bad3b 100644 --- a/src/features/ledger/ledgerNavigatorTypes.tsx +++ b/src/features/ledger/ledgerNavigatorTypes.tsx @@ -1,5 +1,5 @@ import { StackNavigationProp } from '@react-navigation/stack' -import { LedgerDevice } from '../../storage/cloudStorage' +import { LedgerDevice } from '@config/storage/cloudStorage' export type LedgerNavigatorStackParamList = { DeviceChooseType: undefined diff --git a/src/features/lock/LockScreen.tsx b/src/features/lock/LockScreen.tsx index 9cb4252df..8ae0284f5 100644 --- a/src/features/lock/LockScreen.tsx +++ b/src/features/lock/LockScreen.tsx @@ -9,14 +9,14 @@ import { useTranslation } from 'react-i18next' import useAppState from 'react-native-appstate-hook' import { FadeIn, FadeOutDown } from 'react-native-reanimated' import { ThemeProvider } from '@shopify/restyle' -import { darkTheme } from '@theme/theme' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { useAppStorage } from '../../storage/AppStorageProvider' +import { darkTheme } from '@config/theme/theme' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' import { deleteSecureItem, getSecureItem, storeSecureItem, -} from '../../storage/secureStorage' +} from '@config/storage/secureStorage' type Props = { children: React.ReactNode } const LockScreen = ({ children }: Props) => { diff --git a/src/features/migration/SolanaMigration.tsx b/src/features/migration/SolanaMigration.tsx index ec01119d8..bf9ef4aeb 100644 --- a/src/features/migration/SolanaMigration.tsx +++ b/src/features/migration/SolanaMigration.tsx @@ -15,15 +15,15 @@ import IndeterminateProgressBar from '@components/IndeterminateProgressBar' import Text from '@components/Text' import ButtonPressable from '@components/ButtonPressable' import BackScreen from '@components/BackScreen' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import Config from 'react-native-config' import SafeAreaBox from '@components/SafeAreaBox' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { useAppStorage } from '../../storage/AppStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { useSolana } from '@features/solana/SolanaProvider' import * as Logger from '../../utils/logger' import { useAppDispatch } from '../../store/store' import { fetchHotspots } from '../../store/slices/hotspotsSlice' -import { useSolana } from '../../solana/SolanaProvider' async function migrateWallet( provider: Provider, diff --git a/src/features/modals/InsufficientSolConversionModal.tsx b/src/features/modals/InsufficientSolConversionModal.tsx index b52132aa9..572ab4599 100644 --- a/src/features/modals/InsufficientSolConversionModal.tsx +++ b/src/features/modals/InsufficientSolConversionModal.tsx @@ -17,9 +17,9 @@ import { import { useEcosystemTokenSolConvert } from '@hooks/useEcosystemTokensSolConvert' import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { PublicKey } from '@solana/web3.js' -import { useAppStorage } from '@storage/AppStorageProvider' -import { useModal } from '@storage/ModalsProvider' -import { useVisibleTokens } from '@storage/TokensProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { useModal } from '@config/storage/ModalsProvider' +import { useVisibleTokens } from '@config/storage/TokensProvider' import BN from 'bn.js' import React, { FC, @@ -32,8 +32,8 @@ import React, { import { useTranslation } from 'react-i18next' import { Switch } from 'react-native-gesture-handler' import { Edge } from 'react-native-safe-area-context' -import { useSolana } from '../../solana/SolanaProvider' -import * as Logger from '../../utils/logger' +import { useSolana } from '@features/solana/SolanaProvider' +import * as Logger from '@utils/logger' const InsufficientSolConversionModal: FC = () => { const { t } = useTranslation() diff --git a/src/features/notifications/AccountSlider.tsx b/src/features/notifications/AccountSlider.tsx index aed7118a0..01cb5c9e1 100644 --- a/src/features/notifications/AccountSlider.tsx +++ b/src/features/notifications/AccountSlider.tsx @@ -1,15 +1,15 @@ import React, { memo, useCallback, useMemo, useRef } from 'react' -import WalletUpdate from '@assets/images/walletUpdateIcon.svg' -import HeliumUpdate from '@assets/images/heliumUpdateIcon.svg' +import WalletUpdate from '@assets/svgs/walletUpdateIcon.svg' +import HeliumUpdate from '@assets/svgs/heliumUpdateIcon.svg' import { Carousel } from 'react-native-snap-carousel' import { StyleSheet } from 'react-native' import { useAsync } from 'react-async-hook' import AccountIcon from '@components/AccountIcon' import Box from '@components/Box' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useNotificationStorage } from '@config/storage/NotificationStorageProvider' import { wp } from '../../utils/layout' import AccountSliderIcon from './AccountSliderIcon' -import { useNotificationStorage } from '../../storage/NotificationStorageProvider' import { HELIUM_UPDATES_ITEM, WALLET_UPDATES_ITEM } from './notificationTypes' import { isValidAccountHash } from '../../utils/accountUtils' diff --git a/src/features/notifications/AccountSliderIcon.tsx b/src/features/notifications/AccountSliderIcon.tsx index 3a7bd7f5b..7066a4210 100644 --- a/src/features/notifications/AccountSliderIcon.tsx +++ b/src/features/notifications/AccountSliderIcon.tsx @@ -2,7 +2,7 @@ import React, { memo, useCallback, useMemo } from 'react' import TouchableOpacityBox from '@components/TouchableOpacityBox' import Box from '@components/Box' import { heliumAddressToSolAddress } from '@helium/spl-utils' -import { useNotificationStorage } from '../../storage/NotificationStorageProvider' +import { useNotificationStorage } from '@config/storage/NotificationStorageProvider' type Props = { icon: React.ReactNode diff --git a/src/features/notifications/NotificationDetailBanner.tsx b/src/features/notifications/NotificationDetailBanner.tsx index bfc2d1a22..4bef3de12 100644 --- a/src/features/notifications/NotificationDetailBanner.tsx +++ b/src/features/notifications/NotificationDetailBanner.tsx @@ -1,7 +1,7 @@ import React, { memo, useMemo } from 'react' import { Image } from 'react-native' import Box from '@components/Box' -import { useSpacing } from '@theme/themeHooks' +import { useSpacing } from '@config/theme/themeHooks' import { ww } from '../../utils/layout' const NotificationDetailBanner = ({ icon }: { icon: string }) => { diff --git a/src/features/notifications/NotificationDetails.tsx b/src/features/notifications/NotificationDetails.tsx index 9136e0369..1b715bd8e 100644 --- a/src/features/notifications/NotificationDetails.tsx +++ b/src/features/notifications/NotificationDetails.tsx @@ -8,14 +8,14 @@ import BackButton from '@components/BackButton' import usePrevious from '@hooks/usePrevious' import useMount from '@hooks/useMount' import { DelayedFadeIn } from '@components/FadeInOut' -import globalStyles from '@theme/globalStyles' +import globalStyles from '@config/theme/globalStyles' +import { useNotificationStorage } from '@config/storage/NotificationStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { NotificationsListStackParamList } from './notificationTypes' -import { useNotificationStorage } from '../../storage/NotificationStorageProvider' import NotificationDetailBanner from './NotificationDetailBanner' import parseMarkup from '../../utils/parseMarkup' import { useAppDispatch } from '../../store/store' import { markNotificationRead } from '../../store/slices/notificationsSlice' -import { useAccountStorage } from '../../storage/AccountStorageProvider' type Route = RouteProp diff --git a/src/features/notifications/NotificationsList.tsx b/src/features/notifications/NotificationsList.tsx index 5a747b2a5..c39506083 100644 --- a/src/features/notifications/NotificationsList.tsx +++ b/src/features/notifications/NotificationsList.tsx @@ -4,12 +4,12 @@ import { useTranslation } from 'react-i18next' import { SectionList } from 'react-native' import Box from '@components/Box' import Text from '@components/Text' -import { useSpacing } from '@theme/themeHooks' +import { useSpacing } from '@config/theme/themeHooks' import FadeInOut from '@components/FadeInOut' import useHaptic from '@hooks/useHaptic' import ScrollBox from '@components/ScrollBox' +import { useNotificationStorage } from '@config/storage/NotificationStorageProvider' import { NotificationsListNavigationProp } from './notificationTypes' -import { useNotificationStorage } from '../../storage/NotificationStorageProvider' import NotificationListItem from './NotificationListItem' import { Notification } from '../../utils/walletApiV2' diff --git a/src/features/notifications/NotificationsNavigator.tsx b/src/features/notifications/NotificationsNavigator.tsx index f36b62db3..f0bce4d62 100644 --- a/src/features/notifications/NotificationsNavigator.tsx +++ b/src/features/notifications/NotificationsNavigator.tsx @@ -1,6 +1,6 @@ import React, { memo } from 'react' import { createNativeStackNavigator } from '@react-navigation/native-stack' -import { useOpacity } from '@theme/themeHooks' +import { useOpacity } from '@config/theme/themeHooks' import NotificationsScreen from './NotificationsScreen' import NotificationDetails from './NotificationDetails' diff --git a/src/features/notifications/NotificationsScreen.tsx b/src/features/notifications/NotificationsScreen.tsx index 15f9574da..2273a3dd3 100644 --- a/src/features/notifications/NotificationsScreen.tsx +++ b/src/features/notifications/NotificationsScreen.tsx @@ -5,8 +5,8 @@ import Box from '@components/Box' import ButtonPressable from '@components/ButtonPressable' import { DelayedFadeIn } from '@components/FadeInOut' import { ReAnimatedBox } from '@components/AnimatedBox' +import { useNotificationStorage } from '@config/storage/NotificationStorageProvider' import AccountSlider from './AccountSlider' -import { useNotificationStorage } from '../../storage/NotificationStorageProvider' import NotificationsList from './NotificationsList' const NotificationsScreen = () => { diff --git a/src/features/onboarding/AccountAssignScreen.tsx b/src/features/onboarding/AccountAssignScreen.tsx index aee04fc8e..61f13c29b 100644 --- a/src/features/onboarding/AccountAssignScreen.tsx +++ b/src/features/onboarding/AccountAssignScreen.tsx @@ -10,9 +10,12 @@ import { heliumAddressFromSolAddress } from '@helium/spl-utils' import CheckBox from '@react-native-community/checkbox' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { Keypair } from '@solana/web3.js' -import { CSAccountVersion } from '@storage/cloudStorage' -import { storeSecureAccount, toSecureAccount } from '@storage/secureStorage' -import { useColors, useSpacing } from '@theme/themeHooks' +import { CSAccountVersion } from '@config/storage/cloudStorage' +import { + storeSecureAccount, + toSecureAccount, +} from '@config/storage/secureStorage' +import { useColors, useSpacing } from '@config/theme/themeHooks' import { createHash } from 'crypto' import React, { memo, useCallback, useMemo, useState } from 'react' import { useAsyncCallback } from 'react-async-hook' @@ -21,10 +24,10 @@ import { KeyboardAvoidingView, Platform, StyleSheet } from 'react-native' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { accountNetType } from '@utils/accountUtils' import { ResolvedPath } from '@hooks/useDerivationAccounts' -import { AccountsServiceStackParamList } from '@services/AccountsService' -import { RootNavigationProp } from '../../navigation/rootTypes' -import { useSolana } from '../../solana/SolanaProvider' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { AccountsServiceStackParamList } from 'src/app/services/AccountsService' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { RootNavigationProp } from '../../app/rootTypes' import { CreateAccountNavigationProp } from './create/createAccountNavTypes' import { ImportAccountNavigationProp } from './import/importAccountNavTypes' import { useOnboarding } from './OnboardingProvider' diff --git a/src/features/onboarding/AccountConfirmPinScreen.tsx b/src/features/onboarding/AccountConfirmPinScreen.tsx index b5a9a7887..9710f2579 100644 --- a/src/features/onboarding/AccountConfirmPinScreen.tsx +++ b/src/features/onboarding/AccountConfirmPinScreen.tsx @@ -2,14 +2,14 @@ import ConfirmPinView from '@components/ConfirmPinView' import { heliumAddressFromSolAddress } from '@helium/spl-utils' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { Keypair } from '@solana/web3.js' -import { toSecureAccount } from '@storage/secureStorage' +import { toSecureAccount } from '@config/storage/secureStorage' import React, { useCallback } from 'react' import { useTranslation } from 'react-i18next' import { ThemeProvider } from '@shopify/restyle' -import { darkTheme } from '@theme/theme' -import { RootNavigationProp } from '../../navigation/rootTypes' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { useAppStorage } from '../../storage/AppStorageProvider' +import { darkTheme } from '@config/theme/theme' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { RootNavigationProp } from '../../app/rootTypes' import { useOnboarding } from './OnboardingProvider' import { CreateAccountStackParamList } from './create/createAccountNavTypes' import { ImportAccountStackParamList } from './import/importAccountNavTypes' diff --git a/src/features/onboarding/AccountCreatePinScreen.tsx b/src/features/onboarding/AccountCreatePinScreen.tsx index 14bb19d8c..75c218902 100644 --- a/src/features/onboarding/AccountCreatePinScreen.tsx +++ b/src/features/onboarding/AccountCreatePinScreen.tsx @@ -7,7 +7,7 @@ import Keypad from '@components/Keypad' import Box from '@components/Box' import { KeypadInput } from '@components/KeypadButton' import { ThemeProvider } from '@shopify/restyle' -import { darkTheme } from '@theme/theme' +import { darkTheme } from '@config/theme/theme' import { CreateAccountNavigationProp, CreateAccountStackParamList, diff --git a/src/features/onboarding/CreateImportAccountScreen.tsx b/src/features/onboarding/CreateImportAccountScreen.tsx index 824a7ba07..337a46349 100644 --- a/src/features/onboarding/CreateImportAccountScreen.tsx +++ b/src/features/onboarding/CreateImportAccountScreen.tsx @@ -1,15 +1,15 @@ import { useNavigation } from '@react-navigation/native' import React, { memo, useCallback } from 'react' import { useTranslation } from 'react-i18next' -import Plus from '@assets/images/plus.svg' -import DownArrow from '@assets/images/importIcon.svg' -import Ledger from '@assets/images/ledger.svg' -import Keystone from '@assets/images/keystoneLogo.svg' +import Plus from '@assets/svgs/plus.svg' +import DownArrow from '@assets/svgs/importIcon.svg' +import Ledger from '@assets/svgs/ledger.svg' +import Keystone from '@assets/svgs/keystoneLogo.svg' import { useSafeAreaInsets } from 'react-native-safe-area-context' import Box from '@components/Box' import Text from '@components/Text' import SafeAreaBox from '@components/SafeAreaBox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import TouchableOpacityBox from '@components/TouchableOpacityBox' import BackgroundFill from '@components/BackgroundFill' import FinePrint from '@components/FinePrint' diff --git a/src/features/onboarding/NetTypeSegment.tsx b/src/features/onboarding/NetTypeSegment.tsx index 82d62c75b..b59aac73f 100644 --- a/src/features/onboarding/NetTypeSegment.tsx +++ b/src/features/onboarding/NetTypeSegment.tsx @@ -5,13 +5,13 @@ import { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { NetTypes as NetType } from '@helium/address' import { Platform, Switch } from 'react-native' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import TouchableOpacityBox from '@components/TouchableOpacityBox' import Text from '@components/Text' import Box from '@components/Box' -import { useColors, useHitSlop, useSpacing } from '@theme/themeHooks' +import { useColors, useHitSlop, useSpacing } from '@config/theme/themeHooks' +import { useAppStorage } from '@config/storage/AppStorageProvider' import { useOnboarding } from './OnboardingProvider' -import { useAppStorage } from '../../storage/AppStorageProvider' type Props = BoxProps const NetTypeSegment = (boxProps: Props) => { diff --git a/src/features/onboarding/OnboardingNavigator.tsx b/src/features/onboarding/OnboardingNavigator.tsx index b2f1ffef8..aaef1b935 100644 --- a/src/features/onboarding/OnboardingNavigator.tsx +++ b/src/features/onboarding/OnboardingNavigator.tsx @@ -5,7 +5,7 @@ import { } from '@react-navigation/stack' import React, { memo, useMemo } from 'react' import { ThemeProvider } from '@shopify/restyle' -import { darkTheme } from '@theme/theme' +import { darkTheme } from '@config/theme/theme' import LedgerNavigator from '../ledger/LedgerNavigator' import CreateImportAccountScreen from './CreateImportAccountScreen' import CreateAccountNavigator from './create/CreateAccountNavigator' diff --git a/src/features/onboarding/OnboardingProvider.tsx b/src/features/onboarding/OnboardingProvider.tsx index 0afe6caea..822239f11 100644 --- a/src/features/onboarding/OnboardingProvider.tsx +++ b/src/features/onboarding/OnboardingProvider.tsx @@ -10,7 +10,7 @@ import React, { useMemo, useState, } from 'react' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' type OnboardingData = { account?: CSAccount diff --git a/src/features/onboarding/cli-import/CLIAccountImportStartScreen.tsx b/src/features/onboarding/cli-import/CLIAccountImportStartScreen.tsx index 7b69b17c7..fd379fabb 100644 --- a/src/features/onboarding/cli-import/CLIAccountImportStartScreen.tsx +++ b/src/features/onboarding/cli-import/CLIAccountImportStartScreen.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useMemo } from 'react' import { useNavigation } from '@react-navigation/native' import { Edge } from 'react-native-safe-area-context' import { useTranslation } from 'react-i18next' -import Terminal from '@assets/images/terminal.svg' +import Terminal from '@assets/svgs/terminal.svg' import Text from '@components/Text' import SafeAreaBox from '@components/SafeAreaBox' import ButtonPressable from '@components/ButtonPressable' diff --git a/src/features/onboarding/cli-import/CLIAccountNavigator.tsx b/src/features/onboarding/cli-import/CLIAccountNavigator.tsx index 089c2905a..525f78c8a 100644 --- a/src/features/onboarding/cli-import/CLIAccountNavigator.tsx +++ b/src/features/onboarding/cli-import/CLIAccountNavigator.tsx @@ -1,6 +1,6 @@ import * as React from 'react' import { createStackNavigator } from '@react-navigation/stack' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import CLIAccountImportStartScreen from './CLIAccountImportStartScreen' import CLIPasswordScreen from './CLIPasswordScreen' import CLIQrScanner from './CLIQrScanner' diff --git a/src/features/onboarding/cli-import/CLIPasswordScreen.tsx b/src/features/onboarding/cli-import/CLIPasswordScreen.tsx index 409231ee6..c2fb5886a 100644 --- a/src/features/onboarding/cli-import/CLIPasswordScreen.tsx +++ b/src/features/onboarding/cli-import/CLIPasswordScreen.tsx @@ -1,4 +1,4 @@ -import Terminal from '@assets/images/terminal.svg' +import Terminal from '@assets/svgs/terminal.svg' import Box from '@components/Box' import ButtonPressable from '@components/ButtonPressable' import CloseButton from '@components/CloseButton' @@ -8,7 +8,7 @@ import TextInput from '@components/TextInput' import useAlert from '@hooks/useAlert' import { HELIUM_DERIVATION } from '@hooks/useDerivationAccounts' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { createKeypair } from '@storage/secureStorage' +import { createKeypair } from '@config/storage/secureStorage' import React, { useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { TextStyle } from 'react-native' diff --git a/src/features/onboarding/create/AccountCreatePassphraseScreen.tsx b/src/features/onboarding/create/AccountCreatePassphraseScreen.tsx index 3bd07809e..d589b79a4 100644 --- a/src/features/onboarding/create/AccountCreatePassphraseScreen.tsx +++ b/src/features/onboarding/create/AccountCreatePassphraseScreen.tsx @@ -1,14 +1,17 @@ -import Close from '@assets/images/close.svg' -import InfoError from '@assets/images/infoError.svg' +import Close from '@assets/svgs/close.svg' +import InfoError from '@assets/svgs/infoError.svg' import Box from '@components/Box' import CircleLoader from '@components/CircleLoader' import RevealWords from '@components/RevealWords' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' import { useNavigation } from '@react-navigation/native' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { DEFAULT_DERIVATION_PATH, createKeypair } from '@storage/secureStorage' -import { useColors } from '@theme/themeHooks' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { + DEFAULT_DERIVATION_PATH, + createKeypair, +} from '@config/storage/secureStorage' +import { useColors } from '@config/theme/themeHooks' import React, { memo, useCallback, useMemo } from 'react' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' diff --git a/src/features/onboarding/create/AccountCreateStart.tsx b/src/features/onboarding/create/AccountCreateStart.tsx index 044f9ac6e..62f90355b 100644 --- a/src/features/onboarding/create/AccountCreateStart.tsx +++ b/src/features/onboarding/create/AccountCreateStart.tsx @@ -1,14 +1,14 @@ import React, { memo, useCallback } from 'react' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { useTranslation } from 'react-i18next' -import CreateAccount from '@assets/images/createAccount.svg' +import CreateAccount from '@assets/svgs/createAccount.svg' import { useNavigation } from '@react-navigation/native' import Box from '@components/Box' import Text from '@components/Text' import ButtonPressable from '@components/ButtonPressable' import CloseButton from '@components/CloseButton' import SafeAreaBox from '@components/SafeAreaBox' -import { useAccountStorage } from '../../../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { CreateAccountNavigationProp } from './createAccountNavTypes' type Props = { onCreate: () => void; inline?: boolean } diff --git a/src/features/onboarding/create/ConfirmWordsScreen.tsx b/src/features/onboarding/create/ConfirmWordsScreen.tsx index 1307ce173..1a868eb28 100644 --- a/src/features/onboarding/create/ConfirmWordsScreen.tsx +++ b/src/features/onboarding/create/ConfirmWordsScreen.tsx @@ -6,8 +6,8 @@ import Box from '@components/Box' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' import CloseButton from '@components/CloseButton' -import { Color } from '@theme/theme' -import { useColors, usePaddingStyle } from '@theme/themeHooks' +import { Color } from '@config/theme/theme' +import { useColors, usePaddingStyle } from '@config/theme/themeHooks' import { upperCase } from 'lodash' import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view' import useHaptic from '@hooks/useHaptic' diff --git a/src/features/onboarding/create/CreateAccountNavigator.tsx b/src/features/onboarding/create/CreateAccountNavigator.tsx index 215c34ccb..cfeeec13d 100644 --- a/src/features/onboarding/create/CreateAccountNavigator.tsx +++ b/src/features/onboarding/create/CreateAccountNavigator.tsx @@ -4,13 +4,13 @@ import { StackNavigationOptions, } from '@react-navigation/stack' import { memo } from 'react' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import AccountCreatePassphraseScreen from './AccountCreatePassphraseScreen' import AccountEnterPassphraseScreen from './AccountEnterPassphraseScreen' import { CreateAccountStackParamList } from './createAccountNavTypes' import AccountAssignScreen from '../AccountAssignScreen' import AccountCreatePinScreen from '../AccountCreatePinScreen' import AccountConfirmPinScreen from '../AccountConfirmPinScreen' -import { useAccountStorage } from '../../../storage/AccountStorageProvider' import AccountCreateStartScreen from './AccountCreateStartScreen' const CreateAccountStack = createStackNavigator() diff --git a/src/features/onboarding/create/PhraseChip.tsx b/src/features/onboarding/create/PhraseChip.tsx index 4718e6b35..f99ba8987 100644 --- a/src/features/onboarding/create/PhraseChip.tsx +++ b/src/features/onboarding/create/PhraseChip.tsx @@ -1,15 +1,15 @@ /* eslint-disable react/jsx-props-no-spreading */ import React, { useState, memo, useCallback } from 'react' import { upperCase } from 'lodash' -import CheckMark from '@assets/images/checkmark.svg' -import Fail from '@assets/images/fail.svg' +import CheckMark from '@assets/svgs/checkmark.svg' +import Fail from '@assets/svgs/fail.svg' import Text from '@components/Text' import TouchableHighlightBox, { TouchableHighlightBoxProps, } from '@components/TouchableHighlightBox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import Box from '@components/Box' -import { Color } from '@theme/theme' +import { Color } from '@config/theme/theme' type Props = Omit & { title: string diff --git a/src/features/onboarding/import/AccountImportScreen.tsx b/src/features/onboarding/import/AccountImportScreen.tsx index dd2dee383..61b06008a 100644 --- a/src/features/onboarding/import/AccountImportScreen.tsx +++ b/src/features/onboarding/import/AccountImportScreen.tsx @@ -1,11 +1,11 @@ -import Close from '@assets/images/close.svg' +import Close from '@assets/svgs/close.svg' import Box from '@components/Box' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' import useAlert from '@hooks/useAlert' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { Color } from '@theme/theme' -import { useColors, usePaddingStyle } from '@theme/themeHooks' +import { Color } from '@config/theme/theme' +import { useColors, usePaddingStyle } from '@config/theme/themeHooks' import { upperCase } from 'lodash' import React, { useCallback, useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' @@ -13,9 +13,9 @@ import { FlatList } from 'react-native' import { KeyboardAwareScrollView } from 'react-native-keyboard-aware-scroll-view' import { MAIN_DERIVATION_PATHS } from '@hooks/useDerivationAccounts' import { Keypair } from '@solana/web3.js' -import { CSAccount } from '@storage/cloudStorage' -import { useAccountStorage } from '../../../storage/AccountStorageProvider' -import { createKeypair, toSecureAccount } from '../../../storage/secureStorage' +import { CSAccount } from '@config/storage/cloudStorage' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { createKeypair, toSecureAccount } from '@config/storage/secureStorage' import { useOnboarding } from '../OnboardingProvider' import { OnboardingNavigationProp } from '../onboardingTypes' import PassphraseAutocomplete from './PassphraseAutocomplete' diff --git a/src/features/onboarding/import/AccountImportStartScreen.tsx b/src/features/onboarding/import/AccountImportStartScreen.tsx index c573c9d71..a8abb4eee 100644 --- a/src/features/onboarding/import/AccountImportStartScreen.tsx +++ b/src/features/onboarding/import/AccountImportStartScreen.tsx @@ -9,12 +9,12 @@ import ButtonPressable from '@components/ButtonPressable' import TextTransform from '@components/TextTransform' import SafeAreaBox from '@components/SafeAreaBox' import CloseButton from '@components/CloseButton' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { ImportAccountNavigationProp } from './importAccountNavTypes' -import { useAccountStorage } from '../../../storage/AccountStorageProvider' import { useOnboarding } from '../OnboardingProvider' import { MultiAccountStackParamList } from '../multiAccount/MultiAccountNavigatorTypes' import { AddNewAccountNavigationProp } from '../../home/addNewAccount/addNewAccountTypes' -import { RootNavigationProp } from '../../../navigation/rootTypes' +import { RootNavigationProp } from '../../../app/rootTypes' type Route = RouteProp diff --git a/src/features/onboarding/import/ImportAccountNavigator.tsx b/src/features/onboarding/import/ImportAccountNavigator.tsx index bcb0e4c47..5328d66b1 100644 --- a/src/features/onboarding/import/ImportAccountNavigator.tsx +++ b/src/features/onboarding/import/ImportAccountNavigator.tsx @@ -3,13 +3,13 @@ import { createStackNavigator, StackNavigationOptions, } from '@react-navigation/stack' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { ImportAccountStackParamList } from './importAccountNavTypes' import AccountImportStartScreen from './AccountImportStartScreen' import AccountImportScreen from './AccountImportScreen' import AccountAssignScreen from '../AccountAssignScreen' import AccountCreatePinScreen from '../AccountCreatePinScreen' import AccountConfirmPinScreen from '../AccountConfirmPinScreen' -import { useAccountStorage } from '../../../storage/AccountStorageProvider' import CLIAccountNavigator from '../cli-import/CLIAccountNavigator' import ImportSubAccountsScreen from './ImportSubAccountsScreen' diff --git a/src/features/onboarding/import/ImportPrivateKey.tsx b/src/features/onboarding/import/ImportPrivateKey.tsx index bd50c5bd9..c831151a0 100644 --- a/src/features/onboarding/import/ImportPrivateKey.tsx +++ b/src/features/onboarding/import/ImportPrivateKey.tsx @@ -14,12 +14,12 @@ import React, { memo, useCallback, useState } from 'react' import { useAsync, useAsyncCallback } from 'react-async-hook' import { useTranslation } from 'react-i18next' import RNSodium from 'react-native-sodium' -import { RootNavigationProp } from '../../../navigation/rootTypes' -import { useAccountStorage } from '../../../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { DEFAULT_DERIVATION_PATH, createKeypair, -} from '../../../storage/secureStorage' +} from '@config/storage/secureStorage' +import { RootNavigationProp } from '../../../app/rootTypes' import * as Logger from '../../../utils/logger' import { useOnboarding } from '../OnboardingProvider' import { OnboardingStackParamList } from '../onboardingTypes' diff --git a/src/features/onboarding/import/ImportReplaceWordModal.tsx b/src/features/onboarding/import/ImportReplaceWordModal.tsx index ef1594041..35ef755a3 100644 --- a/src/features/onboarding/import/ImportReplaceWordModal.tsx +++ b/src/features/onboarding/import/ImportReplaceWordModal.tsx @@ -1,13 +1,13 @@ import React, { useCallback, useEffect, useState } from 'react' import { Modal } from 'react-native' import { useTranslation } from 'react-i18next' -import Close from '@assets/images/close.svg' -import wordlist from '@constants/wordlists/english.json' +import Close from '@assets/svgs/close.svg' +import wordlist from '@utils/constants/wordlists/english.json' import TextInput from '@components/TextInput' import Box from '@components/Box' import SafeAreaBox from '@components/SafeAreaBox' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import ScrollBox from '@components/ScrollBox' import MatchingWord from './MatchingWord' diff --git a/src/features/onboarding/import/ImportSubAccountsScreen.tsx b/src/features/onboarding/import/ImportSubAccountsScreen.tsx index 0dcacc49e..6deb91fe7 100644 --- a/src/features/onboarding/import/ImportSubAccountsScreen.tsx +++ b/src/features/onboarding/import/ImportSubAccountsScreen.tsx @@ -9,17 +9,17 @@ import { } from '@hooks/useDerivationAccounts' import CheckBox from '@react-native-community/checkbox' import { useNavigation } from '@react-navigation/native' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { DEFAULT_DERIVATION_PATH } from '@storage/secureStorage' -import { useColors } from '@theme/themeHooks' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { DEFAULT_DERIVATION_PATH } from '@config/storage/secureStorage' +import { useColors } from '@config/theme/themeHooks' import { ellipsizeAddress } from '@utils/accountUtils' import { humanReadable } from '@utils/formatting' import BN from 'bn.js' import React, { useCallback, useEffect, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { FlatList, RefreshControl } from 'react-native' -import { RootNavigationProp } from 'src/navigation/rootTypes' -import { AccountsServiceNavigationProp } from '@services/AccountsService/accountServiceTypes' +import { RootNavigationProp } from 'src/app/rootTypes' +import { AccountsServiceNavigationProp } from 'src/app/services/AccountsService/accountServiceTypes' import ScrollBox from '@components/ScrollBox' import { useOnboarding } from '../OnboardingProvider' diff --git a/src/features/onboarding/import/PassphraseAutocomplete.tsx b/src/features/onboarding/import/PassphraseAutocomplete.tsx index 5677f1aa4..52d83b595 100644 --- a/src/features/onboarding/import/PassphraseAutocomplete.tsx +++ b/src/features/onboarding/import/PassphraseAutocomplete.tsx @@ -1,12 +1,12 @@ import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { upperCase } from 'lodash' -import wordlist from '@constants/wordlists/english.json' +import wordlist from '@utils/constants/wordlists/english.json' import TextInput from '@components/TextInput' import Box from '@components/Box' import FabButton from '@components/FabButton' import usePrevious from '@hooks/usePrevious' -import { Color } from '@theme/theme' +import { Color } from '@config/theme/theme' import Clipboard from '@react-native-community/clipboard' import ScrollBox from '@components/ScrollBox' import { ScrollView } from 'react-native-gesture-handler' diff --git a/src/features/payment/PaymentCard.tsx b/src/features/payment/PaymentCard.tsx index e5e515f4e..ecdf01e3d 100644 --- a/src/features/payment/PaymentCard.tsx +++ b/src/features/payment/PaymentCard.tsx @@ -5,8 +5,8 @@ import BN from 'bn.js' import React, { memo, useCallback } from 'react' import { useTranslation } from 'react-i18next' import ButtonPressable from '@components/ButtonPressable' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { checkSecureAccount } from '../../storage/secureStorage' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { checkSecureAccount } from '@config/storage/secureStorage' import { SendDetails } from '../../utils/linking' import PaymentSummary from './PaymentSummary' diff --git a/src/features/payment/PaymentError.tsx b/src/features/payment/PaymentError.tsx index 04d4badfe..c4010c487 100644 --- a/src/features/payment/PaymentError.tsx +++ b/src/features/payment/PaymentError.tsx @@ -1,4 +1,4 @@ -import FailureIcon from '@assets/images/paymentFailure.svg' +import FailureIcon from '@assets/svgs/paymentFailure.svg' import BackgroundFill from '@components/BackgroundFill' import Box from '@components/Box' import Text from '@components/Text' diff --git a/src/features/payment/PaymentItem.tsx b/src/features/payment/PaymentItem.tsx index 8b6ec1753..7bcdce2ba 100644 --- a/src/features/payment/PaymentItem.tsx +++ b/src/features/payment/PaymentItem.tsx @@ -1,5 +1,5 @@ -import AddressIcon from '@assets/images/addressIcon.svg' -import Remove from '@assets/images/remove.svg' +import AddressIcon from '@assets/svgs/addressIcon.svg' +import Remove from '@assets/svgs/remove.svg' import Box from '@components/Box' import MemoInput from '@components/MemoInput' import Text from '@components/Text' @@ -8,8 +8,8 @@ import TouchableOpacityBox from '@components/TouchableOpacityBox' import { useMint } from '@helium/helium-react-hooks' import { BoxProps } from '@shopify/restyle' import { PublicKey } from '@solana/web3.js' -import { Theme } from '@theme/theme' -import { useColors } from '@theme/themeHooks' +import { Theme } from '@config/theme/theme' +import { useColors } from '@config/theme/themeHooks' import { humanReadable } from '@utils/solanaUtils' import BN from 'bn.js' import { toUpper } from 'lodash' @@ -22,7 +22,7 @@ import { } from 'react-native' import { useDebounce } from 'use-debounce' import { shortenAddress } from '@utils/formatting' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import { useBalance } from '../../utils/Balance' import { accountNetType, diff --git a/src/features/payment/PaymentQrScanner.tsx b/src/features/payment/PaymentQrScanner.tsx index 6b8e938eb..74c69fd57 100644 --- a/src/features/payment/PaymentQrScanner.tsx +++ b/src/features/payment/PaymentQrScanner.tsx @@ -4,8 +4,8 @@ import { useNavigation } from '@react-navigation/native' import useHaptic from '@hooks/useHaptic' import useAlert from '@hooks/useAlert' import QrScanner from '@components/QrScanner' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' -import { SendNavigationProp } from '@services/WalletService/pages/SendPage/SentPageNavigator' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' +import { SendNavigationProp } from '@services/WalletService/pages/SendPage' import { parseBurn, parseDelegate, parsePaymentLink } from '../../utils/linking' const PaymentQrScanner = () => { diff --git a/src/features/payment/PaymentScreen.tsx b/src/features/payment/PaymentScreen.tsx index 2cac0e449..fadc09edc 100644 --- a/src/features/payment/PaymentScreen.tsx +++ b/src/features/payment/PaymentScreen.tsx @@ -19,7 +19,7 @@ import { usePublicKey } from '@hooks/usePublicKey' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { NATIVE_MINT } from '@solana/spl-token' import { PublicKey } from '@solana/web3.js' -import { useVisibleTokens } from '@storage/TokensProvider' +import { useVisibleTokens } from '@config/storage/TokensProvider' import { Mints } from '@utils/constants' import { fetchDomainOwner } from '@utils/getDomainOwner' import { @@ -43,19 +43,19 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context' import Toast from 'react-native-simple-toast' import { useSelector } from 'react-redux' import { NavBarHeight } from '@components/ServiceNavBar' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' -import { PaymentRouteParam } from '@services/WalletService' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' +import { PaymentRouteParam } from 'src/app/services/WalletService' import ScrollBox from '@components/ScrollBox' import { SendNavigationProp, SendStackParamList, -} from '@services/WalletService/pages/SendPage/SentPageNavigator' +} from '@services/WalletService/pages/SendPage' import { useAsyncCallback } from 'react-async-hook' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { CSAccount } from '@config/storage/cloudStorage' +import { RootNavigationProp } from '../../app/rootTypes' import useSubmitTxn from '../../hooks/useSubmitTxn' -import { RootNavigationProp } from '../../navigation/rootTypes' -import { useSolana } from '../../solana/SolanaProvider' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { CSAccount } from '../../storage/cloudStorage' import { RootState } from '../../store/rootReducer' import { solanaSlice } from '../../store/slices/solanaSlice' import { useAppDispatch } from '../../store/store' diff --git a/src/features/payment/PaymentSubmit.tsx b/src/features/payment/PaymentSubmit.tsx index 3edd1e90c..7cadcc784 100644 --- a/src/features/payment/PaymentSubmit.tsx +++ b/src/features/payment/PaymentSubmit.tsx @@ -2,7 +2,7 @@ import Box from '@components/Box' import FadeInOut from '@components/FadeInOut' import { SerializedError } from '@reduxjs/toolkit' import { PublicKey } from '@solana/web3.js' -import globalStyles from '@theme/globalStyles' +import globalStyles from '@config/theme/globalStyles' import BN from 'bn.js' import React, { memo, useCallback, useEffect, useMemo, useState } from 'react' import { StyleSheet } from 'react-native' diff --git a/src/features/payment/PaymentSubmitLoading.tsx b/src/features/payment/PaymentSubmitLoading.tsx index 00d91c528..9645285d3 100644 --- a/src/features/payment/PaymentSubmitLoading.tsx +++ b/src/features/payment/PaymentSubmitLoading.tsx @@ -7,7 +7,7 @@ import Text from '@components/Text' import Box from '@components/Box' import ActivityIndicator from '@components/ActivityIndicator' import FadeInOut from '@components/FadeInOut' -import globalStyles from '@theme/globalStyles' +import globalStyles from '@config/theme/globalStyles' type Props = { onVideoEnd: () => void diff --git a/src/features/payment/PaymentSuccess.tsx b/src/features/payment/PaymentSuccess.tsx index 3abf025ef..ef81c5df9 100644 --- a/src/features/payment/PaymentSuccess.tsx +++ b/src/features/payment/PaymentSuccess.tsx @@ -1,4 +1,4 @@ -import SuccessIcon from '@assets/images/paymentSuccess.svg' +import SuccessIcon from '@assets/svgs/paymentSuccess.svg' import Box from '@components/Box' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' diff --git a/src/features/payment/usePaymentsReducer.ts b/src/features/payment/usePaymentsReducer.ts index 847bced9d..4d6d02c5e 100644 --- a/src/features/payment/usePaymentsReducer.ts +++ b/src/features/payment/usePaymentsReducer.ts @@ -3,7 +3,7 @@ import { PublicKey } from '@solana/web3.js' import BN from 'bn.js' import { useReducer } from 'react' import { NATIVE_MINT } from '@solana/spl-token' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import { TXN_FEE_IN_LAMPORTS } from '../../utils/solanaUtils' import { Payment } from './PaymentItem' diff --git a/src/features/settings/AutoGasManager.tsx b/src/features/settings/AutoGasManager.tsx index 26fbb8bd9..8be765507 100644 --- a/src/features/settings/AutoGasManager.tsx +++ b/src/features/settings/AutoGasManager.tsx @@ -6,8 +6,8 @@ import TokenPill from '@components/TokenPill' import { HNT_MINT, IOT_MINT, MOBILE_MINT } from '@helium/spl-utils' import { useNavigation } from '@react-navigation/native' import { PublicKey } from '@solana/web3.js' -import { useAppStorage } from '@storage/AppStorageProvider' -import { useVisibleTokens } from '@storage/TokensProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { useVisibleTokens } from '@config/storage/TokensProvider' import React, { FC, useCallback, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { Switch } from 'react-native' diff --git a/src/features/settings/ConfirmSignoutScreen.tsx b/src/features/settings/ConfirmSignoutScreen.tsx index 1769375fe..26c93b4ff 100644 --- a/src/features/settings/ConfirmSignoutScreen.tsx +++ b/src/features/settings/ConfirmSignoutScreen.tsx @@ -4,15 +4,15 @@ import { useNavigation } from '@react-navigation/native' import { ActivityIndicator, Alert, Platform } from 'react-native' import { useAsync } from 'react-async-hook' import useAlert from '@hooks/useAlert' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import Box from '@components/Box' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' -import ConfirmWordsScreen from '../onboarding/create/ConfirmWordsScreen' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { useAppStorage } from '../../storage/AppStorageProvider' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { getSecureAccount } from '@config/storage/secureStorage' import { SettingsNavigationProp } from './settingsTypes' -import { getSecureAccount } from '../../storage/secureStorage' -import { RootNavigationProp } from '../../navigation/rootTypes' +import ConfirmWordsScreen from '../onboarding/create/ConfirmWordsScreen' +import { RootNavigationProp } from '../../app/rootTypes' const ConfirmSignoutScreen = () => { const { t } = useTranslation() diff --git a/src/features/settings/RevealPrivateKeyScreen.tsx b/src/features/settings/RevealPrivateKeyScreen.tsx index 22e2178c3..2f81d040a 100644 --- a/src/features/settings/RevealPrivateKeyScreen.tsx +++ b/src/features/settings/RevealPrivateKeyScreen.tsx @@ -9,8 +9,8 @@ import TouchableOpacityBox from '@components/TouchableOpacityBox' import CopyAddress from '@components/CopyAddress' import useAlert from '@hooks/useAlert' import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes' -import { getSecureAccount } from '../../storage/secureStorage' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { getSecureAccount } from '@config/storage/secureStorage' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' const RevealPrivateKeyScreen = () => { const { currentAccount } = useAccountStorage() diff --git a/src/features/settings/RevealWordsScreen.tsx b/src/features/settings/RevealWordsScreen.tsx index c6cb9b69c..ed436a114 100644 --- a/src/features/settings/RevealWordsScreen.tsx +++ b/src/features/settings/RevealWordsScreen.tsx @@ -2,11 +2,11 @@ import React, { memo, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { useAsync } from 'react-async-hook' import { useNavigation } from '@react-navigation/native' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import Box from '@components/Box' import BackScreen from '@components/BackScreen' import TextTransform from '@components/TextTransform' -import { getSecureAccount } from '@storage/secureStorage' +import { getSecureAccount } from '@config/storage/secureStorage' import RevealWords from '@components/RevealWords' import ScrollBox from '@components/ScrollBox' diff --git a/src/features/settings/Settings.tsx b/src/features/settings/Settings.tsx index 3e091be71..4f8b8d721 100644 --- a/src/features/settings/Settings.tsx +++ b/src/features/settings/Settings.tsx @@ -7,25 +7,25 @@ import { useAppVersion } from '@hooks/useDevice' import { useExplorer } from '@hooks/useExplorer' import { useNavigation } from '@react-navigation/native' import { Cluster } from '@solana/web3.js' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import React, { ReactText, memo, useCallback, useMemo } from 'react' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { Alert, Linking, Platform, SectionList } from 'react-native' import deviceInfo from 'react-native-device-info' import { SvgUri } from 'react-native-svg' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' import ScrollBox from '@components/ScrollBox' -import { PRIVACY_POLICY, TERMS_OF_SERVICE } from '../../constants/urls' -import { RootNavigationProp } from '../../navigation/rootTypes' -import { useSolana } from '../../solana/SolanaProvider' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { useAppStorage } from '../../storage/AppStorageProvider' -import { useLanguageStorage } from '../../storage/LanguageProvider' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { useLanguageStorage } from '@config/storage/LanguageProvider' import { checkSecureAccount, getSecureAccount, -} from '../../storage/secureStorage' +} from '@config/storage/secureStorage' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' +import { RootNavigationProp } from '../../app/rootTypes' +import { PRIVACY_POLICY, TERMS_OF_SERVICE } from '../../utils/constants/urls' import { persistor } from '../../store/persistence' import { SUPPORTED_LANGUAGUES } from '../../utils/i18n' import SUPPORTED_CURRENCIES from '../../utils/supportedCurrencies' diff --git a/src/features/settings/SettingsConfirmPinScreen.tsx b/src/features/settings/SettingsConfirmPinScreen.tsx index 5e8f1ffbc..f243b1ba3 100644 --- a/src/features/settings/SettingsConfirmPinScreen.tsx +++ b/src/features/settings/SettingsConfirmPinScreen.tsx @@ -3,8 +3,8 @@ import { useTranslation } from 'react-i18next' import { RouteProp, useRoute, useNavigation } from '@react-navigation/native' import ConfirmPinView from '@components/ConfirmPinView' import { ThemeProvider } from '@shopify/restyle' -import { darkTheme } from '@theme/theme' -import { useAppStorage } from '../../storage/AppStorageProvider' +import { darkTheme } from '@config/theme/theme' +import { useAppStorage } from '@config/storage/AppStorageProvider' import { SettingsNavigationProp, SettingsStackParamList } from './settingsTypes' type Route = RouteProp diff --git a/src/features/settings/SettingsCreatePinScreen.tsx b/src/features/settings/SettingsCreatePinScreen.tsx index 1ced39c85..2e6b9e5e0 100644 --- a/src/features/settings/SettingsCreatePinScreen.tsx +++ b/src/features/settings/SettingsCreatePinScreen.tsx @@ -7,7 +7,7 @@ import Keypad from '@components/Keypad' import Box from '@components/Box' import { KeypadInput } from '@components/KeypadButton' import { ThemeProvider } from '@shopify/restyle' -import { darkTheme } from '@theme/theme' +import { darkTheme } from '@config/theme/theme' import { SettingsNavigationProp } from './settingsTypes' const SettingsCreatePinScreen = () => { diff --git a/src/features/settings/SettingsListItem.tsx b/src/features/settings/SettingsListItem.tsx index ec82f5647..e2acec530 100644 --- a/src/features/settings/SettingsListItem.tsx +++ b/src/features/settings/SettingsListItem.tsx @@ -1,16 +1,16 @@ import React, { memo, ReactText, useCallback, useMemo, useRef } from 'react' import { Linking, Platform, Switch } from 'react-native' -import CarotRight from '@assets/images/carot-right.svg' -import LinkImg from '@assets/images/link.svg' +import CarotRight from '@assets/svgs/carot-right.svg' +import LinkImg from '@assets/svgs/link.svg' import { HeliumActionSheetItemType } from '@components/HeliumActionSheetItem' import Text, { TextProps } from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' -import { Color } from '@theme/theme' +import { Color } from '@config/theme/theme' import HeliumActionSheet, { HeliumActionSheetRef, } from '@components/HeliumActionSheet' import Box from '@components/Box' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { hp } from '@utils/layout' import sleep from '@utils/sleep' diff --git a/src/features/settings/SettingsNavigator.tsx b/src/features/settings/SettingsNavigator.tsx index 2769deff6..c4d2fff8e 100644 --- a/src/features/settings/SettingsNavigator.tsx +++ b/src/features/settings/SettingsNavigator.tsx @@ -1,5 +1,5 @@ import { createNativeStackNavigator } from '@react-navigation/native-stack' -import { useOpacity } from '@theme/themeHooks' +import { useOpacity } from '@config/theme/themeHooks' import React, { memo } from 'react' import SecretKeyWarningScreen from '@components/SecretKeyWarningScreen' import SolanaMigration from '../migration/SolanaMigration' diff --git a/src/features/settings/ShareAddressScreen.tsx b/src/features/settings/ShareAddressScreen.tsx index 759c5ce6c..326b9c859 100644 --- a/src/features/settings/ShareAddressScreen.tsx +++ b/src/features/settings/ShareAddressScreen.tsx @@ -1,4 +1,4 @@ -import ShareAddress from '@assets/images/shareAddress.svg' +import ShareAddress from '@assets/svgs/shareAddress.svg' import BackScreen from '@components/BackScreen' import Box from '@components/Box' import CopyAddress from '@components/CopyAddress' @@ -6,9 +6,9 @@ import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' import useCopyText from '@hooks/useCopyText' import useHaptic from '@hooks/useHaptic' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { Spacing } from '@theme/theme' -import { useSpacing } from '@theme/themeHooks' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { Spacing } from '@config/theme/theme' +import { useSpacing } from '@config/theme/themeHooks' import { ellipsizeAddress } from '@utils/accountUtils' import React, { memo, useCallback, useMemo, useRef } from 'react' import { useTranslation } from 'react-i18next' diff --git a/src/features/settings/UpdateAliasScreen.tsx b/src/features/settings/UpdateAliasScreen.tsx index 236a4b611..4702cd9d1 100644 --- a/src/features/settings/UpdateAliasScreen.tsx +++ b/src/features/settings/UpdateAliasScreen.tsx @@ -5,9 +5,9 @@ import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useTranslation } from 'react-i18next' import Box from '@components/Box' import TextInput from '@components/TextInput' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import FabButton from '@components/FabButton' -import { useSpacing } from '@theme/themeHooks' +import { useSpacing } from '@config/theme/themeHooks' import AccountIcon from '@components/AccountIcon' import BackScreen from '@components/BackScreen' import { SettingsNavigationProp } from './settingsTypes' diff --git a/src/solana/AsyncAccountCache.ts b/src/features/solana/AsyncAccountCache.ts similarity index 100% rename from src/solana/AsyncAccountCache.ts rename to src/features/solana/AsyncAccountCache.ts diff --git a/src/solana/CollapsibleWritableAccountPreview.tsx b/src/features/solana/CollapsibleWritableAccountPreview.tsx similarity index 94% rename from src/solana/CollapsibleWritableAccountPreview.tsx rename to src/features/solana/CollapsibleWritableAccountPreview.tsx index 9210ae123..f6f10f002 100644 --- a/src/solana/CollapsibleWritableAccountPreview.tsx +++ b/src/features/solana/CollapsibleWritableAccountPreview.tsx @@ -1,9 +1,9 @@ -import Receive from '@assets/images/receive.svg' -import ChevronDown from '@assets/images/remixChevronDown.svg' -import ChevronUp from '@assets/images/remixChevronUp.svg' -import Send from '@assets/images/send.svg' -import UnknownAccount from '@assets/images/unknownAccount.svg' -import AnchorAccount from '@assets/images/anchorAccount.svg' +import Receive from '@assets/svgs/receive.svg' +import ChevronDown from '@assets/svgs/remixChevronDown.svg' +import ChevronUp from '@assets/svgs/remixChevronUp.svg' +import Send from '@assets/svgs/send.svg' +import UnknownAccount from '@assets/svgs/unknownAccount.svg' +import AnchorAccount from '@assets/svgs/anchorAccount.svg' import Box from '@components/Box' import { Pill } from '@components/Pill' import Text from '@components/Text' @@ -18,7 +18,7 @@ import { import { getMetadata, useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { NATIVE_MINT } from '@solana/spl-token' import { AccountInfo } from '@solana/web3.js' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { shortenAddress } from '@utils/formatting' import { humanReadable } from '@utils/solanaUtils' import { BN } from 'bn.js' diff --git a/src/solana/CollectablePreview.tsx b/src/features/solana/CollectablePreview.tsx similarity index 97% rename from src/solana/CollectablePreview.tsx rename to src/features/solana/CollectablePreview.tsx index a63baf0e5..8b3a3c5c3 100644 --- a/src/solana/CollectablePreview.tsx +++ b/src/features/solana/CollectablePreview.tsx @@ -1,11 +1,11 @@ -import Send from '@assets/images/send.svg' +import Send from '@assets/svgs/send.svg' import Box from '@components/Box' import { Pill } from '@components/Pill' import Text from '@components/Text' import React, { useMemo } from 'react' import ImageBox from '@components/ImageBox' import { ellipsizeAddress } from '@utils/accountUtils' -import { Collectable, CompressedNFT, isCompressedNFT } from '../types/solana' +import { Collectable, CompressedNFT, isCompressedNFT } from '../../types/solana' interface ICollectablePreviewProps { collectable: CompressedNFT | Collectable diff --git a/src/solana/MessagePreview.tsx b/src/features/solana/MessagePreview.tsx similarity index 100% rename from src/solana/MessagePreview.tsx rename to src/features/solana/MessagePreview.tsx diff --git a/src/solana/PaymentPreview.tsx b/src/features/solana/PaymentPreview.tsx similarity index 97% rename from src/solana/PaymentPreview.tsx rename to src/features/solana/PaymentPreview.tsx index eb188caea..f0ac307ca 100644 --- a/src/solana/PaymentPreview.tsx +++ b/src/features/solana/PaymentPreview.tsx @@ -1,4 +1,4 @@ -import Send from '@assets/images/send.svg' +import Send from '@assets/svgs/send.svg' import Box from '@components/Box' import { Pill } from '@components/Pill' import Text from '@components/Text' diff --git a/src/solana/SolanaProvider.tsx b/src/features/solana/SolanaProvider.tsx similarity index 95% rename from src/solana/SolanaProvider.tsx rename to src/features/solana/SolanaProvider.tsx index e296cd168..059425daa 100644 --- a/src/solana/SolanaProvider.tsx +++ b/src/features/solana/SolanaProvider.tsx @@ -30,14 +30,14 @@ import { useSelector } from 'react-redux' import nacl from 'tweetnacl' import KeystoneModal, { KeystoneModalRef, -} from '../features/keystone/KeystoneModal' -import LedgerModal, { LedgerModalRef } from '../features/ledger/LedgerModal' -import { useAccountStorage } from '../storage/AccountStorageProvider' -import { getSessionKey, getSolanaKeypair } from '../storage/secureStorage' -import { RootState } from '../store/rootReducer' -import { appSlice } from '../store/slices/appSlice' -import { useAppDispatch } from '../store/store' -import { getConnection, isVersionedTransaction } from '../utils/solanaUtils' +} from '@features/keystone/KeystoneModal' +import LedgerModal, { LedgerModalRef } from '@features/ledger/LedgerModal' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { getSessionKey, getSolanaKeypair } from '@config/storage/secureStorage' +import { RootState } from '@store/rootReducer' +import { appSlice } from '@store/slices/appSlice' +import { useAppDispatch } from '@store/store' +import { getConnection, isVersionedTransaction } from '@utils/solanaUtils' import { AsyncAccountCache } from './AsyncAccountCache' const useSolanaHook = () => { diff --git a/src/solana/SwapPreview.tsx b/src/features/solana/SwapPreview.tsx similarity index 95% rename from src/solana/SwapPreview.tsx rename to src/features/solana/SwapPreview.tsx index 774c86e18..53caf576b 100644 --- a/src/solana/SwapPreview.tsx +++ b/src/features/solana/SwapPreview.tsx @@ -1,5 +1,5 @@ -import Send from '@assets/images/send.svg' -import Receive from '@assets/images/receive.svg' +import Send from '@assets/svgs/send.svg' +import Receive from '@assets/svgs/receive.svg' import Box from '@components/Box' import CircleLoader from '@components/CircleLoader' import { Pill } from '@components/Pill' @@ -9,7 +9,7 @@ import { useMint } from '@helium/helium-react-hooks' import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { PublicKey } from '@solana/web3.js' import React from 'react' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' interface ISwapPreviewProps { inputMint: PublicKey diff --git a/src/solana/WalletSIgnBottomSheetSimulated.tsx b/src/features/solana/WalletSIgnBottomSheetSimulated.tsx similarity index 97% rename from src/solana/WalletSIgnBottomSheetSimulated.tsx rename to src/features/solana/WalletSIgnBottomSheetSimulated.tsx index 9242f5ba2..b0494e4cf 100644 --- a/src/solana/WalletSIgnBottomSheetSimulated.tsx +++ b/src/features/solana/WalletSIgnBottomSheetSimulated.tsx @@ -1,9 +1,9 @@ -import Checkmark from '@assets/images/checkmark.svg' -import IndentArrow from '@assets/images/indentArrow.svg' -import InfoIcon from '@assets/images/info.svg' -import CancelIcon from '@assets/images/remixCancel.svg' -import ChevronDown from '@assets/images/remixChevronDown.svg' -import ChevronUp from '@assets/images/remixChevronUp.svg' +import Checkmark from '@assets/svgs/checkmark.svg' +import IndentArrow from '@assets/svgs/indentArrow.svg' +import InfoIcon from '@assets/svgs/info.svg' +import CancelIcon from '@assets/svgs/remixCancel.svg' +import ChevronDown from '@assets/svgs/remixChevronDown.svg' +import ChevronUp from '@assets/svgs/remixChevronUp.svg' import Box from '@components/Box' import ButtonPressable from '@components/ButtonPressable' import CircleLoader from '@components/CircleLoader' @@ -26,7 +26,7 @@ import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' import { ScrollView } from 'react-native-gesture-handler' import SafeAreaBox from '@components/SafeAreaBox' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { useSolana } from './SolanaProvider' import WalletSignBottomSheetTransaction from './WalletSignBottomSheetTransaction' import { diff --git a/src/solana/WalletSignBottomSheet.tsx b/src/features/solana/WalletSignBottomSheet.tsx similarity index 95% rename from src/solana/WalletSignBottomSheet.tsx rename to src/features/solana/WalletSignBottomSheet.tsx index 7fa6489d1..654ac5207 100644 --- a/src/solana/WalletSignBottomSheet.tsx +++ b/src/features/solana/WalletSignBottomSheet.tsx @@ -5,7 +5,7 @@ import { BottomSheetModalProvider, BottomSheetScrollView, } from '@gorhom/bottom-sheet' -import { useBorderRadii } from '@theme/themeHooks' +import { useBorderRadii } from '@config/theme/themeHooks' import React, { Ref, forwardRef, @@ -16,9 +16,8 @@ import React, { useRef, useState, } from 'react' -import { useSharedValue } from 'react-native-reanimated' import { ThemeProvider } from '@shopify/restyle' -import { darkTheme } from '@theme/theme' +import { darkTheme } from '@config/theme/theme' import { StyleProp, ViewStyle } from 'react-native' import { WalletSignBottomSheetProps, @@ -38,7 +37,6 @@ const WalletSignBottomSheet = forwardRef( ((value: boolean | PromiseLike) => void) | null >(null) useImperativeHandle(ref, () => ({ show, hide })) - const animatedContentHeight = useSharedValue(0) const borderRadii = useBorderRadii() const bottomSheetModalRef = useRef(null) const [simulated, setSimulated] = useState(false) @@ -146,7 +144,6 @@ const WalletSignBottomSheet = forwardRef( elevation: 24, }} enableDynamicSizing - contentHeight={animatedContentHeight} > diff --git a/src/solana/WalletSignBottomSheetCompact.tsx b/src/features/solana/WalletSignBottomSheetCompact.tsx similarity index 100% rename from src/solana/WalletSignBottomSheetCompact.tsx rename to src/features/solana/WalletSignBottomSheetCompact.tsx diff --git a/src/solana/WalletSignBottomSheetTransaction.tsx b/src/features/solana/WalletSignBottomSheetTransaction.tsx similarity index 97% rename from src/solana/WalletSignBottomSheetTransaction.tsx rename to src/features/solana/WalletSignBottomSheetTransaction.tsx index 8b58e84bb..df97a24d5 100644 --- a/src/solana/WalletSignBottomSheetTransaction.tsx +++ b/src/features/solana/WalletSignBottomSheetTransaction.tsx @@ -1,8 +1,8 @@ -import Alert from '@assets/images/alert.svg' -import ExternalLink from '@assets/images/externalLink.svg' -import ChevronDown from '@assets/images/remixChevronDown.svg' -import ChevronUp from '@assets/images/remixChevronUp.svg' -import UnknownAccount from '@assets/images/unknownAccount.svg' +import Alert from '@assets/svgs/alert.svg' +import ExternalLink from '@assets/svgs/externalLink.svg' +import ChevronDown from '@assets/svgs/remixChevronDown.svg' +import ChevronUp from '@assets/svgs/remixChevronUp.svg' +import UnknownAccount from '@assets/svgs/unknownAccount.svg' import Box from '@components/Box' import { Pill } from '@components/Pill' import Text from '@components/Text' diff --git a/src/solana/WalletSignProvider.tsx b/src/features/solana/WalletSignProvider.tsx similarity index 100% rename from src/solana/WalletSignProvider.tsx rename to src/features/solana/WalletSignProvider.tsx diff --git a/src/solana/WarningBox.tsx b/src/features/solana/WarningBox.tsx similarity index 94% rename from src/solana/WarningBox.tsx rename to src/features/solana/WarningBox.tsx index f95e239af..342c98ff5 100644 --- a/src/solana/WarningBox.tsx +++ b/src/features/solana/WarningBox.tsx @@ -1,7 +1,7 @@ import Box from '@components/Box' import Text from '@components/Text' import React from 'react' -import Alert from '@assets/images/alert.svg' +import Alert from '@assets/svgs/alert.svg' export const WarningBox = ({ header, diff --git a/src/solana/WritableAccountPreview.tsx b/src/features/solana/WritableAccountPreview.tsx similarity index 99% rename from src/solana/WritableAccountPreview.tsx rename to src/features/solana/WritableAccountPreview.tsx index 226e36092..469409d62 100644 --- a/src/solana/WritableAccountPreview.tsx +++ b/src/features/solana/WritableAccountPreview.tsx @@ -1,4 +1,4 @@ -import ArrowRight from '@assets/images/remixArrowRight.svg' +import ArrowRight from '@assets/svgs/remixArrowRight.svg' import Box from '@components/Box' import Text from '@components/Text' import { diff --git a/src/solana/walletSignBottomSheetTypes.tsx b/src/features/solana/walletSignBottomSheetTypes.tsx similarity index 100% rename from src/solana/walletSignBottomSheetTypes.tsx rename to src/features/solana/walletSignBottomSheetTypes.tsx diff --git a/src/features/swaps/SwapItem.tsx b/src/features/swaps/SwapItem.tsx index 33f7e04a6..481296fc7 100644 --- a/src/features/swaps/SwapItem.tsx +++ b/src/features/swaps/SwapItem.tsx @@ -4,8 +4,8 @@ import TokenPill from '@components/TokenPill' import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { BoxProps } from '@shopify/restyle' import { PublicKey } from '@solana/web3.js' -import { Theme } from '@theme/theme' -import { useCreateOpacity } from '@theme/themeHooks' +import { Theme } from '@config/theme/theme' +import { useCreateOpacity } from '@config/theme/themeHooks' import React, { memo, useCallback } from 'react' import { useTranslation } from 'react-i18next' import { GestureResponderEvent, Pressable } from 'react-native' diff --git a/src/features/swaps/SwapNavigator.tsx b/src/features/swaps/SwapNavigator.tsx index e23e95856..219a8f35e 100644 --- a/src/features/swaps/SwapNavigator.tsx +++ b/src/features/swaps/SwapNavigator.tsx @@ -2,7 +2,7 @@ import { createNativeStackNavigator, NativeStackNavigationOptions, } from '@react-navigation/native-stack' -import { JupiterProvider } from '@storage/JupiterProvider' +import { JupiterProvider } from '@config/storage/JupiterProvider' import React, { memo, useMemo } from 'react' import SwappingScreen from './SwappingScreen' import SwapScreen from './SwapScreen' diff --git a/src/features/swaps/SwapScreen.tsx b/src/features/swaps/SwapScreen.tsx index 2b595f275..a696a4949 100644 --- a/src/features/swaps/SwapScreen.tsx +++ b/src/features/swaps/SwapScreen.tsx @@ -1,5 +1,5 @@ -import Menu from '@assets/images/menu.svg' -import Plus from '@assets/images/plus.svg' +import Menu from '@assets/svgs/menu.svg' +import Plus from '@assets/svgs/plus.svg' import AddressBookSelector, { AddressBookRef, } from '@components/AddressBookSelector' @@ -37,11 +37,11 @@ import { useTreasuryPrice } from '@hooks/useTreasuryPrice' import { useNavigation } from '@react-navigation/native' import { NATIVE_MINT } from '@solana/spl-token' import { PublicKey } from '@solana/web3.js' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { useJupiter } from '@storage/JupiterProvider' -import { useVisibleTokens } from '@storage/TokensProvider' -import { CSAccount } from '@storage/cloudStorage' -import { useColors, useHitSlop, useSpacing } from '@theme/themeHooks' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useJupiter } from '@config/storage/JupiterProvider' +import { useVisibleTokens } from '@config/storage/TokensProvider' +import { CSAccount } from '@config/storage/cloudStorage' +import { useColors, useHitSlop, useSpacing } from '@config/theme/themeHooks' import { useBalance } from '@utils/Balance' import { MIN_BALANCE_THRESHOLD } from '@utils/constants' import { @@ -73,7 +73,7 @@ import SegmentedControl from '@components/SegmentedControl' import { Portal } from '@gorhom/portal' import ScrollBox from '@components/ScrollBox' import changeNavigationBarColor from 'react-native-navigation-bar-color' -import { useSolana } from '../../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { solAddressIsValid } from '../../utils/accountUtils' import SwapItem from './SwapItem' import { SwapNavigationProp } from './swapTypes' diff --git a/src/features/swaps/SwappingScreen.tsx b/src/features/swaps/SwappingScreen.tsx index 52f291011..a17b0baaf 100644 --- a/src/features/swaps/SwappingScreen.tsx +++ b/src/features/swaps/SwappingScreen.tsx @@ -19,9 +19,9 @@ import Animated, { FadeIn, FadeOut } from 'react-native-reanimated' import { Edge } from 'react-native-safe-area-context' import { useSelector } from 'react-redux' import 'text-encoding-polyfill' -import ArrowRight from '../../assets/images/arrowRight.svg' -import BackArrow from '../../assets/images/backArrow.svg' -import { TabBarNavigationProp } from '../../navigation/rootTypes' +import ArrowRight from '../../assets/svgs/arrowRight.svg' +import BackArrow from '../../assets/svgs/backArrow.svg' +import { TabBarNavigationProp } from '../../app/rootTypes' import { RootState } from '../../store/rootReducer' import { SwapStackParamList } from './swapTypes' diff --git a/src/features/txnDelegation/LinkWallet.tsx b/src/features/txnDelegation/LinkWallet.tsx index 3f4de13dc..2f86b6632 100644 --- a/src/features/txnDelegation/LinkWallet.tsx +++ b/src/features/txnDelegation/LinkWallet.tsx @@ -18,14 +18,11 @@ import AccountSelector, { } from '@components/AccountSelector' import AccountButton from '@components/AccountButton' import useAlert from '@hooks/useAlert' -import { ServiceSheetNavigationProp } from '@services/serviceSheetTypes' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { ServiceSheetNavigationProp } from 'src/app/services/serviceSheetTypes' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { checkSecureAccount, getKeypair } from '@config/storage/secureStorage' import { formatAccountAlias } from '../../utils/accountUtils' -import { checkSecureAccount, getKeypair } from '../../storage/secureStorage' -import { - RootNavigationProp, - RootStackParamList, -} from '../../navigation/rootTypes' +import { RootNavigationProp, RootStackParamList } from '../../app/rootTypes' import sleep from '../../utils/sleep' type Route = RouteProp diff --git a/src/features/txnDelegation/SignHotspot.tsx b/src/features/txnDelegation/SignHotspot.tsx index 0121c7e3d..e6da5d58a 100644 --- a/src/features/txnDelegation/SignHotspot.tsx +++ b/src/features/txnDelegation/SignHotspot.tsx @@ -14,7 +14,7 @@ import { verifyWalletLinkToken, } from '@helium/wallet-link' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import animalHash from 'angry-purple-tiger' import BN from 'bn.js' import React, { memo, useCallback, useEffect, useMemo, useState } from 'react' @@ -23,13 +23,10 @@ import { useTranslation } from 'react-i18next' import { ActivityIndicator, Linking } from 'react-native' import Config from 'react-native-config' import Toast from 'react-native-simple-toast' -import { ServiceSheetNavigationProp } from '@services/serviceSheetTypes' -import { - RootNavigationProp, - RootStackParamList, -} from '../../navigation/rootTypes' -import { useAccountStorage } from '../../storage/AccountStorageProvider' -import { getKeypair } from '../../storage/secureStorage' +import { ServiceSheetNavigationProp } from 'src/app/services/serviceSheetTypes' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { getKeypair } from '@config/storage/secureStorage' +import { RootNavigationProp, RootStackParamList } from '../../app/rootTypes' import { formatAccountAlias } from '../../utils/accountUtils' import * as Logger from '../../utils/logger' import useSolTxns from './useSolTxns' diff --git a/src/features/txnDelegation/useSolTxns.ts b/src/features/txnDelegation/useSolTxns.ts index e14c1a2e9..b75b1ac64 100644 --- a/src/features/txnDelegation/useSolTxns.ts +++ b/src/features/txnDelegation/useSolTxns.ts @@ -21,8 +21,8 @@ import { useCallback, useMemo, useRef, useState } from 'react' import { useAsync } from 'react-async-hook' import { HeliumEntityManager } from '@helium/idls/lib/types/helium_entity_manager' import { IdlInstruction } from '@coral-xyz/anchor/dist/cjs/idl' -import { useSolana } from '../../solana/SolanaProvider' -import { getKeypair, getSolanaKeypair } from '../../storage/secureStorage' +import { useSolana } from '@features/solana/SolanaProvider' +import { getKeypair, getSolanaKeypair } from '@config/storage/secureStorage' import { submitSolana } from '../../utils/solanaUtils' const ValidTxnKeys = [ diff --git a/src/features/account/AccountActionBar.tsx b/src/features/wallet/AccountActionBar.tsx similarity index 96% rename from src/features/account/AccountActionBar.tsx rename to src/features/wallet/AccountActionBar.tsx index 4f211d126..43d43fb31 100644 --- a/src/features/account/AccountActionBar.tsx +++ b/src/features/wallet/AccountActionBar.tsx @@ -6,9 +6,9 @@ import { PublicKey } from '@solana/web3.js' import React, { useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { LayoutChangeEvent } from 'react-native' -import { WalletServiceNavigationProp } from '@services/WalletService' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' -import { useAppStorage } from '../../storage/AppStorageProvider' +import { WalletServiceNavigationProp } from 'src/app/services/WalletService' +import { WalletNavigationProp } from 'src/app/services/WalletService/pages/WalletPage' +import { useAppStorage } from '@config/storage/AppStorageProvider' export type Action = | 'send' diff --git a/src/features/account/AccountActivityFilter.tsx b/src/features/wallet/AccountActivityFilter.tsx similarity index 100% rename from src/features/account/AccountActivityFilter.tsx rename to src/features/wallet/AccountActivityFilter.tsx diff --git a/src/features/account/AccountBalanceChart.tsx b/src/features/wallet/AccountBalanceChart.tsx similarity index 98% rename from src/features/account/AccountBalanceChart.tsx rename to src/features/wallet/AccountBalanceChart.tsx index 69f73f51f..f4849b4ae 100644 --- a/src/features/account/AccountBalanceChart.tsx +++ b/src/features/wallet/AccountBalanceChart.tsx @@ -10,7 +10,7 @@ import { Platform, processColor, ViewStyle } from 'react-native' import { ChartSelectEvent, LineChart } from 'react-native-charts-wrapper' import { ScrollView } from 'react-native-gesture-handler' import FadeInOut from '@components/FadeInOut' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import useHaptic from '@hooks/useHaptic' import usePrevious from '@hooks/usePrevious' import { AccountBalance } from '../../types/balance' diff --git a/src/features/account/AccountManageTokenListScreen.tsx b/src/features/wallet/AccountManageTokenListScreen.tsx similarity index 95% rename from src/features/account/AccountManageTokenListScreen.tsx rename to src/features/wallet/AccountManageTokenListScreen.tsx index 227315c5c..2fc9f2178 100644 --- a/src/features/account/AccountManageTokenListScreen.tsx +++ b/src/features/wallet/AccountManageTokenListScreen.tsx @@ -9,9 +9,9 @@ import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { usePublicKey } from '@hooks/usePublicKey' import CheckBox from '@react-native-community/checkbox' import { PublicKey } from '@solana/web3.js' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { useVisibleTokens } from '@storage/TokensProvider' -import { useColors } from '@theme/themeHooks' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useVisibleTokens } from '@config/storage/TokensProvider' +import { useColors } from '@config/theme/themeHooks' import { useBalance } from '@utils/Balance' import { getSortValue, humanReadable } from '@utils/solanaUtils' import BN from 'bn.js' @@ -22,9 +22,9 @@ import { FlatList } from 'react-native-gesture-handler' import BackScreen from '@components/BackScreen' import ScrollBox from '@components/ScrollBox' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import { NavBarHeight } from '@components/ServiceNavBar' -import { useSolana } from '../../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { syncTokenAccounts } from '../../store/slices/balancesSlice' import { useAppDispatch } from '../../store/store' import AccountTokenCurrencyBalance from './AccountTokenCurrencyBalance' diff --git a/src/features/account/AccountTokenBalance.tsx b/src/features/wallet/AccountTokenBalance.tsx similarity index 96% rename from src/features/account/AccountTokenBalance.tsx rename to src/features/wallet/AccountTokenBalance.tsx index 2aa378445..bef45dac2 100644 --- a/src/features/account/AccountTokenBalance.tsx +++ b/src/features/wallet/AccountTokenBalance.tsx @@ -7,8 +7,8 @@ import { useCurrentWallet } from '@hooks/useCurrentWallet' import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { BoxProps } from '@shopify/restyle' import { PublicKey } from '@solana/web3.js' -import { useAccountStorage } from '@storage/AccountStorageProvider' -import { TextVariant, Theme } from '@theme/theme' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { TextVariant, Theme } from '@config/theme/theme' import { IOT_SUB_DAO_KEY, MOBILE_SUB_DAO_KEY } from '@utils/constants' import { getEscrowTokenAccount, humanReadable } from '@utils/solanaUtils' import BN from 'bn.js' diff --git a/src/features/account/AccountTokenCurrencyBalance.tsx b/src/features/wallet/AccountTokenCurrencyBalance.tsx similarity index 100% rename from src/features/account/AccountTokenCurrencyBalance.tsx rename to src/features/wallet/AccountTokenCurrencyBalance.tsx diff --git a/src/features/account/AccountTokenScreen.tsx b/src/features/wallet/AccountTokenScreen.tsx similarity index 96% rename from src/features/account/AccountTokenScreen.tsx rename to src/features/wallet/AccountTokenScreen.tsx index 98f3b05dd..cfa6c51c5 100644 --- a/src/features/account/AccountTokenScreen.tsx +++ b/src/features/wallet/AccountTokenScreen.tsx @@ -13,18 +13,18 @@ import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { usePublicKey } from '@hooks/usePublicKey' import { RouteProp, useRoute } from '@react-navigation/native' import { NATIVE_MINT } from '@solana/spl-token' -import { useModal } from '@storage/ModalsProvider' -import { useColors } from '@theme/themeHooks' +import { useModal } from '@config/storage/ModalsProvider' +import { useColors } from '@config/theme/themeHooks' import { GovMints, MIN_BALANCE_THRESHOLD } from '@utils/constants' import React, { useCallback, useMemo, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' import { View } from 'react-native' import { FlatList } from 'react-native-gesture-handler' -import { WalletStackParamList } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' import { PublicKey } from '@solana/web3.js' import ScrollBox from '@components/ScrollBox' -import { useSolana } from '../../solana/SolanaProvider' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { WalletStackParamList } from 'src/app/services/WalletService/pages/WalletPage' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { Activity } from '../../types/activity' import AccountActionBar from './AccountActionBar' import { useActivityFilter } from './AccountActivityFilter' diff --git a/src/features/account/AccountView.tsx b/src/features/wallet/AccountView.tsx similarity index 97% rename from src/features/account/AccountView.tsx rename to src/features/wallet/AccountView.tsx index 3fd3a3d7c..da66a4cde 100644 --- a/src/features/account/AccountView.tsx +++ b/src/features/wallet/AccountView.tsx @@ -4,12 +4,12 @@ import FadeInOut from '@components/FadeInOut' import Text from '@components/Text' import useLayoutHeight from '@hooks/useLayoutHeight' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import { useLanguage } from '@utils/i18n' import { addMinutes } from 'date-fns' import React, { memo, useEffect, useState } from 'react' import { GestureResponderEvent } from 'react-native' -import { useAppStorage } from '../../storage/AppStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' import { AccountBalance } from '../../types/balance' import { numberFormat, useBalance } from '../../utils/Balance' import DateModule from '../../utils/DateModule' diff --git a/src/features/account/AirdropScreen.tsx b/src/features/wallet/AirdropScreen.tsx similarity index 95% rename from src/features/account/AirdropScreen.tsx rename to src/features/wallet/AirdropScreen.tsx index 5308fe844..bc011d2e0 100644 --- a/src/features/account/AirdropScreen.tsx +++ b/src/features/wallet/AirdropScreen.tsx @@ -1,4 +1,4 @@ -import DripLogo from '@assets/images/dripLogo.svg' +import DripLogo from '@assets/svgs/dripLogo.svg' import { ReAnimatedBox } from '@components/AnimatedBox' import BackScreen from '@components/BackScreen' import Box from '@components/Box' @@ -8,7 +8,7 @@ import Text from '@components/Text' import { usePublicKey } from '@hooks/usePublicKey' import { RouteProp, useNavigation, useRoute } from '@react-navigation/native' import { NATIVE_MINT } from '@solana/spl-token' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import * as logger from '@utils/logger' import * as solUtils from '@utils/solanaUtils' import axios from 'axios' @@ -25,14 +25,14 @@ import { } from 'react-native-reanimated' import { useSafeAreaInsets } from 'react-native-safe-area-context' import ScrollBox from '@components/ScrollBox' -import HNT from '@assets/images/hnt.svg' +import HNT from '@assets/svgs/hnt.svg' import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import { NavBarHeight } from '@components/ServiceNavBar' import { WalletNavigationProp, WalletStackParamList, -} from '@services/WalletService/pages/WalletPage/WalletPageNavigator' -import { useSolana } from '../../solana/SolanaProvider' +} from 'src/app/services/WalletService/pages/WalletPage' +import { useSolana } from '@features/solana/SolanaProvider' const DROP_HEIGHT = 79 diff --git a/src/features/account/TokenListItem.tsx b/src/features/wallet/TokenListItem.tsx similarity index 97% rename from src/features/account/TokenListItem.tsx rename to src/features/wallet/TokenListItem.tsx index d636e37e1..6a13e0cf6 100644 --- a/src/features/account/TokenListItem.tsx +++ b/src/features/wallet/TokenListItem.tsx @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-shadow */ -import Arrow from '@assets/images/listItemRight.svg' -import Lock from '@assets/images/lockClosed.svg' +import Arrow from '@assets/svgs/listItemRight.svg' +import Lock from '@assets/svgs/lockClosed.svg' import Box from '@components/Box' import FadeInOut from '@components/FadeInOut' import Text from '@components/Text' @@ -19,18 +19,18 @@ import { useMetaplexMetadata } from '@hooks/useMetaplexMetadata' import usePrevious from '@hooks/usePrevious' import { useNavigation } from '@react-navigation/native' import { PublicKey } from '@solana/web3.js' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { humanReadable } from '@utils/solanaUtils' import BN from 'bn.js' import React, { useCallback, useMemo } from 'react' import { useAsync } from 'react-async-hook' -import { ServiceSheetNavigationProp } from '@services/serviceSheetTypes' -import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' +import { ServiceSheetNavigationProp } from 'src/app/services/serviceSheetTypes' +import { WalletNavigationProp } from 'src/app/services/WalletService/pages/WalletPage' import useAmountLocked from '@hooks/useAmountLocked' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' +import { useSolana } from '@features/solana/SolanaProvider' import AccountTokenCurrencyBalance from './AccountTokenCurrencyBalance' -import { useSolana } from '../../solana/SolanaProvider' export const ITEM_HEIGHT = 72 type Props = { diff --git a/src/services/WalletService/pages/WalletPage/TokensScreen.tsx b/src/features/wallet/TokensScreen.tsx similarity index 91% rename from src/services/WalletService/pages/WalletPage/TokensScreen.tsx rename to src/features/wallet/TokensScreen.tsx index 37b31229d..430d31018 100644 --- a/src/services/WalletService/pages/WalletPage/TokensScreen.tsx +++ b/src/features/wallet/TokensScreen.tsx @@ -4,20 +4,23 @@ import TotalFiatBalance from '@components/TotalFiatBalance' import { AppState, FlatList, Platform, RefreshControl } from 'react-native' import { useBalance } from '@utils/Balance' import { DC_MINT, truthy } from '@helium/spl-utils' -import { DEFAULT_TOKENS, useVisibleTokens } from '@storage/TokensProvider' +import { + DEFAULT_TOKENS, + useVisibleTokens, +} from '@config/storage/TokensProvider' import { PublicKey } from '@solana/web3.js' import { HeliumTokenListItem, TokenListItem, TokenSkeleton, -} from '@features/account/TokenListItem' +} from '@features/wallet/TokenListItem' import { GovMints } from '@utils/constants' -import { useColors, useSpacing } from '@theme/themeHooks' +import { useColors, useSpacing } from '@config/theme/themeHooks' import WalletAlertBanner from '@components/WalletAlertBanner' import { NavBarHeight } from '@components/ServiceNavBar' import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useAsync, useAsyncCallback } from 'react-async-hook' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { useAppDispatch } from '@store/store' import { syncTokenAccounts } from '@store/slices/balancesSlice' import { useAccountFetchCache } from '@helium/account-fetch-cache-hooks' @@ -25,20 +28,20 @@ import { getAssociatedTokenAddressSync } from '@solana/spl-token' import { times } from 'lodash' import TouchableOpacityBox from '@components/TouchableOpacityBox' import { useNavigation } from '@react-navigation/native' -import Config from '@assets/images/config.svg' +import Config from '@assets/svgs/config.svg' import Text from '@components/Text' import { useTranslation } from 'react-i18next' import { getSortValue } from '@utils/solanaUtils' -import { checkSecureAccount } from '@storage/secureStorage' +import { checkSecureAccount } from '@config/storage/secureStorage' import ScrollBox from '@components/ScrollBox' import SharedGroupPreferences from 'react-native-shared-group-preferences' -import { useAppStorage } from '@storage/AppStorageProvider' -import { CSAccount } from '@storage/cloudStorage' -import { RootNavigationProp } from 'src/navigation/rootTypes' -import { useNotificationStorage } from '@storage/NotificationStorageProvider' -import { ServiceSheetNavigationProp } from '@services/serviceSheetTypes' -import { WalletNavigationProp } from './WalletPageNavigator' -import { useSolana } from '../../../../solana/SolanaProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { CSAccount } from '@config/storage/cloudStorage' +import { RootNavigationProp } from 'src/app/rootTypes' +import { useNotificationStorage } from '@config/storage/NotificationStorageProvider' +import { ServiceSheetNavigationProp } from 'src/app/services/serviceSheetTypes' +import { useSolana } from '@features/solana/SolanaProvider' +import { WalletNavigationProp } from '@services/WalletService/pages/WalletPage' const TokensScreen = () => { const widgetGroup = 'group.com.helium.mobile.wallet.widget' diff --git a/src/services/WalletService/pages/WalletPage/TokensTabs.tsx b/src/features/wallet/TokensTabs.tsx similarity index 93% rename from src/services/WalletService/pages/WalletPage/TokensTabs.tsx rename to src/features/wallet/TokensTabs.tsx index 4a507fe84..37109821c 100644 --- a/src/services/WalletService/pages/WalletPage/TokensTabs.tsx +++ b/src/features/wallet/TokensTabs.tsx @@ -2,15 +2,15 @@ import SegmentedControl, { SegmentedControlRef, } from '@components/SegmentedControl' import React, { useCallback, useMemo, useRef } from 'react' -import Tokens from '@assets/images/tokens.svg' -import Collectables from '@assets/images/collectables.svg' +import Tokens from '@assets/svgs/tokens.svg' +import Collectables from '@assets/svgs/collectables.svg' import { MaterialTopTabNavigationOptions, createMaterialTopTabNavigator, } from '@react-navigation/material-top-tabs' import { StackNavigationProp } from '@react-navigation/stack' import NftList from '@features/collectables/NftList' -import { useColors } from '@theme/themeHooks' +import { useColors } from '@config/theme/themeHooks' import { useNavigation } from '@react-navigation/native' import TokensScreen from './TokensScreen' diff --git a/src/features/account/TransactionDetail.tsx b/src/features/wallet/TransactionDetail.tsx similarity index 98% rename from src/features/account/TransactionDetail.tsx rename to src/features/wallet/TransactionDetail.tsx index 1d6170069..e741918ea 100644 --- a/src/features/account/TransactionDetail.tsx +++ b/src/features/wallet/TransactionDetail.tsx @@ -23,9 +23,9 @@ import { useTranslation } from 'react-i18next' import { LayoutChangeEvent } from 'react-native' import { Edge } from 'react-native-safe-area-context' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import { Portal } from '@gorhom/portal' -import { useCreateExplorerUrl } from '../../constants/urls' +import { useCreateExplorerUrl } from '../../utils/constants/urls' import { Activity } from '../../types/activity' import TransactionLineItem from './TransactionLineItem' import { useTxnDetails } from './useTxn' diff --git a/src/features/account/TransactionLineItem.tsx b/src/features/wallet/TransactionLineItem.tsx similarity index 95% rename from src/features/account/TransactionLineItem.tsx rename to src/features/wallet/TransactionLineItem.tsx index da2cca679..d49630f79 100644 --- a/src/features/account/TransactionLineItem.tsx +++ b/src/features/wallet/TransactionLineItem.tsx @@ -1,4 +1,4 @@ -import DetailArrow from '@assets/images/detailArrow.svg' +import DetailArrow from '@assets/svgs/detailArrow.svg' import AccountIcon from '@components/AccountIcon' import Box from '@components/Box' import Text from '@components/Text' @@ -6,12 +6,16 @@ import TouchableOpacityBox from '@components/TouchableOpacityBox' import useAlert from '@hooks/useAlert' import useCopyText from '@hooks/useCopyText' import { useNavigation } from '@react-navigation/native' -import { Color } from '@theme/theme' -import { useColors, useHitSlop, useVerticalHitSlop } from '@theme/themeHooks' +import { Color } from '@config/theme/theme' +import { + useColors, + useHitSlop, + useVerticalHitSlop, +} from '@config/theme/themeHooks' import React, { memo, useCallback, useMemo } from 'react' import { useTranslation } from 'react-i18next' import { Linking } from 'react-native' -import { useAccountStorage } from '../../storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { ellipsizeAddress } from '../../utils/accountUtils' import { locale } from '../../utils/i18n' import { AddressBookNavigationProp } from '../addressBook/addressBookTypes' diff --git a/src/features/account/TxnListItem.tsx b/src/features/wallet/TxnListItem.tsx similarity index 95% rename from src/features/account/TxnListItem.tsx rename to src/features/wallet/TxnListItem.tsx index c7dc47a19..00041ca66 100644 --- a/src/features/account/TxnListItem.tsx +++ b/src/features/wallet/TxnListItem.tsx @@ -1,11 +1,11 @@ -import Pending from '@assets/images/pending.svg' +import Pending from '@assets/svgs/pending.svg' import Box from '@components/Box' import Text from '@components/Text' import TouchableOpacityBox from '@components/TouchableOpacityBox' import { PublicKey } from '@solana/web3.js' import React, { memo, useCallback, useMemo } from 'react' import { BoxProps } from '@shopify/restyle' -import { Theme } from '@theme/theme' +import { Theme } from '@config/theme/theme' import { Activity } from '../../types/activity' import useTxn from './useTxn' diff --git a/src/features/account/useSolanaActivityList.tsx b/src/features/wallet/useSolanaActivityList.tsx similarity index 96% rename from src/features/account/useSolanaActivityList.tsx rename to src/features/wallet/useSolanaActivityList.tsx index 5c74b53ba..2c2e6038d 100644 --- a/src/features/account/useSolanaActivityList.tsx +++ b/src/features/wallet/useSolanaActivityList.tsx @@ -3,8 +3,8 @@ import { PublicKey } from '@solana/web3.js' import { onLogs, removeAccountChangeListener } from '@utils/solanaUtils' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' import { useSelector } from 'react-redux' -import { useSolana } from '../../solana/SolanaProvider' -import { CSAccount } from '../../storage/cloudStorage' +import { useSolana } from '@features/solana/SolanaProvider' +import { CSAccount } from '@config/storage/cloudStorage' import { RootState } from '../../store/rootReducer' import { getTxns } from '../../store/slices/solanaSlice' import { useAppDispatch } from '../../store/store' diff --git a/src/features/account/useTxn.tsx b/src/features/wallet/useTxn.tsx similarity index 97% rename from src/features/account/useTxn.tsx rename to src/features/wallet/useTxn.tsx index f6d1999f6..758dc3d14 100644 --- a/src/features/account/useTxn.tsx +++ b/src/features/wallet/useTxn.tsx @@ -1,5 +1,5 @@ -import TxnReceive from '@assets/images/txnReceive.svg' -import TxnSend from '@assets/images/txnSend.svg' +import TxnReceive from '@assets/svgs/txnReceive.svg' +import TxnSend from '@assets/svgs/txnSend.svg' import { useAccounts } from '@helium/account-fetch-cache-hooks' import { truthy } from '@helium/spl-utils' import { useCurrentWallet } from '@hooks/useCurrentWallet' @@ -11,8 +11,8 @@ import { import { usePublicKey } from '@hooks/usePublicKey' import { Mint, unpackMint } from '@solana/spl-token' import { AccountInfo, LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js' -import { Color } from '@theme/theme' -import { useColors } from '@theme/themeHooks' +import { Color } from '@config/theme/theme' +import { useColors } from '@config/theme/themeHooks' import BN from 'bn.js' import { addMinutes, diff --git a/src/hooks/useAmountLocked.ts b/src/hooks/useAmountLocked.ts index bb2b45fd8..382c4daa3 100644 --- a/src/hooks/useAmountLocked.ts +++ b/src/hooks/useAmountLocked.ts @@ -7,8 +7,8 @@ import { usePositions, } from '@helium/voter-stake-registry-hooks' import { BN } from 'bn.js' +import { useSolana } from '@features/solana/SolanaProvider' import { useCurrentWallet } from './useCurrentWallet' -import { useSolana } from '../solana/SolanaProvider' const useAmountLocked = (mint: PublicKey) => { const wallet = useCurrentWallet() diff --git a/src/hooks/useBrowser.ts b/src/hooks/useBrowser.ts index 607e98278..da3d2531d 100644 --- a/src/hooks/useBrowser.ts +++ b/src/hooks/useBrowser.ts @@ -1,7 +1,7 @@ import { useSelector } from 'react-redux' import { useCallback } from 'react' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { RootState } from '../store/rootReducer' -import { useAccountStorage } from '../storage/AccountStorageProvider' import { BrowserDetails, browserSlice } from '../store/slices/browserSlice' import { useAppDispatch } from '../store/store' diff --git a/src/hooks/useCollectables.ts b/src/hooks/useCollectables.ts index 968211d54..5474a96e7 100644 --- a/src/hooks/useCollectables.ts +++ b/src/hooks/useCollectables.ts @@ -1,8 +1,9 @@ import { useCallback, useEffect, useRef } from 'react' import { useSelector } from 'react-redux' import { WrappedConnection } from '@utils/WrappedConnection' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { CompressedNFT } from '../types/solana' -import { useAccountStorage } from '../storage/AccountStorageProvider' import { RootState } from '../store/rootReducer' import { fetchCollectables, @@ -16,7 +17,6 @@ import { onLogs, removeAccountChangeListener, } from '../utils/solanaUtils' -import { useSolana } from '../solana/SolanaProvider' const useCollectables = (): WalletCollectables & { refresh: () => void diff --git a/src/hooks/useCurrentWallet.ts b/src/hooks/useCurrentWallet.ts index 40ec0bd97..966ffd118 100644 --- a/src/hooks/useCurrentWallet.ts +++ b/src/hooks/useCurrentWallet.ts @@ -1,5 +1,5 @@ import { PublicKey } from '@solana/web3.js' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { usePublicKey } from './usePublicKey' export function useCurrentWallet(): PublicKey | undefined { diff --git a/src/hooks/useDerivationAccounts.ts b/src/hooks/useDerivationAccounts.ts index d5d7c1966..35e402a3c 100644 --- a/src/hooks/useDerivationAccounts.ts +++ b/src/hooks/useDerivationAccounts.ts @@ -13,7 +13,7 @@ import * as ed25519 from 'ed25519-hd-key' import { useEffect, useMemo, useState } from 'react' import Config from 'react-native-config' import { retryWithBackoff } from '@utils/retryWithBackoff' -import { useSolana } from '../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' export const solanaDerivation = (account = -1, change: number | undefined) => { if (account === -1) { diff --git a/src/hooks/useEcosystemTokensSolConvert.ts b/src/hooks/useEcosystemTokensSolConvert.ts index e6200a6a3..a978be381 100644 --- a/src/hooks/useEcosystemTokensSolConvert.ts +++ b/src/hooks/useEcosystemTokensSolConvert.ts @@ -6,7 +6,7 @@ import BN from 'bn.js' import { useMemo } from 'react' import { useAsync } from 'react-async-hook' import { Config } from 'react-native-config' -import { useSolana } from '../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import * as logger from '../utils/logger' import { useBN } from './useBN' import { useCurrentWallet } from './useCurrentWallet' diff --git a/src/hooks/useEnrichedTransactions.ts b/src/hooks/useEnrichedTransactions.ts index a9675eb65..e617fd23a 100644 --- a/src/hooks/useEnrichedTransactions.ts +++ b/src/hooks/useEnrichedTransactions.ts @@ -1,8 +1,8 @@ import AsyncStorage from '@react-native-async-storage/async-storage' import { ConfirmedSignatureInfo } from '@solana/web3.js' import { useCallback, useEffect, useMemo, useRef, useState } from 'react' -import { useSolana } from '../solana/SolanaProvider' -import { useAccountStorage } from '../storage/AccountStorageProvider' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { useAppDispatch } from '../store/store' import { EnrichedTransaction } from '../types/solana' import { diff --git a/src/hooks/useExplorer.ts b/src/hooks/useExplorer.ts index 3cea70f58..3e3d0f41e 100644 --- a/src/hooks/useExplorer.ts +++ b/src/hooks/useExplorer.ts @@ -1,4 +1,4 @@ -import { useAppStorage } from '@storage/AppStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' import { getExplorers, Explorer } from '@utils/walletApiV2' import { useMemo } from 'react' import { useAsync } from 'react-async-hook' diff --git a/src/hooks/useHaptic.ts b/src/hooks/useHaptic.ts index a4ec95f54..e491fe7aa 100644 --- a/src/hooks/useHaptic.ts +++ b/src/hooks/useHaptic.ts @@ -1,4 +1,4 @@ -import { useAppStorage } from '@storage/AppStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' import * as Haptics from 'expo-haptics' export type FeedbackStyle = 'light' | 'medium' | 'heavy' diff --git a/src/hooks/useHeading.ts b/src/hooks/useHeading.ts new file mode 100644 index 000000000..b86df7e31 --- /dev/null +++ b/src/hooks/useHeading.ts @@ -0,0 +1,22 @@ +import { useState, useEffect } from 'react' +import CompassHeading from 'react-native-compass-heading' + +const useHeading = () => { + const [heading, setHeading] = useState(0) + + useEffect(() => { + const degreeUpdateRate = 3 + + CompassHeading.start(degreeUpdateRate, ({ heading: newHeading }) => { + setHeading(newHeading) + }) + + return () => { + CompassHeading.stop() + } + }, []) + + return { heading } +} + +export default useHeading diff --git a/src/hooks/useHotspot.tsx b/src/hooks/useHotspot.tsx index 5a4a2564d..6491fe2b8 100644 --- a/src/hooks/useHotspot.tsx +++ b/src/hooks/useHotspot.tsx @@ -3,7 +3,7 @@ import { init } from '@helium/lazy-distributor-sdk' import { PublicKey, VersionedTransaction } from '@solana/web3.js' import { useEffect, useState } from 'react' import { useAsyncCallback } from 'react-async-hook' -import { useSolana } from '../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { IOT_LAZY_KEY, MOBILE_LAZY_KEY } from '../utils/constants' import * as Logger from '../utils/logger' diff --git a/src/hooks/useHotspotWithMeta.ts b/src/hooks/useHotspotWithMeta.ts index e1395342b..7e0fe80e2 100644 --- a/src/hooks/useHotspotWithMeta.ts +++ b/src/hooks/useHotspotWithMeta.ts @@ -1,7 +1,7 @@ import { PublicKey } from '@solana/web3.js' import { getHotspotWithRewards } from '@utils/solanaUtils' import { useAsync } from 'react-async-hook' -import { useSolana } from '../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { CompressedNFT } from '../types/solana' export const useHotspotWithMetaAndRewards = (hotspot: CompressedNFT) => { diff --git a/src/hooks/useHotspots.ts b/src/hooks/useHotspots.ts index 64bc97cd4..c606a4ac5 100644 --- a/src/hooks/useHotspots.ts +++ b/src/hooks/useHotspots.ts @@ -1,8 +1,8 @@ import BN from 'bn.js' import { useCallback, useEffect, useMemo } from 'react' import { useSelector } from 'react-redux' -import { useSolana } from '../solana/SolanaProvider' -import { useAccountStorage } from '../storage/AccountStorageProvider' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { RootState } from '../store/rootReducer' import { fetchAllHotspots, diff --git a/src/hooks/useImplicitBurn.ts b/src/hooks/useImplicitBurn.ts index 251c6d7ab..3fdde9bb1 100644 --- a/src/hooks/useImplicitBurn.ts +++ b/src/hooks/useImplicitBurn.ts @@ -14,9 +14,9 @@ import BN from 'bn.js' import { Buffer } from 'buffer' import { useAsyncCallback } from 'react-async-hook' import { useTranslation } from 'react-i18next' -import { useSolana } from '../solana/SolanaProvider' -import { useWalletSign } from '../solana/WalletSignProvider' -import { WalletStandardMessageTypes } from '../solana/walletSignBottomSheetTypes' +import { useSolana } from '@features/solana/SolanaProvider' +import { useWalletSign } from '@features/solana/WalletSignProvider' +import { WalletStandardMessageTypes } from '@features/solana/walletSignBottomSheetTypes' export function useImplicitBurn(): { implicitBurn: (requiredDc: number) => void diff --git a/src/hooks/useLedger.ts b/src/hooks/useLedger.ts index 290477ae5..35150b276 100644 --- a/src/hooks/useLedger.ts +++ b/src/hooks/useLedger.ts @@ -8,8 +8,8 @@ import { bs58 } from '@coral-xyz/anchor/dist/cjs/utils/bytes' import { solAddressToHelium } from '@utils/accountUtils' import base58 from 'bs58' import { PublicKey } from '@solana/web3.js' -import { useSolana } from '../solana/SolanaProvider' -import { LedgerDevice } from '../storage/cloudStorage' +import { useSolana } from '@features/solana/SolanaProvider' +import { LedgerDevice } from '@config/storage/cloudStorage' import { runDerivationScheme } from '../utils/heliumLedger' export type LedgerAccount = { diff --git a/src/hooks/useMetaplexMetadata.tsx b/src/hooks/useMetaplexMetadata.tsx index 0a8417df4..ffda9e3dc 100644 --- a/src/hooks/useMetaplexMetadata.tsx +++ b/src/hooks/useMetaplexMetadata.tsx @@ -106,17 +106,20 @@ export function useMetaplexMetadata(mint: PublicKey | undefined): { const { result: json, loading: jsonLoading } = useAsync(async () => { if (!mint) return - const meta = await getMetadata(metadataAcc?.data.uri.trim()) + let meta + try { + meta = await getMetadata(metadataAcc?.data.uri.trim()) + } catch {} dispatch( tokensSlice.actions.setToken({ mint: mint.toBase58(), - name: meta?.name, - symbol: meta?.symbol, + name: metadataAcc?.data?.name || meta?.name, + symbol: metadataAcc?.data?.symbol || meta?.symbol, img: meta?.image, }), ) - return meta + return meta || metadataAcc }, [mint, dispatch, metadataAcc]) if (mint?.equals(NATIVE_MINT)) { @@ -151,7 +154,7 @@ export function useMetaplexMetadata(mint: PublicKey | undefined): { if (cachedToken) { return { - metadata: undefined, + metadata: metadataAcc, loading: false, json: { name: cachedToken.name, diff --git a/src/hooks/useNetworkColor.tsx b/src/hooks/useNetworkColor.tsx index 88cb8383c..d0ab6217d 100644 --- a/src/hooks/useNetworkColor.tsx +++ b/src/hooks/useNetworkColor.tsx @@ -1,6 +1,6 @@ import { useMemo } from 'react' import { NetTypes } from '@helium/address' -import { Color } from '@theme/theme' +import { Color } from '@config/theme/theme' export default ({ defaultColor, diff --git a/src/hooks/useProposalStatus.ts b/src/hooks/useProposalStatus.ts index 0db5228e1..f34cfcbb9 100644 --- a/src/hooks/useProposalStatus.ts +++ b/src/hooks/useProposalStatus.ts @@ -7,7 +7,7 @@ import { PublicKey } from '@solana/web3.js' import { getDerivedProposalState } from '@utils/governanceUtils' import BN from 'bn.js' import { useMemo } from 'react' -import { ProposalV0 } from '../features/governance/governanceTypes' +import { ProposalV0 } from '@features/governance/governanceTypes' function usePublicKey( key: string | PublicKey | undefined, diff --git a/src/hooks/useRentExempt.ts b/src/hooks/useRentExempt.ts index 052ab6609..659d82882 100644 --- a/src/hooks/useRentExempt.ts +++ b/src/hooks/useRentExempt.ts @@ -1,6 +1,6 @@ import { useAsync } from 'react-async-hook' import { LAMPORTS_PER_SOL } from '@solana/web3.js' -import { useSolana } from '../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import * as logger from '../utils/logger' export function useRentExempt(dataLength = 0) { diff --git a/src/hooks/useSolanaHealth.ts b/src/hooks/useSolanaHealth.ts index 49f9490ba..e7d1f93cf 100644 --- a/src/hooks/useSolanaHealth.ts +++ b/src/hooks/useSolanaHealth.ts @@ -2,7 +2,7 @@ import { WrappedConnection } from '@utils/WrappedConnection' import { useMemo, useState } from 'react' import { useAsync } from 'react-async-hook' import { useTranslation } from 'react-i18next' -import { useSolana } from '../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { getCurrentTPS } from '../utils/solanaUtils' let lastUpdated = 0 diff --git a/src/hooks/useSubmitTxn.tsx b/src/hooks/useSubmitTxn.tsx index 8652fcc71..47b7b7b5d 100644 --- a/src/hooks/useSubmitTxn.tsx +++ b/src/hooks/useSubmitTxn.tsx @@ -8,19 +8,19 @@ import { toVersionedTx, } from '@helium/spl-utils' import { PublicKey, Transaction, VersionedTransaction } from '@solana/web3.js' -import { useAccountStorage } from '@storage/AccountStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import i18n from '@utils/i18n' import * as solUtils from '@utils/solanaUtils' import BN from 'bn.js' import React, { useCallback } from 'react' import { ellipsizeAddress } from '@utils/accountUtils' -import { SwapPreview } from '../solana/SwapPreview' -import { CollectablePreview } from '../solana/CollectablePreview' -import { MessagePreview } from '../solana/MessagePreview' -import { PaymentPreivew } from '../solana/PaymentPreview' -import { useSolana } from '../solana/SolanaProvider' -import { useWalletSign } from '../solana/WalletSignProvider' -import { WalletStandardMessageTypes } from '../solana/walletSignBottomSheetTypes' +import { SwapPreview } from '@features/solana/SwapPreview' +import { CollectablePreview } from '@features/solana/CollectablePreview' +import { MessagePreview } from '@features/solana/MessagePreview' +import { PaymentPreivew } from '@features/solana/PaymentPreview' +import { useSolana } from '@features/solana/SolanaProvider' +import { useWalletSign } from '@features/solana/WalletSignProvider' +import { WalletStandardMessageTypes } from '@features/solana/walletSignBottomSheetTypes' import { claimAllRewards, claimRewards, diff --git a/src/services/HotspotService/index.tsx b/src/services/HotspotService/index.tsx deleted file mode 100644 index 39cf9fe6b..000000000 --- a/src/services/HotspotService/index.tsx +++ /dev/null @@ -1,26 +0,0 @@ -import React, { useMemo } from 'react' -import Hotspot from '@assets/images/hotspot.svg' -import ServiceSheetPage, { - ServiceNavBarOption, -} from '@components/ServiceSheetPage' -import CollectablesNavigator from '@features/collectables/CollectablesNavigator' -import { StackNavigationProp } from '@react-navigation/stack' - -export type HotspotServiceStackParamList = { - Hotspot: undefined -} - -export type HotspotServiceNavigationProp = - StackNavigationProp - -const HotspotService = () => { - const options = useMemo((): Array => { - return [ - { name: 'Hotspot', Icon: Hotspot, component: CollectablesNavigator }, - ] - }, []) - - return -} - -export default HotspotService diff --git a/src/services/WalletService/pages/SendPage/index.tsx b/src/services/WalletService/pages/SendPage/index.tsx deleted file mode 100644 index dea286d75..000000000 --- a/src/services/WalletService/pages/SendPage/index.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import React from 'react' -import { ReAnimatedBox } from '@components/AnimatedBox' -import { FadeIn } from 'react-native-reanimated' -import SendPageNavigator from './SentPageNavigator' - -const SendPage = () => { - return ( - - - - ) -} - -export default SendPage diff --git a/src/services/WalletService/pages/WalletPage/index.tsx b/src/services/WalletService/pages/WalletPage/index.tsx deleted file mode 100644 index 6eb2c8c24..000000000 --- a/src/services/WalletService/pages/WalletPage/index.tsx +++ /dev/null @@ -1,8 +0,0 @@ -import React from 'react' -import WalletPageNavigator from './WalletPageNavigator' - -const WalletPage = () => { - return -} - -export default WalletPage diff --git a/src/store/rootReducer.ts b/src/store/rootReducer.ts index c2923b09e..743ffaa1e 100644 --- a/src/store/rootReducer.ts +++ b/src/store/rootReducer.ts @@ -29,6 +29,12 @@ const solanaConfig = { blacklist: ['payment'], } +const appConfig = { + key: appSliceName, + storage: AsyncStorage, + blacklist: ['rootSheetPosition'], +} + const notificationsConfig = { key: notificationsSliceName, storage: AsyncStorage, @@ -57,7 +63,7 @@ const reducer = combineReducers({ notificationsReducer, ), [authSliceName]: authReducer, - [appSliceName]: appReducer, + [appSliceName]: persistReducer(appConfig, appReducer), [hotspotSliceName]: hotspotReducer, [browserSliceName]: browserReducer, [tokensSliceName]: persistReducer(tokensConfig, tokensReducer), diff --git a/src/store/slices/appSlice.ts b/src/store/slices/appSlice.ts index f8f438a3c..b9e12e419 100644 --- a/src/store/slices/appSlice.ts +++ b/src/store/slices/appSlice.ts @@ -4,6 +4,7 @@ import { Cluster } from '@solana/web3.js' export type AppState = { showBanner: boolean cluster?: Cluster + rootSheetPosition?: number } const initialState: AppState = { @@ -20,6 +21,12 @@ const appSlice = createSlice({ setShowBanner: (state, action: PayloadAction) => { state.showBanner = action.payload }, + setRootSheetPosition: ( + state, + action: PayloadAction, + ) => { + state.rootSheetPosition = action.payload + }, }, }) diff --git a/src/store/slices/balancesSlice.ts b/src/store/slices/balancesSlice.ts index db6a9fcef..7e5711193 100644 --- a/src/store/slices/balancesSlice.ts +++ b/src/store/slices/balancesSlice.ts @@ -3,7 +3,7 @@ import { PayloadAction, createAsyncThunk, createSlice } from '@reduxjs/toolkit' import { AccountLayout, TOKEN_PROGRAM_ID, getMint } from '@solana/spl-token' import { Cluster, PublicKey } from '@solana/web3.js' import { PURGE } from 'redux-persist' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import { AccountBalance, Prices, TokenAccount } from '../../types/balance' import { getBalanceHistory, getTokenPrices } from '../../utils/walletApiV2' diff --git a/src/store/slices/browserSlice.ts b/src/store/slices/browserSlice.ts index 0d562d5d0..0b789a719 100644 --- a/src/store/slices/browserSlice.ts +++ b/src/store/slices/browserSlice.ts @@ -1,5 +1,5 @@ import { createSlice, PayloadAction } from '@reduxjs/toolkit' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' export type BrowserDetails = { favorites: string[] diff --git a/src/store/slices/collectablesSlice.ts b/src/store/slices/collectablesSlice.ts index aab9260c8..4a7a4d16f 100644 --- a/src/store/slices/collectablesSlice.ts +++ b/src/store/slices/collectablesSlice.ts @@ -2,7 +2,7 @@ import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit' import { Cluster, Connection, PublicKey } from '@solana/web3.js' import { WrappedConnection } from '@utils/WrappedConnection' import { PURGE } from 'redux-persist' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import { CompressedNFT } from '../../types/solana' import * as solUtils from '../../utils/solanaUtils' diff --git a/src/store/slices/hotspotsSlice.ts b/src/store/slices/hotspotsSlice.ts index e5b566c95..50c1cdf41 100644 --- a/src/store/slices/hotspotsSlice.ts +++ b/src/store/slices/hotspotsSlice.ts @@ -4,10 +4,11 @@ import { createAsyncThunk, createSlice, PayloadAction } from '@reduxjs/toolkit' import { Cluster, PublicKey } from '@solana/web3.js' import { PURGE } from 'redux-persist' import { CompressedNFT } from 'src/types/solana' -import { DEFAULT_PAGE_AMOUNT } from '../../features/collectables/HotspotList' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import * as solUtils from '../../utils/solanaUtils' +const DEFAULT_PAGE_AMOUNT = 20 + export type WalletHotspots = { loading: boolean fetchingMore: boolean diff --git a/src/store/slices/notificationsSlice.ts b/src/store/slices/notificationsSlice.ts index 264ef01d2..8eba9822e 100644 --- a/src/store/slices/notificationsSlice.ts +++ b/src/store/slices/notificationsSlice.ts @@ -1,6 +1,6 @@ import { createAsyncThunk, createSlice } from '@reduxjs/toolkit' import { PURGE } from 'redux-persist' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import * as WalletApi from '../../utils/walletApiV2' type NotificationsByResource = Record diff --git a/src/store/slices/solanaSlice.ts b/src/store/slices/solanaSlice.ts index bc9004977..c779a3551 100644 --- a/src/store/slices/solanaSlice.ts +++ b/src/store/slices/solanaSlice.ts @@ -39,7 +39,7 @@ import { first, last } from 'lodash' import { PURGE } from 'redux-persist' import { LazyDistributor } from '@helium/idls/lib/types/lazy_distributor' import { HeliumEntityManager } from '@helium/idls/lib/types/helium_entity_manager' -import { CSAccount } from '../../storage/cloudStorage' +import { CSAccount } from '@config/storage/cloudStorage' import { Activity } from '../../types/activity' import { CompressedNFT, HotspotWithPendingRewards } from '../../types/solana' import * as Logger from '../../utils/logger' diff --git a/src/store/store.ts b/src/store/store.ts index 99d9fd8e6..101ed96a6 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -8,6 +8,7 @@ import { solanaStatusApi } from './slices/solanaStatusApi' import { name as solanaSliceName } from './slices/solanaSlice' import { name as balancesSliceName } from './slices/balancesSlice' import { name as notificationsSliceName } from './slices/notificationsSlice' +import { name as appSliceName } from './slices/appSlice' import Reactotron from '../../ReactotronConfig' const enhancers: StoreEnhancer[] = [] @@ -24,6 +25,7 @@ const persistConfig = { solanaSliceName, balancesSliceName, notificationsSliceName, + appSliceName, ], } diff --git a/src/utils/Balance.tsx b/src/utils/Balance.tsx index 6e3863ac3..0a6302c6e 100644 --- a/src/utils/Balance.tsx +++ b/src/utils/Balance.tsx @@ -8,7 +8,7 @@ import { toNumber, } from '@helium/spl-utils' import { LAMPORTS_PER_SOL, PublicKey } from '@solana/web3.js' -import { useVisibleTokens } from '@storage/TokensProvider' +import { useVisibleTokens } from '@config/storage/TokensProvider' import BN from 'bn.js' import React, { ReactNode, @@ -21,10 +21,10 @@ import React, { } from 'react' import { useAsync } from 'react-async-hook' import { useSelector } from 'react-redux' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' import usePrevious from '../hooks/usePrevious' -import { useSolana } from '../solana/SolanaProvider' -import { useAccountStorage } from '../storage/AccountStorageProvider' -import { useAppStorage } from '../storage/AppStorageProvider' import { RootState } from '../store/rootReducer' import { syncTokenAccounts } from '../store/slices/balancesSlice' import { useAppDispatch } from '../store/store' diff --git a/src/utils/StoreAtaBalance.ts b/src/utils/StoreAtaBalance.ts index 2e3717dca..04cc8f9b2 100644 --- a/src/utils/StoreAtaBalance.ts +++ b/src/utils/StoreAtaBalance.ts @@ -2,8 +2,8 @@ import { useTokenAccount } from '@helium/helium-react-hooks' import { usePublicKey } from '@hooks/usePublicKey' import { AccountLayout } from '@solana/spl-token' import { useEffect } from 'react' -import { useSolana } from '../solana/SolanaProvider' -import { useAccountStorage } from '../storage/AccountStorageProvider' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { balancesSlice } from '../store/slices/balancesSlice' import { useAppDispatch } from '../store/store' diff --git a/src/utils/StoreSolBalance.ts b/src/utils/StoreSolBalance.ts index 92cf74464..44aad4af7 100644 --- a/src/utils/StoreSolBalance.ts +++ b/src/utils/StoreSolBalance.ts @@ -1,7 +1,7 @@ import { useSolOwnedAmount } from '@helium/helium-react-hooks' import { usePublicKey } from '@hooks/usePublicKey' import { useEffect } from 'react' -import { useSolana } from '../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { balancesSlice } from '../store/slices/balancesSlice' import { useAppDispatch } from '../store/store' diff --git a/src/utils/StoreTokenBalance.ts b/src/utils/StoreTokenBalance.ts index 25d29f74d..399aabf2c 100644 --- a/src/utils/StoreTokenBalance.ts +++ b/src/utils/StoreTokenBalance.ts @@ -2,8 +2,8 @@ import { useTokenAccount } from '@helium/helium-react-hooks' import { AccountLayout } from '@solana/spl-token' import { PublicKey } from '@solana/web3.js' import { useEffect } from 'react' -import { useSolana } from '../solana/SolanaProvider' -import { useAccountStorage } from '../storage/AccountStorageProvider' +import { useSolana } from '@features/solana/SolanaProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' import { balancesSlice } from '../store/slices/balancesSlice' import { useAppDispatch } from '../store/store' diff --git a/src/utils/axios.ts b/src/utils/axios.ts new file mode 100644 index 000000000..4ff523936 --- /dev/null +++ b/src/utils/axios.ts @@ -0,0 +1,24 @@ +import axios, { AxiosError } from 'axios' + +export const handleAxiosError = (e: unknown, verbose = true) => { + if (axios.isAxiosError(e)) { + const axiosError = e as AxiosError + const data = JSON.stringify(axiosError.response?.data, null, 2) + const status = axiosError.response?.status || axiosError.status + const { message } = axiosError + const url = axiosError.config?.url + + let errMessage = message + if (verbose) { + errMessage = `Request ${url} failed: \nData: ${data}\nStatus: ${status}\nMessage: ${message}` + } + // logger.breadcrumb(errMessage) + + // eslint-disable-next-line no-console + console.error(axiosError.request) + return errMessage + } + const msg = (e as Error).message || 'Unknown error' + // logger.breadcrumb(msg) + return msg +} diff --git a/src/utils/camera.ts b/src/utils/camera.ts new file mode 100644 index 000000000..09d781f12 --- /dev/null +++ b/src/utils/camera.ts @@ -0,0 +1,32 @@ +import { Platform } from 'react-native' +import { + check, + request, + PERMISSIONS, + PermissionStatus, +} from 'react-native-permissions' + +export const getCameraPermissionStatus = + async (): Promise => { + try { + if (Platform.OS === 'android') { + return await check(PERMISSIONS.ANDROID.CAMERA) + } + + return await check(PERMISSIONS.IOS.CAMERA) + } catch { + return 'unavailable' + } + } + +export const requestCameraPermission = async (): Promise => { + try { + if (Platform.OS === 'android') { + return await request(PERMISSIONS.ANDROID.CAMERA) + } + + return await request(PERMISSIONS.IOS.CAMERA) + } catch { + return 'unavailable' + } +} diff --git a/src/utils/constants.ts b/src/utils/constants.ts index 2aeff32b7..2c7b46c95 100644 --- a/src/utils/constants.ts +++ b/src/utils/constants.ts @@ -42,3 +42,9 @@ export const MIN_BALANCE_THRESHOLD = 0.02 * LAMPORTS_PER_SOL // Make a smaller batch for the sake of ledger. export const MAX_TRANSACTIONS_PER_SIGNATURE_BATCH = 5 + +export const HELIUM_WORLD_POI = + 'mapbox://styles/petermain/cm2lwnp6k00b701qhepzz65no' + +export const HELIUM_WORLD_NO_LABELS = + 'mapbox://styles/petermain/cm2lwmt9k000a01nt3l29dhhu' diff --git a/src/constants/urls.ts b/src/utils/constants/urls.ts similarity index 90% rename from src/constants/urls.ts rename to src/utils/constants/urls.ts index 0e5904e8c..82f8fe92e 100644 --- a/src/constants/urls.ts +++ b/src/utils/constants/urls.ts @@ -1,5 +1,5 @@ import { useCallback } from 'react' -import { useSolana } from '../solana/SolanaProvider' +import { useSolana } from '@features/solana/SolanaProvider' export const EXPLORER_MAINNET_BASE_URL = 'https://explorer.helium.com' export const EXPLORER_TESTNET_BASE_URL = 'https://testnet-explorer.helium.com/' @@ -11,6 +11,8 @@ export const PUBLIC_API_TEST_URL = 'https://testnet-api.helium.wtf/v1' export const PRIVACY_POLICY = 'https://wallet.helium.com/privacy-policy' export const TERMS_OF_SERVICE = 'https://wallet.helium.com/terms-of-service' +export const HOTSPOT_HELP = 'https://hardware.hellohelium.com/en/' + type UrlType = 'block' | 'txn' | 'account' | 'validator' | 'hotspot' const useCreateExplorerUrl = () => { diff --git a/src/constants/wordlists/english.json b/src/utils/constants/wordlists/english.json similarity index 100% rename from src/constants/wordlists/english.json rename to src/utils/constants/wordlists/english.json diff --git a/src/utils/degree.ts b/src/utils/degree.ts new file mode 100644 index 000000000..2bdf94b77 --- /dev/null +++ b/src/utils/degree.ts @@ -0,0 +1,22 @@ +export const degToCompass = (num: number) => { + const val = Math.floor(num / 22.5 + 0.5) + const arr = [ + 'N', + 'NNE', + 'NE', + 'ENE', + 'E', + 'ESE', + 'SE', + 'SSE', + 'S', + 'SSW', + 'SW', + 'WSW', + 'W', + 'WNW', + 'NW', + 'NNW', + ] + return arr[val % 16] +} diff --git a/src/utils/i18n.tsx b/src/utils/i18n.tsx index 5f8ae1aa8..f7a48db38 100644 --- a/src/utils/i18n.tsx +++ b/src/utils/i18n.tsx @@ -4,7 +4,7 @@ import * as RNLocalize from 'react-native-localize' import { useCallback, useState } from 'react' import AsyncStorage from '@react-native-async-storage/async-storage' import { useAsync } from 'react-async-hook' -import en from '../locales/en' +import en from '@config/locales/en' const locales = RNLocalize.getLocales() diff --git a/src/utils/linking.ts b/src/utils/linking.ts index 2b4a59828..5b6586001 100644 --- a/src/utils/linking.ts +++ b/src/utils/linking.ts @@ -5,10 +5,10 @@ import BN from 'bn.js' import * as Linking from 'expo-linking' import qs from 'qs' import queryString from 'query-string' -import { BurnRouteParam } from '@services/WalletService/pages/WalletPage/WalletPageNavigator' -import { PaymentRouteParam } from '@services/WalletService' -import { RootStackParamList } from '../navigation/rootTypes' -import { useAccountStorage } from '../storage/AccountStorageProvider' +import { BurnRouteParam } from '@services/WalletService/pages/WalletPage' +import { PaymentRouteParam } from 'src/app/services/WalletService' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { RootStackParamList } from '../app/rootTypes' import { solAddressIsValid } from './accountUtils' export const APP_LINK_SCHEME = Linking.createURL('') diff --git a/src/utils/location.ts b/src/utils/location.ts new file mode 100644 index 000000000..5132a61b4 --- /dev/null +++ b/src/utils/location.ts @@ -0,0 +1,44 @@ +import Config from 'react-native-config' +import Geocoder from 'react-native-geocoding' + +export const getAddressFromLatLng = async ( + latitude: number, + longitude: number, +) => { + Geocoder.init(Config.GOOGLE_MAPS_API_KEY || '') + const geocode = await Geocoder.from({ + latitude, + longitude, + }) + const postalCode = geocode.results[0].address_components.find((c) => + c.types.includes('postal_code'), + )?.short_name + const country = geocode.results[0].address_components.find((c) => + c.types.includes('country'), + )?.short_name + let city = geocode.results[0].address_components.find( + (c) => + c.types.includes('locality') || c.types.includes('sublocality_level_1'), + )?.long_name + + const state = geocode.results[0].address_components.find((c) => + c.types.includes('administrative_area_level_1'), + )?.short_name + + const street = geocode.results[0].address_components.find((c) => + c.types.includes('route'), + )?.long_name + + if (!city) { + // if city is still not defined, and address components has a neighborhood, use that + // e.g. liverpool, NY + const neighborhood = geocode.results[0].address_components.find((c) => + c.types.includes('neighborhood'), + ) + if (neighborhood) { + city = neighborhood.long_name + } + } + + return { city, postalCode, country, street, state } +} diff --git a/src/utils/makeApiToken.ts b/src/utils/makeApiToken.ts index 60656c88a..d7358d801 100644 --- a/src/utils/makeApiToken.ts +++ b/src/utils/makeApiToken.ts @@ -1,4 +1,4 @@ -import { getKeypair } from '../storage/secureStorage' +import { getKeypair } from '@config/storage/secureStorage' const makeSignature = async (token: { address: string; time: number }) => { const stringifiedToken = JSON.stringify(token) diff --git a/src/components/map/utils.ts b/src/utils/mapUtils.ts similarity index 81% rename from src/components/map/utils.ts rename to src/utils/mapUtils.ts index 83e3568f4..3f0f5144d 100644 --- a/src/components/map/utils.ts +++ b/src/utils/mapUtils.ts @@ -1,6 +1,5 @@ +import { CameraPadding, CameraStop } from '@rnmapbox/maps' import { ViewProps } from 'react-native' -import { CameraStop } from '@maplibre/maplibre-react-native/javascript/components/Camera' -import { CameraPadding } from '@maplibre/maplibre-react-native' export const MIN_MAP_ZOOM = 2 export const MAX_MAP_ZOOM = 18 @@ -13,6 +12,10 @@ type CameraBounds = CameraPadding & { const WORLD_BOUNDS: CameraBounds = { ne: [-134.827109, 57.785781], sw: [129.767893, -30.955724], + paddingLeft: 0, + paddingRight: 0, + paddingTop: 0, + paddingBottom: 0, } export const INITIAL_MAP_VIEW_STATE: { @@ -24,7 +27,7 @@ export const INITIAL_MAP_VIEW_STATE: { } = { centerCoordinate: [-122.419418, 37.774929], bounds: WORLD_BOUNDS, - zoomLevel: 12, + zoomLevel: 17, animationDuration: 500, } diff --git a/src/utils/reverseGeocode.ts b/src/utils/reverseGeocode.ts new file mode 100644 index 000000000..a699ae071 --- /dev/null +++ b/src/utils/reverseGeocode.ts @@ -0,0 +1,66 @@ +import { useAsync } from 'react-async-hook' +import Config from 'react-native-config' + +const reverseGeocode = async ({ + token, + lat, + lng, +}: { + token: string + lat: number + lng: number +}) => { + if (!lat || !lng) return + + const endpoint = `https://api.mapbox.com/geocoding/v5/mapbox.places/${lng},${lat}.json?access_token=${token}` + const response = await fetch(endpoint) + const results = (await response.json()) as { features: Feature[] } + const features = (results?.features || []) as Feature[] + if (!features.length) return + + return features[0] +} + +export const useReverseGeo = (lat?: number, lng?: number) => { + return useAsync(async () => { + if (!Config.MAPBOX_ACCESS_TOKEN || !lat || !lng) return + return reverseGeocode({ token: Config.MAPBOX_ACCESS_TOKEN, lat, lng }) + }, [lat, lng]) +} + +export default reverseGeocode + +export interface Feature { + id: string + type: string + place_type: string[] + relevance: number + properties: Properties + text: string + place_name: string + center: number[] + geometry: Geometry + address?: string + context?: Context[] + bbox?: number[] +} + +export interface Properties { + accuracy?: string + mapbox_id?: string + wikidata?: string + short_code?: string +} + +export interface Geometry { + type: string + coordinates: number[] +} + +export interface Context { + id: string + mapbox_id?: string + text: string + wikidata?: string + short_code?: string +} diff --git a/src/utils/solanaUtils.ts b/src/utils/solanaUtils.ts index b97593e1a..88cb94a30 100644 --- a/src/utils/solanaUtils.ts +++ b/src/utils/solanaUtils.ts @@ -117,7 +117,7 @@ import { token, walletAdapterIdentity, } from '@metaplex-foundation/js' -import { getSessionKey } from '../storage/secureStorage' +import { getSessionKey } from '@config/storage/secureStorage' import { Activity, Payment } from '../types/activity' import { Collectable, @@ -931,7 +931,8 @@ export const getNFTs = async ( page, '', '', - { showFungible: true }, + // TODO: Update helium-program-library to support new options + { showFungible: true, showCollectionMetadata: true } as any, ) return items diff --git a/src/utils/useBalanceHistory.tsx b/src/utils/useBalanceHistory.tsx index 029708902..8887c3f0d 100644 --- a/src/utils/useBalanceHistory.tsx +++ b/src/utils/useBalanceHistory.tsx @@ -1,12 +1,12 @@ import { useEffect, useRef } from 'react' import { AppState } from 'react-native' import { useSelector } from 'react-redux' -import { useAppStorage } from '../storage/AppStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' +import { useAccountStorage } from '@config/storage/AccountStorageProvider' +import { useSolana } from '@features/solana/SolanaProvider' import { RootState } from '../store/rootReducer' import { useAppDispatch } from '../store/store' import { readBalanceHistory } from '../store/slices/balancesSlice' -import { useAccountStorage } from '../storage/AccountStorageProvider' -import { useSolana } from '../solana/SolanaProvider' export const useBalanceHistory = () => { const { currentAccount } = useAccountStorage() diff --git a/src/utils/usePollTokenPrices.tsx b/src/utils/usePollTokenPrices.tsx index bb0a099c2..8e56e3200 100644 --- a/src/utils/usePollTokenPrices.tsx +++ b/src/utils/usePollTokenPrices.tsx @@ -1,6 +1,6 @@ import { useCallback, useEffect } from 'react' import { useSelector } from 'react-redux' -import { useAppStorage } from '../storage/AppStorageProvider' +import { useAppStorage } from '@config/storage/AppStorageProvider' import { RootState } from '../store/rootReducer' import { useAppDispatch } from '../store/store' import { readTokenPrices } from '../store/slices/balancesSlice' diff --git a/src/utils/walletApiV2.ts b/src/utils/walletApiV2.ts index 42423a534..f5b631c86 100644 --- a/src/utils/walletApiV2.ts +++ b/src/utils/walletApiV2.ts @@ -2,10 +2,10 @@ import axios from 'axios' import Config from 'react-native-config' import { Cluster } from '@solana/web3.js' import { heliumAddressFromSolAddress } from '@helium/spl-utils' -import { getSecureItem } from '../storage/secureStorage' +import { getSecureItem } from '@config/storage/secureStorage' +import { CSAccount } from '@config/storage/cloudStorage' import { AccountBalance, Prices } from '../types/balance' import makeApiToken from './makeApiToken' -import { CSAccount } from '../storage/cloudStorage' export type Notification = { title: string diff --git a/tsconfig.json b/tsconfig.json index ce20e39d7..98139a039 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -42,16 +42,15 @@ "@helium/crypto": ["./node_modules/@helium/crypto-react-native"], "@assets": ["./src/assets"], "@components/*": ["./src/components/*"], - "@constants/*": ["./src/constants/*"], "@components": ["src/components/index"], "@hooks/*": ["./src/hooks/*"], - "@theme/*": ["./src/theme/*"], "@utils/*": ["./src/utils/*"], - "@storage/*": ["./src/storage/*"], + "@config/*": ["./src/config/*"], "@types/*": ["./src/types/*"], "@features/*": ["./src/features/*"], - "@services/*": ["./src/services/*"], - "@store/*": ["./src/store/*"] + "@services/*": ["src/app/services/*"], + "@store/*": ["./src/store/*"], + "@app/*": ["./src/app/*"] } }, "exclude": [ diff --git a/yarn.lock b/yarn.lock index 2fae13c8c..4831d31e1 100644 --- a/yarn.lock +++ b/yarn.lock @@ -34,6 +34,44 @@ __metadata: languageName: node linkType: hard +"@ardatan/relay-compiler@npm:12.0.0": + version: 12.0.0 + resolution: "@ardatan/relay-compiler@npm:12.0.0" + dependencies: + "@babel/core": ^7.14.0 + "@babel/generator": ^7.14.0 + "@babel/parser": ^7.14.0 + "@babel/runtime": ^7.0.0 + "@babel/traverse": ^7.14.0 + "@babel/types": ^7.0.0 + babel-preset-fbjs: ^3.4.0 + chalk: ^4.0.0 + fb-watchman: ^2.0.0 + fbjs: ^3.0.0 + glob: ^7.1.1 + immutable: ~3.7.6 + invariant: ^2.2.4 + nullthrows: ^1.1.1 + relay-runtime: 12.0.0 + signedsource: ^1.0.0 + yargs: ^15.3.1 + peerDependencies: + graphql: "*" + bin: + relay-compiler: bin/relay-compiler + checksum: f0cec120d02961ee8652e0dde72d9e425bc97cad5d0f767d8764cfd30952294eb2838432f33e4da8bb6999d0c13dcd1df128280666bfea373294d98aa8033ae7 + languageName: node + linkType: hard + +"@ardatan/sync-fetch@npm:^0.0.1": + version: 0.0.1 + resolution: "@ardatan/sync-fetch@npm:0.0.1" + dependencies: + node-fetch: ^2.6.1 + checksum: af39bdfb4c2b35bd2c6acc540a5e302730dae17e73d3a18cd1a4aa50c1c741cb1869dffdef1379c491da5ad2e3cfa2bf3a8064e6046c12b46c6a97f54f100a8d + languageName: node + linkType: hard + "@azure/core-asynciterator-polyfill@npm:^1.0.2": version: 1.0.2 resolution: "@azure/core-asynciterator-polyfill@npm:1.0.2" @@ -69,6 +107,17 @@ __metadata: languageName: node linkType: hard +"@babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0": + version: 7.26.2 + resolution: "@babel/code-frame@npm:7.26.2" + dependencies: + "@babel/helper-validator-identifier": ^7.25.9 + js-tokens: ^4.0.0 + picocolors: ^1.0.0 + checksum: db13f5c42d54b76c1480916485e6900748bbcb0014a8aca87f50a091f70ff4e0d0a6db63cade75eb41fcc3d2b6ba0a7f89e343def4f96f00269b41b8ab8dd7b8 + languageName: node + linkType: hard + "@babel/compat-data@npm:^7.17.7, @babel/compat-data@npm:^7.20.1, @babel/compat-data@npm:^7.20.5, @babel/compat-data@npm:^7.22.6, @babel/compat-data@npm:^7.25.2": version: 7.25.2 resolution: "@babel/compat-data@npm:7.25.2" @@ -76,6 +125,13 @@ __metadata: languageName: node linkType: hard +"@babel/compat-data@npm:^7.25.9": + version: 7.26.2 + resolution: "@babel/compat-data@npm:7.26.2" + checksum: d52fae9b0dc59b409d6005ae6b172e89329f46d68136130065ebe923a156fc633e0f1c8600b3e319b9e0f99fd948f64991a5419e2e9431d00d9d235d5f7a7618 + languageName: node + linkType: hard + "@babel/core@npm:7.20.12": version: 7.20.12 resolution: "@babel/core@npm:7.20.12" @@ -122,6 +178,29 @@ __metadata: languageName: node linkType: hard +"@babel/core@npm:^7.14.0, @babel/core@npm:^7.22.9": + version: 7.26.0 + resolution: "@babel/core@npm:7.26.0" + dependencies: + "@ampproject/remapping": ^2.2.0 + "@babel/code-frame": ^7.26.0 + "@babel/generator": ^7.26.0 + "@babel/helper-compilation-targets": ^7.25.9 + "@babel/helper-module-transforms": ^7.26.0 + "@babel/helpers": ^7.26.0 + "@babel/parser": ^7.26.0 + "@babel/template": ^7.25.9 + "@babel/traverse": ^7.25.9 + "@babel/types": ^7.26.0 + convert-source-map: ^2.0.0 + debug: ^4.1.0 + gensync: ^1.0.0-beta.2 + json5: ^2.2.3 + semver: ^6.3.1 + checksum: b296084cfd818bed8079526af93b5dfa0ba70282532d2132caf71d4060ab190ba26d3184832a45accd82c3c54016985a4109ab9118674347a7e5e9bc464894e6 + languageName: node + linkType: hard + "@babel/eslint-parser@npm:^7.20.0": version: 7.25.1 resolution: "@babel/eslint-parser@npm:7.25.1" @@ -136,6 +215,19 @@ __metadata: languageName: node linkType: hard +"@babel/generator@npm:^7.14.0, @babel/generator@npm:^7.18.13, @babel/generator@npm:^7.25.9, @babel/generator@npm:^7.26.0": + version: 7.26.2 + resolution: "@babel/generator@npm:7.26.2" + dependencies: + "@babel/parser": ^7.26.2 + "@babel/types": ^7.26.0 + "@jridgewell/gen-mapping": ^0.3.5 + "@jridgewell/trace-mapping": ^0.3.25 + jsesc: ^3.0.2 + checksum: 6ff850b7d6082619f8c2f518d993cf7254cfbaa20b026282cbef5c9b2197686d076a432b18e36c4d1a42721c016df4f77a8f62c67600775d9683621d534b91b4 + languageName: node + linkType: hard + "@babel/generator@npm:^7.20.0, @babel/generator@npm:^7.20.5, @babel/generator@npm:^7.20.7, @babel/generator@npm:^7.22.15, @babel/generator@npm:^7.25.0, @babel/generator@npm:^7.7.2": version: 7.25.0 resolution: "@babel/generator@npm:7.25.0" @@ -179,6 +271,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-compilation-targets@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-compilation-targets@npm:7.25.9" + dependencies: + "@babel/compat-data": ^7.25.9 + "@babel/helper-validator-option": ^7.25.9 + browserslist: ^4.24.0 + lru-cache: ^5.1.1 + semver: ^6.3.1 + checksum: 3af536e2db358b38f968abdf7d512d425d1018fef2f485d6f131a57a7bcaed32c606b4e148bb230e1508fa42b5b2ac281855a68eb78270f54698c48a83201b9b + languageName: node + linkType: hard + "@babel/helper-create-class-features-plugin@npm:^7.18.6, @babel/helper-create-class-features-plugin@npm:^7.21.0, @babel/helper-create-class-features-plugin@npm:^7.22.11, @babel/helper-create-class-features-plugin@npm:^7.22.15, @babel/helper-create-class-features-plugin@npm:^7.22.5, @babel/helper-create-class-features-plugin@npm:^7.25.0": version: 7.25.0 resolution: "@babel/helper-create-class-features-plugin@npm:7.25.0" @@ -286,6 +391,16 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-imports@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-module-imports@npm:7.25.9" + dependencies: + "@babel/traverse": ^7.25.9 + "@babel/types": ^7.25.9 + checksum: 1b411ce4ca825422ef7065dffae7d8acef52023e51ad096351e3e2c05837e9bf9fca2af9ca7f28dc26d596a588863d0fedd40711a88e350b736c619a80e704e6 + languageName: node + linkType: hard + "@babel/helper-module-transforms@npm:^7.20.11, @babel/helper-module-transforms@npm:^7.22.20, @babel/helper-module-transforms@npm:^7.22.5, @babel/helper-module-transforms@npm:^7.22.9, @babel/helper-module-transforms@npm:^7.24.8": version: 7.25.2 resolution: "@babel/helper-module-transforms@npm:7.25.2" @@ -300,6 +415,19 @@ __metadata: languageName: node linkType: hard +"@babel/helper-module-transforms@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/helper-module-transforms@npm:7.26.0" + dependencies: + "@babel/helper-module-imports": ^7.25.9 + "@babel/helper-validator-identifier": ^7.25.9 + "@babel/traverse": ^7.25.9 + peerDependencies: + "@babel/core": ^7.0.0 + checksum: 942eee3adf2b387443c247a2c190c17c4fd45ba92a23087abab4c804f40541790d51ad5277e4b5b1ed8d5ba5b62de73857446b7742f835c18ebd350384e63917 + languageName: node + linkType: hard + "@babel/helper-optimise-call-expression@npm:^7.22.5, @babel/helper-optimise-call-expression@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-optimise-call-expression@npm:7.24.7" @@ -378,6 +506,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-string-parser@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-string-parser@npm:7.25.9" + checksum: 6435ee0849e101681c1849868278b5aee82686ba2c1e27280e5e8aca6233af6810d39f8e4e693d2f2a44a3728a6ccfd66f72d71826a94105b86b731697cdfa99 + languageName: node + linkType: hard + "@babel/helper-validator-identifier@npm:^7.22.5, @babel/helper-validator-identifier@npm:^7.24.7": version: 7.24.7 resolution: "@babel/helper-validator-identifier@npm:7.24.7" @@ -385,6 +520,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-identifier@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-validator-identifier@npm:7.25.9" + checksum: 5b85918cb1a92a7f3f508ea02699e8d2422fe17ea8e82acd445006c0ef7520fbf48e3dbcdaf7b0a1d571fc3a2715a29719e5226636cb6042e15fe6ed2a590944 + languageName: node + linkType: hard + "@babel/helper-validator-option@npm:^7.18.6, @babel/helper-validator-option@npm:^7.21.0, @babel/helper-validator-option@npm:^7.22.15, @babel/helper-validator-option@npm:^7.24.7, @babel/helper-validator-option@npm:^7.24.8": version: 7.24.8 resolution: "@babel/helper-validator-option@npm:7.24.8" @@ -392,6 +534,13 @@ __metadata: languageName: node linkType: hard +"@babel/helper-validator-option@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/helper-validator-option@npm:7.25.9" + checksum: 9491b2755948ebbdd68f87da907283698e663b5af2d2b1b02a2765761974b1120d5d8d49e9175b167f16f72748ffceec8c9cf62acfbee73f4904507b246e2b3d + languageName: node + linkType: hard + "@babel/helper-wrap-function@npm:^7.25.0": version: 7.25.0 resolution: "@babel/helper-wrap-function@npm:7.25.0" @@ -414,6 +563,16 @@ __metadata: languageName: node linkType: hard +"@babel/helpers@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/helpers@npm:7.26.0" + dependencies: + "@babel/template": ^7.25.9 + "@babel/types": ^7.26.0 + checksum: d77fe8d45033d6007eadfa440355c1355eed57902d5a302f450827ad3d530343430a21210584d32eef2f216ae463d4591184c6fc60cf205bbf3a884561469200 + languageName: node + linkType: hard + "@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.24.7": version: 7.24.7 resolution: "@babel/highlight@npm:7.24.7" @@ -437,6 +596,17 @@ __metadata: languageName: node linkType: hard +"@babel/parser@npm:^7.14.0, @babel/parser@npm:^7.16.8, @babel/parser@npm:^7.25.9, @babel/parser@npm:^7.26.0, @babel/parser@npm:^7.26.2": + version: 7.26.2 + resolution: "@babel/parser@npm:7.26.2" + dependencies: + "@babel/types": ^7.26.0 + bin: + parser: ./bin/babel-parser.js + checksum: c88b5ea0adf357ef909cdc2c31e284a154943edc59f63f6e8a4c20bf773a1b2f3d8c2205e59c09ca7cdad91e7466300114548876529277a80651b6436a48d5d9 + languageName: node + linkType: hard + "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:^7.18.6": version: 7.22.15 resolution: "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@npm:7.22.15" @@ -1717,6 +1887,32 @@ __metadata: languageName: node linkType: hard +"@babel/template@npm:^7.18.10, @babel/template@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/template@npm:7.25.9" + dependencies: + "@babel/code-frame": ^7.25.9 + "@babel/parser": ^7.25.9 + "@babel/types": ^7.25.9 + checksum: 103641fea19c7f4e82dc913aa6b6ac157112a96d7c724d513288f538b84bae04fb87b1f1e495ac1736367b1bc30e10f058b30208fb25f66038e1f1eb4e426472 + languageName: node + linkType: hard + +"@babel/traverse@npm:^7.14.0, @babel/traverse@npm:^7.16.8, @babel/traverse@npm:^7.25.9": + version: 7.25.9 + resolution: "@babel/traverse@npm:7.25.9" + dependencies: + "@babel/code-frame": ^7.25.9 + "@babel/generator": ^7.25.9 + "@babel/parser": ^7.25.9 + "@babel/template": ^7.25.9 + "@babel/types": ^7.25.9 + debug: ^4.3.1 + globals: ^11.1.0 + checksum: 901d325662ff1dd9bc51de00862e01055fa6bc374f5297d7e3731f2f0e268bbb1d2141f53fa82860aa308ee44afdcf186a948f16c83153927925804b95a9594d + languageName: node + linkType: hard + "@babel/traverse@npm:^7.20.0, @babel/traverse@npm:^7.20.12, @babel/traverse@npm:^7.22.15, @babel/traverse@npm:^7.22.20, @babel/traverse@npm:^7.24.7, @babel/traverse@npm:^7.24.8, @babel/traverse@npm:^7.25.0, @babel/traverse@npm:^7.25.2": version: 7.25.3 resolution: "@babel/traverse@npm:7.25.3" @@ -1743,6 +1939,16 @@ __metadata: languageName: node linkType: hard +"@babel/types@npm:^7.16.8, @babel/types@npm:^7.18.13, @babel/types@npm:^7.25.9, @babel/types@npm:^7.26.0": + version: 7.26.0 + resolution: "@babel/types@npm:7.26.0" + dependencies: + "@babel/helper-string-parser": ^7.25.9 + "@babel/helper-validator-identifier": ^7.25.9 + checksum: a3dd37dabac693018872da96edb8c1843a605c1bfacde6c3f504fba79b972426a6f24df70aa646356c0c1b19bdd2c722c623c684a996c002381071680602280d + languageName: node + linkType: hard + "@bcoe/v8-coverage@npm:^0.2.3": version: 0.2.3 resolution: "@bcoe/v8-coverage@npm:0.2.3" @@ -2486,36 +2692,6 @@ __metadata: languageName: node linkType: hard -"@expo/config-plugins@npm:^4.0.3": - version: 4.1.5 - resolution: "@expo/config-plugins@npm:4.1.5" - dependencies: - "@expo/config-types": ^45.0.0 - "@expo/json-file": 8.2.36 - "@expo/plist": 0.0.18 - "@expo/sdk-runtime-versions": ^1.0.0 - "@react-native/normalize-color": ^2.0.0 - chalk: ^4.1.2 - debug: ^4.3.1 - find-up: ~5.0.0 - getenv: ^1.0.0 - glob: 7.1.6 - resolve-from: ^5.0.0 - semver: ^7.3.5 - slash: ^3.0.0 - xcode: ^3.0.1 - xml2js: 0.4.23 - checksum: f631217251281b1e25949adbec175ef1362dd08d837ce676ed8350c1401b5764091ba100f76f42adb623e4cdcde5b270be77ad6606f978d419c07fd8c81b701c - languageName: node - linkType: hard - -"@expo/config-types@npm:^45.0.0": - version: 45.0.0 - resolution: "@expo/config-types@npm:45.0.0" - checksum: 9b4866540654da61af0985ebfc975b3cb690625acf7742443a7e56263bf134b261e22719720982223407f8957d08a3646178c79f482861218882f0956d804021 - languageName: node - linkType: hard - "@expo/config-types@npm:^51.0.0-unreleased": version: 51.0.2 resolution: "@expo/config-types@npm:51.0.2" @@ -2594,17 +2770,6 @@ __metadata: languageName: node linkType: hard -"@expo/json-file@npm:8.2.36": - version: 8.2.36 - resolution: "@expo/json-file@npm:8.2.36" - dependencies: - "@babel/code-frame": ~7.10.4 - json5: ^1.0.1 - write-file-atomic: ^2.3.0 - checksum: 37ce80b3472fef2a56136ebff5993d98ab4fbd45c4d7791ff47be80438dbeabd84bc699a401da0c314357ef65d8fff87a5a1241b3119db2d575878f9321bd1e7 - languageName: node - linkType: hard - "@expo/json-file@npm:^8.3.0, @expo/json-file@npm:~8.3.0": version: 8.3.3 resolution: "@expo/json-file@npm:8.3.3" @@ -2672,17 +2837,6 @@ __metadata: languageName: node linkType: hard -"@expo/plist@npm:0.0.18": - version: 0.0.18 - resolution: "@expo/plist@npm:0.0.18" - dependencies: - "@xmldom/xmldom": ~0.7.0 - base64-js: ^1.2.3 - xmlbuilder: ^14.0.0 - checksum: 42f5743fcd2a07b55a9f048d27cf0f273510ab35dde1f7030b22dc8c30ab2cfb65c6e68f8aa58fbcfa00177fdc7c9696d0004083c9a47c36fd4ac7fea27d6ccc - languageName: node - linkType: hard - "@expo/plist@npm:^0.1.0": version: 0.1.3 resolution: "@expo/plist@npm:0.1.3" @@ -2710,165 +2864,866 @@ __metadata: semver: ^7.6.0 xml2js: 0.6.0 peerDependencies: - expo-modules-autolinking: ">=0.8.1" - checksum: 7210870c33b0fd78c4a1e758f801af3f47e16cf67a3a4a46a12bb10ad242e7925ec7f027dc348b6b4121c04ab76924630730f49debe086ccb95f72dc11c39c10 + expo-modules-autolinking: ">=0.8.1" + checksum: 7210870c33b0fd78c4a1e758f801af3f47e16cf67a3a4a46a12bb10ad242e7925ec7f027dc348b6b4121c04ab76924630730f49debe086ccb95f72dc11c39c10 + languageName: node + linkType: hard + +"@expo/prebuild-config@npm:7.0.8": + version: 7.0.8 + resolution: "@expo/prebuild-config@npm:7.0.8" + dependencies: + "@expo/config": ~9.0.0-beta.0 + "@expo/config-plugins": ~8.0.8 + "@expo/config-types": ^51.0.0-unreleased + "@expo/image-utils": ^0.5.0 + "@expo/json-file": ^8.3.0 + "@react-native/normalize-colors": 0.74.85 + debug: ^4.3.1 + fs-extra: ^9.0.0 + resolve-from: ^5.0.0 + semver: ^7.6.0 + xml2js: 0.6.0 + peerDependencies: + expo-modules-autolinking: ">=0.8.1" + checksum: b3715b10aa5aa9e60e97802feaaa6ddca4330752ec566d9f272e23417d00e2a298b6cc2f0d33f8a46a3c907f10b862d2975b737ba10e194ac834eae48847923b + languageName: node + linkType: hard + +"@expo/rudder-sdk-node@npm:1.1.1": + version: 1.1.1 + resolution: "@expo/rudder-sdk-node@npm:1.1.1" + dependencies: + "@expo/bunyan": ^4.0.0 + "@segment/loosely-validate-event": ^2.0.0 + fetch-retry: ^4.1.1 + md5: ^2.2.1 + node-fetch: ^2.6.1 + remove-trailing-slash: ^0.1.0 + uuid: ^8.3.2 + checksum: 5ce50c1a82f899b135600cb29cddf3fab601938700c8203f16a1394d2ffbf9e2cdd246b92ff635f8415121072d99a7b4a370f715b78f6680594b5a630e8d78c6 + languageName: node + linkType: hard + +"@expo/sdk-runtime-versions@npm:^1.0.0": + version: 1.0.0 + resolution: "@expo/sdk-runtime-versions@npm:1.0.0" + checksum: 0942d5a356f590e8dc795761456cc48b3e2d6a38ad2a02d6774efcdc5a70424e05623b4e3e5d2fec0cdc30f40dde05c14391c781607eed3971bf8676518bfd9d + languageName: node + linkType: hard + +"@expo/spawn-async@npm:^1.5.0, @expo/spawn-async@npm:^1.7.2": + version: 1.7.2 + resolution: "@expo/spawn-async@npm:1.7.2" + dependencies: + cross-spawn: ^7.0.3 + checksum: d99e5ff6d303ec9b0105f97c4fa6c65bca526c7d4d0987997c35cc745fa8224adf009942d01808192ebb9fa30619a53316641958631e85cf17b773d9eeda2597 + languageName: node + linkType: hard + +"@expo/vector-icons@npm:^14.0.0": + version: 14.0.2 + resolution: "@expo/vector-icons@npm:14.0.2" + dependencies: + prop-types: ^15.8.1 + checksum: 49e27ff52eb138745313fa2c39863fb762230b0089b910d668d7f2c06b7e71a0249dc3a26bfc8725d07bdfaadab1dbcbce087b34dfc244b00a15fc02fe4866e2 + languageName: node + linkType: hard + +"@expo/xcpretty@npm:^4.3.0": + version: 4.3.1 + resolution: "@expo/xcpretty@npm:4.3.1" + dependencies: + "@babel/code-frame": 7.10.4 + chalk: ^4.1.0 + find-up: ^5.0.0 + js-yaml: ^4.1.0 + bin: + excpretty: build/cli.js + checksum: dbf3e2d7f501fbbd11baf0c0aa9057c8a87efe0993a82caafd30c66977ac430d03fa84e27b529e3d0b04fee8c6beec1bd135f0522229dca91220561b76309854 + languageName: node + linkType: hard + +"@fastify/ajv-compiler@npm:^3.5.0": + version: 3.5.0 + resolution: "@fastify/ajv-compiler@npm:3.5.0" + dependencies: + ajv: ^8.11.0 + ajv-formats: ^2.1.1 + fast-uri: ^2.0.0 + checksum: 5e5b16469f8d586473d0b32e3a9cf38c0d86ef2a6fb7ea12ed7f3665642bd8eb2dde9adcc317814369cb5a58210bfdac35996fa87d1cc23e88bbc799f0b128b0 + languageName: node + linkType: hard + +"@fastify/cors@npm:^8.1.1": + version: 8.4.0 + resolution: "@fastify/cors@npm:8.4.0" + dependencies: + fastify-plugin: ^4.0.0 + mnemonist: 0.39.5 + checksum: 4fe99623918b9c58f6590dac00fe778f2755eacc47de726acf97b3a3305a414425b393422429efca1b261514100f4092a4ad41bc549c6f6edf60e83f9f5d3701 + languageName: node + linkType: hard + +"@fastify/deepmerge@npm:^1.0.0": + version: 1.3.0 + resolution: "@fastify/deepmerge@npm:1.3.0" + checksum: 33ec927905dca320d7ae9535a1521909f7c82339706345324ab6287ad100589a799b8257c15b0e582c7bb74e2aa4883d82ba0228d7b116aa8789ada4f78d6974 + languageName: node + linkType: hard + +"@fastify/error@npm:^3.2.0": + version: 3.3.0 + resolution: "@fastify/error@npm:3.3.0" + checksum: 202507c8c7f49922cac2f5afc82802151b0bd9c583ca1c2850bf43d0f4cd97eedb3a3388b9016da74f8a01b517a5861d1f666c506dd64fd22995e559bc139264 + languageName: node + linkType: hard + +"@fastify/fast-json-stringify-compiler@npm:^4.3.0": + version: 4.3.0 + resolution: "@fastify/fast-json-stringify-compiler@npm:4.3.0" + dependencies: + fast-json-stringify: ^5.7.0 + checksum: 2734afabe2539d3e15d2bd9f8dfee756d9cd969f7303dc085dd91c744ff61742bb0d3ebd3b561cf3c32be54567048a634b4962f943eb6bd9ed3fbd71cbf6a4fa + languageName: node + linkType: hard + +"@gorhom/bottom-sheet@npm:5.0.4": + version: 5.0.4 + resolution: "@gorhom/bottom-sheet@npm:5.0.4" + dependencies: + "@gorhom/portal": 1.0.14 + invariant: ^2.2.4 + peerDependencies: + "@types/react": "*" + "@types/react-native": "*" + react: "*" + react-native: "*" + react-native-gesture-handler: ">=2.16.1" + react-native-reanimated: ">=3.10.1" + peerDependenciesMeta: + "@types/react": + optional: true + "@types/react-native": + optional: true + checksum: 7ccfca84b0c9555efaa127ef17b6f2a16c15ec48f0db12bde146da9c86d599d126abb2cb8eecfb33811c26574a5ceddaee87d995d5e90ad7166770d6675c414b + languageName: node + linkType: hard + +"@gorhom/portal@npm:1.0.14": + version: 1.0.14 + resolution: "@gorhom/portal@npm:1.0.14" + dependencies: + nanoid: ^3.3.1 + peerDependencies: + react: "*" + react-native: "*" + checksum: 227bb96a2db854ab29bb9da8d4f3823c7f7448358de459709dd1b78522110da564c9a8734c6bc7d7153ed7c99320e0fb5d60b420c2ebb75ecaf2f0d757f410f9 + languageName: node + linkType: hard + +"@graphql-codegen/add@npm:^5.0.3": + version: 5.0.3 + resolution: "@graphql-codegen/add@npm:5.0.3" + dependencies: + "@graphql-codegen/plugin-helpers": ^5.0.3 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 5196b6c64907f03dc1adc0ac4f98ed5fe69abe0eb87027a55dfc14b178cc1fee2bc47f68c8f5a68ce7aa4bc5a4f970f983d1d85b6d7a20489e50657baccd2ad0 + languageName: node + linkType: hard + +"@graphql-codegen/cli@npm:^5.0.0": + version: 5.0.3 + resolution: "@graphql-codegen/cli@npm:5.0.3" + dependencies: + "@babel/generator": ^7.18.13 + "@babel/template": ^7.18.10 + "@babel/types": ^7.18.13 + "@graphql-codegen/client-preset": ^4.4.0 + "@graphql-codegen/core": ^4.0.2 + "@graphql-codegen/plugin-helpers": ^5.0.3 + "@graphql-tools/apollo-engine-loader": ^8.0.0 + "@graphql-tools/code-file-loader": ^8.0.0 + "@graphql-tools/git-loader": ^8.0.0 + "@graphql-tools/github-loader": ^8.0.0 + "@graphql-tools/graphql-file-loader": ^8.0.0 + "@graphql-tools/json-file-loader": ^8.0.0 + "@graphql-tools/load": ^8.0.0 + "@graphql-tools/prisma-loader": ^8.0.0 + "@graphql-tools/url-loader": ^8.0.0 + "@graphql-tools/utils": ^10.0.0 + "@whatwg-node/fetch": ^0.9.20 + chalk: ^4.1.0 + cosmiconfig: ^8.1.3 + debounce: ^1.2.0 + detect-indent: ^6.0.0 + graphql-config: ^5.1.1 + inquirer: ^8.0.0 + is-glob: ^4.0.1 + jiti: ^1.17.1 + json-to-pretty-yaml: ^1.2.2 + listr2: ^4.0.5 + log-symbols: ^4.0.0 + micromatch: ^4.0.5 + shell-quote: ^1.7.3 + string-env-interpolation: ^1.0.1 + ts-log: ^2.2.3 + tslib: ^2.4.0 + yaml: ^2.3.1 + yargs: ^17.0.0 + peerDependencies: + "@parcel/watcher": ^2.1.0 + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + "@parcel/watcher": + optional: true + bin: + gql-gen: cjs/bin.js + graphql-code-generator: cjs/bin.js + graphql-codegen: cjs/bin.js + graphql-codegen-esm: esm/bin.js + checksum: 8a28419b25e73b4edf5006a93243a24ecdcc030b80d19dbf9153326c45382b2654b9275fa5b29035864652e3698196883e93ba593339cba43221c46cc20da697 + languageName: node + linkType: hard + +"@graphql-codegen/client-preset@npm:^4.4.0": + version: 4.5.0 + resolution: "@graphql-codegen/client-preset@npm:4.5.0" + dependencies: + "@babel/helper-plugin-utils": ^7.20.2 + "@babel/template": ^7.20.7 + "@graphql-codegen/add": ^5.0.3 + "@graphql-codegen/gql-tag-operations": 4.0.11 + "@graphql-codegen/plugin-helpers": ^5.1.0 + "@graphql-codegen/typed-document-node": ^5.0.11 + "@graphql-codegen/typescript": ^4.1.1 + "@graphql-codegen/typescript-operations": ^4.3.1 + "@graphql-codegen/visitor-plugin-common": ^5.5.0 + "@graphql-tools/documents": ^1.0.0 + "@graphql-tools/utils": ^10.0.0 + "@graphql-typed-document-node/core": 3.2.0 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 8247074bdb5210c2822e1f3d9c6a37c21d642a4d2241424f1afefdd3a7a29a984da8b9efd250876d6b8f89e056661c70ed70cb96060e71d0f36d5339405f5ed9 + languageName: node + linkType: hard + +"@graphql-codegen/core@npm:^4.0.2": + version: 4.0.2 + resolution: "@graphql-codegen/core@npm:4.0.2" + dependencies: + "@graphql-codegen/plugin-helpers": ^5.0.3 + "@graphql-tools/schema": ^10.0.0 + "@graphql-tools/utils": ^10.0.0 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 5fda4e843174aacd4a481b73b4d259fa2df7ffe4200bd06e95ecd4b3f43aa5969deeaeb51f6cf15a542e99ee5756c3e02a29d9d2ff9891af40e234a8f68ead4d + languageName: node + linkType: hard + +"@graphql-codegen/gql-tag-operations@npm:4.0.11": + version: 4.0.11 + resolution: "@graphql-codegen/gql-tag-operations@npm:4.0.11" + dependencies: + "@graphql-codegen/plugin-helpers": ^5.1.0 + "@graphql-codegen/visitor-plugin-common": 5.5.0 + "@graphql-tools/utils": ^10.0.0 + auto-bind: ~4.0.0 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 68d5eac31547b7012551a72a41caa2be532b85e08efe3efaf7744f27ea4b355a59f032a99f3394b1c2d0eea045d30e2216bf5d86379cbc0e926bf51cb12b4de2 + languageName: node + linkType: hard + +"@graphql-codegen/plugin-helpers@npm:^2.7.2": + version: 2.7.2 + resolution: "@graphql-codegen/plugin-helpers@npm:2.7.2" + dependencies: + "@graphql-tools/utils": ^8.8.0 + change-case-all: 1.0.14 + common-tags: 1.8.2 + import-from: 4.0.0 + lodash: ~4.17.0 + tslib: ~2.4.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 66e0d507ad5db60b67092ebf7632d464d56ab446ac8fd87c293e00d9016944912d8cf9199e3e026b0a9247a50f50c4118a44f49e13675db64211652cd6259b05 + languageName: node + linkType: hard + +"@graphql-codegen/plugin-helpers@npm:^3.0.0": + version: 3.1.2 + resolution: "@graphql-codegen/plugin-helpers@npm:3.1.2" + dependencies: + "@graphql-tools/utils": ^9.0.0 + change-case-all: 1.0.15 + common-tags: 1.8.2 + import-from: 4.0.0 + lodash: ~4.17.0 + tslib: ~2.4.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 4d0c615738570681b5ffd3c07305a35d6aa3e5fd87c9199c0a670b95529ab865b1df978ce584d5b415107a567ac484e56a48db129a6d1d2eb8a254fbd3260e39 + languageName: node + linkType: hard + +"@graphql-codegen/plugin-helpers@npm:^5.0.3, @graphql-codegen/plugin-helpers@npm:^5.1.0": + version: 5.1.0 + resolution: "@graphql-codegen/plugin-helpers@npm:5.1.0" + dependencies: + "@graphql-tools/utils": ^10.0.0 + change-case-all: 1.0.15 + common-tags: 1.8.2 + import-from: 4.0.0 + lodash: ~4.17.0 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 235762e2e7a55898e71fb1d52ef3093c26787c16e7eb5a3df6e06a7b2003da641b9a9c96833091e9fb11f9cf72da9e7c5f19ce124074d5d7d33a419117d050a9 + languageName: node + linkType: hard + +"@graphql-codegen/schema-ast@npm:^4.0.2": + version: 4.1.0 + resolution: "@graphql-codegen/schema-ast@npm:4.1.0" + dependencies: + "@graphql-codegen/plugin-helpers": ^5.0.3 + "@graphql-tools/utils": ^10.0.0 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: cddec7723d708990ac8e33eb8935e72545b60ed7b772452ba45b60e577af950d23503de83f0919d1730f7d52dcb970900d3587d9a54202032164ba3c246d4c10 + languageName: node + linkType: hard + +"@graphql-codegen/typed-document-node@npm:^5.0.11": + version: 5.0.11 + resolution: "@graphql-codegen/typed-document-node@npm:5.0.11" + dependencies: + "@graphql-codegen/plugin-helpers": ^5.1.0 + "@graphql-codegen/visitor-plugin-common": 5.5.0 + auto-bind: ~4.0.0 + change-case-all: 1.0.15 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: c14b16c06910181355c4b3b0d01e023ca394889cf18c1262841280c84c2c00a27692359d8703d4545832183749f185ebf0d519b1ca6970043fce6fb8687aaa9c + languageName: node + linkType: hard + +"@graphql-codegen/typescript-operations@npm:^4.0.1, @graphql-codegen/typescript-operations@npm:^4.3.1": + version: 4.3.1 + resolution: "@graphql-codegen/typescript-operations@npm:4.3.1" + dependencies: + "@graphql-codegen/plugin-helpers": ^5.1.0 + "@graphql-codegen/typescript": ^4.1.1 + "@graphql-codegen/visitor-plugin-common": 5.5.0 + auto-bind: ~4.0.0 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 9618fb8287d6f5d94942da67e48826ae85d9ed2df376a4da686f37438492a4870f209f0473356abd3140762d34021f4c8166a7c8cab63ace8be5f423a8e2f0d3 + languageName: node + linkType: hard + +"@graphql-codegen/typescript-rtk-query@npm:^3.1.1": + version: 3.1.1 + resolution: "@graphql-codegen/typescript-rtk-query@npm:3.1.1" + dependencies: + "@graphql-codegen/plugin-helpers": ^3.0.0 + "@graphql-codegen/visitor-plugin-common": 2.13.1 + auto-bind: ~4.0.0 + change-case-all: 1.0.15 + tslib: ~2.6.0 + peerDependencies: + "@reduxjs/toolkit": ^1.6.0 || ^2.0.0 + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + graphql-request: ^3.4.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + graphql-tag: ^2.0.0 + peerDependenciesMeta: + graphql-request: + optional: true + checksum: 662fb0f3c647c0e09d566b69d21c5ec3f0856d3f33d9efac2c0ed3308a33a9a71ca6058f5a182b26366d5bf4dce077839bb6deb9cfbaa2283e2626cc6b81c68e + languageName: node + linkType: hard + +"@graphql-codegen/typescript@npm:^4.0.1, @graphql-codegen/typescript@npm:^4.1.1": + version: 4.1.1 + resolution: "@graphql-codegen/typescript@npm:4.1.1" + dependencies: + "@graphql-codegen/plugin-helpers": ^5.1.0 + "@graphql-codegen/schema-ast": ^4.0.2 + "@graphql-codegen/visitor-plugin-common": 5.5.0 + auto-bind: ~4.0.0 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 4256dbf935a6780c573864f346b9280271711ea1fe0c746146480faacd77c3b5578479b3daf584a987f3fd83ecfabf486f9cfc58b068460fabae32ee33fbc565 + languageName: node + linkType: hard + +"@graphql-codegen/visitor-plugin-common@npm:2.13.1": + version: 2.13.1 + resolution: "@graphql-codegen/visitor-plugin-common@npm:2.13.1" + dependencies: + "@graphql-codegen/plugin-helpers": ^2.7.2 + "@graphql-tools/optimize": ^1.3.0 + "@graphql-tools/relay-operation-optimizer": ^6.5.0 + "@graphql-tools/utils": ^8.8.0 + auto-bind: ~4.0.0 + change-case-all: 1.0.14 + dependency-graph: ^0.11.0 + graphql-tag: ^2.11.0 + parse-filepath: ^1.0.2 + tslib: ~2.4.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 0c329aa6e435602f2f6c1569ec2091b7850f58cc5dca7ac763c38c82588545ec1110c1de587f5f3949b11ff96f94401d1e63e329607d78424583b276fd08f1ae + languageName: node + linkType: hard + +"@graphql-codegen/visitor-plugin-common@npm:5.5.0, @graphql-codegen/visitor-plugin-common@npm:^5.5.0": + version: 5.5.0 + resolution: "@graphql-codegen/visitor-plugin-common@npm:5.5.0" + dependencies: + "@graphql-codegen/plugin-helpers": ^5.1.0 + "@graphql-tools/optimize": ^2.0.0 + "@graphql-tools/relay-operation-optimizer": ^7.0.0 + "@graphql-tools/utils": ^10.0.0 + auto-bind: ~4.0.0 + change-case-all: 1.0.15 + dependency-graph: ^0.11.0 + graphql-tag: ^2.11.0 + parse-filepath: ^1.0.2 + tslib: ~2.6.0 + peerDependencies: + graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + checksum: 7d2727100be2acdb3a75292093013892bc819c5166905c0d6eab21c5c46561744a2fab252fb43f6b60d4afec8d565416ae7848c2abc413cda7924ef7a7fb6633 + languageName: node + linkType: hard + +"@graphql-tools/apollo-engine-loader@npm:^8.0.0": + version: 8.0.3 + resolution: "@graphql-tools/apollo-engine-loader@npm:8.0.3" + dependencies: + "@ardatan/sync-fetch": ^0.0.1 + "@graphql-tools/utils": ^10.5.5 + "@whatwg-node/fetch": ^0.10.0 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 2c88cf3a44274474cab1350e3e409d00733bf9daf1c828a77b59244bc064798c4e2c046f9e7d08a6f2a451e0bda9619e87a89cee4f7ab16f340da6586cf3bd98 + languageName: node + linkType: hard + +"@graphql-tools/batch-execute@npm:^9.0.5": + version: 9.0.5 + resolution: "@graphql-tools/batch-execute@npm:9.0.5" + dependencies: + "@graphql-tools/utils": ^10.5.5 + dataloader: ^2.2.2 + tslib: ^2.4.0 + value-or-promise: ^1.0.12 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 7ea4d6f59150304862fcafdab31e654b6e175666c6c5c084ce06cfc62936b0e2d02b867d4ce4de804b95b88d4a4575e4c02a5015f0d0a63b6d5eabbf49c36502 + languageName: node + linkType: hard + +"@graphql-tools/code-file-loader@npm:^8.0.0": + version: 8.1.4 + resolution: "@graphql-tools/code-file-loader@npm:8.1.4" + dependencies: + "@graphql-tools/graphql-tag-pluck": 8.3.3 + "@graphql-tools/utils": ^10.5.5 + globby: ^11.0.3 + tslib: ^2.4.0 + unixify: ^1.0.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 08e78e7cbc60d9e2b03972c584d9c6f0224e7da14de35e917a1b1cca3b614cef3fd34a138ea766fe9e04c1aa38c0a6292e1907e451fed1aee1f8e53736a7f290 + languageName: node + linkType: hard + +"@graphql-tools/delegate@npm:^10.1.1": + version: 10.1.1 + resolution: "@graphql-tools/delegate@npm:10.1.1" + dependencies: + "@graphql-tools/batch-execute": ^9.0.5 + "@graphql-tools/executor": ^1.3.2 + "@graphql-tools/schema": ^10.0.7 + "@graphql-tools/utils": ^10.5.5 + "@repeaterjs/repeater": ^3.0.6 + dataloader: ^2.2.2 + dset: ^3.1.2 + tslib: ^2.5.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: d3814c1561eeff07ced69ce18aef861e8e339c7e8b2991d180763ab8eb2078b3bbe46700f363aa44a9b67b8e31b90a81f8bab274fcced9af539930d33f3602a1 + languageName: node + linkType: hard + +"@graphql-tools/documents@npm:^1.0.0": + version: 1.0.1 + resolution: "@graphql-tools/documents@npm:1.0.1" + dependencies: + lodash.sortby: ^4.7.0 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: c6ff859d2673dbf884f19d6319735afacc6bff2df6f8ea3dbf56839d01568f61210f256f0905156f123428cc24962ada26b37903263699fc8cd7efb8849a6508 + languageName: node + linkType: hard + +"@graphql-tools/executor-graphql-ws@npm:^1.3.1": + version: 1.3.1 + resolution: "@graphql-tools/executor-graphql-ws@npm:1.3.1" + dependencies: + "@graphql-tools/utils": ^10.5.5 + "@types/ws": ^8.0.0 + graphql-ws: ^5.14.0 + isomorphic-ws: ^5.0.0 + tslib: ^2.4.0 + ws: ^8.17.1 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 850cef03d4a517bd922a98a82f28e1cf5353f96e53e649403cbc394cb2ef6d3256438d1fe5bba9fb1b2e9bc4b92e4242d4ae4b8f25f393e1d43108dbbadf06b5 + languageName: node + linkType: hard + +"@graphql-tools/executor-http@npm:^1.1.8": + version: 1.1.8 + resolution: "@graphql-tools/executor-http@npm:1.1.8" + dependencies: + "@graphql-tools/utils": ^10.5.5 + "@repeaterjs/repeater": ^3.0.4 + "@whatwg-node/fetch": ^0.10.0 + extract-files: ^11.0.0 + meros: ^1.2.1 + tslib: ^2.4.0 + value-or-promise: ^1.0.12 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 1ec80c125da44547b20040f993cc4f893d0d68ca2b5b2e0471d16acced548c8c9dec53cabce1216c81841fe222bf2addd32f09f2c5fba99c6bb125c06845a492 + languageName: node + linkType: hard + +"@graphql-tools/executor-legacy-ws@npm:^1.1.1": + version: 1.1.1 + resolution: "@graphql-tools/executor-legacy-ws@npm:1.1.1" + dependencies: + "@graphql-tools/utils": ^10.5.5 + "@types/ws": ^8.0.0 + isomorphic-ws: ^5.0.0 + tslib: ^2.4.0 + ws: ^8.17.1 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 08538c986bc121a8c10168ca9a61d6d379f13b19e764b4487ce4166a54e264e2c9472b5c26e3c7b9ce3ea536af24c0bde4acfc4194bc4964b2981c531a367621 + languageName: node + linkType: hard + +"@graphql-tools/executor@npm:^1.3.2": + version: 1.3.2 + resolution: "@graphql-tools/executor@npm:1.3.2" + dependencies: + "@graphql-tools/utils": ^10.5.5 + "@graphql-typed-document-node/core": 3.2.0 + "@repeaterjs/repeater": ^3.0.4 + tslib: ^2.4.0 + value-or-promise: ^1.0.12 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 1bc7c25f19e428bedf322d080f136d6edb113b64572dd1c8fa3f00611c957a64160057f99155715c59f6d39758090268be96b6d9a11b6921f48985d70cda862c + languageName: node + linkType: hard + +"@graphql-tools/git-loader@npm:^8.0.0": + version: 8.0.8 + resolution: "@graphql-tools/git-loader@npm:8.0.8" + dependencies: + "@graphql-tools/graphql-tag-pluck": 8.3.3 + "@graphql-tools/utils": ^10.5.5 + is-glob: 4.0.3 + micromatch: ^4.0.8 + tslib: ^2.4.0 + unixify: ^1.0.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 19a9db2337500d99607bcde6e6aa70de4a7072edd5d221cec5d311475492f56749a775af7f9b0e8981b4d748c11b4926b851cff7c05296a9e509155c1c9bb3f6 + languageName: node + linkType: hard + +"@graphql-tools/github-loader@npm:^8.0.0": + version: 8.0.3 + resolution: "@graphql-tools/github-loader@npm:8.0.3" + dependencies: + "@ardatan/sync-fetch": ^0.0.1 + "@graphql-tools/executor-http": ^1.1.8 + "@graphql-tools/graphql-tag-pluck": ^8.3.3 + "@graphql-tools/utils": ^10.5.5 + "@whatwg-node/fetch": ^0.10.0 + tslib: ^2.4.0 + value-or-promise: ^1.0.12 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: d9fdc88db3733bea4ef7783fd71cd192758201a999159b8286c826cd5b754b0332a090515c7940afc62f126c181c4fa35e62ce57c2acd2dce1472632031bfa53 + languageName: node + linkType: hard + +"@graphql-tools/graphql-file-loader@npm:^8.0.0": + version: 8.0.2 + resolution: "@graphql-tools/graphql-file-loader@npm:8.0.2" + dependencies: + "@graphql-tools/import": 7.0.2 + "@graphql-tools/utils": ^10.5.5 + globby: ^11.0.3 + tslib: ^2.4.0 + unixify: ^1.0.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: ab963352275aeeef5ea40d2759a2c3c4259c1392db4002146cba2d27a3a31299fb97495e891f3e5fa4fc8cd09d1442e2129b3821a70d79fcee437b736c6291ca + languageName: node + linkType: hard + +"@graphql-tools/graphql-tag-pluck@npm:8.3.3, @graphql-tools/graphql-tag-pluck@npm:^8.3.3": + version: 8.3.3 + resolution: "@graphql-tools/graphql-tag-pluck@npm:8.3.3" + dependencies: + "@babel/core": ^7.22.9 + "@babel/parser": ^7.16.8 + "@babel/plugin-syntax-import-assertions": ^7.20.0 + "@babel/traverse": ^7.16.8 + "@babel/types": ^7.16.8 + "@graphql-tools/utils": ^10.5.5 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 9fc3278a0ae0e80114c3d65f550655acc867cc161531ea3ae6aacf400109036329dfa6afcf5b386880298e19ee0a790ebb1a1556d55e49e558b757a5b3beb5b0 languageName: node linkType: hard -"@expo/prebuild-config@npm:7.0.8": - version: 7.0.8 - resolution: "@expo/prebuild-config@npm:7.0.8" +"@graphql-tools/import@npm:7.0.2": + version: 7.0.2 + resolution: "@graphql-tools/import@npm:7.0.2" dependencies: - "@expo/config": ~9.0.0-beta.0 - "@expo/config-plugins": ~8.0.8 - "@expo/config-types": ^51.0.0-unreleased - "@expo/image-utils": ^0.5.0 - "@expo/json-file": ^8.3.0 - "@react-native/normalize-colors": 0.74.85 - debug: ^4.3.1 - fs-extra: ^9.0.0 - resolve-from: ^5.0.0 - semver: ^7.6.0 - xml2js: 0.6.0 + "@graphql-tools/utils": ^10.5.5 + resolve-from: 5.0.0 + tslib: ^2.4.0 peerDependencies: - expo-modules-autolinking: ">=0.8.1" - checksum: b3715b10aa5aa9e60e97802feaaa6ddca4330752ec566d9f272e23417d00e2a298b6cc2f0d33f8a46a3c907f10b862d2975b737ba10e194ac834eae48847923b + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: b6ee488e3720bc41710f7ccf7b499ae5cda63f80a2ebd35d6e2c80b6f36d1ff8345450c6c21f79c5aed8b001c87589c63d6a122236deb7d73ff17582038806c4 languageName: node linkType: hard -"@expo/rudder-sdk-node@npm:1.1.1": - version: 1.1.1 - resolution: "@expo/rudder-sdk-node@npm:1.1.1" +"@graphql-tools/json-file-loader@npm:^8.0.0": + version: 8.0.2 + resolution: "@graphql-tools/json-file-loader@npm:8.0.2" dependencies: - "@expo/bunyan": ^4.0.0 - "@segment/loosely-validate-event": ^2.0.0 - fetch-retry: ^4.1.1 - md5: ^2.2.1 - node-fetch: ^2.6.1 - remove-trailing-slash: ^0.1.0 - uuid: ^8.3.2 - checksum: 5ce50c1a82f899b135600cb29cddf3fab601938700c8203f16a1394d2ffbf9e2cdd246b92ff635f8415121072d99a7b4a370f715b78f6680594b5a630e8d78c6 + "@graphql-tools/utils": ^10.5.5 + globby: ^11.0.3 + tslib: ^2.4.0 + unixify: ^1.0.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 56c53e22ac762ee2c668a33e1ab929cbea86b3ecb95a74290e085ac94385c22b2e7854b4d16094c8289cfaf76712c274bd99725d2f151ddad60d72edf1fdc412 languageName: node linkType: hard -"@expo/sdk-runtime-versions@npm:^1.0.0": - version: 1.0.0 - resolution: "@expo/sdk-runtime-versions@npm:1.0.0" - checksum: 0942d5a356f590e8dc795761456cc48b3e2d6a38ad2a02d6774efcdc5a70424e05623b4e3e5d2fec0cdc30f40dde05c14391c781607eed3971bf8676518bfd9d +"@graphql-tools/load@npm:^8.0.0": + version: 8.0.3 + resolution: "@graphql-tools/load@npm:8.0.3" + dependencies: + "@graphql-tools/schema": ^10.0.7 + "@graphql-tools/utils": ^10.5.5 + p-limit: 3.1.0 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: f50df2d078bd4be008dc487c6c16ed8875f24bbebde677c9f64af444310c05fc2545681d3eafd351331ab4161907e1c86491835fce30656fc7ce50d0bb2b25c2 languageName: node linkType: hard -"@expo/spawn-async@npm:^1.5.0, @expo/spawn-async@npm:^1.7.2": - version: 1.7.2 - resolution: "@expo/spawn-async@npm:1.7.2" +"@graphql-tools/merge@npm:^9.0.0, @graphql-tools/merge@npm:^9.0.8": + version: 9.0.8 + resolution: "@graphql-tools/merge@npm:9.0.8" dependencies: - cross-spawn: ^7.0.3 - checksum: d99e5ff6d303ec9b0105f97c4fa6c65bca526c7d4d0987997c35cc745fa8224adf009942d01808192ebb9fa30619a53316641958631e85cf17b773d9eeda2597 + "@graphql-tools/utils": ^10.5.5 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: f1441595332068d7fe6c344da5ddd0bbc114fc64858f71a6ba6c766d658e68ef20f03cf387aaba7d5f9cf7e97cbf7ebd30f21c99438b742cdd0ecaf0ccbd5719 languageName: node linkType: hard -"@expo/vector-icons@npm:^14.0.0": - version: 14.0.2 - resolution: "@expo/vector-icons@npm:14.0.2" +"@graphql-tools/optimize@npm:^1.3.0": + version: 1.4.0 + resolution: "@graphql-tools/optimize@npm:1.4.0" dependencies: - prop-types: ^15.8.1 - checksum: 49e27ff52eb138745313fa2c39863fb762230b0089b910d668d7f2c06b7e71a0249dc3a26bfc8725d07bdfaadab1dbcbce087b34dfc244b00a15fc02fe4866e2 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: bccbc596f2007ae706ee948e900f3174aa80ef043e8ae3467f735a10df0b31873bafdd20c0ef09b662171363a31e2d0859adb362bbf762da00245f8e9fd501b0 languageName: node linkType: hard -"@expo/xcpretty@npm:^4.3.0": - version: 4.3.1 - resolution: "@expo/xcpretty@npm:4.3.1" +"@graphql-tools/optimize@npm:^2.0.0": + version: 2.0.0 + resolution: "@graphql-tools/optimize@npm:2.0.0" dependencies: - "@babel/code-frame": 7.10.4 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 7f79c0e1852abc571308e887d27d613da5b797256c8c6eb6c5fe7ca77f09e61524778ae281cebc0b698c51d4fe1074e2b8e0d0627b8e2dcf505aa6ed09b49a2f + languageName: node + linkType: hard + +"@graphql-tools/prisma-loader@npm:^8.0.0": + version: 8.0.16 + resolution: "@graphql-tools/prisma-loader@npm:8.0.16" + dependencies: + "@graphql-tools/url-loader": ^8.0.14 + "@graphql-tools/utils": ^10.5.5 + "@types/js-yaml": ^4.0.0 + "@whatwg-node/fetch": ^0.10.0 chalk: ^4.1.0 - find-up: ^5.0.0 - js-yaml: ^4.1.0 - bin: - excpretty: build/cli.js - checksum: dbf3e2d7f501fbbd11baf0c0aa9057c8a87efe0993a82caafd30c66977ac430d03fa84e27b529e3d0b04fee8c6beec1bd135f0522229dca91220561b76309854 + debug: ^4.3.1 + dotenv: ^16.0.0 + graphql-request: ^6.0.0 + http-proxy-agent: ^7.0.0 + https-proxy-agent: ^7.0.0 + jose: ^5.0.0 + js-yaml: ^4.0.0 + lodash: ^4.17.20 + scuid: ^1.1.0 + tslib: ^2.4.0 + yaml-ast-parser: ^0.0.43 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 77ef0f507d488564753fab108ca70df6d4280ab92752ccba4119ee74c435df18815fa3565bec03f6a945611439e3dbe923cd995481b914bf6fa4b4893f214f37 languageName: node linkType: hard -"@fastify/ajv-compiler@npm:^3.5.0": - version: 3.5.0 - resolution: "@fastify/ajv-compiler@npm:3.5.0" +"@graphql-tools/relay-operation-optimizer@npm:^6.5.0": + version: 6.5.18 + resolution: "@graphql-tools/relay-operation-optimizer@npm:6.5.18" dependencies: - ajv: ^8.11.0 - ajv-formats: ^2.1.1 - fast-uri: ^2.0.0 - checksum: 5e5b16469f8d586473d0b32e3a9cf38c0d86ef2a6fb7ea12ed7f3665642bd8eb2dde9adcc317814369cb5a58210bfdac35996fa87d1cc23e88bbc799f0b128b0 + "@ardatan/relay-compiler": 12.0.0 + "@graphql-tools/utils": ^9.2.1 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 56a8c7e6a0bf5fa4d5106276f69c08630a95659eb4300249b3dd28e2057ebb7e7815c51beadf98acdbf695cad5937988d16a3d01ca74fc120c76892968fbeb2b languageName: node linkType: hard -"@fastify/cors@npm:^8.1.1": - version: 8.4.0 - resolution: "@fastify/cors@npm:8.4.0" +"@graphql-tools/relay-operation-optimizer@npm:^7.0.0": + version: 7.0.2 + resolution: "@graphql-tools/relay-operation-optimizer@npm:7.0.2" dependencies: - fastify-plugin: ^4.0.0 - mnemonist: 0.39.5 - checksum: 4fe99623918b9c58f6590dac00fe778f2755eacc47de726acf97b3a3305a414425b393422429efca1b261514100f4092a4ad41bc549c6f6edf60e83f9f5d3701 + "@ardatan/relay-compiler": 12.0.0 + "@graphql-tools/utils": ^10.5.5 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 6eff45ec213d193d72bb1dc67d43ababba0909ddd4700360c26a82668d5e190cebf96940f6337c117a35350aed31b2bd7c9296f2dcd4df2687dbec30e6cdcebe languageName: node linkType: hard -"@fastify/deepmerge@npm:^1.0.0": - version: 1.3.0 - resolution: "@fastify/deepmerge@npm:1.3.0" - checksum: 33ec927905dca320d7ae9535a1521909f7c82339706345324ab6287ad100589a799b8257c15b0e582c7bb74e2aa4883d82ba0228d7b116aa8789ada4f78d6974 +"@graphql-tools/schema@npm:^10.0.0, @graphql-tools/schema@npm:^10.0.7": + version: 10.0.7 + resolution: "@graphql-tools/schema@npm:10.0.7" + dependencies: + "@graphql-tools/merge": ^9.0.8 + "@graphql-tools/utils": ^10.5.5 + tslib: ^2.4.0 + value-or-promise: ^1.0.12 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: d0cf9d286755d4d1ed7d7f33b51f1f1fcf9afdcbc3470078f5face1e49253948963b5a5e8cbdcf08fecc7b016aecbac794428c2269c6c9de91422e5b4375cec1 languageName: node linkType: hard -"@fastify/error@npm:^3.2.0": - version: 3.3.0 - resolution: "@fastify/error@npm:3.3.0" - checksum: 202507c8c7f49922cac2f5afc82802151b0bd9c583ca1c2850bf43d0f4cd97eedb3a3388b9016da74f8a01b517a5861d1f666c506dd64fd22995e559bc139264 +"@graphql-tools/url-loader@npm:^8.0.0, @graphql-tools/url-loader@npm:^8.0.14": + version: 8.0.14 + resolution: "@graphql-tools/url-loader@npm:8.0.14" + dependencies: + "@ardatan/sync-fetch": ^0.0.1 + "@graphql-tools/executor-graphql-ws": ^1.3.1 + "@graphql-tools/executor-http": ^1.1.8 + "@graphql-tools/executor-legacy-ws": ^1.1.1 + "@graphql-tools/utils": ^10.5.5 + "@graphql-tools/wrap": ^10.0.15 + "@types/ws": ^8.0.0 + "@whatwg-node/fetch": ^0.10.0 + isomorphic-ws: ^5.0.0 + tslib: ^2.4.0 + value-or-promise: ^1.0.11 + ws: ^8.17.1 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: fb99bf71e2fbca6a9be35699acb4a9fa850e60e9afec079d89a8c48c4743175ace18de71351ca533957e7f5d0c66358a2c7dc81de4a9fea6b5d618a50bdcf564 languageName: node linkType: hard -"@fastify/fast-json-stringify-compiler@npm:^4.3.0": - version: 4.3.0 - resolution: "@fastify/fast-json-stringify-compiler@npm:4.3.0" +"@graphql-tools/utils@npm:^10.0.0, @graphql-tools/utils@npm:^10.5.5": + version: 10.5.5 + resolution: "@graphql-tools/utils@npm:10.5.5" dependencies: - fast-json-stringify: ^5.7.0 - checksum: 2734afabe2539d3e15d2bd9f8dfee756d9cd969f7303dc085dd91c744ff61742bb0d3ebd3b561cf3c32be54567048a634b4962f943eb6bd9ed3fbd71cbf6a4fa + "@graphql-typed-document-node/core": ^3.1.1 + cross-inspect: 1.0.1 + dset: ^3.1.2 + tslib: ^2.4.0 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: bbc5ea58c286e1a9f82876570f98b29079e224a8b3568ca8df4720de8c790e1cb8772182d1411af99d6ac749b9082810e02f21f0813dc43c4d0438ef9e04e885 languageName: node linkType: hard -"@gorhom/bottom-sheet@npm:4.6.4": - version: 4.6.4 - resolution: "@gorhom/bottom-sheet@npm:4.6.4" +"@graphql-tools/utils@npm:^8.8.0": + version: 8.13.1 + resolution: "@graphql-tools/utils@npm:8.13.1" dependencies: - "@gorhom/portal": 1.0.14 - invariant: ^2.2.4 + tslib: ^2.4.0 peerDependencies: - "@types/react": "*" - "@types/react-native": "*" - react: "*" - react-native: "*" - react-native-gesture-handler: ">=1.10.1" - react-native-reanimated: ">=2.2.0" - peerDependenciesMeta: - "@types/react": - optional: true - "@types/react-native": - optional: true - checksum: 2cea033c4f321b93fdbf61470b507b5efd51425a8ab927b49d7aaa1d9f0568cbcfb188e385311389dbffbafe47b941dbd3e60f74b1d663a1a2d73262e2719f85 + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: ff04fdeb29e9ac596ea53386cd5b23cd741bb14c1997c6b0ba3c34ca165bd82b528a355e8c8e2ba726eb39e833ba9cbb0851ba0addb8c6d367089a1145bf9a49 languageName: node linkType: hard -"@gorhom/portal@npm:1.0.14": - version: 1.0.14 - resolution: "@gorhom/portal@npm:1.0.14" +"@graphql-tools/utils@npm:^9.0.0, @graphql-tools/utils@npm:^9.2.1": + version: 9.2.1 + resolution: "@graphql-tools/utils@npm:9.2.1" dependencies: - nanoid: ^3.3.1 + "@graphql-typed-document-node/core": ^3.1.1 + tslib: ^2.4.0 peerDependencies: - react: "*" - react-native: "*" - checksum: 227bb96a2db854ab29bb9da8d4f3823c7f7448358de459709dd1b78522110da564c9a8734c6bc7d7153ed7c99320e0fb5d60b420c2ebb75ecaf2f0d757f410f9 + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 94ed12df5f49e5c338322ffd931236a687a3d5c443bf499f9baab5d4fcd9792234111142be8aa506a01ca2e82732996c4e1d8f6159ff9cc7fdc5c97f63e55226 + languageName: node + linkType: hard + +"@graphql-tools/wrap@npm:^10.0.15": + version: 10.0.15 + resolution: "@graphql-tools/wrap@npm:10.0.15" + dependencies: + "@graphql-tools/delegate": ^10.1.1 + "@graphql-tools/schema": ^10.0.7 + "@graphql-tools/utils": ^10.5.5 + tslib: ^2.4.0 + value-or-promise: ^1.0.12 + peerDependencies: + graphql: ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0 + checksum: 0fdb6d440cdac8b2dd12f6e0f8c9bd88302c78370b7e33ef7cbacd1e7aa021bb9cc4a73465a81d1ead1f2a2a3f319b852ebcc051d58367b6aa553ed7304da00a languageName: node linkType: hard -"@graphql-typed-document-node/core@npm:^3.1.0": +"@graphql-typed-document-node/core@npm:3.2.0, @graphql-typed-document-node/core@npm:^3.1.0, @graphql-typed-document-node/core@npm:^3.1.1, @graphql-typed-document-node/core@npm:^3.2.0": version: 3.2.0 resolution: "@graphql-typed-document-node/core@npm:3.2.0" peerDependencies: @@ -4260,6 +5115,13 @@ __metadata: languageName: node linkType: hard +"@kamilkisiela/fast-url-parser@npm:^1.1.4": + version: 1.1.4 + resolution: "@kamilkisiela/fast-url-parser@npm:1.1.4" + checksum: 921d305eff1fce5c7c669aee5cfe39e50109968addb496c23f0a42253d030e3cd5865eb01b13245915923bee452db75ba8a8254e69b0d0575d3c168efce7091e + languageName: node + linkType: hard + "@keystonehq/alias-sampling@npm:^0.1.1": version: 0.1.2 resolution: "@keystonehq/alias-sampling@npm:0.1.2" @@ -4551,50 +5413,6 @@ __metadata: languageName: node linkType: hard -"@mapbox/geo-viewport@npm:>= 0.4.0": - version: 0.5.0 - resolution: "@mapbox/geo-viewport@npm:0.5.0" - dependencies: - "@mapbox/sphericalmercator": ^1.2.0 - checksum: 9cb990e177226acbdf7658f3367ed3158d8a77350afb0e1de71fa432e682a8aed4afe2f80d36872eb79666b54432fe6219797d50f2ab4152c51811235b7520a0 - languageName: node - linkType: hard - -"@mapbox/sphericalmercator@npm:^1.2.0": - version: 1.2.0 - resolution: "@mapbox/sphericalmercator@npm:1.2.0" - bin: - bbox: bin/bbox.js - to4326: bin/to4326.js - to900913: bin/to900913.js - xyz: bin/xyz.js - checksum: 515cd9fcadc6626d6352001f6d9dba073fcd10433ceee37d13d4be7fc9a48930b4163b79f53151b71ff9a4410da77bd11c5ff62e3b9d6119bce9031c4d7dabc1 - languageName: node - linkType: hard - -"@maplibre/maplibre-react-native@npm:^9.1.0": - version: 9.1.0 - resolution: "@maplibre/maplibre-react-native@npm:9.1.0" - dependencies: - "@expo/config-plugins": ^4.0.3 - "@mapbox/geo-viewport": ">= 0.4.0" - "@turf/along": 6.5.0 - "@turf/distance": 6.5.0 - "@turf/helpers": 6.5.0 - "@turf/length": 6.5.0 - "@turf/nearest-point-on-line": 6.5.0 - "@types/geojson": ^7946.0.7 - "@types/node": ^18.11.18 - debounce: ^1.2.0 - deprecated-react-native-prop-types: ^4.1.0 - peerDependencies: - prop-types: ^15.8.1 - react: ">=16.6.1" - react-native: ">=0.59.9" - checksum: 288e177f83cec2db2ee055911090dacdf42ce862387d8e9ea3cbcb412ae7df40d41743b09912cf95479094c83a9f268dc5fcc5ebd82d690e55e093007d7b1fe9 - languageName: node - linkType: hard - "@metaplex-foundation/beet-solana@npm:0.4.0, @metaplex-foundation/beet-solana@npm:^0.4.0": version: 0.4.0 resolution: "@metaplex-foundation/beet-solana@npm:0.4.0" @@ -4930,10 +5748,10 @@ __metadata: languageName: node linkType: hard -"@novalabsxyz/mobile-theme@npm:2.0.0-y.25": - version: 2.0.0-y.25 - resolution: "@novalabsxyz/mobile-theme@npm:2.0.0-y.25" - checksum: 54a01e1aef25c406fea2d7d4651dd0f94d62b884bc34dc3a5702e1cbab392969139b5ca9631adae95f8fff81822c34a0a08159cbcbd0a71c722f43d6704205b7 +"@novalabsxyz/mobile-theme@npm:2.0.0-y.26": + version: 2.0.0-y.26 + resolution: "@novalabsxyz/mobile-theme@npm:2.0.0-y.26" + checksum: 48060226173468d998c55c5e75c15d0666a02e03893c94816acb72d514b6c18d0c9a7fd6d4f4f06ad62fc5cb9a7a823d025a6e797a93057716f23b1859b15ef9 languageName: node linkType: hard @@ -5353,6 +6171,16 @@ __metadata: languageName: node linkType: hard +"@react-native-masked-view/masked-view@npm:^0.3.2": + version: 0.3.2 + resolution: "@react-native-masked-view/masked-view@npm:0.3.2" + peerDependencies: + react: ">=16" + react-native: ">=0.57" + checksum: e35ab882148df3f9b71f04355d2fb1b24d6f2aaf29043f80758f398bdf905eed67734b36b072fa8b934923ff4e3d80ccb5e37d8376cb1825272078b96a21dadc + languageName: node + linkType: hard + "@react-native/assets-registry@npm:0.74.87": version: 0.74.87 resolution: "@react-native/assets-registry@npm:0.74.87" @@ -5665,7 +6493,7 @@ __metadata: languageName: node linkType: hard -"@react-native/normalize-color@npm:*, @react-native/normalize-color@npm:^2.0.0": +"@react-native/normalize-color@npm:*": version: 2.1.0 resolution: "@react-native/normalize-color@npm:2.1.0" checksum: 8ccbd40b3c7629f1dc97b3e9aadd95fd3507fcf2e37535a6299a70436ab891c34cbdc4240b07380553d6e85dd909e23d5773b5be1da2906b026312e0b0768838 @@ -5693,13 +6521,6 @@ __metadata: languageName: node linkType: hard -"@react-native/normalize-colors@npm:<0.73.0": - version: 0.72.0 - resolution: "@react-native/normalize-colors@npm:0.72.0" - checksum: c8ec577663394a3390eb34c3cd531350521172bcfad7de309ab111e5f9e3d27c966d4a4387f00972302107be3d8cad584c5794ccfa30939aecc56162e4ddbe25 - languageName: node - linkType: hard - "@react-native/typescript-config@npm:0.74.87": version: 0.74.87 resolution: "@react-native/typescript-config@npm:0.74.87" @@ -5875,6 +6696,41 @@ __metadata: languageName: node linkType: hard +"@repeaterjs/repeater@npm:^3.0.4, @repeaterjs/repeater@npm:^3.0.6": + version: 3.0.6 + resolution: "@repeaterjs/repeater@npm:3.0.6" + checksum: aae878b953162bec77c94b45f2236ddfc01a65308267c7cb30220fa2f8511654a302c0d32aad228c58241d685607d7bb35b6d528b2879355e6636ff08fddb266 + languageName: node + linkType: hard + +"@rnmapbox/maps@npm:^10.1.31": + version: 10.1.31 + resolution: "@rnmapbox/maps@npm:10.1.31" + dependencies: + "@turf/along": 6.5.0 + "@turf/distance": 6.5.0 + "@turf/helpers": 6.5.0 + "@turf/length": 6.5.0 + "@turf/nearest-point-on-line": 6.5.0 + "@types/geojson": ^7946.0.7 + debounce: ^1.2.0 + peerDependencies: + expo: ">=47.0.0" + mapbox-gl: ^2.9.0 + react: ">=16.6.1" + react-dom: ">= 17.0.0" + react-native: ">=0.59.9" + peerDependenciesMeta: + expo: + optional: true + mapbox-gl: + optional: true + react-dom: + optional: true + checksum: f4ac56f9dbc3128b2bfeedd3980668f2c05e92b965297a0be1556b0059fcf15e7c84d9127b32383d6608d65b6986e5e3ed6ef08499091f0a31a6fbb72c0819fb + languageName: node + linkType: hard + "@rnx-kit/chromium-edge-launcher@npm:^1.0.0": version: 1.0.0 resolution: "@rnx-kit/chromium-edge-launcher@npm:1.0.0" @@ -7139,6 +7995,13 @@ __metadata: languageName: node linkType: hard +"@types/js-yaml@npm:^4.0.0": + version: 4.0.9 + resolution: "@types/js-yaml@npm:4.0.9" + checksum: e5e5e49b5789a29fdb1f7d204f82de11cb9e8f6cb24ab064c616da5d6e1b3ccfbf95aa5d1498a9fbd3b9e745564e69b4a20b6c530b5a8bbb2d4eb830cda9bc69 + languageName: node + linkType: hard + "@types/json-schema@npm:^7.0.7, @types/json-schema@npm:^7.0.9": version: 7.0.13 resolution: "@types/json-schema@npm:7.0.13" @@ -7249,7 +8112,7 @@ __metadata: languageName: node linkType: hard -"@types/node@npm:^18.0.0, @types/node@npm:^18.11.18": +"@types/node@npm:^18.0.0": version: 18.19.43 resolution: "@types/node@npm:18.19.43" dependencies: @@ -7440,6 +8303,15 @@ __metadata: languageName: node linkType: hard +"@types/ws@npm:^8.0.0": + version: 8.5.13 + resolution: "@types/ws@npm:8.5.13" + dependencies: + "@types/node": "*" + checksum: f17023ce7b89c6124249c90211803a4aaa02886e12bc2d0d2cd47fa665eeb058db4d871ce4397d8e423f6beea97dd56835dd3fdbb921030fe4d887601e37d609 + languageName: node + linkType: hard + "@types/ws@npm:^8.2.2": version: 8.5.12 resolution: "@types/ws@npm:8.5.12" @@ -8162,6 +9034,50 @@ __metadata: languageName: node linkType: hard +"@whatwg-node/fetch@npm:^0.10.0": + version: 0.10.1 + resolution: "@whatwg-node/fetch@npm:0.10.1" + dependencies: + "@whatwg-node/node-fetch": ^0.7.1 + urlpattern-polyfill: ^10.0.0 + checksum: 7b0c64476d1a8f7c3cd6d946dfda3f39c204049c903d6338a07f1579a1b2771f89e742f71057b7b7beef3ccf8bf8ecc2b019c072719f1fd64509386d7ca102ae + languageName: node + linkType: hard + +"@whatwg-node/fetch@npm:^0.9.20": + version: 0.9.23 + resolution: "@whatwg-node/fetch@npm:0.9.23" + dependencies: + "@whatwg-node/node-fetch": ^0.6.0 + urlpattern-polyfill: ^10.0.0 + checksum: 16c99adecce7eac17220b24c9385f34a30b9c546a790ab8f03f602747746c34ebbd24cf22faa7c921b92463f2e1f6b1ce754da636b4eda1b920720b31f9c41b8 + languageName: node + linkType: hard + +"@whatwg-node/node-fetch@npm:^0.6.0": + version: 0.6.0 + resolution: "@whatwg-node/node-fetch@npm:0.6.0" + dependencies: + "@kamilkisiela/fast-url-parser": ^1.1.4 + busboy: ^1.6.0 + fast-querystring: ^1.1.1 + tslib: ^2.6.3 + checksum: 78a80a3c0ada94ba5256a7d94be5d27a5527b4cdc071ed2c328ff0f434d8446ee1e0464019af79be06c2d032520065f47abb7e492b774a084ac4b13bd4a86c41 + languageName: node + linkType: hard + +"@whatwg-node/node-fetch@npm:^0.7.1": + version: 0.7.2 + resolution: "@whatwg-node/node-fetch@npm:0.7.2" + dependencies: + "@kamilkisiela/fast-url-parser": ^1.1.4 + busboy: ^1.6.0 + fast-querystring: ^1.1.1 + tslib: ^2.6.3 + checksum: 1bba3e512a0d69ae335c01dea0b8a246afc1ea9946ef53437ee632c54215fc044b798bd4aa1f76ed31937ccfb43624413f83dcd62282ab1fb54bd13ccaea2b14 + languageName: node + linkType: hard + "@xmldom/xmldom@npm:^0.8.8": version: 0.8.10 resolution: "@xmldom/xmldom@npm:0.8.10" @@ -8169,7 +9085,7 @@ __metadata: languageName: node linkType: hard -"@xmldom/xmldom@npm:~0.7.0, @xmldom/xmldom@npm:~0.7.7": +"@xmldom/xmldom@npm:~0.7.7": version: 0.7.13 resolution: "@xmldom/xmldom@npm:0.7.13" checksum: b4054078530e5fa8ede9677425deff0fce6d965f4c477ca73f8490d8a089e60b8498a15560425a1335f5ff99ecb851ed2c734b0a9a879299a5694302f212f37a @@ -8401,7 +9317,7 @@ __metadata: languageName: node linkType: hard -"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.2": +"ansi-escapes@npm:^4.2.1, ansi-escapes@npm:^4.3.0, ansi-escapes@npm:^4.3.2": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" dependencies: @@ -8881,6 +9797,13 @@ __metadata: languageName: node linkType: hard +"auto-bind@npm:~4.0.0": + version: 4.0.0 + resolution: "auto-bind@npm:4.0.0" + checksum: 00cad71cce5742faccb7dd65c1b55ebc4f45add4b0c9a1547b10b05bab22813230133b0c892c67ba3eb969a4524710c5e43cc45c72898ec84e56f3a596e7a04f + languageName: node + linkType: hard + "available-typed-arrays@npm:^1.0.7": version: 1.0.7 resolution: "available-typed-arrays@npm:1.0.7" @@ -9623,6 +10546,15 @@ __metadata: languageName: node linkType: hard +"braces@npm:^3.0.3": + version: 3.0.3 + resolution: "braces@npm:3.0.3" + dependencies: + fill-range: ^7.1.1 + checksum: b95aa0b3bd909f6cd1720ffcf031aeaf46154dd88b4da01f9a1d3f7ea866a79eba76a6d01cbc3c422b2ee5cdc39a4f02491058d5df0d7bf6e6a162a832df1f69 + languageName: node + linkType: hard + "brorand@npm:^1.0.1, brorand@npm:^1.1.0": version: 1.1.0 resolution: "brorand@npm:1.1.0" @@ -9717,6 +10649,20 @@ __metadata: languageName: node linkType: hard +"browserslist@npm:^4.24.0": + version: 4.24.2 + resolution: "browserslist@npm:4.24.2" + dependencies: + caniuse-lite: ^1.0.30001669 + electron-to-chromium: ^1.5.41 + node-releases: ^2.0.18 + update-browserslist-db: ^1.1.1 + bin: + browserslist: cli.js + checksum: cf64085f12132d38638f38937a255edb82c7551b164a98577b055dd79719187a816112f7b97b9739e400c4954cd66479c0d7a843cb816e346f4795dc24fd5d97 + languageName: node + linkType: hard + "bs58@npm:5.0.0, bs58@npm:^5.0.0": version: 5.0.0 resolution: "bs58@npm:5.0.0" @@ -9872,6 +10818,15 @@ __metadata: languageName: node linkType: hard +"busboy@npm:^1.6.0": + version: 1.6.0 + resolution: "busboy@npm:1.6.0" + dependencies: + streamsearch: ^1.1.0 + checksum: 32801e2c0164e12106bf236291a00795c3c4e4b709ae02132883fe8478ba2ae23743b11c5735a0aae8afe65ac4b6ca4568b91f0d9fed1fdbc32ede824a73746e + languageName: node + linkType: hard + "bytes@npm:3.0.0": version: 3.0.0 resolution: "bytes@npm:3.0.0" @@ -9961,6 +10916,16 @@ __metadata: languageName: node linkType: hard +"camel-case@npm:^4.1.2": + version: 4.1.2 + resolution: "camel-case@npm:4.1.2" + dependencies: + pascal-case: ^3.1.2 + tslib: ^2.0.3 + checksum: bcbd25cd253b3cbc69be3f535750137dbf2beb70f093bdc575f73f800acc8443d34fd52ab8f0a2413c34f1e8203139ffc88428d8863e4dfe530cfb257a379ad6 + languageName: node + linkType: hard + "camelcase-keys@npm:7.0.2": version: 7.0.2 resolution: "camelcase-keys@npm:7.0.2" @@ -10012,6 +10977,13 @@ __metadata: languageName: node linkType: hard +"caniuse-lite@npm:^1.0.30001669": + version: 1.0.30001680 + resolution: "caniuse-lite@npm:1.0.30001680" + checksum: 2641d2b18c5ab0a6663cb350c5adc81e5ede1a7677d1c7518a8053ada87bf6f206419e1820a2608f76fa5e4f7bea327cbe47df423783e571569a88c0ea645270 + languageName: node + linkType: hard + "capability@npm:^0.2.5": version: 0.2.5 resolution: "capability@npm:0.2.5" @@ -10019,6 +10991,17 @@ __metadata: languageName: node linkType: hard +"capital-case@npm:^1.0.4": + version: 1.0.4 + resolution: "capital-case@npm:1.0.4" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + upper-case-first: ^2.0.2 + checksum: 41fa8fa87f6d24d0835a2b4a9341a3eaecb64ac29cd7c5391f35d6175a0fa98ab044e7f2602e1ec3afc886231462ed71b5b80c590b8b41af903ec2c15e5c5931 + languageName: node + linkType: hard + "case-anything@npm:^2.1.13": version: 2.1.13 resolution: "case-anything@npm:2.1.13" @@ -10061,6 +11044,62 @@ __metadata: languageName: node linkType: hard +"change-case-all@npm:1.0.14": + version: 1.0.14 + resolution: "change-case-all@npm:1.0.14" + dependencies: + change-case: ^4.1.2 + is-lower-case: ^2.0.2 + is-upper-case: ^2.0.2 + lower-case: ^2.0.2 + lower-case-first: ^2.0.2 + sponge-case: ^1.0.1 + swap-case: ^2.0.2 + title-case: ^3.0.3 + upper-case: ^2.0.2 + upper-case-first: ^2.0.2 + checksum: 6ff893e005e1bf115cc2969cc5ca3610f7c6ece9e90b7927ed12c980c7d3ea9a565150d246c6dba0fee21aaacbd38d69b98a4670d96b892c76f66e46616506d3 + languageName: node + linkType: hard + +"change-case-all@npm:1.0.15": + version: 1.0.15 + resolution: "change-case-all@npm:1.0.15" + dependencies: + change-case: ^4.1.2 + is-lower-case: ^2.0.2 + is-upper-case: ^2.0.2 + lower-case: ^2.0.2 + lower-case-first: ^2.0.2 + sponge-case: ^1.0.1 + swap-case: ^2.0.2 + title-case: ^3.0.3 + upper-case: ^2.0.2 + upper-case-first: ^2.0.2 + checksum: e1dabdcd8447a3690f3faf15f92979dfbc113109b50916976e1d5e518e6cfdebee4f05f54d0ca24fb79a4bf835185b59ae25e967bb3dc10bd236a775b19ecc52 + languageName: node + linkType: hard + +"change-case@npm:^4.1.2": + version: 4.1.2 + resolution: "change-case@npm:4.1.2" + dependencies: + camel-case: ^4.1.2 + capital-case: ^1.0.4 + constant-case: ^3.0.4 + dot-case: ^3.0.4 + header-case: ^2.0.4 + no-case: ^3.0.4 + param-case: ^3.0.4 + pascal-case: ^3.1.2 + path-case: ^3.0.4 + sentence-case: ^3.0.4 + snake-case: ^3.0.4 + tslib: ^2.0.3 + checksum: e4bc4a093a1f7cce8b33896665cf9e456e3bc3cc0def2ad7691b1994cfca99b3188d0a513b16855b01a6bd20692fcde12a7d4d87a5615c4c515bbbf0e651f116 + languageName: node + linkType: hard + "char-regex@npm:^1.0.2": version: 1.0.2 resolution: "char-regex@npm:1.0.2" @@ -10178,6 +11217,16 @@ __metadata: languageName: node linkType: hard +"cli-truncate@npm:^2.1.0": + version: 2.1.0 + resolution: "cli-truncate@npm:2.1.0" + dependencies: + slice-ansi: ^3.0.0 + string-width: ^4.2.0 + checksum: bf1e4e6195392dc718bf9cd71f317b6300dc4a9191d052f31046b8773230ece4fa09458813bf0e3455a5e68c0690d2ea2c197d14a8b85a7b5e01c97f4b5feb5d + languageName: node + linkType: hard + "cli-width@npm:^3.0.0": version: 3.0.0 resolution: "cli-width@npm:3.0.0" @@ -10356,6 +11405,13 @@ __metadata: languageName: node linkType: hard +"colorette@npm:^2.0.16": + version: 2.0.20 + resolution: "colorette@npm:2.0.20" + checksum: 0c016fea2b91b733eb9f4bcdb580018f52c0bc0979443dad930e5037a968237ac53d9beb98e218d2e9235834f8eebce7f8e080422d6194e957454255bde71d3d + languageName: node + linkType: hard + "colors@npm:^1.1.2": version: 1.4.0 resolution: "colors@npm:1.4.0" @@ -10421,6 +11477,13 @@ __metadata: languageName: node linkType: hard +"common-tags@npm:1.8.2": + version: 1.8.2 + resolution: "common-tags@npm:1.8.2" + checksum: 767a6255a84bbc47df49a60ab583053bb29a7d9687066a18500a516188a062c4e4cd52de341f22de0b07062e699b1b8fe3cfa1cb55b241cb9301aeb4f45b4dff + languageName: node + linkType: hard + "commondir@npm:^1.0.1": version: 1.0.1 resolution: "commondir@npm:1.0.1" @@ -10518,6 +11581,17 @@ __metadata: languageName: node linkType: hard +"constant-case@npm:^3.0.4": + version: 3.0.4 + resolution: "constant-case@npm:3.0.4" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + upper-case: ^2.0.2 + checksum: 6c3346d51afc28d9fae922e966c68eb77a19d94858dba230dd92d7b918b37d36db50f0311e9ecf6847e43e934b1c01406a0936973376ab17ec2c471fbcfb2cf3 + languageName: node + linkType: hard + "constants-browserify@npm:1.0.0": version: 1.0.0 resolution: "constants-browserify@npm:1.0.0" @@ -10605,6 +11679,23 @@ __metadata: languageName: node linkType: hard +"cosmiconfig@npm:^8.1.0, cosmiconfig@npm:^8.1.3": + version: 8.3.6 + resolution: "cosmiconfig@npm:8.3.6" + dependencies: + import-fresh: ^3.3.0 + js-yaml: ^4.1.0 + parse-json: ^5.2.0 + path-type: ^4.0.0 + peerDependencies: + typescript: ">=4.9.5" + peerDependenciesMeta: + typescript: + optional: true + checksum: dc339ebea427898c9e03bf01b56ba7afbac07fc7d2a2d5a15d6e9c14de98275a9565da949375aee1809591c152c0a3877bb86dbeaf74d5bd5aaa79955ad9e7a0 + languageName: node + linkType: hard + "crc@npm:^3.8.0": version: 3.8.0 resolution: "crc@npm:3.8.0" @@ -10677,6 +11768,15 @@ __metadata: languageName: node linkType: hard +"cross-inspect@npm:1.0.1": + version: 1.0.1 + resolution: "cross-inspect@npm:1.0.1" + dependencies: + tslib: ^2.4.0 + checksum: 7c1e02e0a9670b62416a3ea1df7ae880fdad3aa0a857de8932c4e5f8acd71298c7e3db9da8e9da603f5692cd1879938f5e72e34a9f5d1345987bef656d117fc1 + languageName: node + linkType: hard + "cross-spawn@npm:^6.0.0": version: 6.0.5 resolution: "cross-spawn@npm:6.0.5" @@ -10930,6 +12030,13 @@ __metadata: languageName: node linkType: hard +"dataloader@npm:^2.2.2": + version: 2.2.2 + resolution: "dataloader@npm:2.2.2" + checksum: 4dabd247089c29f194e94d5434d504f99156c5c214a03463c20f3f17f40398d7e179edee69a27c16e315519ac8739042a810090087ae26449a0e685156a02c65 + languageName: node + linkType: hard + "date-fns@npm:2.29.2": version: 2.29.2 resolution: "date-fns@npm:2.29.2" @@ -11194,6 +12301,13 @@ __metadata: languageName: node linkType: hard +"dependency-graph@npm:^0.11.0": + version: 0.11.0 + resolution: "dependency-graph@npm:0.11.0" + checksum: 477204beaa9be69e642bc31ffe7a8c383d0cf48fa27acbc91c5df01431ab913e65c154213d2ef83d034c98d77280743ec85e5da018a97a18dd43d3c0b78b28cd + languageName: node + linkType: hard + "deprecated-react-native-prop-types@npm:2.3.0, deprecated-react-native-prop-types@npm:^2.2.0, deprecated-react-native-prop-types@npm:^2.3.0": version: 2.3.0 resolution: "deprecated-react-native-prop-types@npm:2.3.0" @@ -11205,17 +12319,6 @@ __metadata: languageName: node linkType: hard -"deprecated-react-native-prop-types@npm:^4.1.0": - version: 4.2.3 - resolution: "deprecated-react-native-prop-types@npm:4.2.3" - dependencies: - "@react-native/normalize-colors": <0.73.0 - invariant: ^2.2.4 - prop-types: ^15.8.1 - checksum: 294752f9f15733b66473022d8258a14aac850e4a3db7e802ef189a09871236f5a110f8fe588468ae1df92f24641ae29de05943074dc54da02a5e4262935f913d - languageName: node - linkType: hard - "des.js@npm:^1.0.0": version: 1.1.0 resolution: "des.js@npm:1.1.0" @@ -11240,6 +12343,13 @@ __metadata: languageName: node linkType: hard +"detect-indent@npm:^6.0.0": + version: 6.1.0 + resolution: "detect-indent@npm:6.1.0" + checksum: ab953a73c72dbd4e8fc68e4ed4bfd92c97eb6c43734af3900add963fd3a9316f3bc0578b018b24198d4c31a358571eff5f0656e81a1f3b9ad5c547d58b2d093d + languageName: node + linkType: hard + "detect-libc@npm:^1.0.3": version: 1.0.3 resolution: "detect-libc@npm:1.0.3" @@ -11413,7 +12523,7 @@ __metadata: languageName: node linkType: hard -"dotenv@npm:^16.0.3, dotenv@npm:^16.4.4, dotenv@npm:~16.4.5": +"dotenv@npm:^16.0.0, dotenv@npm:^16.0.3, dotenv@npm:^16.4.4, dotenv@npm:~16.4.5": version: 16.4.5 resolution: "dotenv@npm:16.4.5" checksum: 301a12c3d44fd49888b74eb9ccf9f07a1f5df43f489e7fcb89647a2edcd84c42d6bc349dc8df099cd18f07c35c7b04685c1a4f3e6a6a9e6b30f8d48c15b7f49c @@ -11436,6 +12546,13 @@ __metadata: languageName: node linkType: hard +"dset@npm:^3.1.2": + version: 3.1.4 + resolution: "dset@npm:3.1.4" + checksum: 9a7677e9ffd3c13ad850f7cf367aa94b39984006510e84c3c09b7b88bba0a5b3b7196d85a99d0c4cae4e47d67bdeca43dc1834a41d80f31bcdc86dd26121ecec + languageName: node + linkType: hard + "duplexify@npm:^4.1.2": version: 4.1.2 resolution: "duplexify@npm:4.1.2" @@ -11479,6 +12596,13 @@ __metadata: languageName: node linkType: hard +"electron-to-chromium@npm:^1.5.41": + version: 1.5.56 + resolution: "electron-to-chromium@npm:1.5.56" + checksum: ef8213e3531715d48ca7c61e4b70532d57616271b56642d212297c72ba984bf57621c32d04eb56c19bfb90cf17d421875e6f334deddd191edf28515bebfb9061 + languageName: node + linkType: hard + "elliptic@npm:6.5.4, elliptic@npm:^6.5.3": version: 6.5.4 resolution: "elliptic@npm:6.5.4" @@ -11856,6 +12980,13 @@ __metadata: languageName: node linkType: hard +"escalade@npm:^3.2.0": + version: 3.2.0 + resolution: "escalade@npm:3.2.0" + checksum: 47b029c83de01b0d17ad99ed766347b974b0d628e848de404018f3abee728e987da0d2d370ad4574aa3d5b5bfc368754fd085d69a30f8e75903486ec4b5b709e + languageName: node + linkType: hard + "escape-html@npm:~1.0.3": version: 1.0.3 resolution: "escape-html@npm:1.0.3" @@ -12651,6 +13782,15 @@ __metadata: languageName: node linkType: hard +"expo-location@npm:^17.0.1": + version: 17.0.1 + resolution: "expo-location@npm:17.0.1" + peerDependencies: + expo: "*" + checksum: 1bfadaf16851cff26c14276aae7507daf159b2e62fc0c1e45c0f2288bb83be6314d55b4d4726317beff08d6582735a4b2c06cfdd4969b594a19321c735acdd1d + languageName: node + linkType: hard + "expo-modules-autolinking@npm:1.11.1": version: 1.11.1 resolution: "expo-modules-autolinking@npm:1.11.1" @@ -12773,6 +13913,13 @@ __metadata: languageName: node linkType: hard +"extract-files@npm:^11.0.0": + version: 11.0.0 + resolution: "extract-files@npm:11.0.0" + checksum: 39ebd92772e9a1e30d1e3112fb7db85d353c8243640635668b615ac1d605ceb79fbb13d17829dd308993ef37bb189ad99817f79ab164ae95c9bb3df9f440bd16 + languageName: node + linkType: hard + "eyes@npm:^0.1.8": version: 0.1.8 resolution: "eyes@npm:0.1.8" @@ -12856,7 +14003,7 @@ __metadata: languageName: node linkType: hard -"fast-querystring@npm:^1.0.0": +"fast-querystring@npm:^1.0.0, fast-querystring@npm:^1.1.1": version: 1.1.2 resolution: "fast-querystring@npm:1.1.2" dependencies: @@ -13052,6 +14199,15 @@ __metadata: languageName: node linkType: hard +"fill-range@npm:^7.1.1": + version: 7.1.1 + resolution: "fill-range@npm:7.1.1" + dependencies: + to-regex-range: ^5.0.1 + checksum: b4abfbca3839a3d55e4ae5ec62e131e2e356bf4859ce8480c64c4876100f4df292a63e5bb1618e1d7460282ca2b305653064f01654474aa35c68000980f17798 + languageName: node + linkType: hard + "filter-obj@npm:^1.1.0": version: 1.1.0 resolution: "filter-obj@npm:1.1.0" @@ -13477,6 +14633,13 @@ __metadata: languageName: node linkType: hard +"geolib@npm:^3.3.4": + version: 3.3.4 + resolution: "geolib@npm:3.3.4" + checksum: b5ca8090effd384fec168a957d89416577a92dcb63aedf361a60794e07051e6f2a98a3c2db64de2dd9114ac22c63fbf9ec67b2f61dbc300292040cbd4387942b + languageName: node + linkType: hard + "get-caller-file@npm:^2.0.1, get-caller-file@npm:^2.0.5": version: 2.0.5 resolution: "get-caller-file@npm:2.0.5" @@ -13694,7 +14857,44 @@ __metadata: languageName: node linkType: hard -"graphql-tag@npm:^2.10.1": +"graphql-config@npm:^5.1.1": + version: 5.1.3 + resolution: "graphql-config@npm:5.1.3" + dependencies: + "@graphql-tools/graphql-file-loader": ^8.0.0 + "@graphql-tools/json-file-loader": ^8.0.0 + "@graphql-tools/load": ^8.0.0 + "@graphql-tools/merge": ^9.0.0 + "@graphql-tools/url-loader": ^8.0.0 + "@graphql-tools/utils": ^10.0.0 + cosmiconfig: ^8.1.0 + jiti: ^2.0.0 + minimatch: ^9.0.5 + string-env-interpolation: ^1.0.1 + tslib: ^2.4.0 + peerDependencies: + cosmiconfig-toml-loader: ^1.0.0 + graphql: ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 + peerDependenciesMeta: + cosmiconfig-toml-loader: + optional: true + checksum: fde8aee849def42a5eaf02fbe3e404c91be94a53782c22ff58b29bfcfed7e9be2fba114fa94b4a97e12ea1e5970267ebaa119ba6915b2d4d9bb8f5ae9c5485c2 + languageName: node + linkType: hard + +"graphql-request@npm:^6.0.0": + version: 6.1.0 + resolution: "graphql-request@npm:6.1.0" + dependencies: + "@graphql-typed-document-node/core": ^3.2.0 + cross-fetch: ^3.1.5 + peerDependencies: + graphql: 14 - 16 + checksum: 6d62630a0169574442320651c1f7626c0c602025c3c46b19e09417c9579bb209306ee63de9793a03be2e1701bb7f13971f8545d99bc6573e340f823af0ad35b2 + languageName: node + linkType: hard + +"graphql-tag@npm:^2.10.1, graphql-tag@npm:^2.11.0": version: 2.12.6 resolution: "graphql-tag@npm:2.12.6" dependencies: @@ -13705,6 +14905,15 @@ __metadata: languageName: node linkType: hard +"graphql-ws@npm:^5.14.0": + version: 5.16.0 + resolution: "graphql-ws@npm:5.16.0" + peerDependencies: + graphql: ">=0.11 <=16" + checksum: e3e077ec187a92be3fd5dfae49e23af11a82711d3537064384f6861c2b5ceb339f60dc1871d0026b47ff05e4ed3c941404812a8086347e454688e0e6ef0e69f3 + languageName: node + linkType: hard + "graphql@npm:15.8.0": version: 15.8.0 resolution: "graphql@npm:15.8.0" @@ -13862,6 +15071,16 @@ __metadata: languageName: node linkType: hard +"header-case@npm:^2.0.4": + version: 2.0.4 + resolution: "header-case@npm:2.0.4" + dependencies: + capital-case: ^1.0.4 + tslib: ^2.0.3 + checksum: 571c83eeb25e8130d172218712f807c0b96d62b020981400bccc1503a7cf14b09b8b10498a962d2739eccf231d950e3848ba7d420b58a6acd2f9283439546cd9 + languageName: node + linkType: hard + "helium-wallet@workspace:.": version: 0.0.0-use.local resolution: "helium-wallet@workspace:." @@ -13872,10 +15091,14 @@ __metadata: "@babel/runtime": 7.20.13 "@bonfida/spl-name-service": ^1.1.1 "@coral-xyz/anchor": ^0.28.0 - "@gorhom/bottom-sheet": 4.6.4 + "@gorhom/bottom-sheet": 5.0.4 "@gorhom/portal": 1.0.14 - "@helium/account-fetch-cache": 0.9.14 - "@helium/account-fetch-cache-hooks": 0.9.14 + "@graphql-codegen/cli": ^5.0.0 + "@graphql-codegen/typescript": ^4.0.1 + "@graphql-codegen/typescript-operations": ^4.0.1 + "@graphql-codegen/typescript-rtk-query": ^3.1.1 + "@helium/account-fetch-cache": 0.9.7 + "@helium/account-fetch-cache-hooks": 0.9.7 "@helium/address": 4.10.2 "@helium/circuit-breaker-sdk": ^0.9.14 "@helium/crypto-react-native": 4.8.0 @@ -13910,12 +15133,11 @@ __metadata: "@ledgerhq/react-native-hid": 6.30.0 "@ledgerhq/react-native-hw-transport-ble": 6.29.5 "@ledgerhq/types-devices": ^6.22.4 - "@maplibre/maplibre-react-native": ^9.1.0 "@metaplex-foundation/js": ^0.19.5 "@metaplex-foundation/mpl-bubblegum": 0.6.0 "@metaplex-foundation/mpl-token-metadata": 2.10.0 "@ngraveio/bc-ur": ^1.1.13 - "@novalabsxyz/mobile-theme": 2.0.0-y.25 + "@novalabsxyz/mobile-theme": 2.0.0-y.26 "@onsol/tldparser": ^0.5.3 "@react-native-async-storage/async-storage": 1.18.1 "@react-native-community/blur": 4.3.0 @@ -13924,6 +15146,7 @@ __metadata: "@react-native-community/hooks": 2.8.1 "@react-native-community/netinfo": 9.3.7 "@react-native-community/slider": ^4.5.2 + "@react-native-masked-view/masked-view": ^0.3.2 "@react-native/babel-preset": 0.74.87 "@react-native/eslint-config": 0.74.87 "@react-native/metro-config": 0.74.87 @@ -13934,6 +15157,7 @@ __metadata: "@react-navigation/native-stack": 6.7.0 "@react-navigation/stack": 6.2.2 "@reduxjs/toolkit": 1.9.1 + "@rnmapbox/maps": ^10.1.31 "@shopify/restyle": 2.4.2 "@solana/spl-account-compression": 0.1.4 "@solana/spl-memo": 0.2.3 @@ -14014,9 +15238,11 @@ __metadata: expo-haptics: 13.0.1 expo-linking: 6.3.1 expo-local-authentication: 14.0.1 + expo-location: ^17.0.1 expo-secure-store: 13.0.2 expo-splash-screen: 0.27.5 fuse.js: 6.6.2 + geolib: ^3.3.4 h3-js: 4.1.0 https-browserify: 0.0.1 husky: 7.0.4 @@ -14049,10 +15275,13 @@ __metadata: react-native-clean-project: ^4.0.3 react-native-cli-bump-version: 1.5.0 react-native-codegen: 0.0.7 + react-native-compass-heading: ^1.5.0 + react-native-confetti-cannon: ^1.5.2 react-native-config: 1.4.6 react-native-crypto: 2.2.0 react-native-device-info: 8.7.1 react-native-flash-message: 0.2.1 + react-native-geocoding: ^0.5.0 react-native-gesture-handler: 2.18.1 react-native-get-random-values: 1.8.0 react-native-icloudstore: 0.9.0 @@ -14077,6 +15306,7 @@ __metadata: react-native-share: 7.9.0 react-native-shared-group-preferences: 1.1.24 react-native-simple-toast: 1.1.4 + react-native-skeleton-placeholder: ^5.2.4 react-native-snap-carousel: 4.0.0-beta.6 react-native-sodium: ^0.4.0 react-native-svg: 13.4.0 @@ -14088,6 +15318,7 @@ __metadata: react-native-udp: 2.7.0 react-native-url-polyfill: ^2.0.0 react-native-video: 5.2.1 + react-native-vision-camera: ^4.5.3 react-native-webview: 13.10.5 react-redux: 8.0.4 react-test-renderer: 17.0.2 @@ -14284,7 +15515,7 @@ __metadata: languageName: node linkType: hard -"https-proxy-agent@npm:^7.0.1": +"https-proxy-agent@npm:^7.0.0, https-proxy-agent@npm:^7.0.1": version: 7.0.5 resolution: "https-proxy-agent@npm:7.0.5" dependencies: @@ -14392,6 +15623,13 @@ __metadata: languageName: node linkType: hard +"immutable@npm:~3.7.6": + version: 3.7.6 + resolution: "immutable@npm:3.7.6" + checksum: 8cccfb22d3ecf14fe0c474612e96d6bb5d117493e7639fe6642fb81e78c9ac4b698dd8a322c105001a709ad873ffc90e30bad7db5d9a3ef0b54a6e1db0258e8e + languageName: node + linkType: hard + "import-fresh@npm:^2.0.0": version: 2.0.0 resolution: "import-fresh@npm:2.0.0" @@ -14402,7 +15640,7 @@ __metadata: languageName: node linkType: hard -"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1": +"import-fresh@npm:^3.0.0, import-fresh@npm:^3.2.1, import-fresh@npm:^3.3.0": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" dependencies: @@ -14412,6 +15650,13 @@ __metadata: languageName: node linkType: hard +"import-from@npm:4.0.0": + version: 4.0.0 + resolution: "import-from@npm:4.0.0" + checksum: 1fa29c05b048da18914e91d9a529e5d9b91774bebbfab10e53f59bcc1667917672b971cf102fee857f142e5e433ce69fa1f0a596e1c7d82f9947a5ec352694b9 + languageName: node + linkType: hard + "import-local@npm:^3.0.2": version: 3.1.0 resolution: "import-local@npm:3.1.0" @@ -14490,7 +15735,7 @@ __metadata: languageName: node linkType: hard -"inquirer@npm:^8.2.0": +"inquirer@npm:^8.0.0, inquirer@npm:^8.2.0": version: 8.2.6 resolution: "inquirer@npm:8.2.6" dependencies: @@ -14581,6 +15826,16 @@ __metadata: languageName: node linkType: hard +"is-absolute@npm:^1.0.0": + version: 1.0.0 + resolution: "is-absolute@npm:1.0.0" + dependencies: + is-relative: ^1.0.0 + is-windows: ^1.0.1 + checksum: 9d16b2605eda3f3ce755410f1d423e327ad3a898bcb86c9354cf63970ed3f91ba85e9828aa56f5d6a952b9fae43d0477770f78d37409ae8ecc31e59ebc279b27 + languageName: node + linkType: hard + "is-accessor-descriptor@npm:^0.1.6": version: 0.1.6 resolution: "is-accessor-descriptor@npm:0.1.6" @@ -14834,6 +16089,15 @@ __metadata: languageName: node linkType: hard +"is-glob@npm:4.0.3, is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": + version: 4.0.3 + resolution: "is-glob@npm:4.0.3" + dependencies: + is-extglob: ^2.1.1 + checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4 + languageName: node + linkType: hard + "is-glob@npm:^2.0.0": version: 2.0.1 resolution: "is-glob@npm:2.0.1" @@ -14843,15 +16107,6 @@ __metadata: languageName: node linkType: hard -"is-glob@npm:^4.0.0, is-glob@npm:^4.0.1, is-glob@npm:^4.0.3": - version: 4.0.3 - resolution: "is-glob@npm:4.0.3" - dependencies: - is-extglob: ^2.1.1 - checksum: d381c1319fcb69d341cc6e6c7cd588e17cd94722d9a32dbd60660b993c4fb7d0f19438674e68dfec686d09b7c73139c9166b47597f846af387450224a8101ab4 - languageName: node - linkType: hard - "is-hex-prefixed@npm:1.0.0": version: 1.0.0 resolution: "is-hex-prefixed@npm:1.0.0" @@ -14882,6 +16137,15 @@ __metadata: languageName: node linkType: hard +"is-lower-case@npm:^2.0.2": + version: 2.0.2 + resolution: "is-lower-case@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: ba57dd1201e15fd9b590654736afccf1b3b68e919f40c23ef13b00ebcc639b1d9c2f81fe86415bff3e8eccffec459786c9ac9dc8f3a19cfa4484206c411c1d7d + languageName: node + linkType: hard + "is-map@npm:^2.0.3": version: 2.0.3 resolution: "is-map@npm:2.0.3" @@ -14978,6 +16242,15 @@ __metadata: languageName: node linkType: hard +"is-relative@npm:^1.0.0": + version: 1.0.0 + resolution: "is-relative@npm:1.0.0" + dependencies: + is-unc-path: ^1.0.0 + checksum: 3271a0df109302ef5e14a29dcd5d23d9788e15ade91a40b942b035827ffbb59f7ce9ff82d036ea798541a52913cbf9d2d0b66456340887b51f3542d57b5a4c05 + languageName: node + linkType: hard + "is-retry-allowed@npm:^2.2.0": version: 2.2.0 resolution: "is-retry-allowed@npm:2.2.0" @@ -15042,6 +16315,15 @@ __metadata: languageName: node linkType: hard +"is-unc-path@npm:^1.0.0": + version: 1.0.0 + resolution: "is-unc-path@npm:1.0.0" + dependencies: + unc-path-regex: ^0.1.2 + checksum: e8abfde203f7409f5b03a5f1f8636e3a41e78b983702ef49d9343eb608cdfe691429398e8815157519b987b739bcfbc73ae7cf4c8582b0ab66add5171088eab6 + languageName: node + linkType: hard + "is-unicode-supported@npm:^0.1.0": version: 0.1.0 resolution: "is-unicode-supported@npm:0.1.0" @@ -15049,6 +16331,15 @@ __metadata: languageName: node linkType: hard +"is-upper-case@npm:^2.0.2": + version: 2.0.2 + resolution: "is-upper-case@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: cf4fd43c00c2e72cd5cff911923070b89f0933b464941bd782e2315385f80b5a5acd772db3b796542e5e3cfed735f4dffd88c54d62db1ebfc5c3daa7b1af2bc6 + languageName: node + linkType: hard + "is-valid-path@npm:^0.1.1": version: 0.1.1 resolution: "is-valid-path@npm:0.1.1" @@ -15084,7 +16375,7 @@ __metadata: languageName: node linkType: hard -"is-windows@npm:^1.0.2": +"is-windows@npm:^1.0.1, is-windows@npm:^1.0.2": version: 1.0.2 resolution: "is-windows@npm:1.0.2" checksum: 438b7e52656fe3b9b293b180defb4e448088e7023a523ec21a91a80b9ff8cdb3377ddb5b6e60f7c7de4fa8b63ab56e121b6705fe081b3cf1b828b0a380009ad7 @@ -15184,6 +16475,15 @@ __metadata: languageName: node linkType: hard +"isomorphic-ws@npm:^5.0.0": + version: 5.0.0 + resolution: "isomorphic-ws@npm:5.0.0" + peerDependencies: + ws: "*" + checksum: e20eb2aee09ba96247465fda40c6d22c1153394c0144fa34fe6609f341af4c8c564f60ea3ba762335a7a9c306809349f9b863c8beedf2beea09b299834ad5398 + languageName: node + linkType: hard + "istanbul-lib-coverage@npm:^3.0.0, istanbul-lib-coverage@npm:^3.2.0": version: 3.2.0 resolution: "istanbul-lib-coverage@npm:3.2.0" @@ -15776,6 +17076,24 @@ __metadata: languageName: node linkType: hard +"jiti@npm:^1.17.1": + version: 1.21.6 + resolution: "jiti@npm:1.21.6" + bin: + jiti: bin/jiti.js + checksum: 9ea4a70a7bb950794824683ed1c632e2ede26949fbd348e2ba5ec8dc5efa54dc42022d85ae229cadaa60d4b95012e80ea07d625797199b688cc22ab0e8891d32 + languageName: node + linkType: hard + +"jiti@npm:^2.0.0": + version: 2.4.0 + resolution: "jiti@npm:2.4.0" + bin: + jiti: lib/jiti-cli.mjs + checksum: b7d8c441214e48f6c1be2952a83f40e2b1eb6e94fe81b1fd89370d11a7e322c61eb3fbd9a8d47029e14338414091ebbb575e1a92c645ab30fea6240c5c4957c7 + languageName: node + linkType: hard + "jmespath@npm:0.16.0": version: 0.16.0 resolution: "jmespath@npm:0.16.0" @@ -15803,6 +17121,13 @@ __metadata: languageName: node linkType: hard +"jose@npm:^5.0.0": + version: 5.9.6 + resolution: "jose@npm:5.9.6" + checksum: 4b536da0201858ed4c4582e8bb479081f11e0c63dd0f5e473adde16fc539785e1f2f0409bc1fc7cbbb5b68026776c960b4952da3a06f6fdfff0b9764c9127ae0 + languageName: node + linkType: hard + "js-base64@npm:^3.7.2": version: 3.7.5 resolution: "js-base64@npm:3.7.5" @@ -15850,7 +17175,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:^4.1.0": +"js-yaml@npm:^4.0.0, js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" dependencies: @@ -15960,6 +17285,15 @@ __metadata: languageName: node linkType: hard +"jsesc@npm:^3.0.2": + version: 3.0.2 + resolution: "jsesc@npm:3.0.2" + bin: + jsesc: bin/jsesc + checksum: a36d3ca40574a974d9c2063bf68c2b6141c20da8f2a36bd3279fc802563f35f0527a6c828801295bdfb2803952cf2cf387786c2c90ed564f88d5782475abfe3c + languageName: node + linkType: hard + "jsesc@npm:~0.5.0": version: 0.5.0 resolution: "jsesc@npm:0.5.0" @@ -16055,6 +17389,16 @@ __metadata: languageName: node linkType: hard +"json-to-pretty-yaml@npm:^1.2.2": + version: 1.2.2 + resolution: "json-to-pretty-yaml@npm:1.2.2" + dependencies: + remedial: ^1.0.7 + remove-trailing-spaces: ^1.0.6 + checksum: 4b78480f426e176e5fdac073e05877683bb026f1175deb52d0941b992f9c91a58a812c020f00aa67ba1fc7cadb220539a264146f222e48a48c8bb2a0931cac9b + languageName: node + linkType: hard + "json5@npm:^0.5.1": version: 0.5.1 resolution: "json5@npm:0.5.1" @@ -16064,7 +17408,7 @@ __metadata: languageName: node linkType: hard -"json5@npm:^1.0.1, json5@npm:^1.0.2": +"json5@npm:^1.0.2": version: 1.0.2 resolution: "json5@npm:1.0.2" dependencies: @@ -16518,6 +17862,27 @@ __metadata: languageName: node linkType: hard +"listr2@npm:^4.0.5": + version: 4.0.5 + resolution: "listr2@npm:4.0.5" + dependencies: + cli-truncate: ^2.1.0 + colorette: ^2.0.16 + log-update: ^4.0.0 + p-map: ^4.0.0 + rfdc: ^1.3.0 + rxjs: ^7.5.5 + through: ^2.3.8 + wrap-ansi: ^7.0.0 + peerDependencies: + enquirer: ">= 2.3.0 < 3" + peerDependenciesMeta: + enquirer: + optional: true + checksum: 7af31851abe25969ef0581c6db808117e36af15b131401795182427769d9824f451ba9e8aff6ccd25b6a4f6c8796f816292caf08e5f1f9b1775e8e9c313dc6c5 + languageName: node + linkType: hard + "locate-path@npm:^3.0.0": version: 3.0.0 resolution: "locate-path@npm:3.0.0" @@ -16574,6 +17939,13 @@ __metadata: languageName: node linkType: hard +"lodash.sortby@npm:^4.7.0": + version: 4.7.0 + resolution: "lodash.sortby@npm:4.7.0" + checksum: db170c9396d29d11fe9a9f25668c4993e0c1331bcb941ddbd48fb76f492e732add7f2a47cfdf8e9d740fa59ac41bbfaf931d268bc72aab3ab49e9f89354d718c + languageName: node + linkType: hard + "lodash.throttle@npm:^4.1.1": version: 4.1.1 resolution: "lodash.throttle@npm:4.1.1" @@ -16588,7 +17960,7 @@ __metadata: languageName: node linkType: hard -"lodash@npm:4.17.21, lodash@npm:^4.17.13, lodash@npm:^4.17.21, lodash@npm:^4.17.4": +"lodash@npm:4.17.21, lodash@npm:^4.17.13, lodash@npm:^4.17.20, lodash@npm:^4.17.21, lodash@npm:^4.17.4, lodash@npm:~4.17.0": version: 4.17.21 resolution: "lodash@npm:4.17.21" checksum: eb835a2e51d381e561e508ce932ea50a8e5a68f4ebdd771ea240d3048244a8d13658acbd502cd4829768c56f2e16bdd4340b9ea141297d472517b83868e677f7 @@ -16604,7 +17976,7 @@ __metadata: languageName: node linkType: hard -"log-symbols@npm:^4.1.0": +"log-symbols@npm:^4.0.0, log-symbols@npm:^4.1.0": version: 4.1.0 resolution: "log-symbols@npm:4.1.0" dependencies: @@ -16614,6 +17986,18 @@ __metadata: languageName: node linkType: hard +"log-update@npm:^4.0.0": + version: 4.0.0 + resolution: "log-update@npm:4.0.0" + dependencies: + ansi-escapes: ^4.3.0 + cli-cursor: ^3.1.0 + slice-ansi: ^4.0.0 + wrap-ansi: ^6.2.0 + checksum: ae2f85bbabc1906034154fb7d4c4477c79b3e703d22d78adee8b3862fa913942772e7fa11713e3d96fb46de4e3cabefbf5d0a544344f03b58d3c4bff52aa9eb2 + languageName: node + linkType: hard + "logkitty@npm:^0.7.1": version: 0.7.1 resolution: "logkitty@npm:0.7.1" @@ -16686,6 +18070,15 @@ __metadata: languageName: node linkType: hard +"lower-case-first@npm:^2.0.2": + version: 2.0.2 + resolution: "lower-case-first@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: 33e3da1098ddda219ce125d4ab7a78a944972c0ee8872e95b6ccc35df8ad405284ab233b0ba4d72315ad1a06fe2f0d418ee4cba9ec1ef1c386dea78899fc8958 + languageName: node + linkType: hard + "lower-case@npm:^2.0.2": version: 2.0.2 resolution: "lower-case@npm:2.0.2" @@ -16768,7 +18161,7 @@ __metadata: languageName: node linkType: hard -"map-cache@npm:^0.2.2": +"map-cache@npm:^0.2.0, map-cache@npm:^0.2.2": version: 0.2.2 resolution: "map-cache@npm:0.2.2" checksum: 3067cea54285c43848bb4539f978a15dedc63c03022abeec6ef05c8cb6829f920f13b94bcaf04142fc6a088318e564c4785704072910d120d55dbc2e0c421969 @@ -16961,6 +18354,18 @@ __metadata: languageName: node linkType: hard +"meros@npm:^1.2.1": + version: 1.3.0 + resolution: "meros@npm:1.3.0" + peerDependencies: + "@types/node": ">=13" + peerDependenciesMeta: + "@types/node": + optional: true + checksum: ea86c83fe9357d3eb2f5bad20909e12642c7bc8c10340d9bd0968b48f69ec453de14f7e5032d138ad04cb10d79b8c9fb3c9601bb515e8fbdf9bec4eed62994ad + languageName: node + linkType: hard + "mersenne-twister@npm:^1.1.0": version: 1.1.0 resolution: "mersenne-twister@npm:1.1.0" @@ -17288,6 +18693,16 @@ __metadata: languageName: node linkType: hard +"micromatch@npm:^4.0.5, micromatch@npm:^4.0.8": + version: 4.0.8 + resolution: "micromatch@npm:4.0.8" + dependencies: + braces: ^3.0.3 + picomatch: ^2.3.1 + checksum: 79920eb634e6f400b464a954fcfa589c4e7c7143209488e44baf627f9affc8b1e306f41f4f0deedde97e69cb725920879462d3e750ab3bd3c1aed675bb3a8966 + languageName: node + linkType: hard + "miller-rabin@npm:^4.0.0": version: 4.0.1 resolution: "miller-rabin@npm:4.0.1" @@ -17380,7 +18795,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^9.0.4": +"minimatch@npm:^9.0.4, minimatch@npm:^9.0.5": version: 9.0.5 resolution: "minimatch@npm:9.0.5" dependencies: @@ -17896,6 +19311,15 @@ __metadata: languageName: node linkType: hard +"normalize-path@npm:^2.1.1": + version: 2.1.1 + resolution: "normalize-path@npm:2.1.1" + dependencies: + remove-trailing-separator: ^1.0.1 + checksum: 7e9cbdcf7f5b8da7aa191fbfe33daf290cdcd8c038f422faf1b8a83c972bf7a6d94c5be34c4326cb00fb63bc0fd97d9fbcfaf2e5d6142332c2cd36d2e1b86cea + languageName: node + linkType: hard + "normalize-path@npm:^3.0.0": version: 3.0.0 resolution: "normalize-path@npm:3.0.0" @@ -18310,6 +19734,15 @@ __metadata: languageName: node linkType: hard +"p-limit@npm:3.1.0, p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": + version: 3.1.0 + resolution: "p-limit@npm:3.1.0" + dependencies: + yocto-queue: ^0.1.0 + checksum: 7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 + languageName: node + linkType: hard + "p-limit@npm:^2.0.0, p-limit@npm:^2.2.0": version: 2.3.0 resolution: "p-limit@npm:2.3.0" @@ -18319,15 +19752,6 @@ __metadata: languageName: node linkType: hard -"p-limit@npm:^3.0.2, p-limit@npm:^3.1.0": - version: 3.1.0 - resolution: "p-limit@npm:3.1.0" - dependencies: - yocto-queue: ^0.1.0 - checksum: 7c3690c4dbf62ef625671e20b7bdf1cbc9534e83352a2780f165b0d3ceba21907e77ad63401708145ca4e25bfc51636588d89a8c0aeb715e6c37d1c066430360 - languageName: node - linkType: hard - "p-locate@npm:^3.0.0": version: 3.0.0 resolution: "p-locate@npm:3.0.0" @@ -18399,6 +19823,16 @@ __metadata: languageName: node linkType: hard +"param-case@npm:^3.0.4": + version: 3.0.4 + resolution: "param-case@npm:3.0.4" + dependencies: + dot-case: ^3.0.4 + tslib: ^2.0.3 + checksum: b34227fd0f794e078776eb3aa6247442056cb47761e9cd2c4c881c86d84c64205f6a56ef0d70b41ee7d77da02c3f4ed2f88e3896a8fefe08bdfb4deca037c687 + languageName: node + linkType: hard + "parent-module@npm:^1.0.0": version: 1.0.1 resolution: "parent-module@npm:1.0.1" @@ -18421,6 +19855,17 @@ __metadata: languageName: node linkType: hard +"parse-filepath@npm:^1.0.2": + version: 1.0.2 + resolution: "parse-filepath@npm:1.0.2" + dependencies: + is-absolute: ^1.0.0 + map-cache: ^0.2.0 + path-root: ^0.1.1 + checksum: 6794c3f38d3921f0f7cc63fb1fb0c4d04cd463356ad389c8ce6726d3c50793b9005971f4138975a6d7025526058d5e65e9bfe634d0765e84c4e2571152665a69 + languageName: node + linkType: hard + "parse-json@npm:^4.0.0": version: 4.0.0 resolution: "parse-json@npm:4.0.0" @@ -18466,6 +19911,16 @@ __metadata: languageName: node linkType: hard +"pascal-case@npm:^3.1.2": + version: 3.1.2 + resolution: "pascal-case@npm:3.1.2" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + checksum: ba98bfd595fc91ef3d30f4243b1aee2f6ec41c53b4546bfa3039487c367abaa182471dcfc830a1f9e1a0df00c14a370514fa2b3a1aacc68b15a460c31116873e + languageName: node + linkType: hard + "pascalcase@npm:^0.1.1": version: 0.1.1 resolution: "pascalcase@npm:0.1.1" @@ -18515,6 +19970,16 @@ __metadata: languageName: node linkType: hard +"path-case@npm:^3.0.4": + version: 3.0.4 + resolution: "path-case@npm:3.0.4" + dependencies: + dot-case: ^3.0.4 + tslib: ^2.0.3 + checksum: 61de0526222629f65038a66f63330dd22d5b54014ded6636283e1d15364da38b3cf29e4433aa3f9d8b0dba407ae2b059c23b0104a34ee789944b1bc1c5c7e06d + languageName: node + linkType: hard + "path-dirname@npm:^1.0.2": version: 1.0.2 resolution: "path-dirname@npm:1.0.2" @@ -18564,6 +20029,22 @@ __metadata: languageName: node linkType: hard +"path-root-regex@npm:^0.1.0": + version: 0.1.2 + resolution: "path-root-regex@npm:0.1.2" + checksum: dcd75d1f8e93faabe35a58e875b0f636839b3658ff2ad8c289463c40bc1a844debe0dab73c3398ef9dc8f6ec6c319720aff390cf4633763ddcf3cf4b1bbf7e8b + languageName: node + linkType: hard + +"path-root@npm:^0.1.1": + version: 0.1.1 + resolution: "path-root@npm:0.1.1" + dependencies: + path-root-regex: ^0.1.0 + checksum: ff88aebfc1c59ace510cc06703d67692a11530989920427625e52b66a303ca9b3d4059b0b7d0b2a73248d1ad29bcb342b8b786ec00592f3101d38a45fd3b2e08 + languageName: node + linkType: hard + "path-scurry@npm:^1.11.1": version: 1.11.1 resolution: "path-scurry@npm:1.11.1" @@ -18703,6 +20184,13 @@ __metadata: languageName: node linkType: hard +"picocolors@npm:^1.1.0": + version: 1.1.1 + resolution: "picocolors@npm:1.1.1" + checksum: e1cf46bf84886c79055fdfa9dcb3e4711ad259949e3565154b004b260cd356c5d54b31a1437ce9782624bf766272fe6b0154f5f0c744fb7af5d454d2b60db045 + languageName: node + linkType: hard + "picomatch@npm:^2.0.4, picomatch@npm:^2.2.3, picomatch@npm:^2.3.1": version: 2.3.1 resolution: "picomatch@npm:2.3.1" @@ -19553,6 +21041,23 @@ __metadata: languageName: node linkType: hard +"react-native-compass-heading@npm:^1.5.0": + version: 1.5.0 + resolution: "react-native-compass-heading@npm:1.5.0" + peerDependencies: + react: "*" + react-native: "*" + checksum: 09dfa531c8498937b0cfc4c809cdf049232c85d204e32c1f8923843a8fb00c09efbc9f75e28bd92d7265669e0ae40c9b0b12b567232f1dc080a23ecd8b16145e + languageName: node + linkType: hard + +"react-native-confetti-cannon@npm:^1.5.2": + version: 1.5.2 + resolution: "react-native-confetti-cannon@npm:1.5.2" + checksum: 09026fd93304c0f3c3acfcf8dfc9b25003b30826031dffd81df6eea3b66dcee84f6ac4237719a84d3d71cb430f4fbf53d4c22b64ef17d439d5a3e5986c2ada83 + languageName: node + linkType: hard + "react-native-config@npm:1.4.6": version: 1.4.6 resolution: "react-native-config@npm:1.4.6" @@ -19627,6 +21132,13 @@ __metadata: languageName: node linkType: hard +"react-native-geocoding@npm:^0.5.0": + version: 0.5.0 + resolution: "react-native-geocoding@npm:0.5.0" + checksum: a33e9dc87d104abe19206660e9fa0782090909ca8b58c70eae4690faa92194817724833086b29c57387500cdd9ecd0febd6ccbbd0f4eac0e11a93696429cf9d2 + languageName: node + linkType: hard + "react-native-gesture-handler@npm:2.18.1": version: 2.18.1 resolution: "react-native-gesture-handler@npm:2.18.1" @@ -19903,6 +21415,18 @@ __metadata: languageName: node linkType: hard +"react-native-skeleton-placeholder@npm:^5.2.4": + version: 5.2.4 + resolution: "react-native-skeleton-placeholder@npm:5.2.4" + peerDependencies: + "@react-native-masked-view/masked-view": ^0.2.8 + react: ">=0.14.8" + react-native: ">=0.50.1" + react-native-linear-gradient: ^2.5.6 + checksum: c90176c55d0a8342724c38ed5af8baff8ed879b04feeff027574c3c405f3d1be193614bd65e30ddf46407cb951d412f6cc5e2aa4a8e179c589c865f83bdae39e + languageName: node + linkType: hard + "react-native-snap-carousel@npm:4.0.0-beta.6": version: 4.0.0-beta.6 resolution: "react-native-snap-carousel@npm:4.0.0-beta.6" @@ -20032,6 +21556,26 @@ __metadata: languageName: node linkType: hard +"react-native-vision-camera@npm:^4.5.3": + version: 4.5.3 + resolution: "react-native-vision-camera@npm:4.5.3" + peerDependencies: + "@shopify/react-native-skia": "*" + react: "*" + react-native: "*" + react-native-reanimated: "*" + react-native-worklets-core: "*" + peerDependenciesMeta: + "@shopify/react-native-skia": + optional: true + react-native-reanimated: + optional: true + react-native-worklets-core: + optional: true + checksum: 99d57a70f93134903ae25ef798947f79804ea00e3b58cbb21131115552e6f2950d2a3be9a6a237232ca6bab7b5031aa12d9ca2df659be39dc607d75997317abc + languageName: node + linkType: hard + "react-native-webview@npm:13.10.5": version: 13.10.5 resolution: "react-native-webview@npm:13.10.5" @@ -20468,6 +22012,31 @@ __metadata: languageName: node linkType: hard +"relay-runtime@npm:12.0.0": + version: 12.0.0 + resolution: "relay-runtime@npm:12.0.0" + dependencies: + "@babel/runtime": ^7.0.0 + fbjs: ^3.0.0 + invariant: ^2.2.4 + checksum: 51cdc8a5e04188982452ae4e7c6ac7d6375ee769130d24ce8e8f9cdd45aa7e11ecd68670f56e30dcee1b4974585e88ecce19e69a9868b80cda0db7678c3b8f0a + languageName: node + linkType: hard + +"remedial@npm:^1.0.7": + version: 1.0.8 + resolution: "remedial@npm:1.0.8" + checksum: 12df7c55eb92501d7f33cfe5f5ad12be13bb6ac0c53f494aaa9963d5a5155bb8be2143e8d5e17afa1a500ef5dc71d13642920d35350f2a31b65a9778afab6869 + languageName: node + linkType: hard + +"remove-trailing-separator@npm:^1.0.1": + version: 1.1.0 + resolution: "remove-trailing-separator@npm:1.1.0" + checksum: d3c20b5a2d987db13e1cca9385d56ecfa1641bae143b620835ac02a6b70ab88f68f117a0021838db826c57b31373d609d52e4f31aca75fc490c862732d595419 + languageName: node + linkType: hard + "remove-trailing-slash@npm:^0.1.0": version: 0.1.1 resolution: "remove-trailing-slash@npm:0.1.1" @@ -20475,6 +22044,13 @@ __metadata: languageName: node linkType: hard +"remove-trailing-spaces@npm:^1.0.6": + version: 1.0.8 + resolution: "remove-trailing-spaces@npm:1.0.8" + checksum: 81f615c5cd8dd6a5e3017dcc9af598965575d176d42ef99cfd7b894529991f464e629fd68aba089f5c6bebf5bb8070a5eee56f3b621aba55e8ef524d6a4d4f69 + languageName: node + linkType: hard + "repeat-element@npm:^1.1.2": version: 1.1.4 resolution: "repeat-element@npm:1.1.4" @@ -20537,6 +22113,13 @@ __metadata: languageName: node linkType: hard +"resolve-from@npm:5.0.0, resolve-from@npm:^5.0.0": + version: 5.0.0 + resolution: "resolve-from@npm:5.0.0" + checksum: 4ceeb9113e1b1372d0cd969f3468fa042daa1dd9527b1b6bb88acb6ab55d8b9cd65dbf18819f9f9ddf0db804990901dcdaade80a215e7b2c23daae38e64f5bdf + languageName: node + linkType: hard + "resolve-from@npm:^3.0.0": version: 3.0.0 resolution: "resolve-from@npm:3.0.0" @@ -20551,13 +22134,6 @@ __metadata: languageName: node linkType: hard -"resolve-from@npm:^5.0.0": - version: 5.0.0 - resolution: "resolve-from@npm:5.0.0" - checksum: 4ceeb9113e1b1372d0cd969f3468fa042daa1dd9527b1b6bb88acb6ab55d8b9cd65dbf18819f9f9ddf0db804990901dcdaade80a215e7b2c23daae38e64f5bdf - languageName: node - linkType: hard - "resolve-url@npm:^0.2.1": version: 0.2.1 resolution: "resolve-url@npm:0.2.1" @@ -21041,6 +22617,13 @@ __metadata: languageName: node linkType: hard +"scuid@npm:^1.1.0": + version: 1.1.0 + resolution: "scuid@npm:1.1.0" + checksum: cd094ac3718b0070a222f9a499b280c698fdea10268cc163fa244421099544c1766dd893fdee0e2a8eba5d53ab9d0bcb11067bedff166665030fa6fda25a096b + languageName: node + linkType: hard + "secp256k1@npm:^4.0.0, secp256k1@npm:^4.0.2": version: 4.0.3 resolution: "secp256k1@npm:4.0.3" @@ -21138,6 +22721,17 @@ __metadata: languageName: node linkType: hard +"sentence-case@npm:^3.0.4": + version: 3.0.4 + resolution: "sentence-case@npm:3.0.4" + dependencies: + no-case: ^3.0.4 + tslib: ^2.0.3 + upper-case-first: ^2.0.2 + checksum: 3cfe6c0143e649132365695706702d7f729f484fa7b25f43435876efe7af2478243eefb052bacbcce10babf9319fd6b5b6bc59b94c80a1c819bcbb40651465d5 + languageName: node + linkType: hard + "sequelize-pool@npm:^7.1.0": version: 7.1.0 resolution: "sequelize-pool@npm:7.1.0" @@ -21380,6 +22974,13 @@ __metadata: languageName: node linkType: hard +"signedsource@npm:^1.0.0": + version: 1.0.0 + resolution: "signedsource@npm:1.0.0" + checksum: 64b2c8d7a48de9009cfd3aff62bb7c88abf3b8e0421f17ebb1d7f5ca9cc9c3ad10f5a1e3ae6cd804e4e6121c87b668202ae9057065f058ddfbf34ea65f63945d + languageName: node + linkType: hard + "simple-plist@npm:^1.1.0": version: 1.3.1 resolution: "simple-plist@npm:1.3.1" @@ -21439,6 +23040,17 @@ __metadata: languageName: node linkType: hard +"slice-ansi@npm:^3.0.0": + version: 3.0.0 + resolution: "slice-ansi@npm:3.0.0" + dependencies: + ansi-styles: ^4.0.0 + astral-regex: ^2.0.0 + is-fullwidth-code-point: ^3.0.0 + checksum: 5ec6d022d12e016347e9e3e98a7eb2a592213a43a65f1b61b74d2c78288da0aded781f665807a9f3876b9daa9ad94f64f77d7633a0458876c3a4fdc4eb223f24 + languageName: node + linkType: hard + "slice-ansi@npm:^4.0.0": version: 4.0.0 resolution: "slice-ansi@npm:4.0.0" @@ -21671,6 +23283,15 @@ __metadata: languageName: node linkType: hard +"sponge-case@npm:^1.0.1": + version: 1.0.1 + resolution: "sponge-case@npm:1.0.1" + dependencies: + tslib: ^2.0.3 + checksum: 64f53d930f63c5a9e59d4cae487c1ffa87d25eab682833b01d572cc885e7e3fdbad4f03409a41f03ecb27f1f8959432253eb48332c7007c3388efddb24ba2792 + languageName: node + linkType: hard + "sprintf-js@npm:^1.1.3": version: 1.1.3 resolution: "sprintf-js@npm:1.1.3" @@ -21790,6 +23411,13 @@ __metadata: languageName: node linkType: hard +"streamsearch@npm:^1.1.0": + version: 1.1.0 + resolution: "streamsearch@npm:1.1.0" + checksum: 1cce16cea8405d7a233d32ca5e00a00169cc0e19fbc02aa839959985f267335d435c07f96e5e0edd0eadc6d39c98d5435fb5bbbdefc62c41834eadc5622ad942 + languageName: node + linkType: hard + "strict-uri-encode@npm:^2.0.0": version: 2.0.0 resolution: "strict-uri-encode@npm:2.0.0" @@ -21797,6 +23425,13 @@ __metadata: languageName: node linkType: hard +"string-env-interpolation@npm:^1.0.1": + version: 1.0.1 + resolution: "string-env-interpolation@npm:1.0.1" + checksum: d126329587f635bee65300e4451e7352b9b67e03daeb62f006ca84244cac12a1f6e45176b018653ba0c3ec3b5d980f9ca59d2eeed99cf799501cdaa7f871dc6f + languageName: node + linkType: hard + "string-length@npm:^4.0.1": version: 4.0.2 resolution: "string-length@npm:4.0.2" @@ -22158,6 +23793,15 @@ __metadata: languageName: node linkType: hard +"swap-case@npm:^2.0.2": + version: 2.0.2 + resolution: "swap-case@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: 6e21c9e1b3cd5735eb2af679a99ec3efc78a14e3d4d5e3fd594e254b91cfd37185b3d1c6e41b22f53a2cdf5d1b963ce30c0fe8b78337e3fd43d0137084670a5f + languageName: node + linkType: hard + "table@npm:^6.0.9": version: 6.8.1 resolution: "table@npm:6.8.1" @@ -22357,7 +24001,7 @@ __metadata: languageName: node linkType: hard -"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.6": +"through@npm:2, through@npm:>=2.2.7 <3, through@npm:^2.3.6, through@npm:^2.3.8": version: 2.3.8 resolution: "through@npm:2.3.8" checksum: a38c3e059853c494af95d50c072b83f8b676a9ba2818dcc5b108ef252230735c54e0185437618596c790bbba8fcdaef5b290405981ffa09dce67b1f1bf190cbd @@ -22380,6 +24024,15 @@ __metadata: languageName: node linkType: hard +"title-case@npm:^3.0.3": + version: 3.0.3 + resolution: "title-case@npm:3.0.3" + dependencies: + tslib: ^2.0.3 + checksum: e8b7ea006b53cf3208d278455d9f1e22c409459d7f9878da324fa3b18cc0aef8560924c19c744e870394a5d9cddfdbe029ebae9875909ee7f4fc562e7cbfc53e + languageName: node + linkType: hard + "tmp-promise@npm:^3.0.2": version: 3.0.3 resolution: "tmp-promise@npm:3.0.3" @@ -22524,6 +24177,13 @@ __metadata: languageName: node linkType: hard +"ts-log@npm:^2.2.3": + version: 2.2.7 + resolution: "ts-log@npm:2.2.7" + checksum: c423a5eb54abb9471578902953814d3d0c88b3f237db016998f8998ecf982cb0f748bb8ebf93670eeba9b836ff0ce407d8065a340f3ab218ea7b9442c255b3d4 + languageName: node + linkType: hard + "ts-poet@npm:^6.5.0": version: 6.6.0 resolution: "ts-poet@npm:6.6.0" @@ -22601,6 +24261,27 @@ __metadata: languageName: node linkType: hard +"tslib@npm:^2.5.0, tslib@npm:^2.6.3": + version: 2.8.1 + resolution: "tslib@npm:2.8.1" + checksum: e4aba30e632b8c8902b47587fd13345e2827fa639e7c3121074d5ee0880723282411a8838f830b55100cbe4517672f84a2472667d355b81e8af165a55dc6203a + languageName: node + linkType: hard + +"tslib@npm:~2.4.0": + version: 2.4.1 + resolution: "tslib@npm:2.4.1" + checksum: 19480d6e0313292bd6505d4efe096a6b31c70e21cf08b5febf4da62e95c265c8f571f7b36fcc3d1a17e068032f59c269fab3459d6cd3ed6949eafecf64315fca + languageName: node + linkType: hard + +"tslib@npm:~2.6.0": + version: 2.6.3 + resolution: "tslib@npm:2.6.3" + checksum: 74fce0e100f1ebd95b8995fbbd0e6c91bdd8f4c35c00d4da62e285a3363aaa534de40a80db30ecfd388ed7c313c42d930ee0eaf108e8114214b180eec3dbe6f5 + languageName: node + linkType: hard + "tsutils@npm:^3.21.0": version: 3.21.0 resolution: "tsutils@npm:3.21.0" @@ -22835,6 +24516,13 @@ __metadata: languageName: node linkType: hard +"unc-path-regex@npm:^0.1.2": + version: 0.1.2 + resolution: "unc-path-regex@npm:0.1.2" + checksum: a05fa2006bf4606051c10fc7968f08ce7b28fa646befafa282813aeb1ac1a56f65cb1b577ca7851af2726198d59475bb49b11776036257b843eaacee2860a4ec + languageName: node + linkType: hard + "undici-types@npm:~5.26.4": version: 5.26.5 resolution: "undici-types@npm:5.26.5" @@ -22942,6 +24630,15 @@ __metadata: languageName: node linkType: hard +"unixify@npm:^1.0.0": + version: 1.0.0 + resolution: "unixify@npm:1.0.0" + dependencies: + normalize-path: ^2.1.1 + checksum: 3be30e48579fc6c7390bd59b4ab9e745fede0c164dfb7351cf710bd1dbef8484b1441186205af6bcb13b731c0c88caf9b33459f7bf8c89e79c046e656ae433f0 + languageName: node + linkType: hard + "unpipe@npm:~1.0.0": version: 1.0.0 resolution: "unpipe@npm:1.0.0" @@ -22980,6 +24677,38 @@ __metadata: languageName: node linkType: hard +"update-browserslist-db@npm:^1.1.1": + version: 1.1.1 + resolution: "update-browserslist-db@npm:1.1.1" + dependencies: + escalade: ^3.2.0 + picocolors: ^1.1.0 + peerDependencies: + browserslist: ">= 4.21.0" + bin: + update-browserslist-db: cli.js + checksum: 2ea11bd2562122162c3e438d83a1f9125238c0844b6d16d366e3276d0c0acac6036822dc7df65fc5a89c699cdf9f174acf439c39bedf3f9a2f3983976e4b4c3e + languageName: node + linkType: hard + +"upper-case-first@npm:^2.0.2": + version: 2.0.2 + resolution: "upper-case-first@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: 4487db4701effe3b54ced4b3e4aa4d9ab06c548f97244d04aafb642eedf96a76d5a03cf5f38f10f415531d5792d1ac6e1b50f2a76984dc6964ad530f12876409 + languageName: node + linkType: hard + +"upper-case@npm:^2.0.2": + version: 2.0.2 + resolution: "upper-case@npm:2.0.2" + dependencies: + tslib: ^2.0.3 + checksum: 508723a2b03ab90cf1d6b7e0397513980fab821cbe79c87341d0e96cedefadf0d85f9d71eac24ab23f526a041d585a575cfca120a9f920e44eb4f8a7cf89121c + languageName: node + linkType: hard + "uri-js@npm:^4.2.2": version: 4.4.1 resolution: "uri-js@npm:4.4.1" @@ -23013,6 +24742,13 @@ __metadata: languageName: node linkType: hard +"urlpattern-polyfill@npm:^10.0.0": + version: 10.0.0 + resolution: "urlpattern-polyfill@npm:10.0.0" + checksum: 61d890f151ea4ecf34a3dcab32c65ad1f3cda857c9d154af198260c6e5b2ad96d024593409baaa6d4428dd1ab206c14799bf37fe011117ac93a6a44913ac5aa4 + languageName: node + linkType: hard + "use-debounce@npm:7.0.1": version: 7.0.1 resolution: "use-debounce@npm:7.0.1" @@ -23207,6 +24943,13 @@ __metadata: languageName: node linkType: hard +"value-or-promise@npm:^1.0.11, value-or-promise@npm:^1.0.12": + version: 1.0.12 + resolution: "value-or-promise@npm:1.0.12" + checksum: f53a66c75b7447c90bbaf946a757ca09c094629cb80ba742f59c980ec3a69be0a385a0e75505dedb4e757862f1a994ca4beaf083a831f24d3ffb3d4bb18cd1e1 + languageName: node + linkType: hard + "vary@npm:^1, vary@npm:~1.1.2": version: 1.1.2 resolution: "vary@npm:1.1.2" @@ -23578,6 +25321,21 @@ __metadata: languageName: node linkType: hard +"ws@npm:^8.17.1": + version: 8.18.0 + resolution: "ws@npm:8.18.0" + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ">=5.0.2" + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + checksum: 91d4d35bc99ff6df483bdf029b9ea4bfd7af1f16fc91231a96777a63d263e1eabf486e13a2353970efc534f9faa43bdbf9ee76525af22f4752cbc5ebda333975 + languageName: node + linkType: hard + "xcode@npm:^3.0.1": version: 3.0.1 resolution: "xcode@npm:3.0.1" @@ -23588,16 +25346,6 @@ __metadata: languageName: node linkType: hard -"xml2js@npm:0.4.23": - version: 0.4.23 - resolution: "xml2js@npm:0.4.23" - dependencies: - sax: ">=0.6.0" - xmlbuilder: ~11.0.0 - checksum: ca0cf2dfbf6deeaae878a891c8fbc0db6fd04398087084edf143cdc83d0509ad0fe199b890f62f39c4415cf60268a27a6aed0d343f0658f8779bd7add690fa98 - languageName: node - linkType: hard - "xml2js@npm:0.5.0": version: 0.5.0 resolution: "xml2js@npm:0.5.0" @@ -23698,6 +25446,13 @@ __metadata: languageName: node linkType: hard +"yaml-ast-parser@npm:^0.0.43": + version: 0.0.43 + resolution: "yaml-ast-parser@npm:0.0.43" + checksum: fb5df4c067b6ccbd00953a46faf6ff27f0e290d623c712dc41f330251118f110e22cfd184bbff498bd969cbcda3cd27e0f9d0adb9e6d90eb60ccafc0d8e28077 + languageName: node + linkType: hard + "yaml@npm:^2.2.1, yaml@npm:^2.2.2": version: 2.5.0 resolution: "yaml@npm:2.5.0" @@ -23707,6 +25462,15 @@ __metadata: languageName: node linkType: hard +"yaml@npm:^2.3.1": + version: 2.6.0 + resolution: "yaml@npm:2.6.0" + bin: + yaml: bin.mjs + checksum: e5e74fd75e01bde2c09333d529af9fbb5928c5f7f01bfdefdcb2bf753d4ef489a45cab4deac01c9448f55ca27e691612b81fe3c3a59bb8cb5b0069da0f92cf0b + languageName: node + linkType: hard + "yargs-parser@npm:^18.1.2": version: 18.1.3 resolution: "yargs-parser@npm:18.1.3" @@ -23743,7 +25507,7 @@ __metadata: languageName: node linkType: hard -"yargs@npm:^17.3.1, yargs@npm:^17.6.2": +"yargs@npm:^17.0.0, yargs@npm:^17.3.1, yargs@npm:^17.6.2": version: 17.7.2 resolution: "yargs@npm:17.7.2" dependencies: