From 89db75c52c31ea17ae4f039525c3305855a63aec Mon Sep 17 00:00:00 2001 From: Jono Kemball Date: Sun, 15 Mar 2026 23:37:48 +1300 Subject: [PATCH 1/4] feat(web): move update button to sidebar footer as dismissable pill Move the desktop update button from the sidebar header to the footer, displayed as a pill above the Settings button. The pill shows contextual states: "Update available", "Downloading (X%)", and "Restart to update". Add a dismiss button that hides the notification until the next app launch. --- apps/web/src/components/Sidebar.tsx | 98 +++++++++++++++++++---------- 1 file changed, 65 insertions(+), 33 deletions(-) diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx index 1b43eb4c1..20da23e20 100644 --- a/apps/web/src/components/Sidebar.tsx +++ b/apps/web/src/components/Sidebar.tsx @@ -1,14 +1,16 @@ import { ArrowLeftIcon, ChevronRightIcon, + DownloadIcon, FolderIcon, GitPullRequestIcon, PlusIcon, - RocketIcon, + RotateCwIcon, SettingsIcon, SquarePenIcon, TerminalIcon, TriangleAlertIcon, + XIcon, } from "lucide-react"; import { useCallback, useEffect, useMemo, useRef, useState, type MouseEvent } from "react"; import { @@ -57,7 +59,6 @@ import { isDesktopUpdateButtonDisabled, resolveDesktopUpdateButtonAction, shouldShowArm64IntelBuildWarning, - shouldHighlightDesktopUpdateError, shouldShowDesktopUpdateButton, shouldToastDesktopUpdateActionResult, } from "./desktopUpdate.logic"; @@ -299,6 +300,7 @@ export default function Sidebar() { const dragInProgressRef = useRef(false); const suppressProjectClickAfterDragRef = useRef(false); const [desktopUpdateState, setDesktopUpdateState] = useState(null); + const [updateDismissed, setUpdateDismissed] = useState(false); const selectedThreadIds = useThreadSelectionStore((s) => s.selectedThreadIds); const toggleThreadSelection = useThreadSelectionStore((s) => s.toggleThread); const rangeSelectTo = useThreadSelectionStore((s) => s.rangeSelectTo); @@ -996,7 +998,7 @@ export default function Sidebar() { }; }, []); - const showDesktopUpdateButton = isElectron && shouldShowDesktopUpdateButton(desktopUpdateState); + const showDesktopUpdateButton = isElectron && shouldShowDesktopUpdateButton(desktopUpdateState) && !updateDismissed; const desktopUpdateTooltip = desktopUpdateState ? getDesktopUpdateButtonTooltip(desktopUpdateState) @@ -1012,17 +1014,6 @@ export default function Sidebar() { desktopUpdateState && showArm64IntelBuildWarning ? getArm64IntelBuildWarningDescription(desktopUpdateState) : null; - const desktopUpdateButtonInteractivityClasses = desktopUpdateButtonDisabled - ? "cursor-not-allowed opacity-60" - : "hover:bg-accent hover:text-foreground"; - const desktopUpdateButtonClasses = - desktopUpdateState?.status === "downloaded" - ? "text-emerald-500" - : desktopUpdateState?.status === "downloading" - ? "text-sky-400" - : shouldHighlightDesktopUpdateError(desktopUpdateState) - ? "text-rose-500 animate-pulse" - : "text-amber-500 animate-pulse"; const newThreadShortcutLabel = useMemo( () => shortcutLabelForCommand(keybindings, "chat.newLocal") ?? @@ -1136,25 +1127,6 @@ export default function Sidebar() { <> {wordmark} - {showDesktopUpdateButton && ( - - - - - } - /> - {desktopUpdateTooltip} - - )} ) : ( @@ -1610,6 +1582,66 @@ export default function Sidebar() { + {showDesktopUpdateButton && ( +
+
+
+ + + {desktopUpdateButtonAction === "install" ? ( + <> + + Restart to update + + ) : desktopUpdateState?.status === "downloading" ? ( + <> + + + Downloading{typeof desktopUpdateState.downloadPercent === "number" ? ` (${Math.floor(desktopUpdateState.downloadPercent)}%)` : "…"} + + + ) : ( + <> + + Update available + + )} + + } + /> + {desktopUpdateTooltip} + + {desktopUpdateButtonAction === "download" && ( + + setUpdateDismissed(true)} + > + + + } + /> + Dismiss until next launch + + )} +
+
+ )} {isOnSettings ? ( From 88d359bffce0238c33689123f3075eb7ec0467d0 Mon Sep 17 00:00:00 2001 From: Jono Kemball Date: Sun, 15 Mar 2026 23:58:47 +1300 Subject: [PATCH 2/4] refactor(web): extract SidebarUpdatePill into self-contained component Move all desktop update UI (pill + arm64 warning) into a single SidebarUpdatePill component that owns its own state subscription, action handlers, and dismiss logic. Removes ~220 lines from Sidebar.tsx. --- apps/web/src/components/Sidebar.tsx | 211 +----------------- .../components/sidebar/SidebarUpdatePill.tsx | 197 ++++++++++++++++ 2 files changed, 199 insertions(+), 209 deletions(-) create mode 100644 apps/web/src/components/sidebar/SidebarUpdatePill.tsx diff --git a/apps/web/src/components/Sidebar.tsx b/apps/web/src/components/Sidebar.tsx index 20da23e20..0fc1065c4 100644 --- a/apps/web/src/components/Sidebar.tsx +++ b/apps/web/src/components/Sidebar.tsx @@ -1,16 +1,12 @@ import { ArrowLeftIcon, ChevronRightIcon, - DownloadIcon, FolderIcon, GitPullRequestIcon, PlusIcon, - RotateCwIcon, SettingsIcon, SquarePenIcon, TerminalIcon, - TriangleAlertIcon, - XIcon, } from "lucide-react"; import { useCallback, useEffect, useMemo, useRef, useState, type MouseEvent } from "react"; import { @@ -30,7 +26,6 @@ import { restrictToParentElement, restrictToVerticalAxis } from "@dnd-kit/modifi import { CSS } from "@dnd-kit/utilities"; import { DEFAULT_MODEL_BY_PROVIDER, - type DesktopUpdateState, ProjectId, ThreadId, type GitStatusResult, @@ -52,18 +47,6 @@ import { useComposerDraftStore } from "../composerDraftStore"; import { useHandleNewThread } from "../hooks/useHandleNewThread"; import { selectThreadTerminalState, useTerminalStateStore } from "../terminalStateStore"; import { toastManager } from "./ui/toast"; -import { - getArm64IntelBuildWarningDescription, - getDesktopUpdateActionError, - getDesktopUpdateButtonTooltip, - isDesktopUpdateButtonDisabled, - resolveDesktopUpdateButtonAction, - shouldShowArm64IntelBuildWarning, - shouldShowDesktopUpdateButton, - shouldToastDesktopUpdateActionResult, -} from "./desktopUpdate.logic"; -import { Alert, AlertAction, AlertDescription, AlertTitle } from "./ui/alert"; -import { Button } from "./ui/button"; import { Collapsible, CollapsibleContent } from "./ui/collapsible"; import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip"; import { @@ -90,6 +73,7 @@ import { resolveThreadStatusPill, shouldClearThreadSelectionOnMouseDown, } from "./Sidebar.logic"; +import { SidebarUpdatePill } from "./sidebar/SidebarUpdatePill"; import { useCopyToClipboard } from "~/hooks/useCopyToClipboard"; const EMPTY_KEYBINDINGS: ResolvedKeybindingsConfig = []; @@ -299,8 +283,6 @@ export default function Sidebar() { const renamingInputRef = useRef(null); const dragInProgressRef = useRef(false); const suppressProjectClickAfterDragRef = useRef(false); - const [desktopUpdateState, setDesktopUpdateState] = useState(null); - const [updateDismissed, setUpdateDismissed] = useState(false); const selectedThreadIds = useThreadSelectionStore((s) => s.selectedThreadIds); const toggleThreadSelection = useThreadSelectionStore((s) => s.toggleThread); const rangeSelectTo = useThreadSelectionStore((s) => s.rangeSelectTo); @@ -965,55 +947,6 @@ export default function Sidebar() { }; }, [clearSelection, selectedThreadIds.size]); - useEffect(() => { - if (!isElectron) return; - const bridge = window.desktopBridge; - if ( - !bridge || - typeof bridge.getUpdateState !== "function" || - typeof bridge.onUpdateState !== "function" - ) { - return; - } - - let disposed = false; - let receivedSubscriptionUpdate = false; - const unsubscribe = bridge.onUpdateState((nextState) => { - if (disposed) return; - receivedSubscriptionUpdate = true; - setDesktopUpdateState(nextState); - }); - - void bridge - .getUpdateState() - .then((nextState) => { - if (disposed || receivedSubscriptionUpdate) return; - setDesktopUpdateState(nextState); - }) - .catch(() => undefined); - - return () => { - disposed = true; - unsubscribe(); - }; - }, []); - - const showDesktopUpdateButton = isElectron && shouldShowDesktopUpdateButton(desktopUpdateState) && !updateDismissed; - - const desktopUpdateTooltip = desktopUpdateState - ? getDesktopUpdateButtonTooltip(desktopUpdateState) - : "Update available"; - - const desktopUpdateButtonDisabled = isDesktopUpdateButtonDisabled(desktopUpdateState); - const desktopUpdateButtonAction = desktopUpdateState - ? resolveDesktopUpdateButtonAction(desktopUpdateState) - : "none"; - const showArm64IntelBuildWarning = - isElectron && shouldShowArm64IntelBuildWarning(desktopUpdateState); - const arm64IntelBuildWarningDescription = - desktopUpdateState && showArm64IntelBuildWarning - ? getArm64IntelBuildWarningDescription(desktopUpdateState) - : null; const newThreadShortcutLabel = useMemo( () => shortcutLabelForCommand(keybindings, "chat.newLocal") ?? @@ -1021,64 +954,6 @@ export default function Sidebar() { [keybindings], ); - const handleDesktopUpdateButtonClick = useCallback(() => { - const bridge = window.desktopBridge; - if (!bridge || !desktopUpdateState) return; - if (desktopUpdateButtonDisabled || desktopUpdateButtonAction === "none") return; - - if (desktopUpdateButtonAction === "download") { - void bridge - .downloadUpdate() - .then((result) => { - if (result.completed) { - toastManager.add({ - type: "success", - title: "Update downloaded", - description: "Restart the app from the update button to install it.", - }); - } - if (!shouldToastDesktopUpdateActionResult(result)) return; - const actionError = getDesktopUpdateActionError(result); - if (!actionError) return; - toastManager.add({ - type: "error", - title: "Could not download update", - description: actionError, - }); - }) - .catch((error) => { - toastManager.add({ - type: "error", - title: "Could not start update download", - description: error instanceof Error ? error.message : "An unexpected error occurred.", - }); - }); - return; - } - - if (desktopUpdateButtonAction === "install") { - void bridge - .installUpdate() - .then((result) => { - if (!shouldToastDesktopUpdateActionResult(result)) return; - const actionError = getDesktopUpdateActionError(result); - if (!actionError) return; - toastManager.add({ - type: "error", - title: "Could not install update", - description: actionError, - }); - }) - .catch((error) => { - toastManager.add({ - type: "error", - title: "Could not install update", - description: error instanceof Error ? error.message : "An unexpected error occurred.", - }); - }); - } - }, [desktopUpdateButtonAction, desktopUpdateButtonDisabled, desktopUpdateState]); - const expandThreadListForProject = useCallback((projectId: ProjectId) => { setExpandedThreadListsByProject((current) => { if (current.has(projectId)) return current; @@ -1136,29 +1011,6 @@ export default function Sidebar() { )} - {showArm64IntelBuildWarning && arm64IntelBuildWarningDescription ? ( - - - - Intel build on Apple Silicon - {arm64IntelBuildWarningDescription} - {desktopUpdateButtonAction !== "none" ? ( - - - - ) : null} - - - ) : null}
@@ -1582,66 +1434,7 @@ export default function Sidebar() { - {showDesktopUpdateButton && ( -
-
-
- - - {desktopUpdateButtonAction === "install" ? ( - <> - - Restart to update - - ) : desktopUpdateState?.status === "downloading" ? ( - <> - - - Downloading{typeof desktopUpdateState.downloadPercent === "number" ? ` (${Math.floor(desktopUpdateState.downloadPercent)}%)` : "…"} - - - ) : ( - <> - - Update available - - )} - - } - /> - {desktopUpdateTooltip} - - {desktopUpdateButtonAction === "download" && ( - - setUpdateDismissed(true)} - > - - - } - /> - Dismiss until next launch - - )} -
-
- )} + {isOnSettings ? ( diff --git a/apps/web/src/components/sidebar/SidebarUpdatePill.tsx b/apps/web/src/components/sidebar/SidebarUpdatePill.tsx new file mode 100644 index 000000000..15378fad2 --- /dev/null +++ b/apps/web/src/components/sidebar/SidebarUpdatePill.tsx @@ -0,0 +1,197 @@ +import { DownloadIcon, RotateCwIcon, TriangleAlertIcon, XIcon } from "lucide-react"; +import { useCallback, useEffect, useState } from "react"; +import type { DesktopUpdateState } from "@t3tools/contracts"; +import { isElectron } from "../../env"; +import { toastManager } from "../ui/toast"; +import { + getArm64IntelBuildWarningDescription, + getDesktopUpdateActionError, + getDesktopUpdateButtonTooltip, + isDesktopUpdateButtonDisabled, + resolveDesktopUpdateButtonAction, + shouldShowArm64IntelBuildWarning, + shouldShowDesktopUpdateButton, + shouldToastDesktopUpdateActionResult, +} from "../desktopUpdate.logic"; +import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; + +export function SidebarUpdatePill() { + const [state, setState] = useState(null); + const [dismissed, setDismissed] = useState(false); + + useEffect(() => { + if (!isElectron) return; + const bridge = window.desktopBridge; + if ( + !bridge || + typeof bridge.getUpdateState !== "function" || + typeof bridge.onUpdateState !== "function" + ) { + return; + } + + let disposed = false; + let receivedSubscriptionUpdate = false; + const unsubscribe = bridge.onUpdateState((nextState) => { + if (disposed) return; + receivedSubscriptionUpdate = true; + setState(nextState); + }); + + void bridge + .getUpdateState() + .then((nextState) => { + if (disposed || receivedSubscriptionUpdate) return; + setState(nextState); + }) + .catch(() => undefined); + + return () => { + disposed = true; + unsubscribe(); + }; + }, []); + + const visible = isElectron && shouldShowDesktopUpdateButton(state) && !dismissed; + const tooltip = state ? getDesktopUpdateButtonTooltip(state) : "Update available"; + const disabled = isDesktopUpdateButtonDisabled(state); + const action = state ? resolveDesktopUpdateButtonAction(state) : "none"; + + const showArm64Warning = isElectron && shouldShowArm64IntelBuildWarning(state); + const arm64Description = + state && showArm64Warning ? getArm64IntelBuildWarningDescription(state) : null; + + const handleAction = useCallback(() => { + const bridge = window.desktopBridge; + if (!bridge || !state) return; + if (disabled || action === "none") return; + + if (action === "download") { + void bridge + .downloadUpdate() + .then((result) => { + if (result.completed) { + toastManager.add({ + type: "success", + title: "Update downloaded", + description: "Restart the app from the update button to install it.", + }); + } + if (!shouldToastDesktopUpdateActionResult(result)) return; + const actionError = getDesktopUpdateActionError(result); + if (!actionError) return; + toastManager.add({ + type: "error", + title: "Could not download update", + description: actionError, + }); + }) + .catch((error) => { + toastManager.add({ + type: "error", + title: "Could not start update download", + description: error instanceof Error ? error.message : "An unexpected error occurred.", + }); + }); + return; + } + + if (action === "install") { + void bridge + .installUpdate() + .then((result) => { + if (!shouldToastDesktopUpdateActionResult(result)) return; + const actionError = getDesktopUpdateActionError(result); + if (!actionError) return; + toastManager.add({ + type: "error", + title: "Could not install update", + description: actionError, + }); + }) + .catch((error) => { + toastManager.add({ + type: "error", + title: "Could not install update", + description: error instanceof Error ? error.message : "An unexpected error occurred.", + }); + }); + } + }, [action, disabled, state]); + + if (!visible && !showArm64Warning) return null; + + return ( +
+ {showArm64Warning && arm64Description && ( +
+ + {arm64Description} +
+ )} + {visible && ( +
+
+ + + {action === "install" ? ( + <> + + Restart to update + + ) : state?.status === "downloading" ? ( + <> + + + Downloading + {typeof state.downloadPercent === "number" + ? ` (${Math.floor(state.downloadPercent)}%)` + : "…"} + + + ) : ( + <> + + Update available + + )} + + } + /> + {tooltip} + + {action === "download" && ( + + setDismissed(true)} + > + + + } + /> + Dismiss until next launch + + )} +
+ )} +
+ ); +} From d51faacb777fbb592a5986fd78c4997e13d35abd Mon Sep 17 00:00:00 2001 From: Jono Kemball Date: Mon, 16 Mar 2026 00:06:41 +1300 Subject: [PATCH 3/4] feat(web): restore arm64 warning Alert UI in update pill Use the original Alert component with title and description for the arm64 Intel build warning, remove redundant action button since the update pill handles it, and match sidebar font size with text-xs. --- .../components/sidebar/SidebarUpdatePill.tsx | 98 +++++++++++-------- 1 file changed, 59 insertions(+), 39 deletions(-) diff --git a/apps/web/src/components/sidebar/SidebarUpdatePill.tsx b/apps/web/src/components/sidebar/SidebarUpdatePill.tsx index 15378fad2..d28ab096c 100644 --- a/apps/web/src/components/sidebar/SidebarUpdatePill.tsx +++ b/apps/web/src/components/sidebar/SidebarUpdatePill.tsx @@ -13,51 +13,70 @@ import { shouldShowDesktopUpdateButton, shouldToastDesktopUpdateActionResult, } from "../desktopUpdate.logic"; +import { Alert, AlertDescription, AlertTitle } from "../ui/alert"; import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; export function SidebarUpdatePill() { - const [state, setState] = useState(null); + // TODO: REMOVE - hardcoded for testing arm64 warning + const [state, setState] = useState({ + enabled: true, + status: "available", + currentVersion: "1.0.0", + availableVersion: "1.2.3", + downloadedVersion: null, + downloadPercent: null, + checkedAt: new Date().toISOString(), + message: null, + errorContext: null, + hostArch: "arm64", + appArch: "x64", + runningUnderArm64Translation: true, + canRetry: false, + }); const [dismissed, setDismissed] = useState(false); - useEffect(() => { - if (!isElectron) return; - const bridge = window.desktopBridge; - if ( - !bridge || - typeof bridge.getUpdateState !== "function" || - typeof bridge.onUpdateState !== "function" - ) { - return; - } - - let disposed = false; - let receivedSubscriptionUpdate = false; - const unsubscribe = bridge.onUpdateState((nextState) => { - if (disposed) return; - receivedSubscriptionUpdate = true; - setState(nextState); - }); + // TODO: REMOVE - disabled for testing + // useEffect(() => { + // if (!isElectron) return; + // const bridge = window.desktopBridge; + // if ( + // !bridge || + // typeof bridge.getUpdateState !== "function" || + // typeof bridge.onUpdateState !== "function" + // ) { + // return; + // } + // + // let disposed = false; + // let receivedSubscriptionUpdate = false; + // const unsubscribe = bridge.onUpdateState((nextState) => { + // if (disposed) return; + // receivedSubscriptionUpdate = true; + // setState(nextState); + // }); + // + // void bridge + // .getUpdateState() + // .then((nextState) => { + // if (disposed || receivedSubscriptionUpdate) return; + // setState(nextState); + // }) + // .catch(() => undefined); + // + // return () => { + // disposed = true; + // unsubscribe(); + // }; + // }, []); - void bridge - .getUpdateState() - .then((nextState) => { - if (disposed || receivedSubscriptionUpdate) return; - setState(nextState); - }) - .catch(() => undefined); - - return () => { - disposed = true; - unsubscribe(); - }; - }, []); - - const visible = isElectron && shouldShowDesktopUpdateButton(state) && !dismissed; + // TODO: REMOVE - bypassed isElectron for testing + const visible = /* isElectron && */ shouldShowDesktopUpdateButton(state) && !dismissed; const tooltip = state ? getDesktopUpdateButtonTooltip(state) : "Update available"; const disabled = isDesktopUpdateButtonDisabled(state); const action = state ? resolveDesktopUpdateButtonAction(state) : "none"; - const showArm64Warning = isElectron && shouldShowArm64IntelBuildWarning(state); + // TODO: REMOVE - bypassed isElectron for testing + const showArm64Warning = /* isElectron && */ shouldShowArm64IntelBuildWarning(state); const arm64Description = state && showArm64Warning ? getArm64IntelBuildWarningDescription(state) : null; @@ -124,10 +143,11 @@ export function SidebarUpdatePill() { return (
{showArm64Warning && arm64Description && ( -
- - {arm64Description} -
+ + + Intel build on Apple Silicon + {arm64Description} + )} {visible && (
Date: Mon, 16 Mar 2026 00:08:23 +1300 Subject: [PATCH 4/4] chore(web): remove test mocks from SidebarUpdatePill Restore real bridge subscription and isElectron checks that were hardcoded for local testing. --- .../components/sidebar/SidebarUpdatePill.tsx | 88 ++++++++----------- 1 file changed, 35 insertions(+), 53 deletions(-) diff --git a/apps/web/src/components/sidebar/SidebarUpdatePill.tsx b/apps/web/src/components/sidebar/SidebarUpdatePill.tsx index d28ab096c..3b78f1b06 100644 --- a/apps/web/src/components/sidebar/SidebarUpdatePill.tsx +++ b/apps/web/src/components/sidebar/SidebarUpdatePill.tsx @@ -17,66 +17,48 @@ import { Alert, AlertDescription, AlertTitle } from "../ui/alert"; import { Tooltip, TooltipPopup, TooltipTrigger } from "../ui/tooltip"; export function SidebarUpdatePill() { - // TODO: REMOVE - hardcoded for testing arm64 warning - const [state, setState] = useState({ - enabled: true, - status: "available", - currentVersion: "1.0.0", - availableVersion: "1.2.3", - downloadedVersion: null, - downloadPercent: null, - checkedAt: new Date().toISOString(), - message: null, - errorContext: null, - hostArch: "arm64", - appArch: "x64", - runningUnderArm64Translation: true, - canRetry: false, - }); + const [state, setState] = useState(null); const [dismissed, setDismissed] = useState(false); - // TODO: REMOVE - disabled for testing - // useEffect(() => { - // if (!isElectron) return; - // const bridge = window.desktopBridge; - // if ( - // !bridge || - // typeof bridge.getUpdateState !== "function" || - // typeof bridge.onUpdateState !== "function" - // ) { - // return; - // } - // - // let disposed = false; - // let receivedSubscriptionUpdate = false; - // const unsubscribe = bridge.onUpdateState((nextState) => { - // if (disposed) return; - // receivedSubscriptionUpdate = true; - // setState(nextState); - // }); - // - // void bridge - // .getUpdateState() - // .then((nextState) => { - // if (disposed || receivedSubscriptionUpdate) return; - // setState(nextState); - // }) - // .catch(() => undefined); - // - // return () => { - // disposed = true; - // unsubscribe(); - // }; - // }, []); + useEffect(() => { + if (!isElectron) return; + const bridge = window.desktopBridge; + if ( + !bridge || + typeof bridge.getUpdateState !== "function" || + typeof bridge.onUpdateState !== "function" + ) { + return; + } + + let disposed = false; + let receivedSubscriptionUpdate = false; + const unsubscribe = bridge.onUpdateState((nextState) => { + if (disposed) return; + receivedSubscriptionUpdate = true; + setState(nextState); + }); + + void bridge + .getUpdateState() + .then((nextState) => { + if (disposed || receivedSubscriptionUpdate) return; + setState(nextState); + }) + .catch(() => undefined); + + return () => { + disposed = true; + unsubscribe(); + }; + }, []); - // TODO: REMOVE - bypassed isElectron for testing - const visible = /* isElectron && */ shouldShowDesktopUpdateButton(state) && !dismissed; + const visible = isElectron && shouldShowDesktopUpdateButton(state) && !dismissed; const tooltip = state ? getDesktopUpdateButtonTooltip(state) : "Update available"; const disabled = isDesktopUpdateButtonDisabled(state); const action = state ? resolveDesktopUpdateButtonAction(state) : "none"; - // TODO: REMOVE - bypassed isElectron for testing - const showArm64Warning = /* isElectron && */ shouldShowArm64IntelBuildWarning(state); + const showArm64Warning = isElectron && shouldShowArm64IntelBuildWarning(state); const arm64Description = state && showArm64Warning ? getArm64IntelBuildWarningDescription(state) : null;