Merge pull request #6250 from BlueWallet/discardalert

ADD: Discard changes prompt
This commit is contained in:
GLaDOS 2024-03-09 21:08:34 +00:00 committed by GitHub
commit 8c2ac4ad6a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 60 additions and 3 deletions

View File

@ -48,7 +48,7 @@
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"

View File

@ -4,6 +4,8 @@
"cancel": "Cancel",
"continue": "Continue",
"clipboard": "Clipboard",
"discard_changes": "Discard changes?",
"discard_changes_explain": "You have unsaved changes. Are you sure you want to discard them and leave the screen?",
"enter_password": "Enter password",
"never": "Never",
"of": "{number} of {total}",

View File

@ -3,6 +3,7 @@ import { NativeStackScreenProps } from '@react-navigation/native-stack';
import React, { useCallback, useContext, useEffect, useRef, useState } from 'react';
import {
ActivityIndicator,
Alert,
FlatList,
InteractionManager,
Keyboard,
@ -14,6 +15,7 @@ import {
Switch,
Text,
View,
findNodeHandle,
} from 'react-native';
import { Badge, Icon } from 'react-native-elements';
import {
@ -48,6 +50,7 @@ import { scanQrHelper } from '../../helpers/scan-qr';
import usePrivacy from '../../hooks/usePrivacy';
import loc from '../../loc';
import { isDesktop } from '../../blue_modules/environment';
import ActionSheet from '../ActionSheet';
const fs = require('../../blue_modules/fs');
const prompt = require('../../helpers/prompt');
@ -57,7 +60,7 @@ const ViewEditMultisigCosigners = ({ route }: Props) => {
const hasLoaded = useRef(false);
const { colors } = useTheme();
const { wallets, setWalletsWithNewOrder, isElectrumDisabled, isAdvancedModeEnabled } = useContext(BlueStorageContext);
const { navigate, goBack } = useNavigation();
const { navigate, goBack, dispatch, addListener } = useNavigation();
const openScannerButtonRef = useRef();
const { walletId } = route.params;
const w = useRef(wallets.find((wallet: AbstractWallet) => wallet.getID() === walletId));
@ -77,6 +80,11 @@ const ViewEditMultisigCosigners = ({ route }: Props) => {
const [askPassphrase, setAskPassphrase] = useState(false);
const [isAdvancedModeEnabledRender, setIsAdvancedModeEnabledRender] = useState(false);
const data = useRef<any[]>();
/* discardChangesRef is only so the action sheet can be shown on mac catalyst when a
user tries to leave the screen with unsaved changes.
Why the container view ? It was the easiest to get the ref for. No other reason.
*/
const discardChangesRef = useRef<View>(null);
const { enableBlur, disableBlur } = usePrivacy();
const stylesHook = StyleSheet.create({
@ -109,6 +117,53 @@ const ViewEditMultisigCosigners = ({ route }: Props) => {
color: colors.buttonTextColor,
},
});
useFocusEffect(
useCallback(() => {
const unsubscribe = addListener('beforeRemove', e => {
// Check if there are unsaved changes
if (isSaveButtonDisabled) {
// If there are no unsaved changes, let the user leave the screen
return;
}
// Prevent the default action (going back)
e.preventDefault();
// Show an alert asking the user to discard changes or cancel
if (isDesktop) {
if (!discardChangesRef.current) return dispatch(e.data.action);
const anchor = findNodeHandle(discardChangesRef.current);
if (!anchor) return dispatch(e.data.action);
ActionSheet.showActionSheetWithOptions(
{
options: [loc._.cancel, loc._.ok],
cancelButtonIndex: 0,
title: loc._.discard_changes,
message: loc._.discard_changes_explain,
anchor,
},
buttonIndex => {
if (buttonIndex === 1) {
dispatch(e.data.action);
}
},
);
} else {
Alert.alert(loc._.discard_changes, loc._.discard_changes_explain, [
{ text: loc._.cancel, style: 'cancel', onPress: () => {} },
{
text: loc._.ok,
style: 'default',
// If the user confirms, then we dispatch the action we blocked earlier
onPress: () => dispatch(e.data.action),
},
]);
}
});
return unsubscribe;
}, [isSaveButtonDisabled, addListener, dispatch]),
);
useEffect(() => {
isAdvancedModeEnabled().then(setIsAdvancedModeEnabledRender);
@ -576,7 +631,7 @@ const ViewEditMultisigCosigners = ({ route }: Props) => {
const isPad: boolean = Platform.isPad;
return (
<View style={[styles.root, stylesHook.root]}>
<View style={[styles.root, stylesHook.root]} ref={discardChangesRef}>
<KeyboardAvoidingView
enabled={!isPad}
behavior={Platform.OS === 'ios' ? 'padding' : undefined}