add release notes modal to appmenu

This commit is contained in:
jeffvli
2026-02-03 01:06:52 -08:00
parent 48e50430fe
commit 0dd13cbab1
2 changed files with 55 additions and 11 deletions
@@ -9,6 +9,7 @@ import packageJson from '../../../../../package.json';
import { isServerLock } from '/@/renderer/features/action-required/utils/window-properties'; import { isServerLock } from '/@/renderer/features/action-required/utils/window-properties';
import { ServerList } from '/@/renderer/features/servers/components/server-list'; import { ServerList } from '/@/renderer/features/servers/components/server-list';
import { openSettingsModal } from '/@/renderer/features/settings/utils/open-settings-modal'; import { openSettingsModal } from '/@/renderer/features/settings/utils/open-settings-modal';
import { openReleaseNotesModal } from '/@/renderer/release-notes-modal';
import { useAppStore, useAppStoreActions, useCommandPalette } from '/@/renderer/store'; import { useAppStore, useAppStoreActions, useCommandPalette } from '/@/renderer/store';
import { DropdownMenu, MenuItemProps } from '/@/shared/components/dropdown-menu/dropdown-menu'; import { DropdownMenu, MenuItemProps } from '/@/shared/components/dropdown-menu/dropdown-menu';
import { Icon } from '/@/shared/components/icon/icon'; import { Icon } from '/@/shared/components/icon/icon';
@@ -225,16 +226,19 @@ export const AppMenu = () => {
type: 'divider', type: 'divider',
}, },
{ {
component: 'a',
href: 'https://github.com/jeffvli/feishin/releases',
icon: 'brandGitHub', icon: 'brandGitHub',
id: 'version', id: 'version',
label: t('page.appMenu.version', { label: t('page.appMenu.version', {
postProcess: 'sentenceCase', postProcess: 'sentenceCase',
version: packageJson.version, version: packageJson.version,
}), }),
rightSection: <Icon icon="externalLink" />, onClick: () =>
target: '_blank', openReleaseNotesModal(
t('common.newVersion', {
postProcess: 'sentenceCase',
version: packageJson.version,
}) as string,
),
type: 'item', type: 'item',
}, },
{ {
+47 -7
View File
@@ -2,7 +2,7 @@ import { closeAllModals, openModal } from '@mantine/modals';
import { useQuery } from '@tanstack/react-query'; import { useQuery } from '@tanstack/react-query';
import axios from 'axios'; import axios from 'axios';
import DOMPurify from 'dompurify'; import DOMPurify from 'dompurify';
import { useCallback, useEffect, useMemo, useState } from 'react'; import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import { useTranslation } from 'react-i18next'; import { useTranslation } from 'react-i18next';
import packageJson from '../../package.json'; import packageJson from '../../package.json';
@@ -216,10 +216,14 @@ const ReleaseNotesContent = ({ onDismiss, version }: ReleaseNotesContentProps) =
const WAIT_FOR_LOCAL_STORAGE = 1000 * 2; const WAIT_FOR_LOCAL_STORAGE = 1000 * 2;
export const ReleaseNotesModal = () => { interface ReleaseNotesModalContentWrapperProps {
const { version } = packageJson; setDismissRef?: (fn: (() => void) | undefined) => void;
const { t } = useTranslation(); }
const ReleaseNotesModalContentWrapper = ({
setDismissRef,
}: ReleaseNotesModalContentWrapperProps) => {
const { version } = packageJson;
const [, setValue] = useLocalStorage({ key: 'version' }); const [, setValue] = useLocalStorage({ key: 'version' });
const handleDismiss = useCallback(() => { const handleDismiss = useCallback(() => {
@@ -227,6 +231,36 @@ export const ReleaseNotesModal = () => {
closeAllModals(); closeAllModals();
}, [setValue, version]); }, [setValue, version]);
useEffect(() => {
setDismissRef?.(handleDismiss);
return () => setDismissRef?.(undefined);
}, [handleDismiss, setDismissRef]);
return <ReleaseNotesContent onDismiss={handleDismiss} version={version} />;
};
export const openReleaseNotesModal = (title: string) => {
const dismissRef = { current: null as (() => void) | null };
openModal({
children: (
<ReleaseNotesModalContentWrapper
setDismissRef={(fn) => {
dismissRef.current = fn ?? null;
}}
/>
),
onClose: () => dismissRef.current?.(),
size: 'xl',
title,
});
};
export const ReleaseNotesModal = () => {
const { version } = packageJson;
const { t } = useTranslation();
const dismissRef = useRef<(() => void) | null>(null);
useEffect(() => { useEffect(() => {
const timeoutId = setTimeout(() => { const timeoutId = setTimeout(() => {
const valueFromLocalStorage = localStorage.getItem('version'); const valueFromLocalStorage = localStorage.getItem('version');
@@ -235,8 +269,14 @@ export const ReleaseNotesModal = () => {
// Only show modal if the stored version is different from current version // Only show modal if the stored version is different from current version
if (valueFromLocalStorage !== versionString) { if (valueFromLocalStorage !== versionString) {
openModal({ openModal({
children: <ReleaseNotesContent onDismiss={handleDismiss} version={version} />, children: (
onClose: handleDismiss, <ReleaseNotesModalContentWrapper
setDismissRef={(fn) => {
dismissRef.current = fn ?? null;
}}
/>
),
onClose: () => dismissRef.current?.(),
size: 'xl', size: 'xl',
title: t('common.newVersion', { title: t('common.newVersion', {
postProcess: 'sentenceCase', postProcess: 'sentenceCase',
@@ -249,7 +289,7 @@ export const ReleaseNotesModal = () => {
return () => { return () => {
clearTimeout(timeoutId); clearTimeout(timeoutId);
}; };
}, [handleDismiss, t, version]); }, [t, version]);
return null; return null;
}; };