diff --git a/src/main/index.js b/src/main/index.js index f047bc3..11bee62 100644 --- a/src/main/index.js +++ b/src/main/index.js @@ -2260,7 +2260,7 @@ ipcMain.on('app:quit', () => { }); ipcMain.on('app:open-external', (_event, url) => { - if (typeof url === 'string' && /^https?:\/\//i.test(url)) { + if (typeof url === 'string' && /^https:\/\//i.test(url)) { shell.openExternal(url).catch((e) => console.error('[app:open-external]', e)); } }); diff --git a/src/main/updater/feed-config.js b/src/main/updater/feed-config.js index 1df7c23..b25fdcd 100644 --- a/src/main/updater/feed-config.js +++ b/src/main/updater/feed-config.js @@ -1,33 +1,3 @@ -const REPO = 'amitwh/markdown-converter'; - -const FEEDS = { - github: { - base: `https://github.com/${REPO}/releases/download`, - }, - concreteinfo: { - base: 'https://updates.concreteinfo.co.in/v5', - }, -}; - -function platformSuffix(platform) { - if (platform === 'darwin' || platform === 'mac') return 'mac'; - if (platform === 'win32' || platform === 'windows') return 'windows'; - return 'linux'; -} - -function feedForChannel(channel, version, platform) { - const suffix = platformSuffix(platform); - const f = FEEDS[channel] || FEEDS.github; - if (channel === 'github') { - return `${f.base}/v${version}/latest-${suffix}.yml`; - } - return `${f.base}/latest-${suffix}.yml`; -} - -function resolveFeedUrl(channel, version, platform) { - return feedForChannel(channel, version, platform); -} - function feedConfigFor(channel) { if (channel === 'github') { return { provider: 'github', owner: 'amitwh', repo: 'markdown-converter' }; @@ -35,4 +5,4 @@ function feedConfigFor(channel) { return { provider: 'generic', url: 'https://updates.concreteinfo.co.in/v5' }; } -module.exports = { resolveFeedUrl, feedConfigFor, FEEDS }; \ No newline at end of file +module.exports = { feedConfigFor }; diff --git a/src/renderer/components/UpdateBanner.tsx b/src/renderer/components/UpdateBanner.tsx index 2f0a436..5b4206d 100644 --- a/src/renderer/components/UpdateBanner.tsx +++ b/src/renderer/components/UpdateBanner.tsx @@ -18,6 +18,17 @@ export function UpdateBanner() { ); } + if (state === 'available') { + return ( +
+ A new version (v{version}) is available.{' '} + +
+ ); + } + if (state === 'downloading') { return (
@@ -41,4 +52,4 @@ export function UpdateBanner() { } return null; -} \ No newline at end of file +} diff --git a/src/renderer/components/modals/ThemeSettings.tsx b/src/renderer/components/modals/ThemeSettings.tsx index d20091a..d677b20 100644 --- a/src/renderer/components/modals/ThemeSettings.tsx +++ b/src/renderer/components/modals/ThemeSettings.tsx @@ -10,10 +10,10 @@ export function ThemeSettings() {
- setSetting('theme', v as 'light' | 'dark' | 'auto')}> + setSetting('theme', v as 'light' | 'dark' | 'system')}>
-
+
diff --git a/tests/component/UpdateBanner.test.tsx b/tests/component/UpdateBanner.test.tsx index cc7b92b..6c7ece5 100644 --- a/tests/component/UpdateBanner.test.tsx +++ b/tests/component/UpdateBanner.test.tsx @@ -40,10 +40,17 @@ describe('UpdateBanner', () => { expect(screen.getByText(/couldn.?t check/i)).toBeInTheDocument(); }); + test('shows download CTA when state is available', () => { + useUpdaterStore.setState({ state: 'available', version: '5.0.2' }); + render(); + expect(screen.getByText(/5\.0\.2/)).toBeInTheDocument(); + expect(screen.getByText(/download/i)).toBeInTheDocument(); + }); + test('restart button calls ipc.updater.install', () => { useUpdaterStore.setState({ state: 'ready', version: '5.0.2' }); render(); fireEvent.click(screen.getByRole('button', { name: /restart/i })); expect(useUpdaterStore.getState().install).toBeDefined(); }); -}); \ No newline at end of file +}); diff --git a/tests/unit/main/updater/feed-config.test.js b/tests/unit/main/updater/feed-config.test.js index bf9515d..4a409bc 100644 --- a/tests/unit/main/updater/feed-config.test.js +++ b/tests/unit/main/updater/feed-config.test.js @@ -1,36 +1,5 @@ -const { resolveFeedUrl, feedConfigFor, FEEDS } = require('../../../../src/main/updater/feed-config'); +const { feedConfigFor } = require('../../../../src/main/updater/feed-config'); -describe('feed-config', () => { - test('resolves github channel to GitHub Releases feed', () => { - const url = resolveFeedUrl('github', '5.0.2', 'mac'); - expect(url).toBe('https://github.com/amitwh/markdown-converter/releases/download/v5.0.2/latest-mac.yml'); - }); - - test('resolves concreteinfo channel to CI feed', () => { - const url = resolveFeedUrl('concreteinfo', '5.0.2', 'mac'); - expect(url).toBe('https://updates.concreteinfo.co.in/v5/latest-mac.yml'); - }); - - test('resolves windows platform correctly', () => { - const url = resolveFeedUrl('github', '5.0.2', 'windows'); - expect(url).toContain('latest-windows.yml'); - }); - - test('resolves linux platform correctly', () => { - const url = resolveFeedUrl('github', '5.0.2', 'linux'); - expect(url).toContain('latest-linux.yml'); - }); - - test('falls back to github on unknown channel', () => { - const url = resolveFeedUrl('something-weird', '5.0.2', 'mac'); - expect(url).toContain('github.com'); - }); - - test('exports both feeds as constants', () => { - expect(FEEDS.github).toBeDefined(); - expect(FEEDS.concreteinfo).toBeDefined(); - }); -}); describe('feedConfigFor', () => { test('returns github provider config for github channel', () => { const config = feedConfigFor('github');