Tweak settings for release

This commit is contained in:
Gregory Schier
2024-05-30 10:28:59 -07:00
parent 90637fda6b
commit 2caa735a2e
20 changed files with 191 additions and 227 deletions

View File

@@ -0,0 +1,47 @@
import { getCurrent } from '@tauri-apps/api/webviewWindow';
import { createGlobalState, useKeyPressEvent } from 'react-use';
import { capitalize } from '../../lib/capitalize';
import { TabContent, Tabs } from '../core/Tabs/Tabs';
import { SettingsAppearance } from './SettingsAppearance';
import { SettingsGeneral } from './SettingsGeneral';
enum Tab {
General = 'general',
Appearance = 'appearance',
}
const tabs = [Tab.General, Tab.Appearance];
const useTabState = createGlobalState<string>(tabs[0]!);
export const Settings = () => {
const [tab, setTab] = useTabState();
// Close settings window on escape
// TODO: Could this be put in a better place? Eg. in Rust key listener when creating the window
useKeyPressEvent('Escape', () => getCurrent().close());
return (
<>
<div
data-tauri-drag-region
className="h-[27px] bg-background-highlight-secondary flex items-center justify-center border-b border-background-highlight"
>
Settings
</div>
<Tabs
value={tab}
addBorders
label="Settings"
onChangeValue={setTab}
tabs={tabs.map((value) => ({ value, label: capitalize(value) }))}
>
<TabContent value={Tab.General} className="pt-3 overflow-y-auto h-full px-4">
<SettingsGeneral />
</TabContent>
<TabContent value={Tab.Appearance} className="pt-3 overflow-y-auto h-full px-4">
<SettingsAppearance />
</TabContent>
</Tabs>
</>
);
};

View File

