mirror of
https://github.com/bulwarkmail/native.git
synced 2026-11-04 16:06:41 +00:00
fix: ask about unsaved contact changes on every way out of the form
This commit is contained in:
@@ -4,7 +4,7 @@ import {
|
|||||||
KeyboardAvoidingView, Platform, Modal, Image,
|
KeyboardAvoidingView, Platform, Modal, Image,
|
||||||
} from 'react-native';
|
} from 'react-native';
|
||||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||||
import { useNavigation, useRoute, type RouteProp } from '@react-navigation/native';
|
import { usePreventRemove, useNavigation, useRoute, type RouteProp } from '@react-navigation/native';
|
||||||
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
import type { NativeStackNavigationProp } from '@react-navigation/native-stack';
|
||||||
import DateTimePicker, { type DateTimePickerEvent } from '@react-native-community/datetimepicker';
|
import DateTimePicker, { type DateTimePickerEvent } from '@react-native-community/datetimepicker';
|
||||||
import * as ImagePicker from 'expo-image-picker';
|
import * as ImagePicker from 'expo-image-picker';
|
||||||
@@ -762,9 +762,25 @@ export default function ContactFormScreen() {
|
|||||||
setForm((f) => ({ ...f, [key]: value }));
|
setForm((f) => ({ ...f, [key]: value }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Every way out asks about unsaved changes: the header back, Android's
|
||||||
|
// back and the modal's swipe-down. Only the header back did before.
|
||||||
|
const allowLeaveRef = React.useRef(false);
|
||||||
|
const pendingLeaveRef = React.useRef<(() => void) | null>(null);
|
||||||
|
usePreventRemove(dirty, ({ data }) => {
|
||||||
|
if (allowLeaveRef.current) {
|
||||||
|
navigation.dispatch(data.action);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
pendingLeaveRef.current = () => navigation.dispatch(data.action);
|
||||||
|
setConfirmDiscard(true);
|
||||||
|
});
|
||||||
|
const leave = (go: () => void) => {
|
||||||
|
allowLeaveRef.current = true;
|
||||||
|
go();
|
||||||
|
};
|
||||||
|
|
||||||
const handleBack = () => {
|
const handleBack = () => {
|
||||||
if (dirty) setConfirmDiscard(true);
|
navigation.goBack();
|
||||||
else navigation.goBack();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSave = async () => {
|
const handleSave = async () => {
|
||||||
@@ -834,11 +850,11 @@ export default function ContactFormScreen() {
|
|||||||
const patch = formToPatch(form, existing, !!asGroup || existing?.kind === 'group', allContacts);
|
const patch = formToPatch(form, existing, !!asGroup || existing?.kind === 'group', allContacts);
|
||||||
if (isEdit && existing) {
|
if (isEdit && existing) {
|
||||||
await updateContact(existing.id, patch);
|
await updateContact(existing.id, patch);
|
||||||
navigation.goBack();
|
leave(() => navigation.goBack());
|
||||||
} else {
|
} else {
|
||||||
const created = await createContact(patch, form.addressBookId);
|
const created = await createContact(patch, form.addressBookId);
|
||||||
if (asGroup) navigation.replace('GroupDetail', { groupId: created.id });
|
if (asGroup) leave(() => navigation.replace('GroupDetail', { groupId: created.id }));
|
||||||
else navigation.replace('ContactDetail', { contactId: created.id });
|
else leave(() => navigation.replace('ContactDetail', { contactId: created.id }));
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
Alert.alert(
|
Alert.alert(
|
||||||
@@ -1040,9 +1056,14 @@ export default function ContactFormScreen() {
|
|||||||
confirmText={t('settings.discard', 'Discard')}
|
confirmText={t('settings.discard', 'Discard')}
|
||||||
onConfirm={() => {
|
onConfirm={() => {
|
||||||
setConfirmDiscard(false);
|
setConfirmDiscard(false);
|
||||||
navigation.goBack();
|
const go = pendingLeaveRef.current ?? (() => navigation.goBack());
|
||||||
|
pendingLeaveRef.current = null;
|
||||||
|
leave(go);
|
||||||
|
}}
|
||||||
|
onCancel={() => {
|
||||||
|
pendingLeaveRef.current = null;
|
||||||
|
setConfirmDiscard(false);
|
||||||
}}
|
}}
|
||||||
onCancel={() => setConfirmDiscard(false)}
|
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user