From 1082076133ff185980ba3d6b5a989939ed431e14 Mon Sep 17 00:00:00 2001 From: Mohamed Bassem Date: Mon, 29 Dec 2025 10:20:31 +0000 Subject: feat: add the ability to specify a different changelog version --- apps/web/components/shared/sidebar/Sidebar.tsx | 5 +- .../components/shared/sidebar/SidebarVersion.tsx | 56 +++++++++++++++------- packages/shared/config.ts | 2 + 3 files changed, 44 insertions(+), 19 deletions(-) diff --git a/apps/web/components/shared/sidebar/Sidebar.tsx b/apps/web/components/shared/sidebar/Sidebar.tsx index bf5a626b..3f4780e7 100644 --- a/apps/web/components/shared/sidebar/Sidebar.tsx +++ b/apps/web/components/shared/sidebar/Sidebar.tsx @@ -32,7 +32,10 @@ export default async function Sidebar({ {extraSections} - + ); } diff --git a/apps/web/components/shared/sidebar/SidebarVersion.tsx b/apps/web/components/shared/sidebar/SidebarVersion.tsx index fc2ec5a3..2d6d3380 100644 --- a/apps/web/components/shared/sidebar/SidebarVersion.tsx +++ b/apps/web/components/shared/sidebar/SidebarVersion.tsx @@ -46,36 +46,50 @@ function isStableRelease(version?: string) { } interface SidebarVersionProps { + // The actual version of the server serverVersion?: string; + // The version that should be displayed in the changelog + changeLogVersion?: string; } -export default function SidebarVersion({ serverVersion }: SidebarVersionProps) { +export default function SidebarVersion({ + serverVersion, + changeLogVersion, +}: SidebarVersionProps) { const { disableNewReleaseCheck } = useClientConfig(); const { t } = useTranslation(); - const stableRelease = isStableRelease(serverVersion); + const effectiveChangelogVersion = changeLogVersion ?? serverVersion; + const stableRelease = isStableRelease(effectiveChangelogVersion); const displayVersion = serverVersion ?? "unknown"; + const changelogDisplayVersion = effectiveChangelogVersion ?? displayVersion; const versionLabel = `Karakeep v${displayVersion}`; const releasePageUrl = useMemo(() => { - if (!serverVersion || !isStableRelease(serverVersion)) { + if ( + !effectiveChangelogVersion || + !isStableRelease(effectiveChangelogVersion) + ) { return GITHUB_REPO_URL; } - return `${GITHUB_RELEASE_URL}v${serverVersion}`; - }, [serverVersion]); + return `${GITHUB_RELEASE_URL}v${effectiveChangelogVersion}`; + }, [effectiveChangelogVersion]); const [open, setOpen] = useState(false); const [shouldNotify, setShouldNotify] = useState(false); const releaseNotesQuery = useQuery({ - queryKey: ["sidebar-release-notes", serverVersion], + queryKey: ["sidebar-release-notes", effectiveChangelogVersion], queryFn: async ({ signal }) => { - if (!serverVersion) { + if (!effectiveChangelogVersion) { return ""; } - const response = await fetch(`${RELEASE_API_URL}v${serverVersion}`, { - signal, - }); + const response = await fetch( + `${RELEASE_API_URL}v${effectiveChangelogVersion}`, + { + signal, + }, + ); if (!response.ok) { throw new Error("Failed to load release notes"); @@ -89,7 +103,7 @@ export default function SidebarVersion({ serverVersion }: SidebarVersionProps) { open && stableRelease && !disableNewReleaseCheck && - Boolean(serverVersion), + Boolean(effectiveChangelogVersion), staleTime: RELEASE_NOTES_STALE_TIME, retry: 1, refetchOnWindowFocus: false, @@ -123,30 +137,34 @@ export default function SidebarVersion({ serverVersion }: SidebarVersionProps) { }, [releaseNotesQuery.error, t]); useEffect(() => { - if (!stableRelease || !serverVersion || disableNewReleaseCheck) { + if ( + !stableRelease || + !effectiveChangelogVersion || + disableNewReleaseCheck + ) { setShouldNotify(false); return; } try { const seenVersion = window.localStorage.getItem(LOCAL_STORAGE_KEY); - setShouldNotify(seenVersion !== serverVersion); + setShouldNotify(seenVersion !== effectiveChangelogVersion); } catch (error) { console.warn("Failed to read localStorage:", error); setShouldNotify(true); } - }, [serverVersion, stableRelease, disableNewReleaseCheck]); + }, [effectiveChangelogVersion, stableRelease, disableNewReleaseCheck]); const markReleaseAsSeen = useCallback(() => { - if (!serverVersion) return; + if (!effectiveChangelogVersion) return; try { - window.localStorage.setItem(LOCAL_STORAGE_KEY, serverVersion); + window.localStorage.setItem(LOCAL_STORAGE_KEY, effectiveChangelogVersion); } catch (error) { console.warn("Failed to write to localStorage:", error); // Ignore failures, we still clear the notification for the session } setShouldNotify(false); - }, [serverVersion]); + }, [effectiveChangelogVersion]); const handleOpenChange = useCallback( (nextOpen: boolean) => { @@ -202,7 +220,9 @@ export default function SidebarVersion({ serverVersion }: SidebarVersionProps) { - {t("version.whats_new_title", { version: displayVersion })} + {t("version.whats_new_title", { + version: changelogDisplayVersion, + })} {t("version.release_notes_description")} diff --git a/packages/shared/config.ts b/packages/shared/config.ts index 191e9ecf..c10634e2 100644 --- a/packages/shared/config.ts +++ b/packages/shared/config.ts @@ -129,6 +129,7 @@ const allEnv = z.object({ MAX_WEBHOOKS_PER_USER: z.coerce.number().default(100), // Build only flag SERVER_VERSION: z.string().optional(), + CHANGELOG_VERSION: z.string().optional(), DISABLE_NEW_RELEASE_CHECK: stringBool("false"), // A flag to detect if the user is running in the old separete containers setup @@ -345,6 +346,7 @@ const serverConfigSchema = allEnv.transform((val, ctx) => { assetsDir: val.ASSETS_DIR ?? path.join(val.DATA_DIR, "assets"), maxAssetSizeMb: val.MAX_ASSET_SIZE_MB, serverVersion: val.SERVER_VERSION, + changelogVersion: val.CHANGELOG_VERSION, disableNewReleaseCheck: val.DISABLE_NEW_RELEASE_CHECK, usingLegacySeparateContainers: val.USING_LEGACY_SEPARATE_CONTAINERS, webhook: { -- cgit v1.2.3-70-g09d2