Fix window stoplights

This commit is contained in:
Gregory Schier
2024-05-29 22:59:34 -07:00
parent 8cd3961f87
commit 14b3abf76c
17 changed files with 321 additions and 357 deletions

View File

@@ -3,6 +3,7 @@ import { routePaths, useAppRoutes } from '../hooks/useAppRoutes';
import { DefaultLayout } from './DefaultLayout';
import { RedirectToLatestWorkspace } from './RedirectToLatestWorkspace';
import RouteError from './RouteError';
import { SettingsDialog } from './Settings/SettingsDialog';
import Workspace from './Workspace';
const router = createBrowserRouter([
@@ -36,6 +37,12 @@ const router = createBrowserRouter([
path: '/workspaces/:workspaceId/environments/:environmentId/requests/:requestId',
element: <RedirectLegacyEnvironmentURLs />,
},
{
path: routePaths.workspaceSettings({
workspaceId: ':workspaceId',
}),
element: <SettingsDialog fullscreen />,
},
],
},
]);

View File

@@ -21,7 +21,6 @@ import { useRequestUpdateKey } from '../hooks/useRequestUpdateKey';
import { settingsQueryKey, useSettings } from '../hooks/useSettings';
import { useSyncThemeToDocument } from '../hooks/useSyncThemeToDocument';
import { useSyncWindowTitle } from '../hooks/useSyncWindowTitle';
import { useUpdateSettings } from '../hooks/useUpdateSettings';
import { workspacesQueryKey } from '../hooks/useWorkspaces';
import { useZoom } from '../hooks/useZoom';
import type { Model } from '../lib/models';
@@ -140,7 +139,6 @@ export function GlobalHooks() {
`--editor-font-size: ${editorFontSize}px`,
].join('; ');
}, [settings]);
const updateSettings = useUpdateSettings();
// Handle Zoom. Note, Mac handles it in app menu, so need to also handle keyboard
// shortcuts for Windows/Linux
@@ -149,21 +147,8 @@ export function GlobalHooks() {
useListenToTauriEvent('zoom_in', () => zoom.zoomIn);
useHotKey('app.zoom_out', () => zoom.zoomOut);
useListenToTauriEvent('zoom_out', () => zoom.zoomOut);
useHotKey('app.zoom_out', () => zoom.zoomReset);
useListenToTauriEvent('zoom_out', () => zoom.zoomReset);
useHotKey('app.zoom_out', () => {
if (!settings) return;
updateSettings.mutate({
...settings,
interfaceScale: Math.max(0.4, settings.interfaceScale * 0.9),
});
});
useHotKey('app.zoom_reset', () => {
if (!settings) return;
updateSettings.mutate({ ...settings, interfaceScale: 1 });
});
useHotKey('app.zoom_reset', () => zoom.zoomReset);
useListenToTauriEvent('zoom_reset', () => zoom.zoomReset);
return null;
}

View File

@@ -1,4 +1,3 @@
import { invoke } from '@tauri-apps/api/core';
import React from 'react';
import { useActiveWorkspace } from '../../hooks/useActiveWorkspace';
import { useResolvedAppearance } from '../../hooks/useResolvedAppearance';
@@ -10,10 +9,8 @@ import { trackEvent } from '../../lib/analytics';
import { clamp } from '../../lib/clamp';
import { isThemeDark } from '../../lib/theme/window';
import type { ButtonProps } from '../core/Button';
import { Button } from '../core/Button';
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';
@@ -83,6 +80,7 @@ export function SettingsAppearance() {
name="interfaceFontSize"
label="Font Size"
placeholder="16"
step={0.5}
type="number"
labelPosition="left"
defaultValue={`${settings.interfaceFontSize}`}
@@ -99,6 +97,7 @@ export function SettingsAppearance() {
name="editorFontSize"
label="Editor Font Size"
placeholder="14"
step={0.5}
type="number"
labelPosition="left"
defaultValue={`${settings.editorFontSize}`}
@@ -124,35 +123,40 @@ export function SettingsAppearance() {
trackEvent('setting', 'update', { appearance });
}}
options={[
{ label: 'Sync with OS', value: 'system' },
{ label: 'Automatic', value: 'system' },
{ label: 'Light', value: 'light' },
{ label: 'Dark', value: 'dark' },
]}
/>
<Select
name="lightTheme"
label="Light Theme"
labelPosition="left"
size="sm"
value={activeTheme.light.id}
options={lightThemes}
onChange={async (themeLight) => {
await updateSettings.mutateAsync({ ...settings, themeLight });
trackEvent('setting', 'update', { themeLight });
}}
/>
<Select
name="darkTheme"
label="Dark Theme"
labelPosition="left"
size="sm"
value={activeTheme.dark.id}
options={darkThemes}
onChange={async (themeDark) => {
await updateSettings.mutateAsync({ ...settings, themeDark });
trackEvent('setting', 'update', { themeDark });
}}
/>
{(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 });
}}
/>
)}
<VStack
space={3}
className="mt-3 w-full bg-background p-3 border border-dashed border-background-highlight rounded overflow-x-auto"
@@ -196,18 +200,6 @@ export function SettingsAppearance() {
contentType="application/javascript"
/>
</VStack>
<Button
color="secondary"
variant="border"
size="sm"
className="mr-auto"
rightSlot={<Icon icon="externalLink" />}
onClick={async () => {
await invoke('cmd_new_window', { url: window.location.pathname });
}}
>
Open Preview Window
</Button>
</VStack>
);
}

