From 9dfd6ce34cae7da7add8626f70a755984532e16d Mon Sep 17 00:00:00 2001 From: Matiss Janis Aboltins Date: Tue, 23 Jan 2024 08:23:32 +0000 Subject: [PATCH] :bug: fix uncategorized transaction banner flashing on load (#2273) --- .../src/components/Titlebar.tsx | 64 ++++++++++++------- upcoming-release-notes/2273.md | 6 ++ 2 files changed, 47 insertions(+), 23 deletions(-) create mode 100644 upcoming-release-notes/2273.md diff --git a/packages/desktop-client/src/components/Titlebar.tsx b/packages/desktop-client/src/components/Titlebar.tsx index 57e16344bb8..e0f0d747932 100644 --- a/packages/desktop-client/src/components/Titlebar.tsx +++ b/packages/desktop-client/src/components/Titlebar.tsx @@ -1,4 +1,3 @@ -// @ts-strict-ignore import React, { createContext, useState, @@ -61,7 +60,14 @@ export type TitlebarContextValue = { subscribe: (listener: Listener) => () => void; }; -export const TitlebarContext = createContext(null); +export const TitlebarContext = createContext({ + sendEvent() { + throw new Error('TitlebarContext not initialized'); + }, + subscribe() { + throw new Error('TitlebarContext not initialized'); + }, +}); type TitlebarProviderProps = { children?: ReactNode; @@ -88,26 +94,32 @@ export function TitlebarProvider({ children }: TitlebarProviderProps) { } function UncategorizedButton() { - const count = useSheetValue(queries.uncategorizedCount()); + const count: number | null = useSheetValue(queries.uncategorizedCount()); + if (count === null || count <= 0) { + return null; + } + return ( - count !== 0 && ( - - {count} uncategorized {count === 1 ? 'transaction' : 'transactions'} - - ) + + {count} uncategorized {count === 1 ? 'transaction' : 'transactions'} + ); } -function PrivacyButton({ style }) { +type PrivacyButtonProps = { + style?: CSSProperties; +}; + +function PrivacyButton({ style }: PrivacyButtonProps) { const isPrivacyEnabled = useSelector( - state => state.prefs.local.isPrivacyEnabled, + state => state.prefs.local?.isPrivacyEnabled, ); const { savePrefs } = useActions(); @@ -134,11 +146,13 @@ type SyncButtonProps = { isMobile?: boolean; }; function SyncButton({ style, isMobile = false }: SyncButtonProps) { - const cloudFileId = useSelector(state => state.prefs.local.cloudFileId); + const cloudFileId = useSelector(state => state.prefs.local?.cloudFileId); const { sync } = useActions(); const [syncing, setSyncing] = useState(false); - const [syncState, setSyncState] = useState(null); + const [syncState, setSyncState] = useState< + null | 'offline' | 'local' | 'disabled' | 'error' + >(null); useEffect(() => { const unlisten = listen('sync-event', ({ type, subtype, syncDisabled }) => { @@ -272,8 +286,8 @@ function SyncButton({ style, isMobile = false }: SyncButtonProps) { } function BudgetTitlebar() { - const maxMonths = useSelector(state => state.prefs.global.maxMonths); - const budgetType = useSelector(state => state.prefs.local.budgetType); + const maxMonths = useSelector(state => state.prefs.global?.maxMonths); + const budgetType = useSelector(state => state.prefs.local?.budgetType); const { saveGlobalPrefs } = useActions(); const { sendEvent } = useContext(TitlebarContext); @@ -366,14 +380,18 @@ function BudgetTitlebar() { ); } -export function Titlebar({ style }) { +type TitlebarProps = { + style?: CSSProperties; +}; + +export function Titlebar({ style }: TitlebarProps) { const navigate = useNavigate(); const location = useLocation(); const sidebar = useSidebar(); const { isNarrowWidth } = useResponsive(); const serverURL = useServerURL(); const floatingSidebar = useSelector( - state => state.prefs.global.floatingSidebar, + state => state.prefs.global?.floatingSidebar, ); return isNarrowWidth ? null : ( diff --git a/upcoming-release-notes/2273.md b/upcoming-release-notes/2273.md new file mode 100644 index 00000000000..598e376db58 --- /dev/null +++ b/upcoming-release-notes/2273.md @@ -0,0 +1,6 @@ +--- +category: Bugfix +authors: [MatissJanis] +--- + +Fix 'uncategorized transactions' flashing in the header on page load