Skip to content

Commit 01d5601

Browse files
Nagi-ovoclaude
andcommitted
fix(changelog): skip popup on first install
First-time users have no context for the changelog — suppress the auto-popup and badge so they can explore the extension first. The changelog remains accessible manually. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
1 parent 085442f commit 01d5601

2 files changed

Lines changed: 44 additions & 1 deletion

File tree

src/pages/content/changelog/__tests__/changelog.test.ts

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { describe, expect, it } from 'vitest';
1+
import { beforeEach, describe, expect, it, vi } from 'vitest';
2+
3+
import { StorageKeys } from '@/core/types/common';
24

35
import {
46
extractLocalizedContent,
7+
hasUnreadChangelog,
58
resolveChangelogImageUrl,
69
rewriteChangelogImageUrls,
710
} from '../index';
@@ -160,3 +163,29 @@ describe('rewriteChangelogImageUrls', () => {
160163
expect(result).toBe(source);
161164
});
162165
});
166+
167+
describe('hasUnreadChangelog', () => {
168+
beforeEach(() => {
169+
vi.restoreAllMocks();
170+
});
171+
172+
it('returns false on first install (no dismissed version stored)', async () => {
173+
(chrome.storage.local.get as ReturnType<typeof vi.fn>).mockResolvedValue({});
174+
expect(await hasUnreadChangelog()).toBe(false);
175+
});
176+
177+
it('returns true when dismissed version differs from current', async () => {
178+
(chrome.storage.local.get as ReturnType<typeof vi.fn>).mockResolvedValue({
179+
[StorageKeys.CHANGELOG_DISMISSED_VERSION]: '0.0.1',
180+
});
181+
expect(await hasUnreadChangelog()).toBe(true);
182+
});
183+
184+
it('returns false when dismissed version matches current', async () => {
185+
const { EXTENSION_VERSION } = await import('@/core/utils/version');
186+
(chrome.storage.local.get as ReturnType<typeof vi.fn>).mockResolvedValue({
187+
[StorageKeys.CHANGELOG_DISMISSED_VERSION]: EXTENSION_VERSION,
188+
});
189+
expect(await hasUnreadChangelog()).toBe(false);
190+
});
191+
});

src/pages/content/changelog/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,6 +505,19 @@ async function showChangelogModal(
505505
const result = await chrome.storage.local.get(StorageKeys.CHANGELOG_DISMISSED_VERSION);
506506
const dismissedVersion = result[StorageKeys.CHANGELOG_DISMISSED_VERSION] as string | undefined;
507507
if (dismissedVersion === EXTENSION_VERSION) return null;
508+
// First install — user has never seen any changelog, so the current
509+
// version's notes aren't meaningful. Silently dismiss and let them
510+
// explore the extension first.
511+
if (!dismissedVersion) {
512+
try {
513+
await chrome.storage.local.set({
514+
[StorageKeys.CHANGELOG_DISMISSED_VERSION]: EXTENSION_VERSION,
515+
});
516+
} catch {
517+
// Ignore
518+
}
519+
return null;
520+
}
508521
}
509522

510523
// 2. Try to load the changelog for the target version
@@ -583,6 +596,7 @@ export async function hasUnreadChangelog(): Promise<boolean> {
583596
try {
584597
const result = await chrome.storage.local.get(StorageKeys.CHANGELOG_DISMISSED_VERSION);
585598
const dismissed = result[StorageKeys.CHANGELOG_DISMISSED_VERSION] as string | undefined;
599+
if (!dismissed) return false;
586600
return dismissed !== EXTENSION_VERSION;
587601
} catch {
588602
return false;

0 commit comments

Comments
 (0)