This commit is contained in:
josc146
2023-05-17 23:27:52 +08:00
parent df8eef5f64
commit 00257f2e68
15 changed files with 160 additions and 35 deletions

View File

@@ -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;

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>
}/>
);
};

View File

@@ -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}>

View File

@@ -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>
}/>
);
};
});

View File

@@ -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');

View File

@@ -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();

View File

@@ -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;
}

View File

@@ -19,3 +19,5 @@ export function ReadJson(arg1:string):Promise<any>;
export function SaveJson(arg1:string,arg2:any):Promise<void>;
export function StartServer(arg1:number):Promise<string>;
export function UpdateApp(arg1:string):Promise<boolean>;

View File

@@ -37,3 +37,7 @@ export function SaveJson(arg1, arg2) {
export function StartServer(arg1) {
return window['go']['backend_golang']['App']['StartServer'](arg1);
}
export function UpdateApp(arg1) {
return window['go']['backend_golang']['App']['UpdateApp'](arg1);
}