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,5 @@
export function fireAndForget(promise: Promise<unknown>) {
promise.catch((err: unknown) => {
console.error("Unhandled async error:", err);
});
}

View File

@@ -0,0 +1,63 @@
import type { ActionInvocation, ActionMetadata } from "@yaakapp-internal/proxy-lib";
import { rpc } from "./rpc";
type ActionBinding = {
invocation: ActionInvocation;
meta: ActionMetadata;
keys: { key: string; ctrl: boolean; shift: boolean; alt: boolean; meta: boolean };
};
/** Parse a hotkey string like "Ctrl+Shift+P" into its parts. */
function parseHotkey(hotkey: string): ActionBinding["keys"] {
const parts = hotkey.split("+").map((p) => p.trim().toLowerCase());
return {
ctrl: parts.includes("ctrl") || parts.includes("control"),
shift: parts.includes("shift"),
alt: parts.includes("alt"),
meta: parts.includes("meta") || parts.includes("cmd") || parts.includes("command"),
key:
parts.filter(
(p) => !["ctrl", "control", "shift", "alt", "meta", "cmd", "command"].includes(p),
)[0] ?? "",
};
}
function matchesEvent(binding: ActionBinding["keys"], e: KeyboardEvent): boolean {
return (
e.ctrlKey === binding.ctrl &&
e.shiftKey === binding.shift &&
e.altKey === binding.alt &&
e.metaKey === binding.meta &&
e.key.toLowerCase() === binding.key
);
}
/** Fetch all actions from Rust and register a global keydown listener. */
export async function initHotkeys(): Promise<() => void> {
const { actions } = await rpc("list_actions", {});
const bindings: ActionBinding[] = actions
.filter(
// oxlint-disable-next-line no-redundant-type-constituents -- ActionMetadata resolves at runtime
(entry): entry is [ActionInvocation, ActionMetadata & { defaultHotkey: string }] =>
entry[1].defaultHotkey != null,
)
.map(([invocation, meta]) => ({
invocation,
meta,
keys: parseHotkey(meta.defaultHotkey),
}));
function onKeyDown(e: KeyboardEvent) {
for (const binding of bindings) {
if (matchesEvent(binding.keys, e)) {
e.preventDefault();
void rpc("execute_action", binding.invocation);
return;
}
}
}
window.addEventListener("keydown", onKeyDown);
return () => window.removeEventListener("keydown", onKeyDown);
}

View File

@@ -0,0 +1,17 @@
import type { RpcEventSchema, RpcSchema } from "@yaakapp-internal/proxy-lib";
import { command, subscribe } from "./tauri";
export type Req<K extends keyof RpcSchema> = RpcSchema[K][0];
export type Res<K extends keyof RpcSchema> = RpcSchema[K][1];
export async function rpc<K extends keyof RpcSchema>(cmd: K, payload: Req<K>): Promise<Res<K>> {
return command<Res<K>>("rpc", { cmd, payload });
}
/** Subscribe to a backend event. Returns an unsubscribe function. */
export function listen<K extends keyof RpcEventSchema>(
event: K & string,
callback: (payload: RpcEventSchema[K]) => void,
): () => void {
return subscribe<RpcEventSchema[K]>(event, callback);
}

View File

@@ -0,0 +1,11 @@
import { createModelStore } from "@yaakapp-internal/model-store";
import type { HttpExchange } from "@yaakapp-internal/proxy-lib";
type ProxyModels = {
http_exchange: HttpExchange;
};
export const { dataAtom, applyChange, replaceAll, listAtom, orderedListAtom } =
createModelStore<ProxyModels>(["http_exchange"]);
export const httpExchangesAtom = orderedListAtom("http_exchange", "createdAt", "desc");

View File

@@ -0,0 +1,30 @@
import { invoke } from "@tauri-apps/api/core";
import { listen as tauriListen } from "@tauri-apps/api/event";
import { getCurrentWebviewWindow } from "@tauri-apps/api/webviewWindow";
import { type as tauriOsType } from "@tauri-apps/plugin-os";
/** Call a Tauri command. */
export function command<T>(cmd: string, args?: Record<string, unknown>): Promise<T> {
return invoke(cmd, args) as Promise<T>;
}
/** Subscribe to a Tauri event. Returns an unsubscribe function. */
export function subscribe<T>(event: string, callback: (payload: T) => void): () => void {
let unsub: (() => void) | null = null;
tauriListen<T>(event, (e) => callback(e.payload))
.then((fn) => {
unsub = fn;
})
.catch(console.error);
return () => unsub?.();
}
/** Show the current webview window. */
export function showWindow(): Promise<void> {
return getCurrentWebviewWindow().show();
}
/** Get the current OS type (e.g. "macos", "linux", "windows"). */
export function getOsType() {
return tauriOsType();
}

View File

@@ -0,0 +1,35 @@
import { setWindowTheme } from "@yaakapp-internal/mac-window";
import {
applyThemeToDocument,
defaultDarkTheme,
defaultLightTheme,
getCSSAppearance,
platformFromUserAgent,
setPlatformOnDocument,
subscribeToPreferredAppearance,
type Appearance,
} from "@yaakapp-internal/theme";
import { showWindow } from "./tauri";
setPlatformOnDocument(platformFromUserAgent(navigator.userAgent));
// Apply a quick initial theme based on CSS media query
let preferredAppearance: Appearance = getCSSAppearance();
applyTheme(preferredAppearance);
// Then subscribe to accurate OS appearance detection and changes
subscribeToPreferredAppearance((a) => {
preferredAppearance = a;
applyTheme(preferredAppearance);
});
// Show window after initial theme is applied (window starts hidden to prevent flash)
showWindow().catch(console.error);
function applyTheme(appearance: Appearance) {
const theme = appearance === "dark" ? defaultDarkTheme : defaultLightTheme;
applyThemeToDocument(theme);
if (theme.base.surface != null) {
setWindowTheme(theme.base.surface);
}
}