Merge branch 'main' of github.com:boudra/paseo
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { formatShortcut } from "./format-shortcut";
|
||||
|
||||
describe("formatShortcut", () => {
|
||||
it("uses symbols on macOS", () => {
|
||||
expect(formatShortcut(["mod", "B"], "mac")).toBe("⌘B");
|
||||
expect(formatShortcut(["mod", "E"], "mac")).toBe("⌘E");
|
||||
});
|
||||
|
||||
it("uses Ctrl+ on non-mac platforms", () => {
|
||||
expect(formatShortcut(["mod", "B"], "non-mac")).toBe("Ctrl+B");
|
||||
expect(formatShortcut(["mod", "E"], "non-mac")).toBe("Ctrl+E");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
export type ShortcutKey =
|
||||
| "mod"
|
||||
| "shift"
|
||||
| "alt"
|
||||
| "ctrl"
|
||||
| "meta"
|
||||
| string;
|
||||
|
||||
export type ShortcutOs = "mac" | "non-mac";
|
||||
|
||||
function normalizeKey(key: string): string {
|
||||
if (!key) return "";
|
||||
if (key.length === 1) return key.toUpperCase();
|
||||
return key;
|
||||
}
|
||||
|
||||
export function formatShortcut(keys: ShortcutKey[], os: ShortcutOs): string {
|
||||
const normalized = keys.map((k) => (typeof k === "string" ? k : String(k)));
|
||||
|
||||
if (os === "mac") {
|
||||
const order = ["ctrl", "alt", "shift", "mod", "meta"];
|
||||
const symbols: Record<string, string> = {
|
||||
mod: "⌘",
|
||||
shift: "⇧",
|
||||
alt: "⌥",
|
||||
ctrl: "⌃",
|
||||
meta: "⌘",
|
||||
};
|
||||
|
||||
const modifierSet = new Set(normalized);
|
||||
const mods = order
|
||||
.filter((k) => modifierSet.has(k))
|
||||
.map((k) => symbols[k] ?? "");
|
||||
const main = normalized
|
||||
.filter((k) => !order.includes(k))
|
||||
.map(normalizeKey)
|
||||
.join("");
|
||||
return `${mods.join("")}${main}`;
|
||||
}
|
||||
|
||||
const labels: Record<string, string> = {
|
||||
mod: "Ctrl",
|
||||
shift: "Shift",
|
||||
alt: "Alt",
|
||||
ctrl: "Ctrl",
|
||||
meta: "Win",
|
||||
};
|
||||
return normalized
|
||||
.map((k) => labels[k] ?? normalizeKey(k))
|
||||
.filter(Boolean)
|
||||
.join("+");
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
import { Platform } from "react-native";
|
||||
import { getIsTauriMac } from "@/constants/layout";
|
||||
import type { ShortcutOs } from "@/utils/format-shortcut";
|
||||
|
||||
export function getShortcutOs(): ShortcutOs {
|
||||
if (Platform.OS !== "web") {
|
||||
return Platform.OS === "ios" ? "mac" : "non-mac";
|
||||
}
|
||||
if (getIsTauriMac()) return "mac";
|
||||
if (typeof navigator === "undefined") return "non-mac";
|
||||
const ua = navigator.userAgent ?? "";
|
||||
const platform = (navigator as any).platform ?? "";
|
||||
const isApple =
|
||||
/Macintosh|Mac OS|iPhone|iPad|iPod/i.test(ua) ||
|
||||
/Mac|iPhone|iPad|iPod/i.test(platform);
|
||||
return isApple ? "mac" : "non-mac";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user