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..5c5259d26 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): @@ -1448,6 +1452,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 +1524,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 +1546,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 +1565,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 +1595,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`) @@ -1619,6 +1642,7 @@ DEPENDENCIES: - 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 +1652,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 +1660,16 @@ SPEC REPOS: - BCrypt - BEMCheckBox - Charts + - MapboxCommon + - MapboxCoreMaps + - MapboxMaps - MultiplatformBleAdapter - OneSignalXCFramework - SocketRocket - SwiftAlgorithms - SwiftyJSON - Toast + - Turf - ZXingObjC EXTERNAL SOURCES: @@ -1658,6 +1687,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 +1726,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 +1780,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: @@ -1841,6 +1872,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 +1892,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 +1908,7 @@ SPEC CHECKSUMS: EXBarCodeScanner: e2dd9b42c1b522a2adc9202b1dfbc64cb34456d1 EXConstants: 409690fbfd5afea964e5e9d6c4eb2c2b59222c59 EXImageLoader: ab589d67d6c5f2c33572afea9917304418566334 + EXLocation: 43e9b582ca63a23c6f0a18d8cbe2145b3a388b55 Expo: 798848eae1daf13363d69790986146b08d0cf92f ExpoAsset: 323700f291684f110fb55f0d4022a3362ea9f875 ExpoCamera: a5d000b22cd7dfd2c5904ed960e549de42c96da0 @@ -1891,7 +1927,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 +1959,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 @@ -1966,6 +2005,7 @@ SPEC CHECKSUMS: RNGestureHandler: efed690b8493a00b99654043daeb1335276ac4a2 RNICloudStore: bc6e225811637c09bd1eb055d6cd7448e61cd451 RNLocalize: a64514b46a01375fdfae9349036b4dc7130333b5 + rnmapbox-maps: 961b998761de9672c448aa17144b987410890992 RNOS: 6f2f9a70895bbbfbdad7196abd952e7b01d45027 RNPermissions: 2af759cf053542b2b4b3c4cf9f43874796106f2c RNReactNativeSharedGroupPreferences: 29092869fc2e40d5baca5e15d82fa5c24a668977 @@ -1979,9 +2019,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 diff --git a/package.json b/package.json index 9ff1cb38a..dfad71789 100644 --- a/package.json +++ b/package.json @@ -29,7 +29,7 @@ "@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.7", "@helium/account-fetch-cache-hooks": "0.9.7", @@ -66,12 +66,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", @@ -86,6 +85,7 @@ "@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,6 +134,7 @@ "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", @@ -162,10 +163,12 @@ "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-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", @@ -200,6 +203,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/src/App.tsx b/src/App.tsx index 46f815982..b7208fc88 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -2,7 +2,6 @@ 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' @@ -12,6 +11,7 @@ import globalStyles from '@theme/globalStyles' import { darkTheme } from '@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' @@ -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/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/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 index 4598139bf..41e96f224 100644 --- a/src/assets/images/add.svg +++ b/src/assets/images/add.svg @@ -1,3 +1,3 @@ - + 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/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/cameraCheck.svg b/src/assets/images/cameraCheck.svg new file mode 100644 index 000000000..1e0d2cae6 --- /dev/null +++ b/src/assets/images/cameraCheck.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/chevronDown.svg b/src/assets/images/chevronDown.svg index 5cf6154fd..08f7de437 100644 --- a/src/assets/images/chevronDown.svg +++ b/src/assets/images/chevronDown.svg @@ -1,3 +1,3 @@ - - + + 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/coin.svg b/src/assets/images/coin.svg new file mode 100644 index 000000000..194e302cb --- /dev/null +++ b/src/assets/images/coin.svg @@ -0,0 +1,3 @@ + + + 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/expand.svg b/src/assets/images/expand.svg new file mode 100644 index 000000000..61f5e5bbc --- /dev/null +++ b/src/assets/images/expand.svg @@ -0,0 +1,4 @@ + + + + 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/eyeIcon.svg b/src/assets/images/eyeIcon.svg new file mode 100644 index 000000000..bf0394bd2 --- /dev/null +++ b/src/assets/images/eyeIcon.svg @@ -0,0 +1,3 @@ + + + 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/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/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/infoIcon.svg b/src/assets/images/infoIcon.svg new file mode 100644 index 000000000..913596728 --- /dev/null +++ b/src/assets/images/infoIcon.svg @@ -0,0 +1,3 @@ + + + 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/iotIconNew.svg b/src/assets/images/iotIconNew.svg new file mode 100644 index 000000000..e7e5ed5de --- /dev/null +++ b/src/assets/images/iotIconNew.svg @@ -0,0 +1,4 @@ + + + + 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/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/locationCheckmark.svg b/src/assets/images/locationCheckmark.svg new file mode 100644 index 000000000..dd2a6212c --- /dev/null +++ b/src/assets/images/locationCheckmark.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/map.svg b/src/assets/images/map.svg new file mode 100644 index 000000000..c3f03cc9d --- /dev/null +++ b/src/assets/images/map.svg @@ -0,0 +1,3 @@ + + + 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/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/mobileIconNew.svg b/src/assets/images/mobileIconNew.svg new file mode 100644 index 000000000..c1b543b3f --- /dev/null +++ b/src/assets/images/mobileIconNew.svg @@ -0,0 +1,4 @@ + + + + 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/mobileTextLogo.svg b/src/assets/images/mobileTextLogo.svg new file mode 100644 index 000000000..483d499f1 --- /dev/null +++ b/src/assets/images/mobileTextLogo.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/modalBackButton.svg b/src/assets/images/modalBackButton.svg new file mode 100644 index 000000000..f7e10d41a --- /dev/null +++ b/src/assets/images/modalBackButton.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/modalCheckButton.svg b/src/assets/images/modalCheckButton.svg new file mode 100644 index 000000000..622e26553 --- /dev/null +++ b/src/assets/images/modalCheckButton.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/images/modalForwardButton.svg b/src/assets/images/modalForwardButton.svg new file mode 100644 index 000000000..51f510009 --- /dev/null +++ b/src/assets/images/modalForwardButton.svg @@ -0,0 +1,4 @@ + + + + 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/noCamera.svg b/src/assets/images/noCamera.svg new file mode 100644 index 000000000..f511b9b3a --- /dev/null +++ b/src/assets/images/noCamera.svg @@ -0,0 +1,3 @@ + + + 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/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/puck.png b/src/assets/images/puck.png new file mode 100644 index 000000000..ab26fbedf 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..14064560a 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..6057dc3b3 Binary files /dev/null and b/src/assets/images/puck@3x.png differ diff --git a/src/assets/images/puckShadow.png b/src/assets/images/puckShadow.png new file mode 100644 index 000000000..7e0f992a3 Binary files /dev/null and b/src/assets/images/puckShadow.png differ diff --git a/src/assets/images/puckShadow@2x.png b/src/assets/images/puckShadow@2x.png new file mode 100644 index 000000000..2d1743b11 Binary files /dev/null and b/src/assets/images/puckShadow@2x.png differ diff --git a/src/assets/images/puckShadow@3x.png b/src/assets/images/puckShadow@3x.png new file mode 100644 index 000000000..e9abea732 Binary files /dev/null and b/src/assets/images/puckShadow@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/rightArrow.svg b/src/assets/images/rightArrow.svg new file mode 100644 index 000000000..ab580e6a7 --- /dev/null +++ b/src/assets/images/rightArrow.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/images/rotateIcon.svg b/src/assets/images/rotateIcon.svg new file mode 100644 index 000000000..c06901b72 --- /dev/null +++ b/src/assets/images/rotateIcon.svg @@ -0,0 +1,3 @@ + + + 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/searchIcon.svg b/src/assets/images/searchIcon.svg new file mode 100644 index 000000000..567d7b23b --- /dev/null +++ b/src/assets/images/searchIcon.svg @@ -0,0 +1,3 @@ + + + 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/components/BlurActionSheet.tsx b/src/components/BlurActionSheet.tsx index 18b0819c7..6afbcf4b7 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 { useTranslation } from 'react-i18next' -import SafeAreaBox from './SafeAreaBox' +import { useSpacing } from '@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/FabButton.tsx b/src/components/FabButton.tsx index c8b8a2be9..f55032061 100644 --- a/src/components/FabButton.tsx +++ b/src/components/FabButton.tsx @@ -26,6 +26,7 @@ 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 Expand from '@assets/images/expand.svg' import Box from './Box' import Text from './Text' import ButtonPressAnimation from './ButtonPressAnimation' @@ -49,6 +50,7 @@ type IconName = | 'info' | 'questionMark' | 'browseVoters' + | 'expand' type Props = BoxProps & { backgroundColorOpacity?: number @@ -287,6 +289,8 @@ const FabIcon = ({ icon, pressed, color, colorPressed }: IconProps) => { return case 'browseVoters': return + case 'expand': + return } } diff --git a/src/components/HeliumBottomSheet.tsx b/src/components/HeliumBottomSheet.tsx index 8bb36145b..781e17f72 100644 --- a/src/components/HeliumBottomSheet.tsx +++ b/src/components/HeliumBottomSheet.tsx @@ -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( & { children?: React.ReactNode } +>(({ children, ...rest }, ref) => { + return ( + + {children} + + ) +}) + +export default Map diff --git a/src/components/Search.tsx b/src/components/Search.tsx new file mode 100644 index 000000000..17a58abaa --- /dev/null +++ b/src/components/Search.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import SearchIcon from '@assets/images/searchIcon.svg' +import { BoxProps } from '@shopify/restyle' +import { Theme } from '@theme/theme' +import { useColors, useTextVariants } from '@theme/themeHooks' +import { TextInput } from 'react-native' +import Box from './Box' + +type SearchProps = BoxProps & { + placeholder: string + onChangeText: (text: string) => void +} + +export const Search = ({ placeholder, onChangeText, ...rest }: SearchProps) => { + const textVariants = useTextVariants() + const colors = useColors() + return ( + + + + + ) +} diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 7103b395e..5287da81a 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -2,37 +2,102 @@ import { useColors } from '@theme/themeHooks' import ChevronDown from '@assets/images/chevronDown.svg' import { BoxProps } from '@shopify/restyle' import { Theme } from '@theme/theme' -import React, { useState } from 'react' +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..f30813286 100644 --- a/src/components/ServiceNavBar.tsx +++ b/src/components/ServiceNavBar.tsx @@ -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/TextInputNew.tsx b/src/components/TextInputNew.tsx new file mode 100644 index 000000000..faed387fb --- /dev/null +++ b/src/components/TextInputNew.tsx @@ -0,0 +1,43 @@ +import React from 'react' +import { BoxProps } from '@shopify/restyle' +import { Theme } from '@theme/theme' +import { useColors, useTextVariants } from '@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..f7111c401 100644 --- a/src/components/TextTransform.tsx +++ b/src/components/TextTransform.tsx @@ -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/components/map/utils.ts b/src/components/map/utils.ts deleted file mode 100644 index 83e3568f4..000000000 --- a/src/components/map/utils.ts +++ /dev/null @@ -1,38 +0,0 @@ -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 - -type CameraBounds = CameraPadding & { - ne: number[] - sw: number[] -} - -const WORLD_BOUNDS: CameraBounds = { - ne: [-134.827109, 57.785781], - sw: [129.767893, -30.955724], -} - -export const INITIAL_MAP_VIEW_STATE: { - centerCoordinate: [number, number] - bounds: CameraBounds - zoomLevel: number - animationDuration: number - cameraStop?: CameraStop -} = { - centerCoordinate: [-122.419418, 37.774929], - bounds: WORLD_BOUNDS, - zoomLevel: 12, - animationDuration: 500, -} - -export const MAP_CONTAINER_STYLE: ViewProps['style'] = { - flex: 1, - height: '100%', - width: '100%', - overflow: 'hidden', - position: 'relative', - backgroundColor: 'rgb(0,0,0)', -} diff --git a/src/constants/urls.ts b/src/constants/urls.ts index 0e5904e8c..dc32309c9 100644 --- a/src/constants/urls.ts +++ b/src/constants/urls.ts @@ -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/features/collectables/AssertLocationScreen.tsx b/src/features/collectables/AssertLocationScreen.tsx index 3970d37dd..726180026 100644 --- a/src/features/collectables/AssertLocationScreen.tsx +++ b/src/features/collectables/AssertLocationScreen.tsx @@ -8,7 +8,6 @@ import { DelayedFadeIn, FabButton, FadeInFast, - FadeInOut, ImageBox, ReAnimatedBlurBox, ReAnimatedBox, @@ -16,45 +15,24 @@ import { 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' -import useAlert from '@hooks/useAlert' -import { useCurrentWallet } from '@hooks/useCurrentWallet' import { useEntityKey } from '@hooks/useEntityKey' -import { useForwardGeo } from '@hooks/useForwardGeo' -import { useImplicitBurn } from '@hooks/useImplicitBurn' import { useIotInfo } from '@hooks/useIotInfo' 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' -import * as Logger from '@utils/logger' -import BN from 'bn.js' -import React, { - memo, - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react' +import React, { memo, useCallback, useEffect, useMemo, useState } from 'react' import { useTranslation } from 'react-i18next' import { - Alert, Keyboard, KeyboardAvoidingView, TouchableWithoutFeedback, } from 'react-native' import 'text-encoding-polyfill' -import { useDebounce } from 'use-debounce' -import { useColors, useCreateOpacity, useSpacing } from '@theme/themeHooks' +// import { useDebounce } from 'use-debounce' +import { useColors, useSpacing } from '@theme/themeHooks' import { useSafeAreaInsets } from 'react-native-safe-area-context' import CloseButton from '@components/CloseButton' import { @@ -69,49 +47,23 @@ const AssertLocationScreen = () => { 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 { showOKAlert } = useAlert() const colors = useColors() - const [mapCenter, setMapCenter] = useState() const [searchVisible, setSearchVisible] = useState(false) const [searchValue, setSearchValue] = useState() const [elevGainVisible, setElevGainVisible] = useState(false) const [gain, setGain] = useState() const [elevation, setElevation] = useState() - const [asserting, setAsserting] = useState(false) - const [transactionError, setTransactionError] = useState() - const reverseGeo = useReverseGeo(mapCenter) - const forwardGeo = useForwardGeo() - const { submitUpdateEntityInfo } = useSubmitTxn() const navigation = useNavigation() - const { - maker, - makerDc, - myDcWithHnt, - loadingMyDc, - loadingMakerDc, - locationAssertDcRequirements, - loadingLocationAssertDcRequirements, - } = useOnboardingBalnces(entityKey) - const { implicitBurn } = useImplicitBurn() - const wallet = useCurrentWallet() + const { loadingMyDc, loadingMakerDc, loadingLocationAssertDcRequirements } = + useOnboardingBalnces(entityKey) const { content: { metadata }, } = collectable - const iotLocation = useMemo(() => { - if (!iotInfoAcc?.location) { - return undefined - } - return parseH3BNLocation(iotInfoAcc.location).reverse() - }, [iotInfoAcc]) - const mobileLocation = useMemo(() => { if (!mobileInfoAcc?.location) { return undefined @@ -120,55 +72,35 @@ const AssertLocationScreen = () => { return parseH3BNLocation(mobileInfoAcc.location).reverse() }, [mobileInfoAcc]) - const sameLocation = useMemo(() => { - if (!iotLocation || !mobileLocation) { - return false - } - - return JSON.stringify(iotLocation) === JSON.stringify(mobileLocation) - }, [iotLocation, mobileLocation]) - - 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 ( - iotLocation || - mobileLocation || - initialUserLocation || - INITIAL_MAP_VIEW_STATE.centerCoordinate - ) - }, [initialUserLocation, iotLocation, mobileLocation]) - - 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 [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]) + + // 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]) useEffect(() => { if (!elevGainVisible) { @@ -182,233 +114,221 @@ const AssertLocationScreen = () => { } }, [iotInfoAcc, elevGainVisible, setGain, setElevation]) - const resetGain = useCallback( - () => setGain(iotInfoAcc?.gain ? `${iotInfoAcc.gain / 10}` : undefined), - [iotInfoAcc, setGain], - ) + // const resetGain = useCallback( + // () => setGain(iotInfoAcc?.gain ? `${iotInfoAcc.gain / 10}` : undefined), + // [iotInfoAcc, setGain], + // ) - const resetElevation = useCallback( - () => - setElevation( - iotInfoAcc?.elevation ? `${iotInfoAcc.elevation}` : undefined, - ), - [iotInfoAcc, setElevation], - ) + // const resetElevation = useCallback( + // () => + // setElevation( + // iotInfoAcc?.elevation ? `${iotInfoAcc.elevation}` : undefined, + // ), + // [iotInfoAcc, setElevation], + // ) const handleSearchPress = useCallback(() => { setSearchVisible(!searchVisible) }, [searchVisible, setSearchVisible]) - const hideSearch = useCallback(() => { - setSearchValue(undefined) - setSearchVisible(false) - }, [setSearchValue, setSearchVisible]) - - const hideElevGain = useCallback(() => { - setElevGainVisible(false) - resetGain() - resetElevation() - }, [setElevGainVisible, resetGain, resetElevation]) - - 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'), - }) - } - } - } - - hideSearch() - }, [cameraRef, t, hideSearch, 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) - setTransactionError(undefined) - hideSearch() - } - } - }, [mapRef, mapCenter, setMapCenter, hideSearch]) - - const handleUserLocationPress = useCallback(() => { - if (cameraRef?.current && userLocation?.coords) { - cameraRef.current.setCamera({ - animationDuration: 500, - zoomLevel: MAX_MAP_ZOOM, - centerCoordinate: userLocation?.coords, - }) - } - }, [cameraRef, userLocation?.coords]) - - const assertLocation = useCallback( - async (type: NetworkType) => { - if ( - !mapCenter || - !entityKey || - loadingMakerDc || - loadingLocationAssertDcRequirements || - !wallet - ) - return - - setTransactionError(undefined) - setAsserting(true) - try { - hideElevGain() - if (collectable.ownership.owner.toString() !== wallet.toBase58()) { - throw new Error(t('assertLocationScreen.error.wrongOwner')) - } - const requiredDc = - locationAssertDcRequirements[ - type === 'IOT' ? IOT_MINT.toBase58() : MOBILE_MINT.toBase58() - ] - const insufficientMakerDcBal = (makerDc || new BN(0)).lt(requiredDc) - const insufficientMyDcBal = - !loadingMyDc && (myDcWithHnt || new BN(0)).lt(requiredDc) - - let numLocationChanges = 0 - if (type === 'IOT') { - numLocationChanges = iotInfoAcc?.numLocationAsserts || 0 - } else { - numLocationChanges = mobileInfoAcc?.numLocationAsserts || 0 - } - const isPayer = - insufficientMakerDcBal || - !maker || - numLocationChanges >= maker.locationNonceLimit - if (isPayer && insufficientMyDcBal) { - throw new Error( - t('assertLocationScreen.error.insufficientFunds', { - usd: requiredDc.toNumber() / 100000, - }), - ) - } - if (isPayer) { - await implicitBurn(requiredDc.toNumber()) - } - await submitUpdateEntityInfo({ - type, - entityKey, - lng: mapCenter[0], - lat: mapCenter[1], - elevation, - decimalGain: gain, - payer: isPayer ? wallet.toBase58() : undefined, - }) - setAsserting(false) - - await showOKAlert({ - title: t('assertLocationScreen.success.title'), - message: t('assertLocationScreen.success.message'), - }) - navigation.navigate('HotspotMapScreen', { - hotspot: collectable, - network: type, - }) - } catch (error) { - setAsserting(false) - Logger.error(error) - setTransactionError((error as Error).message) - } - }, - [ - maker, - implicitBurn, - wallet, - mapCenter, - entityKey, - loadingMakerDc, - loadingLocationAssertDcRequirements, - hideElevGain, - locationAssertDcRequirements, - makerDc, - loadingMyDc, - myDcWithHnt, - submitUpdateEntityInfo, - elevation, - gain, - showOKAlert, - t, - navigation, - collectable, - iotInfoAcc?.numLocationAsserts, - mobileInfoAcc?.numLocationAsserts, - ], - ) - - const handleAssertLocationPress = useCallback(async () => { - if (!elevGainVisible) { - Alert.alert( - t('assertLocationScreen.title'), - t('assertLocationScreen.whichLocation'), - [ - { - text: 'Iot', - onPress: () => setElevGainVisible(true), - }, - { - text: 'Mobile', - onPress: async () => assertLocation('MOBILE'), - }, - { - text: t('generic.cancel'), - style: 'destructive', - }, - ], - ) - } else { - // elevGainVisible - // we can assume user is asserting location from elevGain UI - await assertLocation('IOT') - } - }, [t, elevGainVisible, assertLocation]) - - const showError = useMemo(() => { - if (transactionError) return transactionError - }, [transactionError]) - - const disabled = useMemo( - () => - !mapCenter || - reverseGeo.loading || - asserting || - loadingLocationAssertDcRequirements || - loadingMakerDc || - loadingMyDc, - [ - asserting, - mapCenter, - reverseGeo.loading, - loadingLocationAssertDcRequirements, - loadingMakerDc, - loadingMyDc, - ], - ) + // const hideElevGain = useCallback(() => { + // setElevGainVisible(false) + // resetGain() + // resetElevation() + // }, [setElevGainVisible, resetGain, resetElevation]) + + // 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'), + // }) + // } + // } + // } + + // hideSearch() + // }, [cameraRef, t, hideSearch, 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) + // setTransactionError(undefined) + // hideSearch() + // } + // } + // }, [mapRef, mapCenter, setMapCenter, hideSearch]) + + // const handleUserLocationPress = useCallback(() => { + // if (cameraRef?.current && userLocation?.coords) { + // cameraRef.current.setCamera({ + // animationDuration: 500, + // zoomLevel: MAX_MAP_ZOOM, + // centerCoordinate: userLocation?.coords, + // }) + // } + // }, [cameraRef, userLocation?.coords]) + + // const assertLocation = useCallback( + // async (type: NetworkType) => { + // if ( + // !entityKey || + // loadingMakerDc || + // loadingLocationAssertDcRequirements || + // !wallet + // ) + // return + + // setTransactionError(undefined) + // setAsserting(true) + // try { + // hideElevGain() + // if (collectable.ownership.owner.toString() !== wallet.toBase58()) { + // throw new Error(t('assertLocationScreen.error.wrongOwner')) + // } + // const requiredDc = + // locationAssertDcRequirements[ + // type === 'IOT' ? IOT_MINT.toBase58() : MOBILE_MINT.toBase58() + // ] + // const insufficientMakerDcBal = (makerDc || new BN(0)).lt(requiredDc) + // const insufficientMyDcBal = + // !loadingMyDc && (myDcWithHnt || new BN(0)).lt(requiredDc) + + // let numLocationChanges = 0 + // if (type === 'IOT') { + // numLocationChanges = iotInfoAcc?.numLocationAsserts || 0 + // } else { + // numLocationChanges = mobileInfoAcc?.numLocationAsserts || 0 + // } + // const isPayer = + // insufficientMakerDcBal || + // !maker || + // numLocationChanges >= maker.locationNonceLimit + // if (isPayer && insufficientMyDcBal) { + // throw new Error( + // t('assertLocationScreen.error.insufficientFunds', { + // usd: requiredDc.toNumber() / 100000, + // }), + // ) + // } + // if (isPayer) { + // await implicitBurn(requiredDc.toNumber()) + // } + // await submitUpdateEntityInfo({ + // type, + // entityKey, + // lng: mapCenter[0], + // lat: mapCenter[1], + // elevation, + // decimalGain: gain, + // payer: isPayer ? wallet.toBase58() : undefined, + // }) + // setAsserting(false) + + // await showOKAlert({ + // title: t('assertLocationScreen.success.title'), + // message: t('assertLocationScreen.success.message'), + // }) + // navigation.navigate('HotspotMapScreen', { + // hotspot: collectable, + // network: type, + // }) + // } catch (error) { + // setAsserting(false) + // Logger.error(error) + // setTransactionError((error as Error).message) + // } + // }, + // [ + // maker, + // implicitBurn, + // wallet, + // entityKey, + // loadingMakerDc, + // loadingLocationAssertDcRequirements, + // hideElevGain, + // locationAssertDcRequirements, + // makerDc, + // loadingMyDc, + // myDcWithHnt, + // submitUpdateEntityInfo, + // elevation, + // gain, + // showOKAlert, + // t, + // navigation, + // collectable, + // iotInfoAcc?.numLocationAsserts, + // mobileInfoAcc?.numLocationAsserts, + // ], + // ) + + // const handleAssertLocationPress = useCallback(async () => { + // if (!elevGainVisible) { + // Alert.alert( + // t('assertLocationScreen.title'), + // t('assertLocationScreen.whichLocation'), + // [ + // { + // text: 'Iot', + // onPress: () => setElevGainVisible(true), + // }, + // { + // text: 'Mobile', + // onPress: async () => assertLocation('MOBILE'), + // }, + // { + // text: t('generic.cancel'), + // style: 'destructive', + // }, + // ], + // ) + // } else { + // // elevGainVisible + // // we can assume user is asserting location from elevGain UI + // await assertLocation('IOT') + // } + // }, [t, elevGainVisible, assertLocation]) + + // const showError = useMemo(() => { + // if (transactionError) return transactionError + // }, [transactionError]) + + // const disabled = useMemo( + // () => + // asserting || + // loadingLocationAssertDcRequirements || + // loadingMakerDc || + // loadingMyDc, + // [ + // asserting, + // loadingLocationAssertDcRequirements, + // loadingMakerDc, + // loadingMyDc, + // ], + // ) const isLoading = useMemo( () => loadingMyDc || loadingMakerDc || loadingLocationAssertDcRequirements, [loadingMyDc, loadingMakerDc, loadingLocationAssertDcRequirements], ) - const [debouncedDisabled] = useDebounce(disabled, 300) - const [reverseGeoLoading] = useDebounce(reverseGeo.loading, 300) + // const [debouncedDisabled] = useDebounce(disabled, 300) return ( @@ -434,7 +354,7 @@ const AssertLocationScreen = () => { - { ) }) .filter(Boolean)} - + */} { alignItems="center" marginHorizontal="3" > - {reverseGeoLoading && ( - - - - )} - {showError && ( + {/* {showError && ( {showError} - )} - {!reverseGeoLoading && !showError && reverseGeo.result && ( - - - - {reverseGeo.result} - - - - )} + )} */} { width={36} height={36} justifyContent="center" - onPress={handleUserLocationPress} + // onPress={handleUserLocationPress} /> @@ -624,7 +513,7 @@ const AssertLocationScreen = () => { { backgroundColor="primaryText" borderRadius="full" paddingVertical="5" - disabled={disabled} + // disabled={disabled} height={65} alignItems="center" justifyContent="center" - onPress={handleAssertLocationPress} + // onPress={handleAssertLocationPress} style={{ marginBottom: bottom + spacing['0.5'], }} > - {debouncedDisabled || asserting ? ( + {/* {debouncedDisabled ? ( - ) : ( - - {t('assertLocationScreen.title')} - - )} + ) : ( */} + + {t('assertLocationScreen.title')} + + {/* )} */} )} @@ -829,9 +718,9 @@ const AssertLocationScreen = () => { backgroundColorDisabled="base.white" backgroundColorDisabledOpacity={0.0} titleColorDisabled="gray.600" - title={asserting ? '' : t('assertLocationScreen.title')} + // title={asserting ? '' : t('assertLocationScreen.title')} titleColor="primaryBackground" - onPress={handleAssertLocationPress} + // onPress={handleAssertLocationPress} /> diff --git a/src/features/collectables/HotspotMapScreen.tsx b/src/features/collectables/HotspotMapScreen.tsx index c8033b0b5..86a571a53 100644 --- a/src/features/collectables/HotspotMapScreen.tsx +++ b/src/features/collectables/HotspotMapScreen.tsx @@ -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,24 +25,18 @@ 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 { 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 { HotspotWithPendingRewards } from '../../types/solana' import { HotspotMapHotspotDetails } from './HotspotMapHotspotDetails' @@ -57,6 +49,7 @@ import { 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 && ( { {t('gov.assignProxy.selectNetwork')}