Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/main' into bugfix/require-pin
Browse files Browse the repository at this point in the history
  • Loading branch information
ChewingGlass committed Oct 17, 2024
2 parents 475e874 + e9a4af5 commit 7ae122c
Show file tree
Hide file tree
Showing 48 changed files with 2,179 additions and 111 deletions.
1 change: 1 addition & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './shim'
import { ThemeProvider } from '@shopify/restyle'
import React from 'react'
import { ErrorBoundary } from 'react-error-boundary'
Expand Down
21 changes: 2 additions & 19 deletions ios/HeliumWallet.xcworkspace/xcshareddata/swiftpm/Package.resolved
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"originHash" : "e70d3525c8e2819a8b34f22909815dab5c700c25a06c32388f3930f7b3627768",
"pins" : [
{
"identity" : "maplibre-gl-native-distribution",
Expand All @@ -8,25 +9,7 @@
"revision" : "ffda61e298c1490d4860d5184e80d618aaadc089",
"version" : "5.13.0"
}
},
{
"identity" : "swiftui-charts",
"kind" : "remoteSourceControl",
"location" : "https://github.com/spacenation/swiftui-charts",
"state" : {
"revision" : "b044e7eb04d0026490eecb115f4fc07197dad942",
"version" : "1.1.0"
}
},
{
"identity" : "swiftui-shapes",
"kind" : "remoteSourceControl",
"location" : "https://github.com/spacenation/swiftui-shapes.git",
"state" : {
"revision" : "c58b15c37eae9bd20525c6daa93a06a689ca75cb",
"version" : "1.1.0"
}
}
],
"version" : 2
"version" : 3
}
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,15 @@
"@helium/voter-stake-registry-sdk": "0.9.7",
"@helium/wallet-link": "4.11.0",
"@jup-ag/api": "^6.0.6",
"@keystonehq/keystone-sdk": "^0.8.0",
"@ledgerhq/hw-app-solana": "7.0.13",
"@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/mpl-bubblegum": "0.6.0",
"@metaplex-foundation/mpl-token-metadata": "2.10.0",
"@ngraveio/bc-ur": "^1.1.13",
"@onsol/tldparser": "^0.5.3",
"@react-native-async-storage/async-storage": "1.18.1",
"@react-native-community/blur": "4.3.0",
Expand Down
81 changes: 42 additions & 39 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ 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'

