110 lines
3.1 KiB
TypeScript
110 lines
3.1 KiB
TypeScript
/* eslint-disable @typescript-eslint/no-empty-function */
|
|
|
|
import { useAutoplayPayloadStore } from "@/stores/autoplay-payload-store";
|
|
import type { AutoplayPayload } from "@/lib/autoplay-ipc";
|
|
import { apiClient } from "@/api/client";
|
|
import type { Platform } from "./types";
|
|
|
|
declare const __APP_VERSION__: string;
|
|
|
|
function detectWebPlatform(): "darwin" | "win32" | "linux" | "web" {
|
|
if (typeof navigator === "undefined") return "web";
|
|
const ua = navigator.userAgent;
|
|
if (/Mac|iPhone|iPad|iPod/i.test(ua)) return "darwin";
|
|
if (/Win/i.test(ua)) return "win32";
|
|
if (/Linux|X11/i.test(ua)) return "linux";
|
|
return "web";
|
|
}
|
|
|
|
function downloadCrossOrigin(url: string, filename?: string) {
|
|
const a = document.createElement("a");
|
|
a.href = url;
|
|
if (filename) a.download = filename;
|
|
a.target = "_blank";
|
|
a.rel = "noopener noreferrer";
|
|
document.body.appendChild(a);
|
|
a.click();
|
|
document.body.removeChild(a);
|
|
}
|
|
|
|
const baseTitle = typeof document !== "undefined" ? document.title : "llink";
|
|
|
|
function applyDockBadge(count: number) {
|
|
if (typeof document === "undefined") return;
|
|
document.title = count > 0 ? `(${count}) ${baseTitle}` : baseTitle;
|
|
}
|
|
|
|
const NOT_SUPPORTED = "Not supported in the web app";
|
|
|
|
export const webPlatform: Platform = {
|
|
kind: "web",
|
|
|
|
window: {
|
|
minimize: () => {},
|
|
maximize: () => {},
|
|
fullscreen: () => {},
|
|
close: () => {},
|
|
onMaximizeChange: () => () => {},
|
|
platform: detectWebPlatform(),
|
|
},
|
|
|
|
huddle: {
|
|
isSupported: false,
|
|
open: () => { throw new Error(NOT_SUPPORTED); },
|
|
close: () => {},
|
|
getScreenSources: async () => { throw new Error(NOT_SUPPORTED); },
|
|
},
|
|
|
|
screenRecord: {
|
|
isSupported: false,
|
|
start: () => { throw new Error(NOT_SUPPORTED); },
|
|
stop: () => {},
|
|
cancel: () => {},
|
|
onStopRequested: () => () => {},
|
|
getScreenSources: async () => { throw new Error(NOT_SUPPORTED); },
|
|
},
|
|
|
|
autoplay: {
|
|
play: (payload: AutoplayPayload) => {
|
|
useAutoplayPayloadStore.getState().setPayload(payload);
|
|
},
|
|
dismiss: () => {
|
|
useAutoplayPayloadStore.getState().setPayload(null);
|
|
},
|
|
navigate: (d) => {
|
|
useAutoplayPayloadStore.getState().setPayload(null);
|
|
useAutoplayPayloadStore.getState().setPendingNav(d);
|
|
},
|
|
onPlay: (cb) =>
|
|
useAutoplayPayloadStore.subscribe((state, prev) => {
|
|
if (state.payload && state.payload !== prev.payload) cb(state.payload);
|
|
}),
|
|
onStop: (cb) =>
|
|
useAutoplayPayloadStore.subscribe((state, prev) => {
|
|
if (!state.payload && prev.payload) cb();
|
|
}),
|
|
onNavigate: (cb) =>
|
|
useAutoplayPayloadStore.subscribe((state, prev) => {
|
|
if (state.pendingNav && state.pendingNav !== prev.pendingNav) {
|
|
cb({ networkId: state.pendingNav.networkId, streamId: state.pendingNav.streamId });
|
|
}
|
|
}),
|
|
},
|
|
|
|
link: {
|
|
fetchMetadata: (url) => apiClient.getLinkMetadata(url).catch(() => null),
|
|
openExternal: async (url) => {
|
|
window.open(url, "_blank", "noopener,noreferrer");
|
|
},
|
|
},
|
|
|
|
attachment: {
|
|
download: downloadCrossOrigin,
|
|
},
|
|
|
|
app: {
|
|
setDockBadge: applyDockBadge,
|
|
getVersion: async () => __APP_VERSION__,
|
|
},
|
|
};
|