From 1ff27a893bf159956cf5a4aa8262044cec567a81 Mon Sep 17 00:00:00 2001 From: lone-cloud Date: Wed, 3 Sep 2025 20:40:38 -0700 Subject: [PATCH] minor improvements --- src/App.tsx | 17 ++--- src/components/CommandLineArgumentsModal.tsx | 4 +- src/components/EjectConfirmModal.tsx | 2 + src/components/TitleBar.tsx | 5 +- src/components/UpdateAvailableModal.tsx | 3 +- .../screens/Interface/TerminalTab.tsx | 2 +- src/components/screens/Launch/AdvancedTab.tsx | 9 +-- .../screens/Launch/CreateConfigModal.tsx | 2 + src/components/settings/SettingsModal.tsx | 12 +-- src/constants/index.ts | 9 +++ src/main/ipc.ts | 3 +- src/main/managers/KoboldCppManager.ts | 8 -- src/stores/modal.ts | 35 --------- src/utils/assets.ts | 74 +++++++++++++++++-- 14 files changed, 107 insertions(+), 78 deletions(-) delete mode 100644 src/stores/modal.ts diff --git a/src/App.tsx b/src/App.tsx index 1c5d3b5..a16fb82 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -12,7 +12,6 @@ import { TitleBar } from '@/components/TitleBar'; import { ErrorBoundary } from '@/components/ErrorBoundary'; import { useUpdateChecker } from '@/hooks/useUpdateChecker'; import { useKoboldVersions } from '@/hooks/useKoboldVersions'; -import { useModalStore } from '@/stores/modal'; import { safeExecute } from '@/utils/logger'; import { TITLEBAR_HEIGHT } from '@/constants'; import type { DownloadItem } from '@/types/electron'; @@ -25,8 +24,8 @@ export const App = () => { useState('terminal'); const [frontendPreference, setFrontendPreference] = useState('koboldcpp'); - - const { modals, setModalOpen } = useModalStore(); + const [settingsModalOpen, setSettingsModalOpen] = useState(false); + const [ejectConfirmModalOpen, setEjectConfirmModalOpen] = useState(false); const { updateInfo: binaryUpdateInfo, @@ -121,7 +120,7 @@ export const App = () => { if (skipEjectConfirmation) { performEject(); } else { - setModalOpen('ejectConfirm', true); + setEjectConfirmModalOpen(true); } }; @@ -158,7 +157,7 @@ export const App = () => { currentTab={activeInterfaceTab} onTabChange={setActiveInterfaceTab} onEject={handleEject} - onOpenSettings={() => setModalOpen('settings', true)} + onOpenSettings={() => setSettingsModalOpen(true)} frontendPreference={frontendPreference} /> @@ -225,9 +224,9 @@ export const App = () => { /> { - setModalOpen('settings', false); + setSettingsModalOpen(false); const preference = await safeExecute( () => window.electronAPI.config.get( @@ -240,8 +239,8 @@ export const App = () => { currentScreen={currentScreen || undefined} /> setModalOpen('ejectConfirm', false)} + opened={ejectConfirmModalOpen} + onClose={() => setEjectConfirmModalOpen(false)} onConfirm={handleEjectConfirm} /> diff --git a/src/components/CommandLineArgumentsModal.tsx b/src/components/CommandLineArgumentsModal.tsx index 7c17a68..44c9b86 100644 --- a/src/components/CommandLineArgumentsModal.tsx +++ b/src/components/CommandLineArgumentsModal.tsx @@ -1,3 +1,4 @@ +import { MODAL_STYLES_WITH_TITLEBAR } from '@/constants'; import { Modal, Text, @@ -549,7 +550,7 @@ export const CommandLineArgumentsModal = ({ > - + {arg.flag} {arg.aliases && @@ -609,6 +610,7 @@ export const CommandLineArgumentsModal = ({ title="Available Command Line Arguments" size="xl" centered + styles={MODAL_STYLES_WITH_TITLEBAR} > diff --git a/src/components/EjectConfirmModal.tsx b/src/components/EjectConfirmModal.tsx index cdec0c9..f678713 100644 --- a/src/components/EjectConfirmModal.tsx +++ b/src/components/EjectConfirmModal.tsx @@ -1,5 +1,6 @@ import { useState } from 'react'; import { Modal, Text, Group, Button, Checkbox, Stack } from '@mantine/core'; +import { MODAL_STYLES_WITH_TITLEBAR } from '@/constants'; interface EjectConfirmModalProps { opened: boolean; @@ -32,6 +33,7 @@ export const EjectConfirmModal = ({ centered closeOnClickOutside={false} closeOnEscape={false} + styles={MODAL_STYLES_WITH_TITLEBAR} > diff --git a/src/components/TitleBar.tsx b/src/components/TitleBar.tsx index 022c62a..1167715 100644 --- a/src/components/TitleBar.tsx +++ b/src/components/TitleBar.tsx @@ -18,7 +18,6 @@ import { import { useState } from 'react'; import { soundAssets, playSound, initializeAudio } from '@/utils/sounds'; import { useAppUpdateChecker } from '@/hooks/useAppUpdateChecker'; -import { useModalStore } from '@/stores/modal'; import { useLaunchConfigStore } from '@/stores/launchConfig'; import iconUrl from '/icon.png'; import { FRONTENDS, PRODUCT_NAME, TITLEBAR_HEIGHT } from '@/constants'; @@ -45,7 +44,6 @@ export const TitleBar = ({ getInitialValueInEffect: false, }); const { hasUpdate, openReleasePage } = useAppUpdateChecker(); - const { isAnyModalOpen } = useModalStore(); const { isImageGenerationMode } = useLaunchConfigStore(); const [logoClickCount, setLogoClickCount] = useState(0); const [isElephantMode, setIsElephantMode] = useState(false); @@ -106,8 +104,7 @@ export const TitleBar = ({ ? 'var(--mantine-color-dark-8)' : 'var(--mantine-color-gray-1)', borderBottom: '1px solid var(--mantine-color-default-border)', - WebkitAppRegion: - isAnyModalOpen() || isSelectOpen ? 'no-drag' : 'drag', + WebkitAppRegion: isSelectOpen ? 'no-drag' : 'drag', userSelect: 'none', position: 'relative', }} diff --git a/src/components/UpdateAvailableModal.tsx b/src/components/UpdateAvailableModal.tsx index cfac1e5..991afbf 100644 --- a/src/components/UpdateAvailableModal.tsx +++ b/src/components/UpdateAvailableModal.tsx @@ -13,7 +13,7 @@ import { Download, X, ExternalLink } from 'lucide-react'; import { useState } from 'react'; import type { InstalledVersion, DownloadItem } from '@/types/electron'; import { getDisplayNameFromPath } from '@/utils/version'; -import { GITHUB_API } from '@/constants'; +import { GITHUB_API, MODAL_STYLES_WITH_TITLEBAR } from '@/constants'; import { safeExecute } from '@/utils/logger'; interface UpdateAvailableModalProps { @@ -57,6 +57,7 @@ export const UpdateAvailableModal = ({ centered closeOnClickOutside={false} closeOnEscape={!isDownloading && !isUpdating} + styles={MODAL_STYLES_WITH_TITLEBAR} > diff --git a/src/components/screens/Interface/TerminalTab.tsx b/src/components/screens/Interface/TerminalTab.tsx index 5bbbf44..bd8c974 100644 --- a/src/components/screens/Interface/TerminalTab.tsx +++ b/src/components/screens/Interface/TerminalTab.tsx @@ -139,7 +139,7 @@ export const TerminalTab = ({ margin: 0, fontFamily: 'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace', - fontSize: '0.875rem', + fontSize: '0.875em', lineHeight: 1.4, color: isDark ? 'var(--mantine-color-gray-0)' diff --git a/src/components/screens/Launch/AdvancedTab.tsx b/src/components/screens/Launch/AdvancedTab.tsx index 975f7ab..45a4b0a 100644 --- a/src/components/screens/Launch/AdvancedTab.tsx +++ b/src/components/screens/Launch/AdvancedTab.tsx @@ -11,7 +11,6 @@ import { InfoTooltip } from '@/components/InfoTooltip'; import { CheckboxWithTooltip } from '@/components/CheckboxWithTooltip'; import { CommandLineArgumentsModal } from '@/components/CommandLineArgumentsModal'; import { useLaunchConfig } from '@/hooks/useLaunchConfig'; -import { useModalStore } from '@/stores/modal'; import { safeExecute } from '@/utils/logger'; export const AdvancedTab = () => { @@ -38,7 +37,7 @@ export const AdvancedTab = () => { handleMoecpuChange, handleMoeexpertsChange, } = useLaunchConfig(); - const { modals, setModalOpen } = useModalStore(); + const [commandLineModalOpen, setCommandLineModalOpen] = useState(false); const [backendSupport, setBackendSupport] = useState<{ noavx2: boolean; failsafe: boolean; @@ -222,7 +221,7 @@ export const AdvancedTab = () => { @@ -237,8 +236,8 @@ export const AdvancedTab = () => { setModalOpen('commandLineArguments', false)} + opened={commandLineModalOpen} + onClose={() => setCommandLineModalOpen(false)} onAddArgument={handleAddArgument} /> diff --git a/src/components/screens/Launch/CreateConfigModal.tsx b/src/components/screens/Launch/CreateConfigModal.tsx index 34699aa..2960df6 100644 --- a/src/components/screens/Launch/CreateConfigModal.tsx +++ b/src/components/screens/Launch/CreateConfigModal.tsx @@ -1,3 +1,4 @@ +import { MODAL_STYLES_WITH_TITLEBAR } from '@/constants'; import { Modal, TextInput, Group, Button, Stack } from '@mantine/core'; import { useState, useEffect } from 'react'; @@ -45,6 +46,7 @@ export const CreateConfigModal = ({ onClose={handleClose} title="Create New Configuration" size="sm" + styles={MODAL_STYLES_WITH_TITLEBAR} > - this.koboldManager.getCurrentInstallDir() + this.configManager.getInstallDir() ); ipcMain.handle('kobold:selectInstallDirectory', () => @@ -187,6 +187,7 @@ export class IPCHandlers { try { const logsDir = this.logManager.getLogsDirectory(); await shell.openPath(logsDir); + return { success: true }; } catch (error) { this.logManager.logError('Failed to open logs folder:', error as Error); throw new Error( diff --git a/src/main/managers/KoboldCppManager.ts b/src/main/managers/KoboldCppManager.ts index 2a62b16..78dd1dc 100644 --- a/src/main/managers/KoboldCppManager.ts +++ b/src/main/managers/KoboldCppManager.ts @@ -531,14 +531,6 @@ export class KoboldCppManager { } } - getCurrentInstallDir() { - return this.configManager.getInstallDir(); - } - - getWindowManager() { - return this.windowManager; - } - async selectInstallDirectory(): Promise { const result = await dialog.showOpenDialog({ properties: ['openDirectory', 'createDirectory'], diff --git a/src/stores/modal.ts b/src/stores/modal.ts deleted file mode 100644 index a9ad9e6..0000000 --- a/src/stores/modal.ts +++ /dev/null @@ -1,35 +0,0 @@ -import { create } from 'zustand'; - -interface ModalState { - modals: { - settings: boolean; - ejectConfirm: boolean; - updateAvailable: boolean; - commandLineArguments: boolean; - }; - setModalOpen: ( - modalName: keyof ModalState['modals'], - isOpen: boolean - ) => void; - isAnyModalOpen: () => boolean; -} - -export const useModalStore = create((set, get) => ({ - modals: { - settings: false, - ejectConfirm: false, - updateAvailable: false, - commandLineArguments: false, - }, - setModalOpen: (modalName, isOpen) => - set((state) => ({ - modals: { - ...state.modals, - [modalName]: isOpen, - }, - })), - isAnyModalOpen: () => { - const { modals } = get(); - return Object.values(modals).some(Boolean); - }, -})); diff --git a/src/utils/assets.ts b/src/utils/assets.ts index 1d6c095..985e07f 100644 --- a/src/utils/assets.ts +++ b/src/utils/assets.ts @@ -54,11 +54,69 @@ export const sortDownloadsByType = ( return a.name.localeCompare(b.name); }); -export const pretifyBinName = (binName: string) => - binName - .replace('koboldcpp-', '') - .replace('-x64', ' (x64) ') - .replace(' -', ' ') - .replace('rocm', '- ROCm') - .replace('nocuda', '- NoCUDA') - .replace('oldpc', '- OldPC'); +export const pretifyBinName = (binName: string): string => { + const cleanName = stripAssetExtensions(binName); + + let name = cleanName.replace(/^koboldcpp[-_]?/, ''); + + if (!name) { + return 'Windows (x64)'; + } + + const platforms = { + linux: 'Linux', + mac: 'macOS', + }; + + const architectures = { + x64: 'x64', + arm64: 'ARM64', + }; + + const variants = { + rocm: 'ROCm', + nocuda: 'NoCUDA', + oldpc: 'OldPC', + }; + + const parts: string[] = []; + let workingName = name.toLowerCase(); + + let platform = ''; + for (const [key, value] of Object.entries(platforms)) { + if (workingName.includes(key)) { + platform = value; + workingName = workingName.replace(key, '').replace(/^-+|-+$/g, ''); + break; + } + } + + let arch = ''; + for (const [key, value] of Object.entries(architectures)) { + if (workingName.includes(key)) { + arch = value; + workingName = workingName.replace(key, '').replace(/^-+|-+$/g, ''); + break; + } + } + + const foundVariants: string[] = []; + for (const [key, value] of Object.entries(variants)) { + if (workingName.includes(key)) { + foundVariants.push(value); + workingName = workingName.replace(key, '').replace(/^-+|-+$/g, ''); + } + } + + if (platform) parts.push(platform); + if (arch) parts.push(`(${arch})`); + if (foundVariants.length > 0) { + parts.push(`- ${foundVariants.join(', ')}`); + } + + if (parts.length === 0) { + return cleanName.replace('koboldcpp-', '').replace(/^-+/, '') || 'Standard'; + } + + return parts.join(' '); +};