@@ -5,19 +5,23 @@ import { useResolvedTheme } from '../../hooks/useResolvedTheme';
import { useSettings } from '../../hooks/useSettings';
import { useThemes } from '../../hooks/useThemes';
import { useUpdateSettings } from '../../hooks/useUpdateSettings';
import { trackEvent } from '../../lib/analytics';
import { clamp } from '../../lib/clamp';
import { isThemeDark } from '../../lib/theme/window';
import type { ButtonProps } from '../core/Button';
import { Checkbox } from '../core/Checkbox';
import { Editor } from '../core/Editor';
import type { IconProps } from '../core/Icon';
import { Icon } from '../core/Icon';
import { IconButton } from '../core/IconButton';
import { PlainInput } from '../core/PlainInput';
import type { SelectOption } from '../core/Select';
import { Select } from '../core/Select';
import { Separator } from '../core/Separator';
import { HStack, VStack } from '../core/Stacks';
const fontSizes = [
8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
].map((n) => ({ label: `${n}`, value: `${n}` }));
const buttonColors: ButtonProps['color'][] = [
'primary',
'info',
@@ -75,39 +79,28 @@ export function SettingsAppearance() {
return (
<VStack space={2} className="mb-4">
<PlainInput
<Select
size="sm"
name="interfaceFontSize"
label="Font Size"
placeholder="16"
step={0.5}
type="number"
labelPosition="left"
defaultValue={`${settings.interfaceFontSize}`}
validate={(value) => parseInt(value) >= 8 && parseInt(value) <= 30}
onChange={(v) =>
updateSettings.mutate({
...settings,
interfaceFontSize: clamp(parseInt(v) || 16, 8, 30),
})
}
value={`${settings.interfaceFontSize}`}
options={fontSizes}
onChange={(v) => updateSettings.mutate({ interfaceFontSize: parseInt(v) })}
/>
<PlainInput
<Select
size="sm"
name="editorFontSize"
label="Editor Font Size"
placeholder="14"
step={0.5}
type="number"
labelPosition="left"
defaultValue={`${settings.editorFontSize}`}
validate={(value) => parseInt(value) >= 8 && parseInt(value) <= 30}
onChange={(v) =>
updateSettings.mutate({
...settings,
editorFontSize: clamp(parseInt(v) || 14, 8, 30),
})
}
value={`${settings.editorFontSize}`}
options={fontSizes}
onChange={(v) => updateSettings.mutate({ editorFontSize: clamp(parseInt(v) || 14, 8, 30) })}
/>
<Checkbox
checked={settings.editorSoftWrap}
title="Wrap Editor Lines"
onChange={(editorSoftWrap) => updateSettings.mutate({ editorSoftWrap })}
/>
<Separator className="my-4" />
@@ -118,9 +111,8 @@ export function SettingsAppearance() {
labelPosition="left"
size="sm"
value={settings.appearance}
onChange={async (appearance) => {
await updateSettings.mutateAsync({ ...settings, appearance });
trackEvent('setting', 'update', { appearance });
onChange={(appearance) => {
updateSettings.mutateAsync({ appearance });
}}
options={[
{ label: 'Automatic', value: 'system' },
@@ -128,42 +120,41 @@ export function SettingsAppearance() {
{ label: 'Dark', value: 'dark' },
]}
/>
{(settings.appearance === 'system' || settings.appearance === 'light') && (
<Select
name="lightTheme"
label={settings.appearance === 'system' ? 'Light Theme' : 'Theme'}
labelPosition="left"
size="sm"
value={activeTheme.light.id}
options={lightThemes}
onChange={async (themeLight) => {
await updateSettings.mutateAsync({ ...settings, themeLight });
trackEvent('setting', 'update', { themeLight });
}}
/>
)}
{(settings.appearance === 'system' || settings.appearance === 'dark') && (
<Select
name="darkTheme"
label={settings.appearance === 'system' ? 'Dark Theme' : 'Theme'}
labelPosition="left"
size="sm"
value={activeTheme.dark.id}
options={darkThemes}
onChange={async (themeDark) => {
await updateSettings.mutateAsync({ ...settings, themeDark });
trackEvent('setting', 'update', { themeDark });
}}
/>
)}
<HStack space={2}>
{(settings.appearance === 'system' || settings.appearance === 'light') && (
<Select
hideLabel
leftSlot={<Icon icon="sun" />}
name="lightTheme"
label="Light Theme"
size="sm"
value={activeTheme.light.id}
options={lightThemes}
onChange={(themeLight) => updateSettings.mutateAsync({ ...settings, themeLight })}
/>
)}
{(settings.appearance === 'system' || settings.appearance === 'dark') && (
<Select
hideLabel
name="darkTheme"
label="Dark Theme"
leftSlot={<Icon icon="moon" />}
size="sm"
value={activeTheme.dark.id}
options={darkThemes}
onChange={(themeDark) => updateSettings.mutateAsync({ ...settings, themeDark })}
/>
)}
</HStack>
<VStack
space={3}
className="mt-3 w-full bg-background p-3 border border-dashed border-background-highlight rounded overflow-x-auto"
>
<div className="text-fg font-bold">
Theme Preview <span className="text-fg-subtle">({appearance})</span>
</div>
<HStack className="text-fg font-bold" alignItems="center" space={2}>
Theme Preview{' '}
<Icon icon={appearance === 'dark' ? 'moon' : 'sun'} className="text-fg-subtle" />
</HStack>
<HStack space={1.5} alignItems="center" className="w-full">
{buttonColors.map((c, i) => (
<IconButton

View File

@@ -1,61 +0,0 @@
import classNames from 'classnames';
import { createGlobalState } from 'react-use';
import { useAppInfo } from '../../hooks/useAppInfo';
import { capitalize } from '../../lib/capitalize';
import { TabContent, Tabs } from '../core/Tabs/Tabs';
import { SettingsAppearance } from './SettingsAppearance';
import { SettingsDesign } from './SettingsDesign';
import { SettingsGeneral } from './SettingsGeneral';
enum Tab {
General = 'general',
Appearance = 'appearance',
// Dev-only
Design = 'design',
}
const tabs = [Tab.General, Tab.Appearance, Tab.Design];
const useTabState = createGlobalState<string>(tabs[0]!);
interface Props {
fullscreen?: true;
}
export const SettingsDialog = ({ fullscreen }: Props) => {
const [tab, setTab] = useTabState();
const appInfo = useAppInfo();
const isDev = appInfo?.isDev ?? false;
return (
<div className={classNames(!fullscreen && 'w-[70vw] max-w-[40rem] h-[80vh]')}>
{fullscreen && (
<div
data-tauri-drag-region
className="h-[27px] bg-background-highlight-secondary flex items-center justify-center border-b border-background-highlight"
>
Settings
</div>
)}
<Tabs
value={tab}
addBorders
label="Settings"
onChangeValue={setTab}
tabs={tabs
.filter((t) => t !== Tab.Design || isDev)
.map((value) => ({ value, label: capitalize(value) }))}
>
<TabContent value={Tab.General} className="pt-3 overflow-y-auto h-full px-4">
<SettingsGeneral />
</TabContent>
<TabContent value={Tab.Appearance} className="pt-3 overflow-y-auto h-full px-4">
<SettingsAppearance />
</TabContent>
<TabContent value={Tab.Design} className="pt-3 overflow-y-auto h-full px-4">
<SettingsDesign />
</TabContent>
</Tabs>
</div>
);
};

View File

@@ -5,7 +5,6 @@ import { useCheckForUpdates } from '../../hooks/useCheckForUpdates';
import { useSettings } from '../../hooks/useSettings';
import { useUpdateSettings } from '../../hooks/useUpdateSettings';
import { useUpdateWorkspace } from '../../hooks/useUpdateWorkspace';
import { trackEvent } from '../../lib/analytics';
import { Checkbox } from '../core/Checkbox';
import { Heading } from '../core/Heading';
import { IconButton } from '../core/IconButton';
@@ -36,10 +35,7 @@ export function SettingsGeneral() {
labelPosition="left"
size="sm"
value={settings.updateChannel}
onChange={(updateChannel) => {
trackEvent('setting', 'update', { update_channel: updateChannel });
updateSettings.mutate({ ...settings, updateChannel });
}}
onChange={(updateChannel) => updateSettings.mutate({ updateChannel })}
options={[
{ label: 'Release', value: 'stable' },
{ label: 'Early Bird (Beta)', value: 'beta' },
@@ -77,23 +73,15 @@ export function SettingsGeneral() {
<Checkbox
checked={workspace.settingValidateCertificates}
title="Validate TLS Certificates"
onChange={(settingValidateCertificates) => {
trackEvent('workspace', 'update', {
validate_certificates: JSON.stringify(settingValidateCertificates),
});
updateWorkspace.mutate({ settingValidateCertificates });
}}
onChange={(settingValidateCertificates) =>
updateWorkspace.mutate({ settingValidateCertificates })
}
/>
<Checkbox
checked={workspace.settingFollowRedirects}
title="Follow Redirects"
onChange={(settingFollowRedirects) => {
trackEvent('workspace', 'update', {
follow_redirects: JSON.stringify(settingFollowRedirects),
});
updateWorkspace.mutate({ settingFollowRedirects });
}}
onChange={(settingFollowRedirects) => updateWorkspace.mutate({ settingFollowRedirects })}
/>
</VStack>