SplashLib.preventAutoHideAsync().catch(() => {
/* reloading the app might trigger some race conditions, ignore them */
Expand Down Expand Up @@ -122,46 +123,48 @@ const App = () => {
<WalletOnboardingProvider
baseUrl={Config.ONBOARDING_API_URL}
>
<WalletConnectProvider>
<HotspotOnboardingProvider
baseUrl={Config.ONBOARDING_API_URL}
>
<LockScreen>
{accountsRestored && (
<>
<NavigationContainer
theme={navTheme}
linking={linking}
ref={navigationRef}
>
<BalanceProvider>
<TokensProvider>
<ModalProvider>
<WalletSignProvider>
<GovernanceProvider>
<AutoGasBanner />
<NetworkAwareStatusBar />
<RootNavigator />
<KeystoneOnboardingProvider>
<WalletConnectProvider>
<HotspotOnboardingProvider
baseUrl={Config.ONBOARDING_API_URL}
>
<LockScreen>
{accountsRestored && (
<>
<NavigationContainer
theme={navTheme}
linking={linking}
ref={navigationRef}
>
<BalanceProvider>
<TokensProvider>
<ModalProvider>
<WalletSignProvider>
<GovernanceProvider>
<AutoGasBanner />
<NetworkAwareStatusBar />
<RootNavigator />

{/* place app specific modals here */}
<InsufficientSolConversionModal />
</GovernanceProvider>
</WalletSignProvider>
</ModalProvider>
</TokensProvider>
</BalanceProvider>
</NavigationContainer>
<SecurityScreen
visible={
appState !== 'active' &&
appState !== 'unknown'
}
/>
</>
)}
</LockScreen>
</HotspotOnboardingProvider>
</WalletConnectProvider>
{/* place app specific modals here */}
<InsufficientSolConversionModal />
</GovernanceProvider>
</WalletSignProvider>
</ModalProvider>
</TokensProvider>
</BalanceProvider>
</NavigationContainer>
<SecurityScreen
visible={
appState !== 'active' &&
appState !== 'unknown'
}
/>
</>
)}
</LockScreen>
</HotspotOnboardingProvider>
</WalletConnectProvider>
</KeystoneOnboardingProvider>
</WalletOnboardingProvider>
</SplashScreen>
</SolanaProvider>
Expand Down
Binary file added src/assets/images/connectKeystoneLogo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions src/assets/images/keystoneLogo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/scannerLine.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions src/assets/images/warningKeystone.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/components/BackScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,8 @@ const BackScreen = ({
</TouchableOpacityBox>
)}
</Box>
<Box padding={padding || 'lx'} flex={flex || 1} {...rest}>
{/* if padding is not set, set it to 'lx' , if padding set to 'none' , set it to 0 */}
<Box padding={padding ?? 'lx'} flex={flex || 1} {...rest}>
{children}
</Box>
</SafeAreaBox>
Expand Down
101 changes: 101 additions & 0 deletions src/components/CameraScannerLayout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import React, { useEffect } from 'react'
import { Image } from 'react-native'
import Animated, {
useSharedValue,
useAnimatedStyle,
withRepeat,
withTiming,
} from 'react-native-reanimated'
import Box from './Box'

const SCANNER_SIZE = 300
const SCANNER_LINE_HEIGHT = 43
const SCAN_DURATION = 2000
const BORDER_SEGMENT_SIZE = 40
export const CameraScannerLayout = () => {
const linePosition = useSharedValue<number>(-SCANNER_LINE_HEIGHT)
const animatedStyle = useAnimatedStyle(() => ({
transform: [{ translateY: linePosition.value }],
}))

useEffect(() => {
linePosition.value = withRepeat(
withTiming(SCANNER_SIZE, {
duration: SCAN_DURATION,
}),
-1,
)
}, [linePosition])

return (
<Box
position="absolute"
top={0}
left={0}
right={0}
bottom={0}
justifyContent="center"
alignItems="center"
opacity={0.5}
backgroundColor="primaryBackground"
>
<Box
position="relative"
width={SCANNER_SIZE}
height={SCANNER_SIZE}
justifyContent="space-between"
alignItems="center"
overflow="hidden"
>
{/* top left */}
<Box
position="absolute"
borderColor="hntBlue"
width={BORDER_SEGMENT_SIZE}
height={BORDER_SEGMENT_SIZE}
borderTopWidth={4}
borderLeftWidth={4}
top={0}
left={0}
/>
{/* top right */}
<Box
position="absolute"
borderColor="hntBlue"
width={BORDER_SEGMENT_SIZE}
height={BORDER_SEGMENT_SIZE}
borderTopWidth={4}
borderRightWidth={4}
top={0}
right={0}
/>
{/* bottom left */}
<Box
position="absolute"
borderColor="hntBlue"
width={BORDER_SEGMENT_SIZE}
height={BORDER_SEGMENT_SIZE}
borderBottomWidth={4}
borderLeftWidth={4}
bottom={0}
left={0}
/>
{/* bottom right */}
<Box
position="absolute"
borderColor="hntBlue"
width={BORDER_SEGMENT_SIZE}
height={BORDER_SEGMENT_SIZE}
borderBottomWidth={4}
borderRightWidth={4}
bottom={0}
right={0}
/>
{/* animated scanner line */}
<Animated.View style={animatedStyle}>
<Image source={require('../assets/images/scannerLine.png')} />
</Animated.View>
</Box>
</Box>
)
}
98 changes: 98 additions & 0 deletions src/components/DynamicQrScanner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/* eslint-disable no-console */
import React, { useEffect, useState } from 'react'
import { BarcodeScanningResult, Camera, CameraView } from 'expo-camera'
import { Linking, Platform, StyleSheet } from 'react-native'
import { useNavigation } from '@react-navigation/native'
import { useAsync } from 'react-async-hook'
import { useTranslation } from 'react-i18next'
import useAlert from '@hooks/useAlert'
import { CameraScannerLayout } from './CameraScannerLayout'
import Box from './Box'
import BackScreen from './BackScreen'
import ProgressBar from './ProgressBar'
import Text from './Text'

type Props = {
progress: number
onBarCodeScanned: (data: string) => void
}
const DynamicQrScanner = ({ onBarCodeScanned, progress }: Props) => {
const [hasPermission, setHasPermission] = useState<boolean>()
const navigation = useNavigation()
const { showOKCancelAlert } = useAlert()
const { t } = useTranslation()

useEffect(() => {
Camera.requestCameraPermissionsAsync().then(
({ status }: { status: string }) => {
setHasPermission(status === 'granted')
},
)
}, [])

useAsync(async () => {
if (hasPermission !== false) return

// if permission is not granted, show alert to open settings
const decision = await showOKCancelAlert({
title: t('qrScanner.deniedAlert.title'),
message: t('qrScanner.deniedAlert.message'),
ok: t('qrScanner.deniedAlert.ok'),
})

// if user clicks ok, open settings
if (decision) {
if (Platform.OS === 'ios') {
Linking.openURL('app-settings:')
} else {
Linking.openSettings()
}
}

// if user clicks cancel, go back to the previous screen
if (decision === false) {
navigation.goBack()
}
}, [hasPermission, navigation, showOKCancelAlert])

const handleBarCodeScanned = (result: BarcodeScanningResult) => {
onBarCodeScanned(result.data)
}

return (
<BackScreen padding="none">
{/* if permission is not granted, show a black screen and notice alert modal */}
{hasPermission !== true && <Box />}

{hasPermission === true && (
<Box flex={1}>
<CameraView
onBarcodeScanned={handleBarCodeScanned}
barcodeScannerSettings={{ barcodeTypes: ['qr'] }}
style={StyleSheet.absoluteFillObject}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
ratio="16:9"
/>
<CameraScannerLayout />

<Box position="absolute" bottom="20%" width="70%" alignSelf="center">
<ProgressBar progress={progress} />
</Box>

<Box
position="absolute"
bottom="10%"
alignSelf="center"
paddingHorizontal="s"
>
<Text variant="subtitle3" marginTop="xxxl" textAlign="center">
{t('keystone.payment.scanTxQrcodeScreenSubtitle3')}
</Text>
</Box>
</Box>
)}
</BackScreen>
)
}
export default DynamicQrScanner
Loading

0 comments on commit 7ae122c

Please sign in to comment.