Skip to content

Commit

Permalink
Merge pull request #786 from alephium/mw-fix-black-screen
Browse files Browse the repository at this point in the history
Fix stuck in black screen
  • Loading branch information
nop33 authored Aug 20, 2024
2 parents 4cdccd4 + 18ddd26 commit c4d91cf
Show file tree
Hide file tree
Showing 6 changed files with 41 additions and 45 deletions.
5 changes: 5 additions & 0 deletions .changeset/wise-jars-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@alephium/mobile-wallet": patch
---

Fix authentication issues
22 changes: 6 additions & 16 deletions apps/mobile-wallet/src/features/auto-lock/useAutoLock.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,20 +17,15 @@ along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { appBecameInactive } from '@alephium/shared'
import { useCallback, useEffect, useRef, useState } from 'react'
import { useEffect, useRef, useState } from 'react'
import { AppState, AppStateStatus } from 'react-native'
import BackgroundTimer from 'react-native-background-timer'

import { useAppDispatch, useAppSelector } from '~/hooks/redux'

interface UseAutoLockProps {
unlockApp: () => Promise<void>
onAuthRequired: () => void
}

let lockTimer: number | undefined

const useAutoLock = ({ unlockApp, onAuthRequired }: UseAutoLockProps) => {
const useAutoLock = (unlockApp: () => Promise<void>) => {
const appState = useRef<AppStateStatus>('active')
const settingsLoadedFromStorage = useAppSelector((s) => s.settings.loadedFromStorage)
const isCameraOpen = useAppSelector((s) => s.app.isCameraOpen)
Expand All @@ -41,25 +36,19 @@ const useAutoLock = ({ unlockApp, onAuthRequired }: UseAutoLockProps) => {

const [isAppStateChangeCallbackRegistered, setIsAppStateChangeCallbackRegistered] = useState(false)

const lockApp = useCallback(() => {
if (biometricsRequiredForAppAccess) onAuthRequired()

dispatch(appBecameInactive())
}, [biometricsRequiredForAppAccess, dispatch, onAuthRequired])

useEffect(() => {
if (!settingsLoadedFromStorage) return

const handleAppStateChange = (nextAppState: AppStateStatus) => {
if (autoLockSeconds !== -1) {
if (nextAppState === 'background' && isWalletUnlocked && !isCameraOpen) {
if (autoLockSeconds === 0) {
lockApp()
dispatch(appBecameInactive())
} else {
clearBackgroundTimer()
lockTimer = BackgroundTimer.setTimeout(() => {
if (lockTimer) {
lockApp()
dispatch(appBecameInactive())
}
}, autoLockSeconds * 1000)
}
Expand All @@ -70,6 +59,8 @@ const useAutoLock = ({ unlockApp, onAuthRequired }: UseAutoLockProps) => {
unlockApp()
}
}
} else if (nextAppState === 'active' && !isWalletUnlocked) {
unlockApp()
}

appState.current = nextAppState
Expand All @@ -91,7 +82,6 @@ const useAutoLock = ({ unlockApp, onAuthRequired }: UseAutoLockProps) => {
isAppStateChangeCallbackRegistered,
isCameraOpen,
isWalletUnlocked,
lockApp,
settingsLoadedFromStorage,
unlockApp
])
Expand Down
31 changes: 8 additions & 23 deletions apps/mobile-wallet/src/navigation/RootStackNavigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -140,12 +140,11 @@ export default RootStackNavigation
const AppUnlockModal = () => {
const dispatch = useAppDispatch()
const isWalletUnlocked = useAppSelector((s) => s.wallet.isUnlocked)
const biometricsRequiredForAppAccess = useAppSelector((s) => s.settings.usesBiometrics)
const navigation = useNavigation<NavigationProp<RootStackParamList>>()
const { triggerBiometricsAuthGuard } = useBiometricsAuthGuard()
const { t } = useTranslation()

const [isAuthModalVisible, setIsAuthModalVisible] = useState(false)

const { width, height } = Dimensions.get('window')
const [dimensions, setDimensions] = useState({ width, height })

Expand All @@ -155,10 +154,6 @@ const AppUnlockModal = () => {
setDimensions({ width, height })
}

const openAuthModal = useCallback(() => {
setIsAuthModalVisible(true)
}, [])

const initializeAppWithStoredWallet = useCallback(async () => {
try {
dispatch(walletUnlocked(await getStoredWallet()))
Expand All @@ -168,8 +163,6 @@ const AppUnlockModal = () => {
if (!lastRoute || ['LandingScreen', 'LoginWithPinScreen'].includes(lastRoute)) {
resetNavigation(navigation)
}

setIsAuthModalVisible(false)
} catch (error) {
const message = 'Could not initialize app with stored wallet'
showExceptionToast(error, message)
Expand All @@ -188,7 +181,6 @@ const AppUnlockModal = () => {
try {
await triggerBiometricsAuthGuard({
settingsToCheck: 'appAccess',
onPromptDisplayed: openAuthModal,
successCallback: initializeAppWithStoredWallet
})

Expand Down Expand Up @@ -252,23 +244,16 @@ const AppUnlockModal = () => {
showExceptionToast(e, t('Could not unlock app'))
}
}
}, [
dispatch,
initializeAppWithStoredWallet,
isWalletUnlocked,
navigation,
openAuthModal,
t,
triggerBiometricsAuthGuard
])
}, [dispatch, initializeAppWithStoredWallet, isWalletUnlocked, navigation, t, triggerBiometricsAuthGuard])

useAutoLock({
unlockApp,
onAuthRequired: openAuthModal
})
useAutoLock(unlockApp)

return (
<Modal animationType="none" onLayout={handleScreenLayoutChange} visible={isAuthModalVisible}>
<Modal
visible={biometricsRequiredForAppAccess && !isWalletUnlocked}
onLayout={handleScreenLayoutChange}
animationType="none"
>
<View style={{ backgroundColor: 'black', flex: 1 }}>
<CoolAlephiumCanvas {...dimensions} onPress={unlockApp} />
</View>
Expand Down
20 changes: 18 additions & 2 deletions apps/mobile-wallet/src/screens/LandingScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see <http://www.gnu.org/licenses/>.
*/

import { useFocusEffect } from '@react-navigation/native'
import { StackScreenProps } from '@react-navigation/stack'
import { Canvas, RadialGradient, Rect, vec } from '@shopify/react-native-skia'
import { useEffect, useState } from 'react'
import { useCallback, useEffect, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { AppState, Dimensions, Image, LayoutChangeEvent, Platform, StatusBar } from 'react-native'
import Animated, {
Expand All @@ -37,7 +38,7 @@ import styled, { ThemeProvider, useTheme } from 'styled-components/native'
import AppText from '~/components/AppText'
import Button from '~/components/buttons/Button'
import Screen, { ScreenProps } from '~/components/layout/Screen'
import { useAppDispatch } from '~/hooks/redux'
import { useAppDispatch, useAppSelector } from '~/hooks/redux'
import altLogoSrc from '~/images/logos/alephiumHackLogo.png'
import AlephiumLogo from '~/images/logos/AlephiumLogo'
import RootStackParamList from '~/navigation/rootStackRoutes'
Expand All @@ -46,6 +47,7 @@ import { methodSelected, WalletGenerationMethod } from '~/store/walletGeneration
import { BORDER_RADIUS_BIG, BORDER_RADIUS_HUGE } from '~/style/globalStyle'
import { themes } from '~/style/themes'
import { showExceptionToast } from '~/utils/layout'
import { resetNavigation } from '~/utils/navigation'

interface LandingScreenProps extends StackScreenProps<RootStackParamList, 'LandingScreen'>, ScreenProps {}

Expand All @@ -57,11 +59,25 @@ const LandingScreen = ({ navigation, ...props }: LandingScreenProps) => {
const insets = useSafeAreaInsets()
const theme = useTheme()
const { t } = useTranslation()
const isWalletUnlocked = useAppSelector((s) => s.wallet.isUnlocked)

const { width, height } = Dimensions.get('window')
const [dimensions, setDimensions] = useState({ width, height })
const [showNewWalletButtons, setShowNewWalletButtons] = useState(false)

// Normally, when the app is unlocked, this screen is not in focus. However, under certain conditions we end up with
// an unlocked wallet and no screen in focus at all. This happens when:
// 1. the auto-lock is set to anything but "Fast"
// 2. the user manually kills the app before the auto-lock timer completes
// 3. the WalletConnect feature is activated
// Since there is no screen in focus and since the default screen set in the RootStackNavigation is this screen, we
// need to navigate back to the dashboard.
useFocusEffect(
useCallback(() => {
if (isWalletUnlocked) resetNavigation(navigation)
}, [isWalletUnlocked, navigation])
)

useEffect(() => {
const unsubscribeBlurListener = navigation.addListener('blur', () => {
StatusBar.setBarStyle(theme.name === 'light' ? 'dark-content' : 'light-content')
Expand Down
2 changes: 1 addition & 1 deletion patches/react-native-background-actions@3.0.1.patch
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ index b67ef4d1837363489a1749acb852997a6c93c1b5..6aa30a826c2f17a35ccd30b64291d3d2
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application>
- <service android:name=".RNBackgroundActionsTask"/>
+ <service android:name=".RNBackgroundActionsTask" android:foregroundServiceType="dataSync" />
+ <service android:name=".RNBackgroundActionsTask" android:foregroundServiceType="dataSync" android:stopWithTask="true" />
</application>
</manifest>
diff --git a/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java b/android/src/main/java/com/asterinet/react/bgactions/RNBackgroundActionsTask.java
Expand Down
6 changes: 3 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit c4d91cf

Please sign in to comment.