View File

@@ -18,13 +18,25 @@ enum Tab {
const tabs = [Tab.General, Tab.Appearance, Tab.Design];
const useTabState = createGlobalState<string>(tabs[0]!);
export const SettingsDialog = () => {
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('w-[70vw] max-w-[40rem]', 'h-[80vh]')}>
<div className={classNames(!fullscreen && 'w-[70vw] max-w-[40rem] h-[80vh]')}>
{fullscreen && (
<div
data-tauri-drag-region
className="h-[38px] bg-background-highlight-secondary flex items-center justify-center border-b border-background-highlight"
>
Settings
</div>
)}
<Tabs
value={tab}
addBorders

View File

@@ -1,6 +1,9 @@
import { invoke } from '@tauri-apps/api/core';
import { open } from '@tauri-apps/plugin-shell';
import { useRef } from 'react';
import { useActiveWorkspaceId } from '../hooks/useActiveWorkspaceId';
import { useAppInfo } from '../hooks/useAppInfo';
import { useAppRoutes } from '../hooks/useAppRoutes';
import { useCheckForUpdates } from '../hooks/useCheckForUpdates';
import { useExportData } from '../hooks/useExportData';
import { useImportData } from '../hooks/useImportData';
@@ -20,6 +23,8 @@ export function SettingsDropdown() {
const dropdownRef = useRef<DropdownRef>(null);
const dialog = useDialog();
const checkForUpdates = useCheckForUpdates();
const routes = useAppRoutes();
const workspaceId = useActiveWorkspaceId();
const showSettings = () => {
dialog.show({
@@ -58,6 +63,20 @@ export function SettingsDropdown() {
});
},
},
{
key: 'foo',
label: 'Foo',
hotKeyAction: 'hotkeys.showHelp',
leftSlot: <Icon icon="keyboard" />,
onSelect: async () => {
if (!workspaceId) return;
await invoke('cmd_new_nested_window', {
url: routes.paths.workspaceSettings({ workspaceId }),
label: 'settings',
title: 'Yaak Settings',
});
},
},
{
key: 'import-data',
label: 'Import Data',

View File

@@ -7,6 +7,7 @@ import { HStack } from './Stacks';
export type PlainInputProps = Omit<InputProps, 'wrapLines' | 'onKeyDown' | 'type'> & {
type: 'text' | 'password' | 'number';
step?: number;
};
export const PlainInput = forwardRef<HTMLInputElement, PlainInputProps>(function Input(

View File

@@ -1,9 +1,9 @@
import { useNavigate } from 'react-router-dom';
import { QUERY_ENVIRONMENT_ID } from './useActiveEnvironmentId';
import { useActiveWorkspaceId } from './useActiveWorkspaceId';
import { useActiveRequestId } from './useActiveRequestId';
import type { Environment } from '../lib/models';
import { useCallback } from 'react';
import { useNavigate } from 'react-router-dom';
import type { Environment } from '../lib/models';
import { QUERY_ENVIRONMENT_ID } from './useActiveEnvironmentId';
import { useActiveRequestId } from './useActiveRequestId';
import { useActiveWorkspaceId } from './useActiveWorkspaceId';
export type RouteParamsWorkspace = {
workspaceId: string;
@@ -18,6 +18,9 @@ export const routePaths = {
workspaces() {
return '/workspaces';
},
workspaceSettings({ workspaceId } = { workspaceId: ':workspaceId' } as RouteParamsWorkspace) {
return `/workspaces/${workspaceId}/settings`;
},
workspace(
{ workspaceId, environmentId } = {
workspaceId: ':workspaceId',

View File

@@ -12,6 +12,7 @@ export function useSettings() {
queryKey: settingsQueryKey(),
queryFn: async () => {
const settings = (await invoke('cmd_get_settings')) as Settings;
console.log('SETTINGS', settings);
return [settings];
},
}).data?.[0] ?? undefined

View File

@@ -1,4 +1,3 @@
import { emit } from '@tauri-apps/api/event';
import { getCurrent } from '@tauri-apps/api/webviewWindow';
import { useEffect } from 'react';
import { fallbackRequestName } from '../lib/fallbackRequestName';
@@ -12,7 +11,12 @@ export function useSyncWindowTitle() {
const activeWorkspace = useActiveWorkspace();
const activeEnvironment = useActiveEnvironment();
const osInfo = useOsInfo();
useEffect(() => {
if (osInfo?.osType == null) {
return;
}
let newTitle = activeWorkspace ? activeWorkspace.name : 'Yaak';
if (activeEnvironment) {
newTitle += ` [${activeEnvironment.name}]`;
@@ -25,9 +29,10 @@ export function useSyncWindowTitle() {
// TODO: This resets the stoplight position so we can't use it on macOS yet. Perhaps
// we can
if (osInfo?.osType !== 'macos') {
console.log('DO IT', osInfo?.osType);
getCurrent().setTitle(newTitle).catch(console.error);
} else {
emit('yaak_title_changed', newTitle).catch(console.error);
// emit('yaak_title_changed', newTitle).catch(console.error);
}
}, [activeEnvironment, activeRequest, activeWorkspace, osInfo?.osType]);
}

View File

@@ -2,7 +2,6 @@ import { catppuccin } from './themes/catppuccin';
import { github } from './themes/github';
import { hotdogStand } from './themes/hotdog-stand';
import { monokaiPro } from './themes/monokai-pro';
import { relaxing } from './themes/relaxing';
import { rosePine } from './themes/rose-pine';
import { yaak, yaakDark, yaakLight } from './themes/yaak';
@@ -12,7 +11,6 @@ export const defaultLightTheme = yaakLight;
export const yaakThemes = [
...yaak,
...catppuccin,
...relaxing,
...rosePine,
...github,
...monokaiPro,

View File

@@ -3,7 +3,7 @@ import type { YaakTheme } from '../window';
const githubDark: YaakTheme = {
id: 'github-dark',
name: 'GitHub',
name: 'GitHub Dark',
background: new Color('#0d1218', 'dark'),
backgroundHighlight: new Color('#171c23', 'dark'),
backgroundHighlightSecondary: new Color('#1c2127', 'dark'),
@@ -36,7 +36,7 @@ const githubDark: YaakTheme = {
export const githubLight: YaakTheme = {
id: 'github-light',
name: 'GitHub',
name: 'GitHub Light',
background: new Color('#ffffff', 'light'),
backgroundHighlight: new Color('hsl(210,15%,92%)', 'light'),
backgroundHighlightSecondary: new Color('hsl(210,29%,94%)', 'light'),

View File

@@ -1,20 +0,0 @@
import { Color } from '../color';
import type { YaakTheme } from '../window';
const relaxingDefault: YaakTheme = {
name: 'Relaxing',
id: 'relaxing',
background: new Color('#2b1e3b', 'dark'),
foreground: new Color('#ede2f5', 'dark'),
colors: {
primary: new Color('#cba6f7', 'dark'),
secondary: new Color('#bac2de', 'dark'),
info: new Color('#89b4fa', 'dark'),
success: new Color('#a6e3a1', 'dark'),
notice: new Color('#f9e2af', 'dark'),
warning: new Color('#fab387', 'dark'),
danger: new Color('#f38ba8', 'dark'),
},
};
export const relaxing = [relaxingDefault];

View File

@@ -3,7 +3,7 @@ import type { YaakTheme } from '../window';
export const yaakLight: YaakTheme = {
id: 'yaak-light',
name: 'Yaak',
name: 'Yaak Light',
background: new Color('hsl(216,24%,100%)', 'light'),
backgroundHighlight: new Color('hsl(216,24%,93%)', 'light'),
backgroundHighlightSecondary: new Color('hsl(216,24%,87%)', 'light'),
@@ -30,7 +30,7 @@ export const yaakLight: YaakTheme = {
export const yaakDark: YaakTheme = {
id: 'yaak-dark',
name: 'Yaak',
name: 'Yaak Dark',
background: new Color('hsl(244,23%,14%)', 'dark'),
backgroundHighlight: new Color('hsl(244,23%,23%)', 'dark'),
backgroundHighlightSecondary: new Color('hsl(244,23%,20%)', 'dark'),