update
This commit is contained in:
@@ -23,14 +23,16 @@
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
import {FluentProvider, Tab, TabList, webDarkTheme} from '@fluentui/react-components';
|
||||
import {FluentProvider, Tab, TabList, webDarkTheme, webLightTheme} from '@fluentui/react-components';
|
||||
import {FC, useEffect, useState} from 'react';
|
||||
import {Route, Routes, useLocation, useNavigate} from 'react-router';
|
||||
import {pages} from './pages';
|
||||
import {useMediaQuery} from 'usehooks-ts';
|
||||
import {ToastContainer} from 'react-toastify';
|
||||
import commonStore from './stores/commonStore';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
|
||||
const App: FC = () => {
|
||||
const App: FC = observer(() => {
|
||||
const navigate = useNavigate();
|
||||
const location = useLocation();
|
||||
const mq = useMediaQuery('(min-width: 640px)');
|
||||
@@ -43,7 +45,7 @@ const App: FC = () => {
|
||||
useEffect(() => setPath(location.pathname), [location]);
|
||||
|
||||
return (
|
||||
<FluentProvider theme={webDarkTheme} className="h-screen">
|
||||
<FluentProvider theme={commonStore.settings.darkMode ? webDarkTheme : webLightTheme} className="h-screen">
|
||||
<div className="flex h-full">
|
||||
<div className="flex flex-col w-16 sm:w-48 p-2 justify-between">
|
||||
<TabList
|
||||
@@ -93,10 +95,10 @@ const App: FC = () => {
|
||||
rtl={false}
|
||||
pauseOnFocusLoss={false}
|
||||
draggable={false}
|
||||
theme={'dark'}
|
||||
theme={commonStore.settings.darkMode ? 'dark' : 'light'}
|
||||
/>
|
||||
</FluentProvider>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default App;
|
||||
|
||||
@@ -1,9 +1,21 @@
|
||||
import {FC, ReactElement} from 'react';
|
||||
import {Label, Tooltip} from '@fluentui/react-components';
|
||||
|
||||
export const Labeled: FC<{ label: string; desc?: string, content: ReactElement }> = ({label, desc, content}) => {
|
||||
export const Labeled: FC<{
|
||||
label: string; desc?: string, content: ReactElement, flex?: boolean, spaceBetween?: boolean
|
||||
}> = ({
|
||||
label,
|
||||
desc,
|
||||
content,
|
||||
flex,
|
||||
spaceBetween
|
||||
}) => {
|
||||
return (
|
||||
<div className="grid grid-cols-2 items-center">
|
||||
<div className={
|
||||
(flex ? 'flex' : 'grid grid-cols-2') + ' ' +
|
||||
(spaceBetween ? 'justify-between' : '') + ' ' +
|
||||
'items-center'
|
||||
}>
|
||||
{desc ?
|
||||
<Tooltip content={desc} showDelay={0} hideDelay={0} relationship="description">
|
||||
<Label>{label}</Label>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import React, {FC, ReactElement} from 'react';
|
||||
import {Divider, Text} from '@fluentui/react-components';
|
||||
|
||||
export const Page: FC<{ title: string; content: ReactElement }> = ({title, content = true}) => {
|
||||
export const Page: FC<{ title: string; content: ReactElement }> = ({title, content}) => {
|
||||
return (
|
||||
<div className="flex flex-col gap-2 p-2 h-full">
|
||||
<Text size={600}>{title}</Text>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import React, {FC} from 'react';
|
||||
import {Text} from '@fluentui/react-components';
|
||||
import {Page} from '../components/Page';
|
||||
import {PresenceBadge} from '@fluentui/react-components';
|
||||
|
||||
export const Chat: FC = () => {
|
||||
return (
|
||||
<div className="flex flex-col box-border gap-5 p-2">
|
||||
<Text size={600}>In Development</Text>
|
||||
</div>
|
||||
<Page title="Chat" content={
|
||||
<div className="flex flex-col gap-2 overflow-hidden">
|
||||
<PresenceBadge/>
|
||||
</div>
|
||||
}/>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ import {DownloadFile, OpenFileFolder} from '../../wailsjs/go/backend_golang/App'
|
||||
import manifest from '../../../manifest.json';
|
||||
import {toast} from 'react-toastify';
|
||||
import {Page} from '../components/Page';
|
||||
import {refreshModels} from '../utils';
|
||||
import {refreshModels, saveConfigs} from '../utils';
|
||||
|
||||
const columns: TableColumnDefinition<ModelSourceItem>[] = [
|
||||
createTableColumn<ModelSourceItem>({
|
||||
@@ -134,6 +134,7 @@ export const Models: FC = observer(() => {
|
||||
<Text weight="medium">Model Source Manifest List</Text>
|
||||
<ToolTipButton desc="Refresh" icon={<ArrowClockwise20Regular/>} onClick={() => {
|
||||
refreshModels(false);
|
||||
saveConfigs();
|
||||
}}/>
|
||||
</div>
|
||||
<Text size={100}>
|
||||
|
||||
@@ -1,10 +1,40 @@
|
||||
import React, {FC} from 'react';
|
||||
import {Text} from '@fluentui/react-components';
|
||||
import {Page} from '../components/Page';
|
||||
import {Dropdown, Option, Switch} from '@fluentui/react-components';
|
||||
import {Labeled} from '../components/Labeled';
|
||||
import commonStore from '../stores/commonStore';
|
||||
import {observer} from 'mobx-react-lite';
|
||||
|
||||
export const Settings: FC = () => {
|
||||
export const Settings: FC = observer(() => {
|
||||
return (
|
||||
<div className="flex flex-col box-border gap-5 p-2">
|
||||
<Text size={600}>In Development</Text>
|
||||
</div>
|
||||
<Page title="Settings" content={
|
||||
<div className="flex flex-col gap-2 overflow-hidden">
|
||||
<Labeled label="Language" flex spaceBetween content={
|
||||
<Dropdown style={{minWidth: 0}} listbox={{style: {minWidth: 0}}}
|
||||
value="English"
|
||||
selectedOptions={['English']}
|
||||
onOptionSelect={(_, data) => {
|
||||
if (data.optionText) {
|
||||
}
|
||||
}}>
|
||||
<Option>English</Option>
|
||||
<Option>简体中文</Option>
|
||||
</Dropdown>
|
||||
}/>
|
||||
<Labeled label="Dark Mode" flex spaceBetween content={
|
||||
<Switch checked={commonStore.settings.darkMode}
|
||||
onChange={(e, data) => {
|
||||
commonStore.setSettings({
|
||||
darkMode: data.checked
|
||||
});
|
||||
}}/>
|
||||
}/>
|
||||
<Labeled label="Automatic Updates Check" flex spaceBetween content={
|
||||
<Switch checked={commonStore.settings.autoUpdatesCheck}
|
||||
onChange={(e, data) => {
|
||||
}}/>
|
||||
}/>
|
||||
</div>
|
||||
}/>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
@@ -11,6 +11,10 @@ async function initConfig() {
|
||||
await ReadJson('config.json').then((configData: LocalConfig) => {
|
||||
if (configData.modelSourceManifestList)
|
||||
commonStore.setModelSourceManifestList(configData.modelSourceManifestList);
|
||||
|
||||
if (configData.settings)
|
||||
commonStore.setSettings(configData.settings, false);
|
||||
|
||||
if (configData.modelConfigs && Array.isArray(configData.modelConfigs))
|
||||
commonStore.setModelConfigs(configData.modelConfigs, false);
|
||||
else throw new Error('Invalid config.json');
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import {makeAutoObservable} from 'mobx';
|
||||
import {saveConfigs} from '../utils';
|
||||
import {getNavigatorLanguage, isSystemLightMode, saveConfigs, Settings} from '../utils';
|
||||
import {WindowSetDarkTheme, WindowSetLightTheme} from '../../wailsjs/runtime';
|
||||
|
||||
export enum ModelStatus {
|
||||
Offline,
|
||||
@@ -82,6 +83,11 @@ class CommonStore {
|
||||
modelConfigs: ModelConfig[] = [];
|
||||
modelSourceManifestList: string = 'https://cdn.jsdelivr.net/gh/josstorer/RWKV-Runner/manifest.json;';
|
||||
modelSourceList: ModelSourceItem[] = [];
|
||||
settings: Settings = {
|
||||
language: getNavigatorLanguage(),
|
||||
darkMode: !isSystemLightMode(),
|
||||
autoUpdatesCheck: true
|
||||
};
|
||||
|
||||
getCurrentModelConfig = () => {
|
||||
return this.modelConfigs[this.currentModelConfigIndex];
|
||||
@@ -139,6 +145,18 @@ class CommonStore {
|
||||
setModelSourceList = (value: ModelSourceItem[]) => {
|
||||
this.modelSourceList = value;
|
||||
};
|
||||
|
||||
setSettings = (value: Partial<Settings>, saveConfig: boolean = true) => {
|
||||
this.settings = {...this.settings, ...value};
|
||||
|
||||
if (this.settings.darkMode)
|
||||
WindowSetDarkTheme();
|
||||
else
|
||||
WindowSetLightTheme();
|
||||
|
||||
if (saveConfig)
|
||||
saveConfigs();
|
||||
};
|
||||
}
|
||||
|
||||
export default new CommonStore();
|
||||
@@ -6,10 +6,17 @@ export type Cache = {
|
||||
models: ModelSourceItem[]
|
||||
}
|
||||
|
||||
export type Settings = {
|
||||
language: string,
|
||||
darkMode: boolean
|
||||
autoUpdatesCheck: boolean
|
||||
}
|
||||
|
||||
export type LocalConfig = {
|
||||
modelSourceManifestList: string
|
||||
currentModelConfigIndex: number
|
||||
modelConfigs: ModelConfig[]
|
||||
settings: Settings
|
||||
}
|
||||
|
||||
export async function refreshBuiltInModels(readCache: boolean = false) {
|
||||
@@ -122,7 +129,8 @@ export const saveConfigs = async () => {
|
||||
const data: LocalConfig = {
|
||||
modelSourceManifestList: commonStore.modelSourceManifestList,
|
||||
currentModelConfigIndex: commonStore.currentModelConfigIndex,
|
||||
modelConfigs: commonStore.modelConfigs
|
||||
modelConfigs: commonStore.modelConfigs,
|
||||
settings: commonStore.settings
|
||||
};
|
||||
return SaveJson('config.json', data);
|
||||
};
|
||||
@@ -132,4 +140,14 @@ export const saveCache = async () => {
|
||||
models: commonStore.modelSourceList
|
||||
};
|
||||
return SaveJson('cache.json', data);
|
||||
};
|
||||
};
|
||||
|
||||
export function getNavigatorLanguage() {
|
||||
// const l = navigator.language.toLowerCase();
|
||||
// if (['zh-hk', 'zh-mo', 'zh-tw', 'zh-cht', 'zh-hant'].includes(l)) return 'zhHant'
|
||||
return navigator.language.substring(0, 2);
|
||||
}
|
||||
|
||||
export function isSystemLightMode() {
|
||||
return window.matchMedia && window.matchMedia('(prefers-color-scheme: light)').matches;
|
||||
}
|
||||
Reference in New Issue
Block a user