Files
wehub-resource-sync 6ede33ccdb
Build and Push Docker Images / create_manifest (web, surfsense-web, , cpu) (push) Has been cancelled
Build and Push Docker Images / finalize_release (push) Has been cancelled
Obsidian Plugin Lint / lint (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_web, cpu, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-24.04-arm, linux/arm64, arm64, , runner, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_web, cpu, ./surfsense_web/Dockerfile, web, surfsense-web, ubuntu-latest, linux/amd64, amd64, , runner, false, cpu) (push) Has been cancelled
Build and Push Docker Images / compute_version (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cpu, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, , production, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cpu, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, , production, false, cpu) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu126, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, -cuda126, production, true, cuda126) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu126, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, -cuda126, production, true, cuda126) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu128, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-24.04-arm, linux/arm64, arm64, -cuda, production, true, cuda) (push) Has been cancelled
Build and Push Docker Images / build (./surfsense_backend, cu128, ./surfsense_backend/Dockerfile, backend, surfsense-backend, ubuntu-latest, linux/amd64, amd64, -cuda, production, true, cuda) (push) Has been cancelled
Build and Push Docker Images / verify_digests (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, , cpu) (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, -cuda, cuda) (push) Has been cancelled
Build and Push Docker Images / create_manifest (backend, surfsense-backend, -cuda126, cuda126) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:33:44 +08:00

70 lines
1.6 KiB
TypeScript

import { useCallback, useEffect, useState } from "react";
interface NavigatorUAData {
platform: string;
}
function getIsMac() {
if (typeof navigator === "undefined") return false;
// Modern API (Chromium browsers: Chrome, Edge, Opera)
const uaData = (navigator as Navigator & { userAgentData?: NavigatorUAData }).userAgentData;
if (uaData?.platform) {
return uaData.platform === "macOS";
}
// Fallback for Firefox/Safari
return /Mac|iPhone/.test(navigator.platform);
}
/**
* Returns a helper that formats keyboard shortcut strings with
* platform-aware modifier symbols.
*
* SSR-safe: returns an empty string until mounted so there is no hydration
* mismatch.
*/
export function usePlatformShortcut() {
const [ready, setReady] = useState(false);
const [isMac, setIsMac] = useState(false);
useEffect(() => {
setIsMac(getIsMac());
setReady(true);
}, []);
const resolveKeys = useCallback(
(keys: string[]) => {
const mod = isMac ? "⌘" : "Ctrl";
const shift = isMac ? "⇧" : "Shift";
const alt = isMac ? "⌥" : "Alt";
return keys.map((k) => {
if (k === "Mod") return mod;
if (k === "Shift") return shift;
if (k === "Alt") return alt;
return k;
});
},
[isMac]
);
const shortcut = useCallback(
(...keys: string[]) => {
if (!ready) return "";
return `(${resolveKeys(keys).join("+")})`;
},
[ready, resolveKeys]
);
const shortcutKeys = useCallback(
(...keys: string[]) => {
if (!ready) return [];
return resolveKeys(keys);
},
[ready, resolveKeys]
);
return { shortcut, shortcutKeys, isMac, ready };
}