diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index a4d225d..5894033 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -23,18 +23,18 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -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 { 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'; -import {useTranslation} from 'react-i18next'; +import { observer } from 'mobx-react-lite'; +import { useTranslation } from 'react-i18next'; const App: FC = observer(() => { - const {t} = useTranslation(); + const { t } = useTranslation(); const navigate = useNavigate(); const location = useLocation(); const mq = useMediaQuery('(min-width: 640px)'); @@ -42,24 +42,24 @@ const App: FC = observer(() => { const [path, setPath] = useState(pages[0].path); const selectTab = (selectedPath: unknown) => - typeof selectedPath === 'string' ? navigate({pathname: selectedPath}) : null; + typeof selectedPath === 'string' ? navigate({ pathname: selectedPath }) : null; useEffect(() => setPath(location.pathname), [location]); return ( + theme={commonStore.settings.darkMode ? webDarkTheme : webLightTheme} + data-theme={commonStore.settings.darkMode ? 'dark' : 'light'}>
selectTab(value)} + onTabSelect={(_, { value }) => selectTab(value)} vertical > - {pages.filter(page => page.top).map(({label, path, icon}, index) => ( + {pages.filter(page => page.top).map(({ label, path, icon }, index) => ( {mq && t(label)} @@ -69,10 +69,10 @@ const App: FC = observer(() => { size="large" appearance="subtle" selectedValue={path} - onTabSelect={(_, {value}) => selectTab(value)} + onTabSelect={(_, { value }) => selectTab(value)} vertical > - {pages.filter(page => !page.top).map(({label, path, icon}, index) => ( + {pages.filter(page => !page.top).map(({ label, path, icon }, index) => ( {mq && t(label)} @@ -81,8 +81,8 @@ const App: FC = observer(() => {
- {pages.map(({path, element}, index) => ( - + {pages.map(({ path, element }, index) => ( + ))}
diff --git a/frontend/src/_locales/i18n-react.ts b/frontend/src/_locales/i18n-react.ts index 8e6d557..a04e279 100644 --- a/frontend/src/_locales/i18n-react.ts +++ b/frontend/src/_locales/i18n-react.ts @@ -1,7 +1,7 @@ -import i18n, {changeLanguage} from 'i18next'; -import {initReactI18next} from 'react-i18next'; -import {resources} from './resources'; -import {getUserLanguage} from '../utils'; +import i18n, { changeLanguage } from 'i18next'; +import { initReactI18next } from 'react-i18next'; +import { resources } from './resources'; +import { getUserLanguage } from '../utils'; i18n.use(initReactI18next).init({ resources, diff --git a/frontend/src/_locales/i18n.ts b/frontend/src/_locales/i18n.ts index a5c5e4e..dc30d1b 100644 --- a/frontend/src/_locales/i18n.ts +++ b/frontend/src/_locales/i18n.ts @@ -1,6 +1,6 @@ -import i18n, {changeLanguage} from 'i18next'; -import {resources} from './resources'; -import {getUserLanguage} from '../utils'; +import i18n, { changeLanguage } from 'i18next'; +import { resources } from './resources'; +import { getUserLanguage } from '../utils'; i18n.init({ resources diff --git a/frontend/src/_locales/resources.ts b/frontend/src/_locales/resources.ts index bd327d2..073cb6b 100644 --- a/frontend/src/_locales/resources.ts +++ b/frontend/src/_locales/resources.ts @@ -1,4 +1,4 @@ -import zhHans from './zh-hans/main.json' +import zhHans from './zh-hans/main.json'; export const resources = { zh: { @@ -34,4 +34,4 @@ export const resources = { // zhHant: { // translation: zhHant, // }, -} +}; diff --git a/frontend/src/apis/index.ts b/frontend/src/apis/index.ts index 72d0c1a..52148dd 100644 --- a/frontend/src/apis/index.ts +++ b/frontend/src/apis/index.ts @@ -1,4 +1,4 @@ -import commonStore, {ModelStatus} from '../stores/commonStore'; +import commonStore, { ModelStatus } from '../stores/commonStore'; export const readRoot = async () => { const port = commonStore.getCurrentModelConfig().apiParameters.apiPort; @@ -11,7 +11,7 @@ export const exit = async (timeout?: number) => { setTimeout(() => controller.abort(), timeout); const port = commonStore.getCurrentModelConfig().apiParameters.apiPort; - return fetch(`http://127.0.0.1:${port}/exit`, {method: 'POST', signal: controller.signal}); + return fetch(`http://127.0.0.1:${port}/exit`, { method: 'POST', signal: controller.signal }); }; export const switchModel = async (body: any) => { @@ -43,7 +43,7 @@ export const getStatus = async (timeout?: number): Promise r.json()).then(data => { + await fetch(`http://127.0.0.1:${port}/status`, { signal: controller.signal }).then(r => r.json()).then(data => { ret = data.status; }).catch(() => { }); diff --git a/frontend/src/components/ConfigSelector.tsx b/frontend/src/components/ConfigSelector.tsx index b916ad5..59f905f 100644 --- a/frontend/src/components/ConfigSelector.tsx +++ b/frontend/src/components/ConfigSelector.tsx @@ -1,16 +1,16 @@ -import {FC} from 'react'; -import {observer} from 'mobx-react-lite'; -import {Dropdown, Option} from '@fluentui/react-components'; +import { FC } from 'react'; +import { observer } from 'mobx-react-lite'; +import { Dropdown, Option } from '@fluentui/react-components'; import commonStore from '../stores/commonStore'; -export const ConfigSelector: FC<{ size?: 'small' | 'medium' | 'large' }> = observer(({size}) => { - return { - if (data.optionValue) - commonStore.setCurrentConfigIndex(Number(data.optionValue)); - }}> +export const ConfigSelector: FC<{ size?: 'small' | 'medium' | 'large' }> = observer(({ size }) => { + return { + if (data.optionValue) + commonStore.setCurrentConfigIndex(Number(data.optionValue)); + }}> {commonStore.modelConfigs.map((config, index) => )} diff --git a/frontend/src/components/CopyButton.tsx b/frontend/src/components/CopyButton.tsx index 74abc24..71a2ea6 100644 --- a/frontend/src/components/CopyButton.tsx +++ b/frontend/src/components/CopyButton.tsx @@ -1,25 +1,25 @@ -import {FC, useState} from 'react'; -import {CheckIcon, CopyIcon} from '@primer/octicons-react'; -import {useTranslation} from 'react-i18next'; -import {ClipboardSetText} from '../../wailsjs/runtime'; -import {ToolTipButton} from './ToolTipButton'; +import { FC, useState } from 'react'; +import { CheckIcon, CopyIcon } from '@primer/octicons-react'; +import { useTranslation } from 'react-i18next'; +import { ClipboardSetText } from '../../wailsjs/runtime'; +import { ToolTipButton } from './ToolTipButton'; -export const CopyButton: FC<{ content: string }> = ({content}) => { - const {t} = useTranslation(); +export const CopyButton: FC<{ content: string }> = ({ content }) => { + const { t } = useTranslation(); const [copied, setCopied] = useState(false); const onClick = () => { ClipboardSetText(content) - .then(() => setCopied(true)) - .then(() => - setTimeout(() => { - setCopied(false); - }, 600) - ); + .then(() => setCopied(true)) + .then(() => + setTimeout(() => { + setCopied(false); + }, 600) + ); }; return ( - : } - onClick={onClick}/> + : } + onClick={onClick} /> ); }; diff --git a/frontend/src/components/Labeled.tsx b/frontend/src/components/Labeled.tsx index ffbfd22..483bc6a 100644 --- a/frontend/src/components/Labeled.tsx +++ b/frontend/src/components/Labeled.tsx @@ -1,16 +1,16 @@ -import {FC, ReactElement} from 'react'; -import {Label, Tooltip} from '@fluentui/react-components'; +import { FC, ReactElement } from 'react'; +import { Label, Tooltip } from '@fluentui/react-components'; import classnames from 'classnames'; export const Labeled: FC<{ label: string; desc?: string | null, content: ReactElement, flex?: boolean, spaceBetween?: boolean }> = ({ - label, - desc, - content, - flex, - spaceBetween - }) => { + label, + desc, + content, + flex, + spaceBetween +}) => { return (
= ({href, children}) => { +const Hyperlink: FC = ({ href, children }) => { return ( { BrowserOpenURL(href); }} diff --git a/frontend/src/components/NumberInput.tsx b/frontend/src/components/NumberInput.tsx index c5d99da..4a4e841 100644 --- a/frontend/src/components/NumberInput.tsx +++ b/frontend/src/components/NumberInput.tsx @@ -1,6 +1,6 @@ -import React, {CSSProperties, FC} from 'react'; -import {Input} from '@fluentui/react-components'; -import {SliderOnChangeData} from '@fluentui/react-slider'; +import React, { CSSProperties, FC } from 'react'; +import { Input } from '@fluentui/react-components'; +import { SliderOnChangeData } from '@fluentui/react-slider'; export const NumberInput: FC<{ value: number, @@ -9,23 +9,23 @@ export const NumberInput: FC<{ step?: number, onChange?: (ev: React.ChangeEvent, data: SliderOnChangeData) => void style?: CSSProperties -}> = ({value, min, max, step, onChange, style}) => { +}> = ({ value, min, max, step, onChange, style }) => { return ( { - onChange?.(e, {value: Number(data.value)}); - }} - onBlur={(e) => { - if (onChange) { - if (step) { - const offset = (min > 0 ? min : 0) - (max < 0 ? max : 0); - value = Number((( - Math.round((value - offset) / step) * step) - + offset) - .toFixed(2)); // avoid precision issues - } - onChange(e, {value: Math.max(Math.min(value, max), min)}); - } - }}/> + onChange={(e, data) => { + onChange?.(e, { value: Number(data.value) }); + }} + onBlur={(e) => { + if (onChange) { + if (step) { + const offset = (min > 0 ? min : 0) - (max < 0 ? max : 0); + value = Number((( + Math.round((value - offset) / step) * step) + + offset) + .toFixed(2)); // avoid precision issues + } + onChange(e, { value: Math.max(Math.min(value, max), min) }); + } + }} /> ); }; diff --git a/frontend/src/components/Page.tsx b/frontend/src/components/Page.tsx index 5f55c92..f835a24 100644 --- a/frontend/src/components/Page.tsx +++ b/frontend/src/components/Page.tsx @@ -1,11 +1,11 @@ -import React, {FC, ReactElement} from 'react'; -import {Divider, Text} from '@fluentui/react-components'; +import React, { FC, ReactElement } from 'react'; +import { Divider, Text } from '@fluentui/react-components'; -export const Page: FC<{ title: string; content: ReactElement }> = ({title, content}) => { +export const Page: FC<{ title: string; content: ReactElement }> = ({ title, content }) => { return (
{title} - + {content}
); diff --git a/frontend/src/components/ReadButton.tsx b/frontend/src/components/ReadButton.tsx index 9a2f7ea..fe95bf6 100644 --- a/frontend/src/components/ReadButton.tsx +++ b/frontend/src/components/ReadButton.tsx @@ -1,14 +1,14 @@ -import {FC, useState} from 'react'; -import {MuteIcon, UnmuteIcon} from '@primer/octicons-react'; -import {useTranslation} from 'react-i18next'; -import {ToolTipButton} from './ToolTipButton'; +import { FC, useState } from 'react'; +import { MuteIcon, UnmuteIcon } from '@primer/octicons-react'; +import { useTranslation } from 'react-i18next'; +import { ToolTipButton } from './ToolTipButton'; import commonStore from '../stores/commonStore'; -import {observer} from 'mobx-react-lite'; +import { observer } from 'mobx-react-lite'; const synth = window.speechSynthesis; -export const ReadButton: FC<{ content: string }> = observer(({content}) => { - const {t} = useTranslation(); +export const ReadButton: FC<{ content: string }> = observer(({ content }) => { + const { t } = useTranslation(); const [speaking, setSpeaking] = useState(false); let lang: string = commonStore.settings.language; if (lang === 'dev') @@ -46,7 +46,8 @@ export const ReadButton: FC<{ content: string }> = observer(({content}) => { }; return ( - : } - onClick={speaking ? stopSpeak : startSpeak}/> + : } + onClick={speaking ? stopSpeak : startSpeak} /> ); }); diff --git a/frontend/src/components/RunButton.tsx b/frontend/src/components/RunButton.tsx index 8c3d6f3..72f2080 100644 --- a/frontend/src/components/RunButton.tsx +++ b/frontend/src/components/RunButton.tsx @@ -1,6 +1,12 @@ import React, { FC, MouseEventHandler, ReactElement } from 'react'; import commonStore, { ModelStatus } from '../stores/commonStore'; -import { AddToDownloadList, DepCheck, FileExists, InstallPyDep, StartServer } from '../../wailsjs/go/backend_golang/App'; +import { + AddToDownloadList, + DepCheck, + FileExists, + InstallPyDep, + StartServer +} from '../../wailsjs/go/backend_golang/App'; import { Button } from '@fluentui/react-components'; import { observer } from 'mobx-react-lite'; import { exit, readRoot, switchModel, updateConfig } from '../apis'; @@ -29,141 +35,141 @@ const iconModeButtonIcon: { [modelStatus: number]: ReactElement } = { export const RunButton: FC<{ onClickRun?: MouseEventHandler, iconMode?: boolean }> = observer(({ - onClickRun, - iconMode - }) => { - const { t } = useTranslation(); - const navigate = useNavigate(); + onClickRun, + iconMode +}) => { + const { t } = useTranslation(); + const navigate = useNavigate(); - const onClickMainButton = async () => { - if (commonStore.modelStatus === ModelStatus.Offline) { - commonStore.setModelStatus(ModelStatus.Starting); + const onClickMainButton = async () => { + if (commonStore.modelStatus === ModelStatus.Offline) { + commonStore.setModelStatus(ModelStatus.Starting); - const modelConfig = commonStore.getCurrentModelConfig(); - let modelName = '' - let modelPath = '' - if (modelConfig && modelConfig.modelParameters) { - modelName = modelConfig.modelParameters.modelName; - modelPath = `./${manifest.localModelDir}/${modelName}`; - } else { - toast(t('Model Config Exception'), { type: 'error' }); + const modelConfig = commonStore.getCurrentModelConfig(); + let modelName = ''; + let modelPath = ''; + if (modelConfig && modelConfig.modelParameters) { + modelName = modelConfig.modelParameters.modelName; + modelPath = `./${manifest.localModelDir}/${modelName}`; + } else { + toast(t('Model Config Exception'), { type: 'error' }); + commonStore.setModelStatus(ModelStatus.Offline); + return; + } + + if (!commonStore.depComplete) { + let depErrorMsg = ''; + await DepCheck().catch((e) => { + depErrorMsg = e.message || e; + WindowShow(); + if (depErrorMsg === 'python zip not found') { + toastWithButton(t('Python target not found, would you like to download it?'), t('Download'), () => { + toastWithButton(`${t('Downloading')} Python`, t('Check'), () => { + navigate({ pathname: '/downloads' }); + }, { autoClose: 3000 }); + AddToDownloadList('python-3.10.11-embed-amd64.zip', 'https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip'); + }); + } else if (depErrorMsg.includes('DepCheck Error')) { + toastWithButton(t('Python dependencies are incomplete, would you like to install them?'), t('Install'), () => { + InstallPyDep(commonStore.settings.cnMirror); + setTimeout(WindowShow, 1000); + }); + } else { + toast(depErrorMsg, { type: 'error' }); + } + }); + if (depErrorMsg) { commonStore.setModelStatus(ModelStatus.Offline); return; } + commonStore.setDepComplete(true); + saveCache(); + } - if (!commonStore.depComplete) { - let depErrorMsg = ''; - await DepCheck().catch((e) => { - depErrorMsg = e.message || e; - WindowShow(); - if (depErrorMsg === 'python zip not found') { - toastWithButton(t('Python target not found, would you like to download it?'), t('Download'), () => { - toastWithButton(`${t('Downloading')} Python`, t('Check'), () => { - navigate({ pathname: '/downloads' }); - }, { autoClose: 3000 }); - AddToDownloadList('python-3.10.11-embed-amd64.zip', 'https://www.python.org/ftp/python/3.10.11/python-3.10.11-embed-amd64.zip'); - }); - } else if (depErrorMsg.includes('DepCheck Error')) { - toastWithButton(t('Python dependencies are incomplete, would you like to install them?'), t('Install'), () => { - InstallPyDep(commonStore.settings.cnMirror); - setTimeout(WindowShow, 1000) - }); - } else { - toast(depErrorMsg, { type: 'error' }); - } - }); - if (depErrorMsg) { - commonStore.setModelStatus(ModelStatus.Offline); - return; - } - commonStore.setDepComplete(true); - saveCache(); - } - - if (!await FileExists(modelPath)) { - toastWithButton(t('Model file not found'), t('Download'), () => { - const downloadUrl = commonStore.modelSourceList.find(item => item.name === modelName)?.downloadUrl; - if (downloadUrl) { - toastWithButton(`${t('Downloading')} ${modelName}`, t('Check'), () => { + if (!await FileExists(modelPath)) { + toastWithButton(t('Model file not found'), t('Download'), () => { + const downloadUrl = commonStore.modelSourceList.find(item => item.name === modelName)?.downloadUrl; + if (downloadUrl) { + toastWithButton(`${t('Downloading')} ${modelName}`, t('Check'), () => { navigate({ pathname: '/downloads' }); }, - { autoClose: 3000 }); - AddToDownloadList(modelPath, downloadUrl); - } else { - toast(t('Can not find download url'), { type: 'error' }); - } - }); - - commonStore.setModelStatus(ModelStatus.Offline); - return; - } - - const port = modelConfig.apiParameters.apiPort; - - await exit(1000).catch(() => { + { autoClose: 3000 }); + AddToDownloadList(modelPath, downloadUrl); + } else { + toast(t('Can not find download url'), { type: 'error' }); + } }); - StartServer(port); - setTimeout(WindowShow, 1000) - let timeoutCount = 6; - let loading = false; - const intervalId = setInterval(() => { - readRoot() - .then(r => { - if (r.ok && !loading) { - clearInterval(intervalId); - commonStore.setModelStatus(ModelStatus.Loading); - loading = true; + commonStore.setModelStatus(ModelStatus.Offline); + return; + } + + const port = modelConfig.apiParameters.apiPort; + + await exit(1000).catch(() => { + }); + StartServer(port); + setTimeout(WindowShow, 1000); + + let timeoutCount = 6; + let loading = false; + const intervalId = setInterval(() => { + readRoot() + .then(r => { + if (r.ok && !loading) { + clearInterval(intervalId); + commonStore.setModelStatus(ModelStatus.Loading); + loading = true; + toast(t('Loading Model'), { type: 'info' }); + updateConfig({ + max_tokens: modelConfig.apiParameters.maxResponseToken, + temperature: modelConfig.apiParameters.temperature, + top_p: modelConfig.apiParameters.topP, + presence_penalty: modelConfig.apiParameters.presencePenalty, + frequency_penalty: modelConfig.apiParameters.frequencyPenalty + }); + switchModel({ + model: `${manifest.localModelDir}/${modelConfig.modelParameters.modelName}`, + strategy: getStrategy(modelConfig) + }).then((r) => { + if (r.ok) { + commonStore.setModelStatus(ModelStatus.Working); + toastWithButton(t('Startup Completed'), t('Chat'), () => { + navigate({ pathname: '/chat' }); + }, { type: 'success', autoClose: 3000 }); + } else if (r.status === 304) { toast(t('Loading Model'), { type: 'info' }); - updateConfig({ - max_tokens: modelConfig.apiParameters.maxResponseToken, - temperature: modelConfig.apiParameters.temperature, - top_p: modelConfig.apiParameters.topP, - presence_penalty: modelConfig.apiParameters.presencePenalty, - frequency_penalty: modelConfig.apiParameters.frequencyPenalty - }); - switchModel({ - model: `${manifest.localModelDir}/${modelConfig.modelParameters.modelName}`, - strategy: getStrategy(modelConfig) - }).then((r) => { - if (r.ok) { - commonStore.setModelStatus(ModelStatus.Working); - toastWithButton(t('Startup Completed'), t('Chat'), () => { - navigate({ pathname: '/chat' }); - }, { type: 'success', autoClose: 3000 }); - } else if (r.status === 304) { - toast(t('Loading Model'), { type: 'info' }); - } else { - commonStore.setModelStatus(ModelStatus.Offline); - toast(t('Failed to switch model'), { type: 'error' }); - } - }).catch(() => { - commonStore.setModelStatus(ModelStatus.Offline); - toast(t('Failed to switch model'), { type: 'error' }); - }); + } else { + commonStore.setModelStatus(ModelStatus.Offline); + toast(t('Failed to switch model'), { type: 'error' }); } }).catch(() => { - if (timeoutCount <= 0) { - clearInterval(intervalId); - commonStore.setModelStatus(ModelStatus.Offline); - } + commonStore.setModelStatus(ModelStatus.Offline); + toast(t('Failed to switch model'), { type: 'error' }); }); + } + }).catch(() => { + if (timeoutCount <= 0) { + clearInterval(intervalId); + commonStore.setModelStatus(ModelStatus.Offline); + } + }); - timeoutCount--; - }, 1000); - } else { - commonStore.setModelStatus(ModelStatus.Offline); - exit(); - } - }; + timeoutCount--; + }, 1000); + } else { + commonStore.setModelStatus(ModelStatus.Offline); + exit(); + } + }; - const onClick = async (e: any) => { - if (commonStore.modelStatus === ModelStatus.Offline) - await onClickRun?.(e); - await onClickMainButton(); - }; + const onClick = async (e: any) => { + if (commonStore.modelStatus === ModelStatus.Offline) + await onClickRun?.(e); + await onClickMainButton(); + }; - return (iconMode ? + return (iconMode ? {t(mainButtonText[commonStore.modelStatus])} - ); - }); + ); +}); diff --git a/frontend/src/components/Section.tsx b/frontend/src/components/Section.tsx index ce65058..643c298 100644 --- a/frontend/src/components/Section.tsx +++ b/frontend/src/components/Section.tsx @@ -1,10 +1,10 @@ -import {FC, ReactElement} from 'react'; -import {Card, Text} from '@fluentui/react-components'; +import { FC, ReactElement } from 'react'; +import { Card, Text } from '@fluentui/react-components'; export const Section: FC<{ title: string; desc?: string | null, content: ReactElement, outline?: boolean }> = - ({title, desc, content, outline = true}) => { + ({ title, desc, content, outline = true }) => { return (
diff --git a/frontend/src/components/ToolTipButton.tsx b/frontend/src/components/ToolTipButton.tsx index e1099d5..8e684c2 100644 --- a/frontend/src/components/ToolTipButton.tsx +++ b/frontend/src/components/ToolTipButton.tsx @@ -1,5 +1,5 @@ -import React, {FC, MouseEventHandler, ReactElement} from 'react'; -import {Button, Tooltip} from '@fluentui/react-components'; +import React, { FC, MouseEventHandler, ReactElement } from 'react'; +import { Button, Tooltip } from '@fluentui/react-components'; export const ToolTipButton: FC<{ text?: string | null, @@ -11,19 +11,19 @@ export const ToolTipButton: FC<{ disabled?: boolean, onClick?: MouseEventHandler }> = ({ - text, - desc, - icon, - size, - shape, - appearance, - disabled, - onClick - }) => { + text, + desc, + icon, + size, + shape, + appearance, + disabled, + onClick +}) => { return ( + appearance={appearance}>{text} ); }; diff --git a/frontend/src/components/ValuedSlider.tsx b/frontend/src/components/ValuedSlider.tsx index 2d0f337..c62dbb0 100644 --- a/frontend/src/components/ValuedSlider.tsx +++ b/frontend/src/components/ValuedSlider.tsx @@ -1,7 +1,7 @@ -import React, {FC, useEffect, useRef} from 'react'; -import {Slider, Text} from '@fluentui/react-components'; -import {SliderOnChangeData} from '@fluentui/react-slider'; -import {NumberInput} from './NumberInput'; +import React, { FC, useEffect, useRef } from 'react'; +import { Slider, Text } from '@fluentui/react-components'; +import { SliderOnChangeData } from '@fluentui/react-slider'; +import { NumberInput } from './NumberInput'; export const ValuedSlider: FC<{ value: number, @@ -10,7 +10,7 @@ export const ValuedSlider: FC<{ step?: number, input?: boolean onChange?: (ev: React.ChangeEvent, data: SliderOnChangeData) => void -}> = ({value, min, max, step, input, onChange}) => { +}> = ({ value, min, max, step, input, onChange }) => { const sliderRef = useRef(null); useEffect(() => { if (step && sliderRef.current && sliderRef.current.parentElement) { @@ -21,11 +21,11 @@ export const ValuedSlider: FC<{ return (
- + {input - ? + ? : {value}}
); diff --git a/frontend/src/main.tsx b/frontend/src/main.tsx index 3494ad1..259ed82 100644 --- a/frontend/src/main.tsx +++ b/frontend/src/main.tsx @@ -1,10 +1,10 @@ import React from 'react'; -import {createRoot} from 'react-dom/client'; +import { createRoot } from 'react-dom/client'; import './style.scss'; import 'react-toastify/dist/ReactToastify.css'; import App from './App'; -import {HashRouter} from 'react-router-dom'; -import {startup} from './startup'; +import { HashRouter } from 'react-router-dom'; +import { startup } from './startup'; import './_locales/i18n-react'; startup().then(() => { @@ -14,7 +14,7 @@ startup().then(() => { root.render( - + ); }); diff --git a/frontend/src/pages/About.tsx b/frontend/src/pages/About.tsx index d778cfd..70bafc5 100644 --- a/frontend/src/pages/About.tsx +++ b/frontend/src/pages/About.tsx @@ -1,14 +1,14 @@ -import React, {FC} from 'react'; -import {useTranslation} from 'react-i18next'; -import {Page} from '../components/Page'; +import React, { FC } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Page } from '../components/Page'; import MarkdownRender from '../components/MarkdownRender'; -import {observer} from 'mobx-react-lite'; +import { observer } from 'mobx-react-lite'; import commonStore from '../stores/commonStore'; export type AboutContent = { [lang: string]: string } export const About: FC = observer(() => { - const {t} = useTranslation(); + const { t } = useTranslation(); const lang: string = commonStore.settings.language; return ( @@ -18,6 +18,6 @@ export const About: FC = observer(() => { {lang in commonStore.about ? commonStore.about[lang] : commonStore.about['en']}
- }/> + } /> ); }); diff --git a/frontend/src/pages/Configs.tsx b/frontend/src/pages/Configs.tsx index 1b741cc..2e636b3 100644 --- a/frontend/src/pages/Configs.tsx +++ b/frontend/src/pages/Configs.tsx @@ -734,7 +734,7 @@ export const Configs: FC = observer(() => { }).catch(e => { toast(`${t('Convert Failed')} - ${e.message || e}`, { type: 'error' }); }); - setTimeout(WindowShow, 1000) + setTimeout(WindowShow, 1000); } else { toast(`${t('Model Not Found')} - ${modelPath}`, { type: 'error' }); } diff --git a/frontend/src/pages/Downloads.tsx b/frontend/src/pages/Downloads.tsx index 942b1a4..1813cb5 100644 --- a/frontend/src/pages/Downloads.tsx +++ b/frontend/src/pages/Downloads.tsx @@ -1,13 +1,13 @@ -import React, {FC, useEffect} from 'react'; -import {useTranslation} from 'react-i18next'; -import {Page} from '../components/Page'; -import {observer} from 'mobx-react-lite'; +import React, { FC, useEffect } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Page } from '../components/Page'; +import { observer } from 'mobx-react-lite'; import commonStore from '../stores/commonStore'; -import {Divider, Field, ProgressBar} from '@fluentui/react-components'; -import {bytesToGb, bytesToKb, bytesToMb, refreshLocalModels} from '../utils'; -import {ToolTipButton} from '../components/ToolTipButton'; -import {Folder20Regular, Pause20Regular, Play20Regular} from '@fluentui/react-icons'; -import {ContinueDownload, OpenFileFolder, PauseDownload} from '../../wailsjs/go/backend_golang/App'; +import { Divider, Field, ProgressBar } from '@fluentui/react-components'; +import { bytesToGb, bytesToKb, bytesToMb, refreshLocalModels } from '../utils'; +import { ToolTipButton } from '../components/ToolTipButton'; +import { Folder20Regular, Pause20Regular, Play20Regular } from '@fluentui/react-icons'; +import { ContinueDownload, OpenFileFolder, PauseDownload } from '../../wailsjs/go/backend_golang/App'; export type DownloadStatus = { name: string; @@ -22,11 +22,11 @@ export type DownloadStatus = { } export const Downloads: FC = observer(() => { - const {t} = useTranslation(); + const { t } = useTranslation(); const finishedModelsLen = commonStore.downloadList.filter((status) => status.done && status.name.endsWith('.pth')).length; useEffect(() => { if (finishedModelsLen > 0) - refreshLocalModels({models: commonStore.modelSourceList}, false); + refreshLocalModels({ models: commonStore.modelSourceList }, false); console.log('finishedModelsLen:', finishedModelsLen); }, [finishedModelsLen]); @@ -51,26 +51,26 @@ export const Downloads: FC = observer(() => { validationState={status.done ? 'success' : 'none'} >
- + {!status.done && : } - onClick={() => { - if (status.downloading) - PauseDownload(status.url); - else - ContinueDownload(status.url); - }}/>} - } onClick={() => { + icon={status.downloading ? : } + onClick={() => { + if (status.downloading) + PauseDownload(status.url); + else + ContinueDownload(status.url); + }} />} + } onClick={() => { OpenFileFolder(status.path); - }}/> + }} />
- +
; }) }
- }/> + } /> ); }); diff --git a/frontend/src/pages/Home.tsx b/frontend/src/pages/Home.tsx index c074ce5..e1f6ab1 100644 --- a/frontend/src/pages/Home.tsx +++ b/frontend/src/pages/Home.tsx @@ -1,5 +1,5 @@ -import {CompoundButton, Link, Text} from '@fluentui/react-components'; -import React, {FC, ReactElement} from 'react'; +import { CompoundButton, Link, Text } from '@fluentui/react-components'; +import React, { FC, ReactElement } from 'react'; import banner from '../assets/images/banner.jpg'; import { Chat20Regular, @@ -7,13 +7,13 @@ import { DocumentSettings20Regular, Storage20Regular } from '@fluentui/react-icons'; -import {useNavigate} from 'react-router'; -import {observer} from 'mobx-react-lite'; -import {RunButton} from '../components/RunButton'; +import { useNavigate } from 'react-router'; +import { observer } from 'mobx-react-lite'; +import { RunButton } from '../components/RunButton'; import manifest from '../../../manifest.json'; -import {BrowserOpenURL} from '../../wailsjs/runtime'; -import {useTranslation} from 'react-i18next'; -import {ConfigSelector} from '../components/ConfigSelector'; +import { BrowserOpenURL } from '../../wailsjs/runtime'; +import { useTranslation } from 'react-i18next'; +import { ConfigSelector } from '../components/ConfigSelector'; import MarkdownRender from '../components/MarkdownRender'; import commonStore from '../stores/commonStore'; @@ -31,40 +31,40 @@ const navCards: NavCard[] = [ label: 'Chat', desc: 'Go to chat page', path: '/chat', - icon: + icon: }, { label: 'Configs', desc: 'Manage your configs', path: '/configs', - icon: + icon: }, { label: 'Models', desc: 'Manage models', path: '/models', - icon: + icon: }, { label: 'Train', desc: '', path: '/train', - icon: + icon: } ]; export const Home: FC = observer(() => { - const {t} = useTranslation(); + const { t } = useTranslation(); const navigate = useNavigate(); const lang: string = commonStore.settings.language; const onClickNavCard = (path: string) => { - navigate({pathname: path}); + navigate({ pathname: path }); }; return (
- +
{t('Introduction')}
@@ -74,9 +74,9 @@ export const Home: FC = observer(() => {
- {navCards.map(({label, path, icon, desc}, index) => ( + {navCards.map(({ label, path, icon, desc }, index) => ( onClickNavCard(path)}> + size="large" onClick={() => onClickNavCard(path)}> {t(label)} ))} @@ -84,8 +84,8 @@ export const Home: FC = observer(() => {
- - + +
diff --git a/frontend/src/pages/Models.tsx b/frontend/src/pages/Models.tsx index 4676369..e06a5f0 100644 --- a/frontend/src/pages/Models.tsx +++ b/frontend/src/pages/Models.tsx @@ -1,4 +1,4 @@ -import React, {FC} from 'react'; +import React, { FC } from 'react'; import { createTableColumn, DataGrid, @@ -12,17 +12,17 @@ import { Text, Textarea } from '@fluentui/react-components'; -import {ToolTipButton} from '../components/ToolTipButton'; -import {ArrowClockwise20Regular, ArrowDownload20Regular, Folder20Regular, Open20Regular} from '@fluentui/react-icons'; -import {observer} from 'mobx-react-lite'; +import { ToolTipButton } from '../components/ToolTipButton'; +import { ArrowClockwise20Regular, ArrowDownload20Regular, Folder20Regular, Open20Regular } from '@fluentui/react-icons'; +import { observer } from 'mobx-react-lite'; import commonStore from '../stores/commonStore'; -import {BrowserOpenURL} from '../../wailsjs/runtime'; -import {AddToDownloadList, OpenFileFolder} from '../../wailsjs/go/backend_golang/App'; +import { BrowserOpenURL } from '../../wailsjs/runtime'; +import { AddToDownloadList, OpenFileFolder } from '../../wailsjs/go/backend_golang/App'; import manifest from '../../../manifest.json'; -import {Page} from '../components/Page'; -import {bytesToGb, refreshModels, saveConfigs, toastWithButton} from '../utils'; -import {useTranslation} from 'react-i18next'; -import {useNavigate} from 'react-router'; +import { Page } from '../components/Page'; +import { bytesToGb, refreshModels, saveConfigs, toastWithButton } from '../utils'; +import { useTranslation } from 'react-i18next'; +import { useNavigate } from 'react-router'; export type ModelSourceItem = { name: string; @@ -43,7 +43,7 @@ const columns: TableColumnDefinition[] = [ return a.name.localeCompare(b.name); }, renderHeaderCell: () => { - const {t} = useTranslation(); + const { t } = useTranslation(); return t('File'); }, @@ -69,7 +69,7 @@ const columns: TableColumnDefinition[] = [ return 0; }, renderHeaderCell: () => { - const {t} = useTranslation(); + const { t } = useTranslation(); return t('Desc'); }, @@ -91,7 +91,7 @@ const columns: TableColumnDefinition[] = [ return a.size - b.size; }, renderHeaderCell: () => { - const {t} = useTranslation(); + const { t } = useTranslation(); return t('Size'); }, @@ -113,7 +113,7 @@ const columns: TableColumnDefinition[] = [ return b.lastUpdatedMs - a.lastUpdatedMs; }, renderHeaderCell: () => { - const {t} = useTranslation(); + const { t } = useTranslation(); return t('Last updated'); }, @@ -128,12 +128,12 @@ const columns: TableColumnDefinition[] = [ return a.isLocal ? -1 : 1; }, renderHeaderCell: () => { - const {t} = useTranslation(); + const { t } = useTranslation(); return t('Actions'); }, renderCell: (item) => { - const {t} = useTranslation(); + const { t } = useTranslation(); const navigate = useNavigate(); return ( @@ -141,21 +141,21 @@ const columns: TableColumnDefinition[] = [
{ item.isLocal && - } onClick={() => { + } onClick={() => { OpenFileFolder(`./${manifest.localModelDir}/${item.name}`); - }}/> + }} /> } {item.downloadUrl && !item.isLocal && - } onClick={() => { + } onClick={() => { toastWithButton(`${t('Downloading')} ${item.name}`, t('Check'), () => { - navigate({pathname: '/downloads'}); + navigate({ pathname: '/downloads' }); }, - {autoClose: 3000}); + { autoClose: 3000 }); AddToDownloadList(`./${manifest.localModelDir}/${item.name}`, item.downloadUrl!); - }}/>} - {item.url && } onClick={() => { + }} />} + {item.url && } onClick={() => { BrowserOpenURL(item.url!); - }}/>} + }} />}
); @@ -164,7 +164,7 @@ const columns: TableColumnDefinition[] = [ ]; export const Models: FC = observer(() => { - const {t} = useTranslation(); + const { t } = useTranslation(); return ( {
{t('Model Source Manifest List')} - } onClick={() => { + } onClick={() => { refreshModels(false); saveConfigs(); - }}/> + }} />
{t('Provide JSON file URLs for the models manifest. Separate URLs with semicolons. The "models" field in JSON files will be parsed into the following table.')}