improve mobile view

This commit is contained in:
josc146 2023-11-09 12:21:01 +08:00
parent 07797537d1
commit f03c9cf25f
4 changed files with 61 additions and 58 deletions

View File

@ -51,10 +51,10 @@ const App: FC = observer(() => {
useEffect(() => setPath(location.pathname), [location]); useEffect(() => setPath(location.pathname), [location]);
return ( return (
<FluentProvider className="h-screen" <FluentProvider
theme={commonStore.settings.darkMode ? webDarkTheme : webLightTheme} theme={commonStore.settings.darkMode ? webDarkTheme : webLightTheme}
data-theme={commonStore.settings.darkMode ? 'dark' : 'light'}> data-theme={commonStore.settings.darkMode ? 'dark' : 'light'}>
<div className="flex h-full"> <div className="flex h-screen">
<div className="flex flex-col w-16 sm:w-48 p-2 justify-between"> <div className="flex flex-col w-16 sm:w-48 p-2 justify-between">
<TabList <TabList
size="large" size="large"

View File

@ -19,11 +19,13 @@ import { defaultCompositionPrompt } from './defaultConfigs';
import { FileExists, OpenFileFolder, OpenSaveFileDialogBytes } from '../../wailsjs/go/backend_golang/App'; import { FileExists, OpenFileFolder, OpenSaveFileDialogBytes } from '../../wailsjs/go/backend_golang/App';
import { getServerRoot, toastWithButton } from '../utils'; import { getServerRoot, toastWithButton } from '../utils';
import { CompositionParams } from '../types/composition'; import { CompositionParams } from '../types/composition';
import { useMediaQuery } from 'usehooks-ts';
let compositionSseController: AbortController | null = null; let compositionSseController: AbortController | null = null;
const CompositionPanel: FC = observer(() => { const CompositionPanel: FC = observer(() => {
const { t } = useTranslation(); const { t } = useTranslation();
const mq = useMediaQuery('(min-width: 640px)');
const inputRef = useRef<HTMLTextAreaElement>(null); const inputRef = useRef<HTMLTextAreaElement>(null);
const port = commonStore.getCurrentModelConfig().apiParameters.apiPort; const port = commonStore.getCurrentModelConfig().apiParameters.apiPort;
const visualizerRef = useRef<VisualizerElement>(null); const visualizerRef = useRef<VisualizerElement>(null);
@ -204,62 +206,64 @@ const CompositionPanel: FC = observer(() => {
setPrompt(e.target.value); setPrompt(e.target.value);
}} }}
/> />
<div className="flex flex-col gap-1 max-h-48 sm:max-w-sm sm:max-h-full overflow-x-hidden overflow-y-auto p-1"> <div className="flex flex-col gap-1 max-h-48 sm:max-w-sm sm:max-h-full">
<Labeled flex breakline label={t('Max Response Token')} <div className="flex flex-col gap-1 grow overflow-x-hidden overflow-y-auto p-1">
desc={t('By default, the maximum number of tokens that can be answered in a single response, it can be changed by the user by specifying API parameters.')} <Labeled flex breakline label={t('Max Response Token')}
content={ desc={t('By default, the maximum number of tokens that can be answered in a single response, it can be changed by the user by specifying API parameters.')}
<ValuedSlider value={params.maxResponseToken} min={100} max={4100} content={
step={100} <ValuedSlider value={params.maxResponseToken} min={100} max={4100}
input step={100}
onChange={(e, data) => { input
setParams({ onChange={(e, data) => {
maxResponseToken: data.value setParams({
}); maxResponseToken: data.value
}} /> });
} /> }} />
<Labeled flex breakline label={t('Temperature')} } />
desc={t('Sampling temperature, it\'s like giving alcohol to a model, the higher the stronger the randomness and creativity, while the lower, the more focused and deterministic it will be.')} <Labeled flex breakline label={t('Temperature')}
content={ desc={t('Sampling temperature, it\'s like giving alcohol to a model, the higher the stronger the randomness and creativity, while the lower, the more focused and deterministic it will be.')}
<ValuedSlider value={params.temperature} min={0} max={2} step={0.1} content={
input <ValuedSlider value={params.temperature} min={0} max={2} step={0.1}
onChange={(e, data) => { input
setParams({ onChange={(e, data) => {
temperature: data.value setParams({
}); temperature: data.value
}} /> });
} /> }} />
<Labeled flex breakline label={t('Top_P')} } />
desc={t('Just like feeding sedatives to the model. Consider the results of the top n% probability mass, 0.1 considers the top 10%, with higher quality but more conservative, 1 considers all results, with lower quality but more diverse.')} <Labeled flex breakline label={t('Top_P')}
content={ desc={t('Just like feeding sedatives to the model. Consider the results of the top n% probability mass, 0.1 considers the top 10%, with higher quality but more conservative, 1 considers all results, with lower quality but more diverse.')}
<ValuedSlider value={params.topP} min={0} max={1} step={0.1} input content={
onChange={(e, data) => { <ValuedSlider value={params.topP} min={0} max={1} step={0.1} input
setParams({ onChange={(e, data) => {
topP: data.value setParams({
}); topP: data.value
}} /> });
} /> }} />
<div className="grow" /> } />
<Checkbox className="select-none" <div className="grow" />
size="large" label={t('Use Local Sound Font')} checked={params.useLocalSoundFont} <Checkbox className="select-none"
onChange={async (_, data) => { size="large" label={t('Use Local Sound Font')} checked={params.useLocalSoundFont}
if (data.checked) { onChange={async (_, data) => {
if (!await FileExists('assets/sound-font/accordion/instrument.json')) { if (data.checked) {
toast(t('Failed to load local sound font, please check if the files exist - assets/sound-font'), if (!await FileExists('assets/sound-font/accordion/instrument.json')) {
{ type: 'warning' }); toast(t('Failed to load local sound font, please check if the files exist - assets/sound-font'),
return; { type: 'warning' });
return;
}
} }
} setParams({
useLocalSoundFont: data.checked as boolean
});
setSoundFont();
}} />
<Checkbox className="select-none"
size="large" label={t('Auto Play At The End')} checked={params.autoPlay} onChange={(_, data) => {
setParams({ setParams({
useLocalSoundFont: data.checked as boolean autoPlay: data.checked as boolean
}); });
setSoundFont();
}} /> }} />
<Checkbox className="select-none" </div>
size="large" label={t('Auto Play At The End')} checked={params.autoPlay} onChange={(_, data) => {
setParams({
autoPlay: data.checked as boolean
});
}} />
<div className="flex justify-between gap-2"> <div className="flex justify-between gap-2">
<ToolTipButton desc={t('Regenerate')} icon={<ArrowSync20Regular />} onClick={() => { <ToolTipButton desc={t('Regenerate')} icon={<ArrowSync20Regular />} onClick={() => {
compositionSseController?.abort(); compositionSseController?.abort();
@ -298,7 +302,7 @@ const CompositionPanel: FC = observer(() => {
ref={playerRef} ref={playerRef}
style={{ width: '100%' }} style={{ width: '100%' }}
/> />
<Button icon={<Save28Regular />} <Button icon={<Save28Regular />} size={mq ? 'large' : 'medium'} appearance={mq ? 'secondary' : 'subtle'}
onClick={() => { onClick={() => {
if (params.midi) { if (params.midi) {
OpenSaveFileDialogBytes('*.mid', 'music.mid', Array.from(new Uint8Array(params.midi))).then((path) => { OpenSaveFileDialogBytes('*.mid', 'music.mid', Array.from(new Uint8Array(params.midi))).then((path) => {
@ -314,7 +318,7 @@ const CompositionPanel: FC = observer(() => {
} }
}} }}
> >
{t('Save')} {mq ? t('Save') : ''}
</Button> </Button>
</div> </div>
</div> </div>

View File

@ -89,7 +89,7 @@ const Home: FC = observer(() => {
return commonStore.platform === 'web' ? return commonStore.platform === 'web' ?
( (
<div className="flex flex-col gap-2 h-full"> <div className="flex flex-col gap-2 h-full overflow-x-hidden overflow-y-auto">
<img className="rounded-xl select-none object-cover grow" <img className="rounded-xl select-none object-cover grow"
style={{ maxHeight: '40%' }} src={banner} /> style={{ maxHeight: '40%' }} src={banner} />
<div className="grow"></div> <div className="grow"></div>

View File

@ -14,7 +14,6 @@
body { body {
margin: 0; margin: 0;
overflow: hidden;
width: 100%; width: 100%;
height: 100%; height: 100%;
} }