mirror of
https://github.com/jakejarvis/sofa.git
synced 2026-10-15 23:55:43 -04:00
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:
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);
|
||||||
|
|||||||
Reference in new issue
Block a user