diff --git a/packages/ui/src/stores/releases.ts b/packages/ui/src/stores/releases.ts index e993513d..f55bae70 100644 --- a/packages/ui/src/stores/releases.ts +++ b/packages/ui/src/stores/releases.ts @@ -1,30 +1,68 @@ -import { createSignal } from "solid-js" +import { createEffect, createSignal } from "solid-js" import type { LatestReleaseInfo, WorkspaceEventPayload } from "../../../server/src/api-types" import { getServerMeta } from "../lib/server-meta" import { serverEvents } from "../lib/server-events" import { showToastNotification, ToastHandle } from "../lib/notifications" import { getLogger } from "../lib/logger" +import { hasInstances, showFolderSelection } from "./ui" const log = getLogger("actions") const [availableRelease, setAvailableRelease] = createSignal(null) let initialized = false +let visibilityEffectInitialized = false let activeToast: ToastHandle | null = null +let activeToastVersion: string | null = null function dismissActiveToast() { if (activeToast) { activeToast.dismiss() activeToast = null + activeToastVersion = null } } +function ensureVisibilityEffect() { + if (visibilityEffectInitialized) { + return + } + visibilityEffectInitialized = true + + createEffect(() => { + const release = availableRelease() + const shouldShow = Boolean(release) && (!hasInstances() || showFolderSelection()) + + if (!shouldShow || !release) { + dismissActiveToast() + return + } + + if (!activeToast || activeToastVersion !== release.version) { + dismissActiveToast() + activeToast = showToastNotification({ + title: `CodeNomad ${release.version}`, + message: release.channel === "dev" ? "Dev release build available." : "New stable build on GitHub.", + variant: "info", + duration: Number.POSITIVE_INFINITY, + position: "bottom-right", + action: { + label: "View release", + href: release.url, + }, + }) + activeToastVersion = release.version + } + }) +} + export function initReleaseNotifications() { if (initialized) { return } initialized = true + ensureVisibilityEffect() void refreshFromMeta() serverEvents.on("app.releaseAvailable", (event) => { @@ -47,22 +85,9 @@ async function refreshFromMeta() { function applyRelease(release: LatestReleaseInfo | null | undefined) { if (!release) { setAvailableRelease(null) - dismissActiveToast() return } setAvailableRelease(release) - dismissActiveToast() - activeToast = showToastNotification({ - title: `CodeNomad ${release.version}`, - message: release.channel === "dev" ? "Dev release build available." : "New stable build on GitHub.", - variant: "info", - duration: Number.POSITIVE_INFINITY, - position: "bottom-right", - action: { - label: "View release", - href: release.url, - }, - }) } export function useAvailableRelease() {