Add optimistic update for away status toggling (#10395)

Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com>
This commit is contained in:
Danila 2023-07-28 15:18:29 +03:00 committed by GitHub
parent 4bc4ff8193
commit e8339030c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 24 additions and 7 deletions

View File

@ -848,6 +848,7 @@
"team_view_user_availability_disabled": "User needs to accept invite to view availability",
"set_as_away": "Set yourself as away",
"set_as_free": "Disable away status",
"toggle_away_error": "Error updating away status",
"user_away": "This user is currently away.",
"user_away_description": "The person you are trying to book has set themselves to away, and therefore is not accepting new bookings.",
"meet_people_with_the_same_tokens": "Meet people with the same tokens",

View File

@ -312,6 +312,7 @@ function UserDropdown({ small }: UserDropdownProps) {
const { t } = useLocale();
const { data: user } = useMeQuery();
const { data: avatar } = useAvatarQuery();
const utils = trpc.useContext();
useEffect(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
//@ts-ignore
@ -324,16 +325,31 @@ function UserDropdown({ small }: UserDropdownProps) {
});
});
const mutation = trpc.viewer.away.useMutation({
onMutate: async ({ away }) => {
await utils.viewer.me.cancel();
const previousValue = utils.viewer.me.getData();
if (previousValue) {
utils.viewer.me.setData(undefined, { ...previousValue, away });
}
return { previousValue };
},
onError: (_, __, context) => {
if (context?.previousValue) {
utils.viewer.me.setData(undefined, context.previousValue);
}
showToast(t("toggle_away_error"), "error");
},
onSettled() {
utils.viewer.me.invalidate();
},
});
const utils = trpc.useContext();
const [helpOpen, setHelpOpen] = useState(false);
const [menuOpen, setMenuOpen] = useState(false);
if (!user) {
return null;
}
const onHelpItemSelect = () => {
setHelpOpen(false);
setMenuOpen(false);
@ -344,6 +360,7 @@ function UserDropdown({ small }: UserDropdownProps) {
if (!user) {
return null;
}
return (
<Dropdown open={menuOpen}>
<DropdownMenuTrigger asChild onClick={() => setMenuOpen((menuOpen) => !menuOpen)}>
@ -425,8 +442,7 @@ function UserDropdown({ small }: UserDropdownProps) {
<Moon className={classNames("text-default", props.className)} aria-hidden="true" />
)}
onClick={() => {
mutation.mutate({ away: !user?.away });
utils.viewer.me.invalidate();
mutation.mutate({ away: !user.away });
}}>
{user.away ? t("set_as_free") : t("set_as_away")}
</DropdownItem>
@ -434,7 +450,7 @@ function UserDropdown({ small }: UserDropdownProps) {
<DropdownMenuSeparator />
<DropdownMenuItem>
<DropdownItem
StartIcon={(props) => <Discord className="text-default h-4 w-4" />}
StartIcon={() => <Discord className="text-default h-4 w-4" />}
target="_blank"
rel="noreferrer"
href={JOIN_DISCORD}>