feat(overlay): add in-app changelog modal

- Add a changelog modal opened from tray "View Changelog" or the update notification's "What's New" button; renders in-player or in its own window like the help modal
- Fetch changelog from the newest published release so newer-than-installed notes are visible, falling back to the bundled CHANGELOG.md on failure
- Group versions by minor line (current expanded, older folded), badge the installed version, tag newer ones "New"
- Support J/K/arrow navigation, Enter to fold/unfold, R to refetch, Esc to close
- Add changelog parsing/semver-compare utils and changelog IPC channel/runtime; bundle CHANGELOG.md into packaged builds
- Replace release/release-notes.md with changes/changelog-modal.md changeset entry
This commit is contained in:
2026-08-05 01:20:52 -07:00
parent a0dde4ee3e
commit 3a97239ade
48 changed files with 2697 additions and 113 deletions
+7 -2
View File
@@ -4,6 +4,7 @@ import type {
KikuMergePreviewRequest,
KikuMergePreviewResponse,
} from './anki';
import type { ChangelogSnapshot } from './changelog';
import type { ResolvedConfig, ShortcutsConfig } from './config';
import type {
CompiledSessionBinding,
@@ -507,6 +508,8 @@ export interface ElectronAPI {
onRuntimeOptionsChanged: (callback: (options: RuntimeOptionState[]) => void) => void;
onOpenRuntimeOptions: (callback: () => void) => void;
onOpenSessionHelp: (callback: () => void) => void;
onOpenChangelog: (callback: () => void) => void;
getChangelogSnapshot: (options?: { refresh?: boolean }) => Promise<ChangelogSnapshot>;
onOpenControllerSelect: (callback: () => void) => void;
onOpenControllerDebug: (callback: () => void) => void;
onOpenJimaku: (callback: () => void) => void;
@@ -563,7 +566,8 @@ export interface ElectronAPI {
| 'controller-debug'
| 'subtitle-sidebar'
| 'session-help'
| 'character-dictionary',
| 'character-dictionary'
| 'changelog',
) => void;
notifyOverlayModalOpened: (
modal:
@@ -578,7 +582,8 @@ export interface ElectronAPI {
| 'controller-debug'
| 'subtitle-sidebar'
| 'session-help'
| 'character-dictionary',
| 'character-dictionary'
| 'changelog',
) => void;
reportOverlayContentBounds: (measurement: OverlayContentMeasurement) => void;
onConfigHotReload: (callback: (payload: ConfigHotReloadPayload) => void) => void;