From fe2dfc02c4cf24b036da72a83d1c88c70ca47d52 Mon Sep 17 00:00:00 2001 From: Egor Date: Sun, 7 Sep 2025 00:17:16 -0700 Subject: [PATCH] open all links in electron windows, minor refactors --- eslint.config.ts | 6 -- package.json | 3 +- src/components/ModelFileField.tsx | 7 ++- src/components/TitleBar.tsx | 10 +++- src/components/UpdateAvailableModal.tsx | 5 -- src/components/screens/Download.tsx | 6 +- src/components/settings/AboutTab.tsx | 7 +-- src/components/settings/GeneralTab.tsx | 16 ++--- src/components/settings/SettingsModal.tsx | 3 - src/components/settings/VersionsTab.tsx | 73 +++++++---------------- src/constants/patches.ts | 1 - src/hooks/useAppUpdateChecker.ts | 8 +-- src/hooks/useKoboldVersions.ts | 24 ++------ src/main/ipc.ts | 14 ----- src/main/managers/WindowManager.ts | 17 +----- src/preload/index.ts | 1 - src/types/electron.d.ts | 1 - yarn.lock | 10 ---- 18 files changed, 52 insertions(+), 160 deletions(-) diff --git a/eslint.config.ts b/eslint.config.ts index 3ab5089..7a2a225 100644 --- a/eslint.config.ts +++ b/eslint.config.ts @@ -3,7 +3,6 @@ import globals from 'globals'; import tseslint from '@typescript-eslint/eslint-plugin'; import tsParser from '@typescript-eslint/parser'; import reactHooks from 'eslint-plugin-react-hooks'; -import reactRefresh from 'eslint-plugin-react-refresh'; import react from 'eslint-plugin-react'; import importPlugin from 'eslint-plugin-import'; import sonarjs from 'eslint-plugin-sonarjs'; @@ -50,7 +49,6 @@ const config = [ plugins: { '@typescript-eslint': tseslint, 'react-hooks': reactHooks, - 'react-refresh': reactRefresh, react: react, import: importPlugin, sonarjs: sonarjs, @@ -80,10 +78,6 @@ const config = [ 'no-unused-vars': 'off', '@typescript-eslint/no-explicit-any': 'warn', - 'react-refresh/only-export-components': [ - 'warn', - { allowConstantExport: true }, - ], 'react/function-component-definition': [ 'error', { diff --git a/package.json b/package.json index bc107c8..0635450 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "gerbil", "productName": "Gerbil", - "version": "1.0.4", + "version": "1.0.5", "description": "Run Large Language Models locally", "main": "out/main/index.js", "homepage": "./", @@ -54,7 +54,6 @@ "eslint-plugin-no-comments": "^1.1.10", "eslint-plugin-react": "^7.37.5", "eslint-plugin-react-hooks": "^5.2.0", - "eslint-plugin-react-refresh": "^0.4.20", "eslint-plugin-sonarjs": "^3.0.5", "globals": "^16.3.0", "jiti": "^2.5.1", diff --git a/src/components/ModelFileField.tsx b/src/components/ModelFileField.tsx index 4a148b7..1f49813 100644 --- a/src/components/ModelFileField.tsx +++ b/src/components/ModelFileField.tsx @@ -57,9 +57,10 @@ export const ModelFileField = ({ {showSearchHF && ( + {latestRelease && ( + + + Latest release: {latestRelease.release.tag_name} + + + + Release notes + + + + + )} {allVersions.map((version, index) => { diff --git a/src/constants/patches.ts b/src/constants/patches.ts index e967945..8dcb60f 100644 --- a/src/constants/patches.ts +++ b/src/constants/patches.ts @@ -140,7 +140,6 @@ export const KLITE_AUTOSCROLL_PATCHES = ` const currentHeight = el.scrollHeight; const lastHeight = lastScrollHeights[id] || currentHeight; - // Calculate dynamic threshold based on recent growth const heightGrowth = Math.max(0, currentHeight - lastHeight); const dynamicThreshold = Math.min(Math.max(heightGrowth * 1.2, 30), 200); diff --git a/src/hooks/useAppUpdateChecker.ts b/src/hooks/useAppUpdateChecker.ts index 3fa568d..6f30f55 100644 --- a/src/hooks/useAppUpdateChecker.ts +++ b/src/hooks/useAppUpdateChecker.ts @@ -57,12 +57,6 @@ export const useAppUpdateChecker = () => { } }, []); - const openReleasePage = useCallback(() => { - if (updateInfo?.releaseUrl) { - window.electronAPI.app.openExternal(updateInfo.releaseUrl); - } - }, [updateInfo]); - useEffect(() => { checkForAppUpdates(); }, [checkForAppUpdates]); @@ -72,7 +66,7 @@ export const useAppUpdateChecker = () => { isChecking, lastChecked, checkForAppUpdates, - openReleasePage, + releaseUrl: updateInfo?.releaseUrl, hasUpdate: updateInfo?.hasUpdate || false, }; }; diff --git a/src/hooks/useKoboldVersions.ts b/src/hooks/useKoboldVersions.ts index 4017baa..846bff0 100644 --- a/src/hooks/useKoboldVersions.ts +++ b/src/hooks/useKoboldVersions.ts @@ -10,6 +10,7 @@ import type { GitHubAsset, InstalledVersion, } from '@/types/electron'; +import { sortDownloadsByType } from '@/utils/assets'; interface CachedReleaseData { releases: DownloadItem[]; @@ -137,15 +138,7 @@ interface UseKoboldVersionsReturn { loadingRemote: boolean; downloading: string | null; downloadProgress: Record; - loadRemoteVersions: () => Promise; - refresh: () => Promise; handleDownload: (params: HandleDownloadParams) => Promise; - setDownloading: (value: string | null) => void; - setDownloadProgress: ( - value: - | Record - | ((prev: Record) => Record) - ) => void; getLatestReleaseWithDownloadStatus: () => Promise; } @@ -186,7 +179,7 @@ export const useKoboldVersions = (): UseKoboldVersionsReturn => { if (rocm) { allDownloads.push(rocm); } - setAvailableDownloads(allDownloads); + setAvailableDownloads(sortDownloadsByType(allDownloads)); setLoadingRemote(false); return; } @@ -203,7 +196,7 @@ export const useKoboldVersions = (): UseKoboldVersionsReturn => { allDownloads.push(rocm); } - setAvailableDownloads(allDownloads); + setAvailableDownloads(sortDownloadsByType(allDownloads)); } catch (err) { error('Failed to load remote versions:', err as Error); const cached = loadFromCache(); @@ -213,7 +206,7 @@ export const useKoboldVersions = (): UseKoboldVersionsReturn => { if (rocm) { allDownloads.push(rocm); } - setAvailableDownloads(allDownloads); + setAvailableDownloads(sortDownloadsByType(allDownloads)); } } finally { setLoadingRemote(false); @@ -257,11 +250,6 @@ export const useKoboldVersions = (): UseKoboldVersionsReturn => { [] ); - const refresh = useCallback(async () => { - localStorage.removeItem(CACHE_KEY); - await loadRemoteVersions(); - }, [loadRemoteVersions]); - useEffect(() => { loadPlatform(); }, [loadPlatform]); @@ -296,11 +284,7 @@ export const useKoboldVersions = (): UseKoboldVersionsReturn => { loadingRemote, downloading, downloadProgress, - loadRemoteVersions, - refresh, handleDownload, - setDownloading, - setDownloadProgress, getLatestReleaseWithDownloadStatus, }; }; diff --git a/src/main/ipc.ts b/src/main/ipc.ts index 9717b65..49817b9 100644 --- a/src/main/ipc.ts +++ b/src/main/ipc.ts @@ -169,20 +169,6 @@ export class IPCHandlers { arch: process.arch, })); - ipcMain.handle('app:openExternal', async (_, url) => { - try { - await shell.openExternal(url); - } catch (error) { - this.logManager.logError( - 'Failed to open external URL:', - error as Error - ); - throw new Error( - `Failed to open external URL: ${(error as Error).message}` - ); - } - }); - ipcMain.handle('app:showLogsFolder', async () => { try { const logsDir = this.logManager.getLogsDirectory(); diff --git a/src/main/managers/WindowManager.ts b/src/main/managers/WindowManager.ts index ca772c5..18237d4 100644 --- a/src/main/managers/WindowManager.ts +++ b/src/main/managers/WindowManager.ts @@ -87,20 +87,9 @@ export class WindowManager { } }); - this.mainWindow.webContents.setWindowOpenHandler(({ url }) => { - const parsedUrl = new URL(url); - - if ( - parsedUrl.hostname === 'localhost' || - parsedUrl.hostname === '127.0.0.1' - ) { - return { action: 'allow' }; - } - - shell.openExternal(url); - - return { action: 'deny' }; - }); + this.mainWindow.webContents.setWindowOpenHandler(() => ({ + action: 'allow', + })); this.mainWindow.on('close', () => { app.quit(); diff --git a/src/preload/index.ts b/src/preload/index.ts index 4a21dbc..2c86052 100644 --- a/src/preload/index.ts +++ b/src/preload/index.ts @@ -76,7 +76,6 @@ const koboldAPI: KoboldAPI = { }; const appAPI: AppAPI = { - openExternal: (url) => ipcRenderer.invoke('app:openExternal', url), showLogsFolder: () => ipcRenderer.invoke('app:showLogsFolder'), getVersion: () => ipcRenderer.invoke('app:getVersion'), getVersionInfo: () => ipcRenderer.invoke('app:getVersionInfo'), diff --git a/src/types/electron.d.ts b/src/types/electron.d.ts index 8863f6a..6d19279 100644 --- a/src/types/electron.d.ts +++ b/src/types/electron.d.ts @@ -142,7 +142,6 @@ export interface VersionInfo { } export interface AppAPI { - openExternal: (url: string) => Promise; showLogsFolder: () => Promise; getVersion: () => Promise; getVersionInfo: () => Promise; diff --git a/yarn.lock b/yarn.lock index 3e3d585..09fb2de 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3083,15 +3083,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react-refresh@npm:^0.4.20": - version: 0.4.20 - resolution: "eslint-plugin-react-refresh@npm:0.4.20" - peerDependencies: - eslint: ">=8.40" - checksum: 10c0/2ccf4ba28f1dcbcb9e773e46eae1e61e568bba69281a700eb26fd762152e4e90a78c991f9c8173342a7cd2a82f3f52fedb40a1e81360cef9c40ea5b814fa3613 - languageName: node - linkType: hard - "eslint-plugin-react@npm:^7.37.5": version: 7.37.5 resolution: "eslint-plugin-react@npm:7.37.5" @@ -3654,7 +3645,6 @@ __metadata: eslint-plugin-no-comments: "npm:^1.1.10" eslint-plugin-react: "npm:^7.37.5" eslint-plugin-react-hooks: "npm:^5.2.0" - eslint-plugin-react-refresh: "npm:^0.4.20" eslint-plugin-sonarjs: "npm:^3.0.5" execa: "npm:^9.6.0" globals: "npm:^16.3.0"