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');