From e4141c763b16f9ce5cb5d9eae579b58e741be1f9 Mon Sep 17 00:00:00 2001 From: binarybaron <86064887+binarybaron@users.noreply.github.com> Date: Tue, 3 Sep 2024 12:28:30 +0200 Subject: [PATCH] feat(tauri): Initialize Context in background (#59) This PR does the following: - The Context (including Bitcoin wallet, Monero wallet, ...) is initialized in the background. This allows the window to be displayed instantly upon startup. - Host sends events to Guest about progress of Context initialization. Those events are used to display an alert in the navigation bar. - If a Tauri command is invoked which requires the Context to be available, an error will be returned - As soon as the Context becomes available the `Guest` requests the history and Bitcoin balance - Re-enables Material UI animations --- src-gui/src/renderer/components/App.tsx | 12 +- .../components/PromiseInvokeButton.tsx | 85 +++++++---- .../components/alert/DaemonStatusAlert.tsx | 76 ++++++++++ .../components/alert/RpcStatusAlert.tsx | 30 ---- .../modal/swap/pages/init/InitPage.tsx | 1 + .../navigation/NavigationFooter.tsx | 7 +- .../components/pages/help/RpcControlBox.tsx | 14 +- .../history/table/HistoryRowExpanded.tsx | 26 ++-- src-gui/src/renderer/index.tsx | 8 +- src-gui/src/renderer/rpc.ts | 14 +- src-gui/src/renderer/store/storeRenderer.ts | 3 + src-gui/src/store/features/rpcSlice.ts | 67 ++------- src-gui/src/store/hooks.ts | 4 + src-gui/src/store/middleware/storeListener.ts | 28 ++++ src-tauri/src/lib.rs | 133 +++++++++++++----- swap/src/cli/api.rs | 29 +++- swap/src/cli/api/tauri_bindings.rs | 23 +++ 17 files changed, 369 insertions(+), 191 deletions(-) create mode 100644 src-gui/src/renderer/components/alert/DaemonStatusAlert.tsx delete mode 100644 src-gui/src/renderer/components/alert/RpcStatusAlert.tsx create mode 100644 src-gui/src/store/middleware/storeListener.ts diff --git a/src-gui/src/renderer/components/App.tsx b/src-gui/src/renderer/components/App.tsx index 581b333a0..7e4dc89ae 100644 --- a/src-gui/src/renderer/components/App.tsx +++ b/src-gui/src/renderer/components/App.tsx @@ -26,19 +26,11 @@ const theme = createTheme({ }, secondary: indigo, }, - transitions: { - create: () => "none", - }, - props: { - MuiButtonBase: { - disableRipple: true, - }, - }, typography: { overline: { - textTransform: 'none', // This prevents the text from being all caps + textTransform: "none", // This prevents the text from being all caps }, - } + }, }); function InnerContent() { diff --git a/src-gui/src/renderer/components/PromiseInvokeButton.tsx b/src-gui/src/renderer/components/PromiseInvokeButton.tsx index c4044da1c..1acdfaa7a 100644 --- a/src-gui/src/renderer/components/PromiseInvokeButton.tsx +++ b/src-gui/src/renderer/components/PromiseInvokeButton.tsx @@ -1,33 +1,44 @@ -import { Button, ButtonProps, IconButton } from "@material-ui/core"; +import { + Button, + ButtonProps, + IconButton, + IconButtonProps, + Tooltip, +} from "@material-ui/core"; import CircularProgress from "@material-ui/core/CircularProgress"; import { useSnackbar } from "notistack"; import { ReactNode, useState } from "react"; +import { useIsContextAvailable } from "store/hooks"; interface PromiseInvokeButtonProps { - onSuccess?: (data: T) => void; + onSuccess: (data: T) => void | null; onClick: () => Promise; - onPendingChange?: (isPending: boolean) => void; - isLoadingOverride?: boolean; - isIconButton?: boolean; - loadIcon?: ReactNode; - disabled?: boolean; - displayErrorSnackbar?: boolean; - tooltipTitle?: string; + onPendingChange: (isPending: boolean) => void | null; + isLoadingOverride: boolean; + isIconButton: boolean; + loadIcon: ReactNode; + disabled: boolean; + displayErrorSnackbar: boolean; + tooltipTitle: string | null; + requiresContext: boolean; } export default function PromiseInvokeButton({ - disabled, - onSuccess, + disabled = false, + onSuccess = null, onClick, endIcon, - loadIcon, - isLoadingOverride, - isIconButton, - displayErrorSnackbar, - onPendingChange, + loadIcon = null, + isLoadingOverride = false, + isIconButton = false, + displayErrorSnackbar = false, + onPendingChange = null, + requiresContext = true, + tooltipTitle = null, ...rest }: ButtonProps & PromiseInvokeButtonProps) { const { enqueueSnackbar } = useSnackbar(); + const isContextAvailable = useIsContextAvailable(); const [isPending, setIsPending] = useState(false); @@ -36,7 +47,7 @@ export default function PromiseInvokeButton({ ? loadIcon || : endIcon; - async function handleClick(event: React.MouseEvent) { + async function handleClick() { if (!isPending) { try { onPendingChange?.(true); @@ -57,18 +68,34 @@ export default function PromiseInvokeButton({ } } - const isDisabled = disabled || isLoading; + const requiresContextButNotAvailable = requiresContext && !isContextAvailable; + const isDisabled = disabled || isLoading || requiresContextButNotAvailable; - return isIconButton ? ( - - {actualEndIcon} - - ) : ( -