355b14faef
Enable App Store builds without EAS, iOS 18 App Intents plugins, and signing fixes for distribution export. Add mobile invoice PDF preview, compact line items, and more reliable shortcut deep-link handling. Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
1.8 KiB
TypeScript
66 lines
1.8 KiB
TypeScript
import * as Linking from "expo-linking";
|
|
|
|
export type ShortcutAction = "clock-in" | "clock-out" | "open-timer";
|
|
|
|
export type ParsedShortcut = {
|
|
action: ShortcutAction;
|
|
title: string;
|
|
clientId: string;
|
|
};
|
|
|
|
function queryParam(value: string | string[] | undefined): string {
|
|
if (Array.isArray(value)) return value[0] ?? "";
|
|
return value ?? "";
|
|
}
|
|
|
|
function normalizeShortcutPath(hostname: string | null, path: string | null): string | null {
|
|
const host = (hostname ?? "").replace(/^\/+|\/+$/g, "");
|
|
const segment = (path ?? "").replace(/^\/+|\/+$/g, "");
|
|
|
|
if (host === "shortcuts" && segment) {
|
|
return segment;
|
|
}
|
|
|
|
const combined = [host, segment].filter(Boolean).join("/");
|
|
const match = combined.match(/(?:^|\/)shortcuts\/(clock-in|clock-out)$/);
|
|
if (match?.[1]) return match[1];
|
|
|
|
if (combined === "clock-in" || combined === "clock-out") {
|
|
return combined;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/** Parse `beenvoice://shortcuts/clock-in` and related URLs from Shortcuts / Siri. */
|
|
export function parseShortcutUrl(url: string | null | undefined): ParsedShortcut | null {
|
|
if (!url) return null;
|
|
|
|
const parsed = Linking.parse(url);
|
|
if (parsed.scheme !== "beenvoice") return null;
|
|
|
|
const path = (parsed.path ?? "").replace(/^\/+/, "");
|
|
const host = parsed.hostname ?? "";
|
|
|
|
if (path === "timer" || host === "timer") {
|
|
return { action: "open-timer", title: "", clientId: "" };
|
|
}
|
|
|
|
const shortcutAction = normalizeShortcutPath(host, path);
|
|
if (shortcutAction === "clock-in" || shortcutAction === "clock-out") {
|
|
return {
|
|
action: shortcutAction,
|
|
title: queryParam(parsed.queryParams?.title),
|
|
clientId: queryParam(parsed.queryParams?.clientId),
|
|
};
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
export const SHORTCUT_URLS = {
|
|
timer: "beenvoice://timer",
|
|
clockIn: "beenvoice://shortcuts/clock-in",
|
|
clockOut: "beenvoice://shortcuts/clock-out",
|
|
} as const;
|