Split codebase (#455)

This commit is contained in:
Gregory Schier
2026-05-07 15:50:10 -07:00
committed by GitHub
parent d2dc719cc6
commit 10559c8f4f
742 changed files with 7686 additions and 3249 deletions

View File

@@ -0,0 +1,241 @@
import { type } from "@tauri-apps/plugin-os";
import { useFonts } from "@yaakapp-internal/fonts";
import { useLicense } from "@yaakapp-internal/license";
import type { EditorKeymap, Settings } from "@yaakapp-internal/models";
import { patchModel, settingsAtom } from "@yaakapp-internal/models";
import { clamp, Heading, HStack, Icon, VStack } from "@yaakapp-internal/ui";
import { useAtomValue } from "jotai";
import { useState } from "react";
import { activeWorkspaceAtom } from "../../hooks/useActiveWorkspace";
import { showConfirm } from "../../lib/confirm";
import { invokeCmd } from "../../lib/tauri";
import { CargoFeature } from "../CargoFeature";
import { Button } from "../core/Button";
import { Checkbox } from "../core/Checkbox";
import { Link } from "../core/Link";
import { Select } from "../core/Select";
const NULL_FONT_VALUE = "__NULL_FONT__";
const fontSizeOptions = [
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 keymaps: { value: EditorKeymap; label: string }[] = [
{ value: "default", label: "Default" },
{ value: "vim", label: "Vim" },
{ value: "vscode", label: "VSCode" },
{ value: "emacs", label: "Emacs" },
];
export function SettingsInterface() {
const workspace = useAtomValue(activeWorkspaceAtom);
const settings = useAtomValue(settingsAtom);
const fonts = useFonts();
if (settings == null || workspace == null) {
return null;
}
return (
<VStack space={3} className="mb-4">
<div className="mb-3">
<Heading>Interface</Heading>
<p className="text-text-subtle">Tweak settings related to the user interface.</p>
</div>
<Select
name="switchWorkspaceBehavior"
label="Open workspace behavior"
size="sm"
help="When opening a workspace, should it open in the current window or a new window?"
value={
settings.openWorkspaceNewWindow === true
? "new"
: settings.openWorkspaceNewWindow === false
? "current"
: "ask"
}
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" },
{ label: "Open in current window", value: "current" },
{ label: "Open in new window", value: "new" },
]}
/>
<HStack space={2} alignItems="end">
{fonts.data && (
<Select
size="sm"
name="uiFont"
label="Interface font"
value={settings.interfaceFont ?? NULL_FONT_VALUE}
options={[
{ label: "System default", value: NULL_FONT_VALUE },
...(fonts.data.uiFonts.map((f) => ({
label: f,
value: f,
})) ?? []),
// Some people like monospace fonts for the UI
...(fonts.data.editorFonts.map((f) => ({
label: f,
value: f,
})) ?? []),
]}
onChange={async (v) => {
const interfaceFont = v === NULL_FONT_VALUE ? null : v;
await patchModel(settings, { interfaceFont });
}}
/>
)}
<Select
hideLabel
size="sm"
name="interfaceFontSize"
label="Interface Font Size"
defaultValue="14"
value={`${settings.interfaceFontSize}`}
options={fontSizeOptions}
onChange={(v) => patchModel(settings, { interfaceFontSize: Number.parseInt(v, 10) })}
/>
</HStack>
<HStack space={2} alignItems="end">
{fonts.data && (
<Select
size="sm"
name="editorFont"
label="Editor font"
value={settings.editorFont ?? NULL_FONT_VALUE}
options={[
{ label: "System default", value: NULL_FONT_VALUE },
...(fonts.data.editorFonts.map((f) => ({
label: f,
value: f,
})) ?? []),
]}
onChange={async (v) => {
const editorFont = v === NULL_FONT_VALUE ? null : v;
await patchModel(settings, { editorFont });
}}
/>
)}
<Select
hideLabel
size="sm"
name="editorFontSize"
label="Editor Font Size"
defaultValue="12"
value={`${settings.editorFontSize}`}
options={fontSizeOptions}
onChange={(v) =>
patchModel(settings, { editorFontSize: clamp(Number.parseInt(v, 10) || 14, 8, 30) })
}
/>
</HStack>
<Select
leftSlot={<Icon icon="keyboard" color="secondary" />}
size="sm"
name="editorKeymap"
label="Editor keymap"
value={`${settings.editorKeymap}`}
options={keymaps}
onChange={(v) => patchModel(settings, { editorKeymap: v })}
/>
<Checkbox
checked={settings.editorSoftWrap}
title="Wrap editor lines"
onChange={(editorSoftWrap) => patchModel(settings, { editorSoftWrap })}
/>
<Checkbox
checked={settings.coloredMethods}
title="Colorize request methods"
onChange={(coloredMethods) => patchModel(settings, { coloredMethods })}
/>
<CargoFeature feature="license">
<LicenseSettings settings={settings} />
</CargoFeature>
<NativeTitlebarSetting settings={settings} />
{type() !== "macos" && (
<Checkbox
checked={settings.hideWindowControls}
title="Hide window controls"
help="Hide the close/maximize/minimize controls on Windows or Linux"
onChange={(hideWindowControls) => patchModel(settings, { hideWindowControls })}
/>
)}
</VStack>
);
}
function NativeTitlebarSetting({ settings }: { settings: Settings }) {
const [nativeTitlebar, setNativeTitlebar] = useState(settings.useNativeTitlebar);
return (
<div className="flex gap-1 overflow-hidden h-2xs">
<Checkbox
checked={nativeTitlebar}
title="Native title bar"
help="Use the operating system's standard title bar and window controls"
onChange={setNativeTitlebar}
/>
{settings.useNativeTitlebar !== nativeTitlebar && (
<Button
color="primary"
size="2xs"
onClick={async () => {
await patchModel(settings, { useNativeTitlebar: nativeTitlebar });
await invokeCmd("cmd_restart");
}}
>
Apply and Restart
</Button>
)}
</div>
);
}
function LicenseSettings({ settings }: { settings: Settings }) {
const license = useLicense();
if (license.check.data?.status !== "personal_use") {
return null;
}
return (
<Checkbox
checked={settings.hideLicenseBadge}
title="Hide personal use badge"
onChange={async (hideLicenseBadge) => {
if (hideLicenseBadge) {
const confirmed = await showConfirm({
id: "hide-license-badge",
title: "Confirm Personal Use",
confirmText: "Confirm",
description: (
<VStack space={3}>
<p>Hey there 👋🏼</p>
<p>
Yaak is free for personal projects and learning.{" "}
<strong>If youre using Yaak at work, a license is required.</strong>
</p>
<p>
Licenses help keep Yaak independent and sustainable.{" "}
<Link href="https://yaak.app/pricing?s=badge">Purchase a License </Link>
</p>
</VStack>
),
requireTyping: "Personal Use",
color: "info",
});
if (!confirmed) {
return; // Cancel
}
}
await patchModel(settings, { hideLicenseBadge });
}}
/>
);
}