From e8339030c2588120bb35894cf73e61328f5dec26 Mon Sep 17 00:00:00 2001 From: Danila Date: Fri, 28 Jul 2023 15:18:29 +0300 Subject: [PATCH] Add optimistic update for away status toggling (#10395) Co-authored-by: sean-brydon <55134778+sean-brydon@users.noreply.github.com> --- apps/web/public/static/locales/en/common.json | 1 + packages/features/shell/Shell.tsx | 30 ++++++++++++++----- 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/apps/web/public/static/locales/en/common.json b/apps/web/public/static/locales/en/common.json index d6871a6812..c0146fb054 100644 --- a/apps/web/public/static/locales/en/common.json +++ b/apps/web/public/static/locales/en/common.json @@ -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", diff --git a/packages/features/shell/Shell.tsx b/packages/features/shell/Shell.tsx index a2fbf62d88..ef4010616e 100644 --- a/packages/features/shell/Shell.tsx +++ b/packages/features/shell/Shell.tsx @@ -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 ( setMenuOpen((menuOpen) => !menuOpen)}> @@ -425,8 +442,7 @@ function UserDropdown({ small }: UserDropdownProps) {