fix(native): show account edits immediately and save name on first tap

Bypass the 5-minute session cookie cache when refetching after name/avatar edits, keep taps on Save/Cancel working with the keyboard open, add Return-to-save, trim the name, and guard against double submit.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
jakeandClaude Sonnet 5.5 committed 2026-10-05 13:07:54 -04:00
1 parent fbc6ac90a3
commit 0afc60f28c
1 file changed
+24 -4
@@ -124,7 +124,8 @@ export default function SettingsScreen() {
toast.success(t`Name updated`); toast.success(t`Name updated`);
setIsEditingName(false); setIsEditingName(false);
queryClient.invalidateQueries({ queryKey: orpc.account.key() }); queryClient.invalidateQueries({ queryKey: orpc.account.key() });
refetchSession(); // Bypass the 5-minute session cookie cache, which would return the pre-edit user.
void refetchSession({ query: { disableCookieCache: true } });
}, },
onError: () => toast.error(t`Failed to update name`), onError: () => toast.error(t`Failed to update name`),
}), }),
@@ -135,7 +136,8 @@ export default function SettingsScreen() {
onSuccess: () => { onSuccess: () => {
toast.success(t`Profile picture updated`); toast.success(t`Profile picture updated`);
queryClient.invalidateQueries({ queryKey: orpc.account.key() }); queryClient.invalidateQueries({ queryKey: orpc.account.key() });
refetchSession(); // Bypass the 5-minute session cookie cache, which would return the pre-edit user.
void refetchSession({ query: { disableCookieCache: true } });
}, },
onError: () => toast.error(t`Failed to upload avatar`), onError: () => toast.error(t`Failed to upload avatar`),
}), }),
@@ -146,7 +148,8 @@ export default function SettingsScreen() {
onSuccess: () => { onSuccess: () => {
toast.success(t`Profile picture removed`); toast.success(t`Profile picture removed`);
queryClient.invalidateQueries({ queryKey: orpc.account.key() }); queryClient.invalidateQueries({ queryKey: orpc.account.key() });
refetchSession(); // Bypass the 5-minute session cookie cache, which would return the pre-edit user.
void refetchSession({ query: { disableCookieCache: true } });
}, },
onError: () => toast.error(t`Failed to remove profile picture`), onError: () => toast.error(t`Failed to remove profile picture`),
}), }),
@@ -240,11 +243,18 @@ export default function SettingsScreen() {
]); ]);
}; };
const saveName = () => {
const name = nameInput.trim();
if (!name || updateName.isPending) return;
updateName.mutate({ name });
};
return ( return (
<ScrollView <ScrollView
className="bg-background" className="bg-background"
contentContainerStyle={settingsContentContainerStyle} contentContainerStyle={settingsContentContainerStyle}
contentInsetAdjustmentBehavior="automatic" contentInsetAdjustmentBehavior="automatic"
keyboardShouldPersistTaps="handled"
scrollToOverflowEnabled scrollToOverflowEnabled
refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />} refreshControl={<RefreshControl refreshing={refreshing} onRefresh={onRefresh} />}
> >
@@ -329,14 +339,24 @@ export default function SettingsScreen() {
value={nameInput} value={nameInput}
accessibilityLabel={t`Display name`} accessibilityLabel={t`Display name`}
onChangeText={setNameInput} onChangeText={setNameInput}
// oxlint-disable-next-line jsx-a11y/no-autofocus -- user just tapped the name to edit it
autoFocus
returnKeyType="done"
onSubmitEditing={saveName}
maxLength={100}
className="border-primary text-foreground min-h-10 flex-1 border-b py-2 font-sans text-base" className="border-primary text-foreground min-h-10 flex-1 border-b py-2 font-sans text-base"
/> />
<Pressable onPress={() => updateName.mutate({ name: nameInput })}> <Pressable
onPress={saveName}
disabled={updateName.isPending}
accessibilityRole="button"
>
<Text className="text-primary text-sm"> <Text className="text-primary text-sm">
<Trans>Save</Trans> <Trans>Save</Trans>
</Text> </Text>
</Pressable> </Pressable>
<Pressable <Pressable
accessibilityRole="button"
onPress={() => { onPress={() => {
setNameInput(session?.user?.name ?? ""); setNameInput(session?.user?.name ?? "");
setIsEditingName(false); setIsEditingName(false);