mirror of
https://github.com/mountain-loop/yaak.git
synced 2026-03-29 21:51:59 +02:00
Generalized frontend model store (#193)
This commit is contained in:
@@ -1,10 +1,10 @@
|
||||
import type { EditorKeymap } from '@yaakapp-internal/models';
|
||||
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import React from 'react';
|
||||
import { useActiveWorkspace } from '../../hooks/useActiveWorkspace';
|
||||
import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace';
|
||||
import { useResolvedAppearance } from '../../hooks/useResolvedAppearance';
|
||||
import { useResolvedTheme } from '../../hooks/useResolvedTheme';
|
||||
import { useSettings } from '../../hooks/useSettings';
|
||||
import { useUpdateSettings } from '../../hooks/useUpdateSettings';
|
||||
import { clamp } from '../../lib/clamp';
|
||||
import { getThemes } from '../../lib/theme/themes';
|
||||
import { isThemeDark } from '../../lib/theme/window';
|
||||
@@ -62,9 +62,8 @@ const icons: IconProps['icon'][] = [
|
||||
const { themes } = getThemes();
|
||||
|
||||
export function SettingsAppearance() {
|
||||
const workspace = useActiveWorkspace();
|
||||
const settings = useSettings();
|
||||
const updateSettings = useUpdateSettings();
|
||||
const workspace = useAtomValue(activeWorkspaceAtom);
|
||||
const settings = useAtomValue(settingsAtom);
|
||||
const appearance = useResolvedAppearance();
|
||||
const activeTheme = useResolvedTheme();
|
||||
|
||||
@@ -93,18 +92,20 @@ export function SettingsAppearance() {
|
||||
name="interfaceFontSize"
|
||||
label="Font Size"
|
||||
labelPosition="left"
|
||||
defaultValue="15"
|
||||
value={`${settings.interfaceFontSize}`}
|
||||
options={fontSizeOptions}
|
||||
onChange={(v) => updateSettings.mutate({ interfaceFontSize: parseInt(v) })}
|
||||
onChange={(v) => patchModel(settings, { interfaceFontSize: parseInt(v) })}
|
||||
/>
|
||||
<Select
|
||||
size="sm"
|
||||
name="editorFontSize"
|
||||
label="Editor Font Size"
|
||||
labelPosition="left"
|
||||
defaultValue="13"
|
||||
value={`${settings.editorFontSize}`}
|
||||
options={fontSizeOptions}
|
||||
onChange={(v) => updateSettings.mutate({ editorFontSize: clamp(parseInt(v) || 14, 8, 30) })}
|
||||
onChange={(v) => patchModel(settings, { editorFontSize: clamp(parseInt(v) || 14, 8, 30) })}
|
||||
/>
|
||||
<Select
|
||||
size="sm"
|
||||
@@ -113,12 +114,12 @@ export function SettingsAppearance() {
|
||||
labelPosition="left"
|
||||
value={`${settings.editorKeymap}`}
|
||||
options={keymaps}
|
||||
onChange={(v) => updateSettings.mutate({ editorKeymap: v })}
|
||||
onChange={(v) => patchModel(settings, { editorKeymap: v })}
|
||||
/>
|
||||
<Checkbox
|
||||
checked={settings.editorSoftWrap}
|
||||
title="Wrap Editor Lines"
|
||||
onChange={(editorSoftWrap) => updateSettings.mutate({ editorSoftWrap })}
|
||||
onChange={(editorSoftWrap) => patchModel(settings, { editorSoftWrap })}
|
||||
/>
|
||||
|
||||
<Separator className="my-4" />
|
||||
@@ -129,7 +130,7 @@ export function SettingsAppearance() {
|
||||
labelPosition="top"
|
||||
size="sm"
|
||||
value={settings.appearance}
|
||||
onChange={(appearance) => updateSettings.mutate({ appearance })}
|
||||
onChange={(appearance) => patchModel(settings, { appearance })}
|
||||
options={[
|
||||
{ label: 'Automatic', value: 'system' },
|
||||
{ label: 'Light', value: 'light' },
|
||||
@@ -147,7 +148,7 @@ export function SettingsAppearance() {
|
||||
className="flex-1"
|
||||
value={activeTheme.light.id}
|
||||
options={lightThemes}
|
||||
onChange={(themeLight) => updateSettings.mutate({ ...settings, themeLight })}
|
||||
onChange={(themeLight) => patchModel(settings, { themeLight })}
|
||||
/>
|
||||
)}
|
||||
{(settings.appearance === 'system' || settings.appearance === 'dark') && (
|
||||
@@ -160,7 +161,7 @@ export function SettingsAppearance() {
|
||||
size="sm"
|
||||
value={activeTheme.dark.id}
|
||||
options={darkThemes}
|
||||
onChange={(themeDark) => updateSettings.mutate({ ...settings, themeDark })}
|
||||
onChange={(themeDark) => patchModel(settings, { themeDark })}
|
||||
/>
|
||||
)}
|
||||
</HStack>
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
import { revealItemInDir } from '@tauri-apps/plugin-opener';
|
||||
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
|
||||
import { useAtomValue } from 'jotai/index';
|
||||
import React from 'react';
|
||||
import { upsertWorkspace } from '../../commands/upsertWorkspace';
|
||||
import { useActiveWorkspace } from '../../hooks/useActiveWorkspace';
|
||||
import { activeWorkspaceAtom } from '../../hooks/useActiveWorkspace';
|
||||
import { useAppInfo } from '../../hooks/useAppInfo';
|
||||
import { useCheckForUpdates } from '../../hooks/useCheckForUpdates';
|
||||
import { useSettings } from '../../hooks/useSettings';
|
||||
import { useUpdateSettings } from '../../hooks/useUpdateSettings';
|
||||
import { revealInFinderText } from '../../lib/reveal';
|
||||
import { Checkbox } from '../core/Checkbox';
|
||||
import { Heading } from '../core/Heading';
|
||||
@@ -17,9 +16,8 @@ import { Separator } from '../core/Separator';
|
||||
import { VStack } from '../core/Stacks';
|
||||
|
||||
export function SettingsGeneral() {
|
||||
const workspace = useActiveWorkspace();
|
||||
const settings = useSettings();
|
||||
const updateSettings = useUpdateSettings();
|
||||
const workspace = useAtomValue(activeWorkspaceAtom);
|
||||
const settings = useAtomValue(settingsAtom);
|
||||
const appInfo = useAppInfo();
|
||||
const checkForUpdates = useCheckForUpdates();
|
||||
|
||||
@@ -37,7 +35,7 @@ export function SettingsGeneral() {
|
||||
labelClassName="w-[14rem]"
|
||||
size="sm"
|
||||
value={settings.updateChannel}
|
||||
onChange={(updateChannel) => updateSettings.mutate({ updateChannel })}
|
||||
onChange={(updateChannel) => patchModel(settings, { updateChannel })}
|
||||
options={[
|
||||
{ label: 'Stable (less frequent)', value: 'stable' },
|
||||
{ label: 'Beta (more frequent)', value: 'beta' },
|
||||
@@ -65,10 +63,10 @@ export function SettingsGeneral() {
|
||||
? 'current'
|
||||
: 'ask'
|
||||
}
|
||||
onChange={(v) => {
|
||||
if (v === 'current') updateSettings.mutate({ openWorkspaceNewWindow: false });
|
||||
else if (v === 'new') updateSettings.mutate({ openWorkspaceNewWindow: true });
|
||||
else updateSettings.mutate({ openWorkspaceNewWindow: null });
|
||||
onChange={async (v) => {
|
||||
if (v === 'current') await patchModel(settings, { openWorkspaceNewWindow: false });
|
||||
else if (v === 'new') await patchModel(settings, { openWorkspaceNewWindow: true });
|
||||
else await patchModel(settings, { openWorkspaceNewWindow: null });
|
||||
}}
|
||||
options={[
|
||||
{ label: 'Always Ask', value: 'ask' },
|
||||
@@ -96,9 +94,7 @@ export function SettingsGeneral() {
|
||||
labelPosition="left"
|
||||
defaultValue={`${workspace.settingRequestTimeout}`}
|
||||
validate={(value) => parseInt(value) >= 0}
|
||||
onChange={(v) =>
|
||||
upsertWorkspace.mutate({ ...workspace, settingRequestTimeout: parseInt(v) || 0 })
|
||||
}
|
||||
onChange={(v) => patchModel(workspace, { settingRequestTimeout: parseInt(v) || 0 })}
|
||||
type="number"
|
||||
/>
|
||||
|
||||
@@ -106,7 +102,7 @@ export function SettingsGeneral() {
|
||||
checked={workspace.settingValidateCertificates}
|
||||
title="Validate TLS Certificates"
|
||||
onChange={(settingValidateCertificates) =>
|
||||
upsertWorkspace.mutate({ ...workspace, settingValidateCertificates })
|
||||
patchModel(workspace, { settingValidateCertificates })
|
||||
}
|
||||
/>
|
||||
|
||||
@@ -114,8 +110,7 @@ export function SettingsGeneral() {
|
||||
checked={workspace.settingFollowRedirects}
|
||||
title="Follow Redirects"
|
||||
onChange={(settingFollowRedirects) =>
|
||||
upsertWorkspace.mutate({
|
||||
...workspace,
|
||||
patchModel(workspace, {
|
||||
settingFollowRedirects,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -118,8 +118,8 @@ export function SettingsLicense() {
|
||||
className="max-w-sm"
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
await activate.mutateAsync({ licenseKey: key });
|
||||
toggleActivateFormVisible();
|
||||
activate.mutate({ licenseKey: key });
|
||||
}}
|
||||
>
|
||||
<PlainInput
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { openUrl } from '@tauri-apps/plugin-opener';
|
||||
import type { Plugin } from '@yaakapp-internal/models';
|
||||
import type { Plugin} from '@yaakapp-internal/models';
|
||||
import { pluginsAtom } from '@yaakapp-internal/models';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import React from 'react';
|
||||
import { useInstallPlugin } from '../../hooks/useInstallPlugin';
|
||||
import { usePluginInfo } from '../../hooks/usePluginInfo';
|
||||
import { usePlugins, useRefreshPlugins } from '../../hooks/usePlugins';
|
||||
import { useRefreshPlugins } from '../../hooks/usePlugins';
|
||||
import { useUninstallPlugin } from '../../hooks/useUninstallPlugin';
|
||||
import { Button } from '../core/Button';
|
||||
import { IconButton } from '../core/IconButton';
|
||||
@@ -14,7 +16,7 @@ import { SelectFile } from '../SelectFile';
|
||||
|
||||
export function SettingsPlugins() {
|
||||
const [directory, setDirectory] = React.useState<string | null>(null);
|
||||
const plugins = usePlugins();
|
||||
const plugins = useAtomValue(pluginsAtom);
|
||||
const createPlugin = useInstallPlugin();
|
||||
const refreshPlugins = useRefreshPlugins();
|
||||
return (
|
||||
@@ -61,12 +63,7 @@ export function SettingsPlugins() {
|
||||
/>
|
||||
<HStack>
|
||||
{directory && (
|
||||
<Button
|
||||
size="xs"
|
||||
type="submit"
|
||||
color="primary"
|
||||
className="ml-auto"
|
||||
>
|
||||
<Button size="xs" type="submit" color="primary" className="ml-auto">
|
||||
Add Plugin
|
||||
</Button>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { patchModel, settingsAtom } from '@yaakapp-internal/models';
|
||||
import { useAtomValue } from 'jotai';
|
||||
import React from 'react';
|
||||
import { useSettings } from '../../hooks/useSettings';
|
||||
import { useUpdateSettings } from '../../hooks/useUpdateSettings';
|
||||
import { Checkbox } from '../core/Checkbox';
|
||||
import { PlainInput } from '../core/PlainInput';
|
||||
import { Select } from '../core/Select';
|
||||
@@ -8,8 +8,7 @@ import { Separator } from '../core/Separator';
|
||||
import { HStack, VStack } from '../core/Stacks';
|
||||
|
||||
export function SettingsProxy() {
|
||||
const settings = useSettings();
|
||||
const updateSettings = useUpdateSettings();
|
||||
const settings = useAtomValue(settingsAtom);
|
||||
|
||||
return (
|
||||
<VStack space={1.5} className="mb-4">
|
||||
@@ -19,11 +18,11 @@ export function SettingsProxy() {
|
||||
hideLabel
|
||||
size="sm"
|
||||
value={settings.proxy?.type ?? 'automatic'}
|
||||
onChange={(v) => {
|
||||
onChange={async (v) => {
|
||||
if (v === 'automatic') {
|
||||
updateSettings.mutate({ proxy: undefined });
|
||||
await patchModel(settings, { proxy: undefined });
|
||||
} else if (v === 'enabled') {
|
||||
updateSettings.mutate({
|
||||
await patchModel(settings, {
|
||||
proxy: {
|
||||
type: 'enabled',
|
||||
http: '',
|
||||
@@ -32,7 +31,7 @@ export function SettingsProxy() {
|
||||
},
|
||||
});
|
||||
} else {
|
||||
updateSettings.mutate({ proxy: { type: 'disabled' } });
|
||||
await patchModel(settings, { proxy: { type: 'disabled' } });
|
||||
}
|
||||
}}
|
||||
options={[
|
||||
@@ -49,10 +48,10 @@ export function SettingsProxy() {
|
||||
label="HTTP"
|
||||
placeholder="localhost:9090"
|
||||
defaultValue={settings.proxy?.http}
|
||||
onChange={(http) => {
|
||||
onChange={async (http) => {
|
||||
const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : '';
|
||||
const auth = settings.proxy?.type === 'enabled' ? settings.proxy.auth : null;
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
<PlainInput
|
||||
@@ -60,10 +59,10 @@ export function SettingsProxy() {
|
||||
label="HTTPS"
|
||||
placeholder="localhost:9090"
|
||||
defaultValue={settings.proxy?.https}
|
||||
onChange={(https) => {
|
||||
onChange={async (https) => {
|
||||
const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : '';
|
||||
const auth = settings.proxy?.type === 'enabled' ? settings.proxy.auth : null;
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
</HStack>
|
||||
@@ -71,11 +70,11 @@ export function SettingsProxy() {
|
||||
<Checkbox
|
||||
checked={settings.proxy.auth != null}
|
||||
title="Enable authentication"
|
||||
onChange={(enabled) => {
|
||||
onChange={async (enabled) => {
|
||||
const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : '';
|
||||
const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : '';
|
||||
const auth = enabled ? { user: '', password: '' } : null;
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
|
||||
@@ -87,13 +86,13 @@ export function SettingsProxy() {
|
||||
label="User"
|
||||
placeholder="myUser"
|
||||
defaultValue={settings.proxy.auth.user}
|
||||
onChange={(user) => {
|
||||
onChange={async (user) => {
|
||||
const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : '';
|
||||
const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : '';
|
||||
const password =
|
||||
settings.proxy?.type === 'enabled' ? (settings.proxy.auth?.password ?? '') : '';
|
||||
const auth = { user, password };
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
<PlainInput
|
||||
@@ -102,13 +101,13 @@ export function SettingsProxy() {
|
||||
type="password"
|
||||
placeholder="s3cretPassw0rd"
|
||||
defaultValue={settings.proxy.auth.password}
|
||||
onChange={(password) => {
|
||||
onChange={async (password) => {
|
||||
const https = settings.proxy?.type === 'enabled' ? settings.proxy.https : '';
|
||||
const http = settings.proxy?.type === 'enabled' ? settings.proxy.http : '';
|
||||
const user =
|
||||
settings.proxy?.type === 'enabled' ? (settings.proxy.auth?.user ?? '') : '';
|
||||
const auth = { user, password };
|
||||
updateSettings.mutate({ proxy: { type: 'enabled', http, https, auth } });
|
||||
await patchModel(settings, { proxy: { type: 'enabled', http, https, auth } });
|
||||
}}
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
Reference in New Issue
Block a user