refactor periodic update check to use github releases instead of electron-builder (#2259)

- resolves an issue related to electron-builder continuing to download and install updates despite only calling checkForUpdates
- adds indicator to settings / app menu on new version found
This commit is contained in:
jeffvli
2026-07-19 12:13:28 -07:00
parent f8b611fd4c
commit f9b9f9ab06
10 changed files with 146 additions and 102 deletions
@@ -1,6 +1,7 @@
import { closeAllModals, openModal } from '@mantine/modals';
import { useTranslation } from 'react-i18next';
import { UpdateAvailableButton } from '/@/renderer/features/settings/components/update-available-button';
import { useSettingSearchContext } from '/@/renderer/features/settings/context/search-context';
import { LibraryHeaderBar } from '/@/renderer/features/shared/components/library-header-bar';
import { SearchInput } from '/@/renderer/features/shared/components/search-input';
@@ -14,9 +15,10 @@ import { Text } from '/@/shared/components/text/text';
export type SettingsHeaderProps = {
setSearch: (search: string) => void;
showUpdateAvailable?: boolean;
};
export const SettingsHeader = ({ setSearch }: SettingsHeaderProps) => {
export const SettingsHeader = ({ setSearch, showUpdateAvailable }: SettingsHeaderProps) => {
const { t } = useTranslation();
const { reset } = useSettingsStoreActions();
const search = useSettingSearchContext();
@@ -48,6 +50,7 @@ export const SettingsHeader = ({ setSearch }: SettingsHeaderProps) => {
</LibraryHeaderBar.Title>
</Group>
<Group>
{showUpdateAvailable && <UpdateAvailableButton />}
<SearchInput
defaultValue={search}
onChange={(event) => setSearch(event.target.value.toLocaleLowerCase())}
@@ -9,7 +9,7 @@ export const SettingsContextModal = () => {
return (
<SettingSearchContext.Provider value={search}>
<SettingsHeader setSearch={setSearch} />
<SettingsHeader setSearch={setSearch} showUpdateAvailable />
<SettingsContent />
</SettingSearchContext.Provider>
);
@@ -0,0 +1,26 @@
import { useTranslation } from 'react-i18next';
import { toTag } from '/@/renderer/hooks';
import { useLatestVersion } from '/@/renderer/store';
import { Button } from '/@/shared/components/button/button';
export const UpdateAvailableButton = () => {
const { t } = useTranslation();
const { currentVersion, isUpdateAvailable, latestVersion } = useLatestVersion();
if (!isUpdateAvailable || !latestVersion) {
return null;
}
return (
<Button
component="a"
href={`https://github.com/jeffvli/feishin/releases/tag/${toTag(latestVersion || currentVersion)}`}
size="compact-sm"
target="_blank"
variant="filled"
>
{t('common.newVersionAvailable')}: v{latestVersion}
</Button>
);
};
@@ -4,11 +4,11 @@ import { Fragment, ReactNode } from 'react';
import { useTranslation } from 'react-i18next';
import { Link, useNavigate } from 'react-router';
import packageJson from '../../../../../package.json';
import styles from './app-menu.module.css';
import { isServerLock } from '/@/renderer/features/action-required/utils/window-properties';
import { ServerList } from '/@/renderer/features/servers/components/server-list';
import { UpdateAvailableButton } from '/@/renderer/features/settings/components/update-available-button';
import { openSettingsModal } from '/@/renderer/features/settings/utils/open-settings-modal';
import { ServerSelector } from '/@/renderer/features/sidebar/components/server-selector';
import { openReleaseNotesModal } from '/@/renderer/release-notes-modal';
@@ -18,10 +18,12 @@ import {
useCommandPalette,
useCurrentServer,
useGeneralSettings,
useLatestVersion,
useSettingsStoreActions,
} from '/@/renderer/store';
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
import { DropdownMenu, MenuItemProps } from '/@/shared/components/dropdown-menu/dropdown-menu';
import { Flex } from '/@/shared/components/flex/flex';
import { Group } from '/@/shared/components/group/group';
import { Icon } from '/@/shared/components/icon/icon';
import { toast } from '/@/shared/components/toast/toast';
@@ -138,6 +140,8 @@ export const AppMenu = () => {
});
};
const { currentVersion } = useLatestVersion();
const serverHeaderMenuItems: MenuItem[] = currentServer
? [
{
@@ -270,10 +274,10 @@ export const AppMenu = () => {
{
icon: 'brandGitHub',
id: 'version',
label: t('page.appMenu.version', { version: packageJson.version }),
label: t('page.appMenu.version', { version: currentVersion }),
onClick: () =>
openReleaseNotesModal(
t('common.newVersion', { version: packageJson.version }) as string,
t('common.newVersion', { version: currentVersion }) as string,
),
type: 'item',
},
@@ -301,6 +305,15 @@ export const AppMenu = () => {
},
type: 'conditional-item',
},
{
component: (
<Flex align="center" justify="center" w="100%">
<UpdateAvailableButton />
</Flex>
),
id: 'update-available',
type: 'custom',
},
{
id: 'divider-5',
type: 'divider',