mirror of
https://github.com/lone-cloud/gerbil
synced 2026-06-03 09:33:10 -07:00
better terminal transition, main window bg color based on theme preference, center the launched window on open
This commit is contained in:
parent
de0718b8ee
commit
a3a74af342
10 changed files with 159 additions and 51 deletions
20
src/App.tsx
20
src/App.tsx
|
|
@ -40,10 +40,6 @@ export const App = () => {
|
||||||
downloadProgress,
|
downloadProgress,
|
||||||
} = useKoboldVersions();
|
} = useKoboldVersions();
|
||||||
|
|
||||||
const setCurrentScreenWithTransition = (screen: Screen) => {
|
|
||||||
setCurrentScreen(screen);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const checkInstallation = async () => {
|
const checkInstallation = async () => {
|
||||||
await safeExecute(async () => {
|
await safeExecute(async () => {
|
||||||
|
|
@ -58,11 +54,11 @@ export const App = () => {
|
||||||
setFrontendPreference(preference || 'koboldcpp');
|
setFrontendPreference(preference || 'koboldcpp');
|
||||||
|
|
||||||
if (!hasSeenWelcome) {
|
if (!hasSeenWelcome) {
|
||||||
setCurrentScreenWithTransition('welcome');
|
setCurrentScreen('welcome');
|
||||||
} else if (currentVersion) {
|
} else if (currentVersion) {
|
||||||
setCurrentScreenWithTransition('launch');
|
setCurrentScreen('launch');
|
||||||
} else {
|
} else {
|
||||||
setCurrentScreenWithTransition('download');
|
setCurrentScreen('download');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentVersion) {
|
if (currentVersion) {
|
||||||
|
|
@ -99,17 +95,17 @@ export const App = () => {
|
||||||
}, 'Error refreshing versions after download:');
|
}, 'Error refreshing versions after download:');
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setCurrentScreenWithTransition('launch');
|
setCurrentScreen('launch');
|
||||||
}, 100);
|
}, 100);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleLaunch = () => {
|
const handleLaunch = () => {
|
||||||
setActiveInterfaceTab('terminal');
|
setActiveInterfaceTab('terminal');
|
||||||
setCurrentScreenWithTransition('interface');
|
setCurrentScreen('interface');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleBackToLaunch = () => {
|
const handleBackToLaunch = () => {
|
||||||
setCurrentScreenWithTransition('launch');
|
setCurrentScreen('launch');
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleEject = async () => {
|
const handleEject = async () => {
|
||||||
|
|
@ -141,9 +137,9 @@ export const App = () => {
|
||||||
|
|
||||||
const versions = await window.electronAPI.kobold.getInstalledVersions();
|
const versions = await window.electronAPI.kobold.getInstalledVersions();
|
||||||
if (versions.length > 0) {
|
if (versions.length > 0) {
|
||||||
setCurrentScreenWithTransition('launch');
|
setCurrentScreen('launch');
|
||||||
} else {
|
} else {
|
||||||
setCurrentScreenWithTransition('download');
|
setCurrentScreen('download');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,6 @@ import {
|
||||||
import {
|
import {
|
||||||
Box,
|
Box,
|
||||||
ScrollArea,
|
ScrollArea,
|
||||||
Text,
|
|
||||||
ActionIcon,
|
ActionIcon,
|
||||||
useComputedColorScheme,
|
useComputedColorScheme,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
|
|
@ -36,12 +35,21 @@ export const TerminalTab = forwardRef<TerminalTabRef, TerminalTabProps>(
|
||||||
const [terminalContent, setTerminalContent] = useState<string>('');
|
const [terminalContent, setTerminalContent] = useState<string>('');
|
||||||
const [isUserScrolling, setIsUserScrolling] = useState<boolean>(false);
|
const [isUserScrolling, setIsUserScrolling] = useState<boolean>(false);
|
||||||
const [shouldAutoScroll, setShouldAutoScroll] = useState<boolean>(true);
|
const [shouldAutoScroll, setShouldAutoScroll] = useState<boolean>(true);
|
||||||
|
const [isVisible, setIsVisible] = useState<boolean>(false);
|
||||||
const scrollAreaRef = useRef<HTMLDivElement>(null);
|
const scrollAreaRef = useRef<HTMLDivElement>(null);
|
||||||
const viewportRef = useRef<HTMLDivElement>(null);
|
const viewportRef = useRef<HTMLDivElement>(null);
|
||||||
const lastScrollTop = useRef<number>(0);
|
const lastScrollTop = useRef<number>(0);
|
||||||
|
|
||||||
const isDark = computedColorScheme === 'dark';
|
const isDark = computedColorScheme === 'dark';
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setIsVisible(true);
|
||||||
|
}, 150);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, []);
|
||||||
|
|
||||||
const handleScroll = ({ y }: { y: number }) => {
|
const handleScroll = ({ y }: { y: number }) => {
|
||||||
if (!viewportRef.current) return;
|
if (!viewportRef.current) return;
|
||||||
|
|
||||||
|
|
@ -143,29 +151,25 @@ export const TerminalTab = forwardRef<TerminalTabRef, TerminalTabProps>(
|
||||||
offsetScrollbars={false}
|
offsetScrollbars={false}
|
||||||
>
|
>
|
||||||
<Box p="md">
|
<Box p="md">
|
||||||
{terminalContent.length === 0 ? (
|
<div
|
||||||
<Text c="dimmed" style={{ fontFamily: 'inherit' }}>
|
style={{
|
||||||
Starting...
|
margin: 0,
|
||||||
</Text>
|
fontFamily:
|
||||||
) : (
|
'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
||||||
<div
|
fontSize: '0.875em',
|
||||||
style={{
|
lineHeight: 1.4,
|
||||||
margin: 0,
|
color: isDark
|
||||||
fontFamily:
|
? 'var(--mantine-color-gray-0)'
|
||||||
'ui-monospace, SFMono-Regular, "SF Mono", Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
: 'var(--mantine-color-dark-filled)',
|
||||||
fontSize: '0.875em',
|
whiteSpace: 'pre-wrap',
|
||||||
lineHeight: 1.4,
|
wordBreak: 'break-word',
|
||||||
color: isDark
|
opacity: isVisible ? 1 : 0,
|
||||||
? 'var(--mantine-color-gray-0)'
|
transition: 'opacity 0.2s ease-in-out',
|
||||||
: 'var(--mantine-color-dark-filled)',
|
}}
|
||||||
whiteSpace: 'pre-wrap',
|
dangerouslySetInnerHTML={{
|
||||||
wordBreak: 'break-word',
|
__html: processTerminalContent(terminalContent),
|
||||||
}}
|
}}
|
||||||
dangerouslySetInnerHTML={{
|
/>
|
||||||
__html: processTerminalContent(terminalContent),
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</Box>
|
</Box>
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@ import {
|
||||||
useComputedColorScheme,
|
useComputedColorScheme,
|
||||||
Slider,
|
Slider,
|
||||||
TextInput,
|
TextInput,
|
||||||
|
type MantineColorScheme,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { Sun, Moon, Monitor } from 'lucide-react';
|
import { Sun, Moon, Monitor } from 'lucide-react';
|
||||||
import { useState, useEffect } from 'react';
|
import { useState, useEffect } from 'react';
|
||||||
|
|
@ -32,19 +33,40 @@ export const AppearanceTab = () => {
|
||||||
);
|
);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const loadZoomLevel = async () => {
|
const loadSettings = async () => {
|
||||||
const currentZoom = await safeExecute(
|
const [currentZoom, savedColorScheme] = await Promise.all([
|
||||||
() => window.electronAPI.app.getZoomLevel(),
|
safeExecute(
|
||||||
'Failed to load zoom level:'
|
() => window.electronAPI.app.getZoomLevel(),
|
||||||
);
|
'Failed to load zoom level:'
|
||||||
|
),
|
||||||
|
safeExecute(
|
||||||
|
() => window.electronAPI.app.getColorScheme(),
|
||||||
|
'Failed to load color scheme:'
|
||||||
|
),
|
||||||
|
]);
|
||||||
|
|
||||||
if (typeof currentZoom === 'number') {
|
if (typeof currentZoom === 'number') {
|
||||||
setZoomLevel(currentZoom);
|
setZoomLevel(currentZoom);
|
||||||
setZoomPercentage(zoomLevelToPercentage(currentZoom).toString());
|
setZoomPercentage(zoomLevelToPercentage(currentZoom).toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (savedColorScheme && savedColorScheme !== colorScheme) {
|
||||||
|
setColorScheme(savedColorScheme as MantineColorScheme);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
void loadZoomLevel();
|
void loadSettings();
|
||||||
}, []);
|
}, [colorScheme, setColorScheme]);
|
||||||
|
|
||||||
|
const handleColorSchemeChange = async (value: string) => {
|
||||||
|
const newColorScheme = value as MantineColorScheme;
|
||||||
|
setColorScheme(newColorScheme);
|
||||||
|
|
||||||
|
await safeExecute(
|
||||||
|
() => window.electronAPI.app.setColorScheme(newColorScheme),
|
||||||
|
'Failed to save color scheme:'
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
const handleZoomChange = async (newZoomLevel: number) => {
|
const handleZoomChange = async (newZoomLevel: number) => {
|
||||||
setZoomLevel(newZoomLevel);
|
setZoomLevel(newZoomLevel);
|
||||||
|
|
@ -83,9 +105,7 @@ export const AppearanceTab = () => {
|
||||||
<SegmentedControl
|
<SegmentedControl
|
||||||
fullWidth
|
fullWidth
|
||||||
value={colorScheme}
|
value={colorScheme}
|
||||||
onChange={(value) =>
|
onChange={handleColorSchemeChange}
|
||||||
setColorScheme(value as 'light' | 'dark' | 'auto')
|
|
||||||
}
|
|
||||||
styles={(theme) => ({
|
styles={(theme) => ({
|
||||||
indicator: {
|
indicator: {
|
||||||
backgroundColor: isDark
|
backgroundColor: isDark
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import {
|
||||||
Select,
|
Select,
|
||||||
Box,
|
Box,
|
||||||
Anchor,
|
Anchor,
|
||||||
|
Badge,
|
||||||
} from '@mantine/core';
|
} from '@mantine/core';
|
||||||
import { Folder, FolderOpen, Monitor } from 'lucide-react';
|
import { Folder, FolderOpen, Monitor } from 'lucide-react';
|
||||||
import type { FrontendPreference } from '@/types';
|
import type { FrontendPreference } from '@/types';
|
||||||
|
|
@ -24,6 +25,7 @@ interface FrontendRequirement {
|
||||||
interface FrontendConfig {
|
interface FrontendConfig {
|
||||||
value: string;
|
value: string;
|
||||||
label: string;
|
label: string;
|
||||||
|
badges: string[];
|
||||||
requirements?: FrontendRequirement[];
|
requirements?: FrontendRequirement[];
|
||||||
requirementCheck?: () => Promise<boolean>;
|
requirementCheck?: () => Promise<boolean>;
|
||||||
}
|
}
|
||||||
|
|
@ -44,10 +46,15 @@ export const GeneralTab = ({
|
||||||
|
|
||||||
const frontendConfigs: FrontendConfig[] = useMemo(
|
const frontendConfigs: FrontendConfig[] = useMemo(
|
||||||
() => [
|
() => [
|
||||||
{ value: 'koboldcpp', label: 'Built-in Interface' },
|
{
|
||||||
|
value: 'koboldcpp',
|
||||||
|
label: 'Built-in Interface',
|
||||||
|
badges: ['Text', 'Image'],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
value: 'sillytavern',
|
value: 'sillytavern',
|
||||||
label: FRONTENDS.SILLYTAVERN,
|
label: FRONTENDS.SILLYTAVERN,
|
||||||
|
badges: ['Text', 'Image'],
|
||||||
requirements: [
|
requirements: [
|
||||||
{
|
{
|
||||||
id: 'nodejs',
|
id: 'nodejs',
|
||||||
|
|
@ -60,6 +67,7 @@ export const GeneralTab = ({
|
||||||
{
|
{
|
||||||
value: 'openwebui',
|
value: 'openwebui',
|
||||||
label: FRONTENDS.OPENWEBUI,
|
label: FRONTENDS.OPENWEBUI,
|
||||||
|
badges: ['Text'],
|
||||||
requirements: [
|
requirements: [
|
||||||
{
|
{
|
||||||
id: 'uv',
|
id: 'uv',
|
||||||
|
|
@ -186,6 +194,30 @@ export const GeneralTab = ({
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const renderSelectOption = ({
|
||||||
|
option,
|
||||||
|
}: {
|
||||||
|
option: { value: string; label: string; disabled?: boolean };
|
||||||
|
}) => {
|
||||||
|
const config = frontendConfigs.find((c) => c.value === option.value);
|
||||||
|
if (!config) return <Text>{option.label}</Text>;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Group justify="space-between" wrap="nowrap">
|
||||||
|
<Text size="sm" truncate c={option.disabled ? 'dimmed' : undefined}>
|
||||||
|
{config.label}
|
||||||
|
</Text>
|
||||||
|
<Group gap={4}>
|
||||||
|
{config.badges.map((badge) => (
|
||||||
|
<Badge key={badge} size="sm" variant="light" color="blue">
|
||||||
|
{badge}
|
||||||
|
</Badge>
|
||||||
|
))}
|
||||||
|
</Group>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Stack gap="lg" h="100%">
|
<Stack gap="lg" h="100%">
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -258,6 +290,7 @@ export const GeneralTab = ({
|
||||||
disabled: !isFrontendAvailable(config.value),
|
disabled: !isFrontendAvailable(config.value),
|
||||||
}))}
|
}))}
|
||||||
leftSection={<Monitor style={{ width: rem(16), height: rem(16) }} />}
|
leftSection={<Monitor style={{ width: rem(16), height: rem(16) }} />}
|
||||||
|
renderOption={renderSelectOption}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Box mt="sm">
|
<Box mt="sm">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { ipcMain, shell, app } from 'electron';
|
import { ipcMain, shell, app } from 'electron';
|
||||||
import * as os from 'os';
|
import * as os from 'os';
|
||||||
|
import type { MantineColorScheme } from '@mantine/core';
|
||||||
import {
|
import {
|
||||||
launchKoboldCpp,
|
launchKoboldCpp,
|
||||||
downloadRelease,
|
downloadRelease,
|
||||||
|
|
@ -19,6 +20,8 @@ import {
|
||||||
getSelectedConfig,
|
getSelectedConfig,
|
||||||
setSelectedConfig,
|
setSelectedConfig,
|
||||||
getInstallDir,
|
getInstallDir,
|
||||||
|
getColorScheme,
|
||||||
|
setColorScheme,
|
||||||
} from '@/main/modules/config';
|
} from '@/main/modules/config';
|
||||||
import { logError, getLogsDirectory } from '@/main/modules/logging';
|
import { logError, getLogsDirectory } from '@/main/modules/logging';
|
||||||
import { getSillyTavernManager } from '@/main/modules/sillytavern';
|
import { getSillyTavernManager } from '@/main/modules/sillytavern';
|
||||||
|
|
@ -198,6 +201,15 @@ export function setupIPCHandlers() {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
ipcMain.handle('app:getColorScheme', () => getColorScheme());
|
||||||
|
|
||||||
|
ipcMain.handle(
|
||||||
|
'app:setColorScheme',
|
||||||
|
async (_, colorScheme: MantineColorScheme) => {
|
||||||
|
await setColorScheme(colorScheme);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const mainWindow = getMainWindow();
|
const mainWindow = getMainWindow();
|
||||||
if (mainWindow) {
|
if (mainWindow) {
|
||||||
mainWindow.webContents.once('did-finish-load', async () => {
|
mainWindow.webContents.once('did-finish-load', async () => {
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,10 @@ import { logError } from '@/main/modules/logging';
|
||||||
import { readJsonFile, writeJsonFile } from '@/utils/fs';
|
import { readJsonFile, writeJsonFile } from '@/utils/fs';
|
||||||
import { getConfigDir } from '@/utils/path';
|
import { getConfigDir } from '@/utils/path';
|
||||||
import type { FrontendPreference } from '@/types';
|
import type { FrontendPreference } from '@/types';
|
||||||
|
import type { MantineColorScheme } from '@mantine/core';
|
||||||
import { homedir } from 'os';
|
import { homedir } from 'os';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import { nativeTheme } from 'electron';
|
||||||
import { PRODUCT_NAME } from '@/constants';
|
import { PRODUCT_NAME } from '@/constants';
|
||||||
|
|
||||||
type ConfigValue = string | number | boolean | unknown[] | undefined;
|
type ConfigValue = string | number | boolean | unknown[] | undefined;
|
||||||
|
|
@ -13,6 +15,7 @@ interface AppConfig {
|
||||||
currentKoboldBinary?: string;
|
currentKoboldBinary?: string;
|
||||||
selectedConfig?: string;
|
selectedConfig?: string;
|
||||||
frontendPreference?: FrontendPreference;
|
frontendPreference?: FrontendPreference;
|
||||||
|
colorScheme?: MantineColorScheme;
|
||||||
[key: string]: ConfigValue;
|
[key: string]: ConfigValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,3 +95,24 @@ export async function setSelectedConfig(configName: string) {
|
||||||
config.selectedConfig = configName;
|
config.selectedConfig = configName;
|
||||||
await saveConfig();
|
await saveConfig();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getColorScheme() {
|
||||||
|
return config.colorScheme || 'auto';
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setColorScheme(colorScheme: MantineColorScheme) {
|
||||||
|
config.colorScheme = colorScheme;
|
||||||
|
await saveConfig();
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getBackgroundColor(): string {
|
||||||
|
const colorScheme = getColorScheme();
|
||||||
|
|
||||||
|
if (colorScheme === 'light') {
|
||||||
|
return '#ffffff';
|
||||||
|
} else if (colorScheme === 'dark') {
|
||||||
|
return '#1a1b1e';
|
||||||
|
} else {
|
||||||
|
return nativeTheme.shouldUseDarkColors ? '#1a1b1e' : '#ffffff';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -642,7 +642,7 @@ export async function launchKoboldCpp(
|
||||||
|
|
||||||
koboldProcess = child;
|
koboldProcess = child;
|
||||||
|
|
||||||
const commandLine = `$ ${currentVersion.path} ${finalArgs.join(' ')}`;
|
const commandLine = `${currentVersion.path} ${finalArgs.join(' ')}`;
|
||||||
|
|
||||||
sendKoboldOutput(commandLine);
|
sendKoboldOutput(commandLine);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4,21 +4,29 @@ import { stripVTControlCharacters } from 'util';
|
||||||
import { PRODUCT_NAME } from '../../constants';
|
import { PRODUCT_NAME } from '../../constants';
|
||||||
import type { IPCChannel, IPCChannelPayloads } from '@/types/ipc';
|
import type { IPCChannel, IPCChannelPayloads } from '@/types/ipc';
|
||||||
import { isDevelopment } from '@/utils/environment';
|
import { isDevelopment } from '@/utils/environment';
|
||||||
|
import { getBackgroundColor } from './config';
|
||||||
|
|
||||||
let mainWindow: BrowserWindow | null = null;
|
let mainWindow: BrowserWindow | null = null;
|
||||||
|
|
||||||
export function createMainWindow() {
|
export function createMainWindow() {
|
||||||
const { size } = screen.getPrimaryDisplay();
|
const { size } = screen.getPrimaryDisplay();
|
||||||
const windowHeight = Math.floor(size.height * 0.86);
|
const windowHeight = Math.floor(size.height * 0.86);
|
||||||
|
const windowWidth = 800;
|
||||||
|
|
||||||
|
const icon = isDevelopment
|
||||||
|
? join(__dirname, '../../src/assets/icon.png')
|
||||||
|
: join(__dirname, '../../assets/icon.png');
|
||||||
|
|
||||||
mainWindow = new BrowserWindow({
|
mainWindow = new BrowserWindow({
|
||||||
width: 1000,
|
width: windowWidth,
|
||||||
height: windowHeight,
|
height: windowHeight,
|
||||||
|
x: Math.floor((size.width - windowWidth) / 2),
|
||||||
|
y: Math.floor((size.height - windowHeight) / 2),
|
||||||
frame: false,
|
frame: false,
|
||||||
title: PRODUCT_NAME,
|
title: PRODUCT_NAME,
|
||||||
show: false,
|
show: false,
|
||||||
backgroundColor: '#ffffff',
|
backgroundColor: getBackgroundColor(),
|
||||||
icon: join(__dirname, '../../src/assets/icon.png'),
|
icon,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
|
|
@ -60,6 +68,11 @@ export function createMainWindow() {
|
||||||
|
|
||||||
mainWindow.webContents.setWindowOpenHandler(() => ({
|
mainWindow.webContents.setWindowOpenHandler(() => ({
|
||||||
action: 'allow',
|
action: 'allow',
|
||||||
|
overrideBrowserWindowOptions: {
|
||||||
|
icon,
|
||||||
|
title: PRODUCT_NAME,
|
||||||
|
backgroundColor: getBackgroundColor(),
|
||||||
|
},
|
||||||
}));
|
}));
|
||||||
|
|
||||||
mainWindow.on('close', () => {
|
mainWindow.on('close', () => {
|
||||||
|
|
|
||||||
|
|
@ -84,6 +84,9 @@ const appAPI: AppAPI = {
|
||||||
closeWindow: () => ipcRenderer.invoke('app:closeWindow'),
|
closeWindow: () => ipcRenderer.invoke('app:closeWindow'),
|
||||||
getZoomLevel: () => ipcRenderer.invoke('app:getZoomLevel'),
|
getZoomLevel: () => ipcRenderer.invoke('app:getZoomLevel'),
|
||||||
setZoomLevel: (level) => ipcRenderer.invoke('app:setZoomLevel', level),
|
setZoomLevel: (level) => ipcRenderer.invoke('app:setZoomLevel', level),
|
||||||
|
getColorScheme: () => ipcRenderer.invoke('app:getColorScheme'),
|
||||||
|
setColorScheme: (colorScheme) =>
|
||||||
|
ipcRenderer.invoke('app:setColorScheme', colorScheme),
|
||||||
};
|
};
|
||||||
|
|
||||||
const configAPI: ConfigAPI = {
|
const configAPI: ConfigAPI = {
|
||||||
|
|
|
||||||
3
src/types/electron.d.ts
vendored
3
src/types/electron.d.ts
vendored
|
|
@ -5,6 +5,7 @@ import type {
|
||||||
GPUMemoryInfo,
|
GPUMemoryInfo,
|
||||||
} from '@/types/hardware';
|
} from '@/types/hardware';
|
||||||
import type { BackendOption, BackendSupport } from '@/types';
|
import type { BackendOption, BackendSupport } from '@/types';
|
||||||
|
import type { MantineColorScheme } from '@mantine/core';
|
||||||
|
|
||||||
export interface GitHubAsset {
|
export interface GitHubAsset {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -150,6 +151,8 @@ export interface AppAPI {
|
||||||
closeWindow: () => void;
|
closeWindow: () => void;
|
||||||
getZoomLevel: () => Promise<number>;
|
getZoomLevel: () => Promise<number>;
|
||||||
setZoomLevel: (level: number) => Promise<void>;
|
setZoomLevel: (level: number) => Promise<void>;
|
||||||
|
getColorScheme: () => Promise<MantineColorScheme>;
|
||||||
|
setColorScheme: (colorScheme: MantineColorScheme) => Promise<void>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ConfigAPI {
|
export interface ConfigAPI {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue