164 lines
4.0 KiB
TypeScript
164 lines
4.0 KiB
TypeScript
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
|
|
const BASE_URL = process.env.REACT_APP_ARCAST_SERVER_BASE_URL ?? ""
|
|
|
|
export interface AppInfos {
|
|
defaultApp: string;
|
|
apps: App[];
|
|
}
|
|
|
|
export interface App {
|
|
id: string;
|
|
title: { [lang: string]: string };
|
|
description: { [lang: string]: string };
|
|
icon: string;
|
|
hidden: boolean;
|
|
}
|
|
|
|
export const usePlayerAppInfos = () => {
|
|
return useQuery({
|
|
queryKey: ["appsInfos"],
|
|
queryFn: getAppInfos,
|
|
select: (appInfos) => appInfos ?? { apps: [], defaultApp: "main" }
|
|
})
|
|
}
|
|
|
|
export async function getAppInfos() {
|
|
const response = await fetch(`${BASE_URL}/api/v1/apps`);
|
|
const result = await response.json();
|
|
const appInfos = result.data as AppInfos;
|
|
return appInfos;
|
|
}
|
|
|
|
|
|
export interface Status {
|
|
id: string
|
|
status: string
|
|
title: string
|
|
url: string
|
|
}
|
|
|
|
export const usePlayerStatus = () => {
|
|
return useQuery({
|
|
queryKey: ["playerStatus"],
|
|
queryFn: getStatus,
|
|
select: (status) => status ?? {}
|
|
})
|
|
}
|
|
|
|
export async function getStatus() {
|
|
const response = await fetch(`${BASE_URL}/api/v1/status`);
|
|
const result = await response.json();
|
|
const appInfos = result.data as Status;
|
|
return appInfos;
|
|
}
|
|
|
|
export interface BroadcastChannel {
|
|
opened: boolean
|
|
send: (data: string | ArrayBufferLike | Blob | ArrayBufferView) => void
|
|
close: () => void
|
|
}
|
|
|
|
export function getBroadcastChannel(channelId: string, onmessage?: (data: any) => void): BroadcastChannel {
|
|
let location: Location | URL = window.location
|
|
if (BASE_URL !== "") {
|
|
location = new URL(BASE_URL)
|
|
}
|
|
|
|
let scheme = "wss";
|
|
if (location.protocol === "http:") {
|
|
scheme = "ws";
|
|
}
|
|
|
|
var ws = new WebSocket(
|
|
`${scheme}://${location.host}/api/v1/broadcast/${channelId}`
|
|
);
|
|
|
|
const pending: (string | ArrayBufferLike | Blob | ArrayBufferView)[] = []
|
|
|
|
var channel = {
|
|
opened: false,
|
|
send: (message: string | ArrayBufferLike | Blob | ArrayBufferView) => {
|
|
if (channel.opened) {
|
|
ws.send(message);
|
|
} else {
|
|
pending.push(message)
|
|
}
|
|
},
|
|
close: () => {
|
|
ws.close();
|
|
},
|
|
};
|
|
|
|
ws.onmessage = (evt: MessageEvent<any>) => {
|
|
if (typeof onmessage !== "function") {
|
|
return;
|
|
}
|
|
|
|
onmessage(evt.data);
|
|
};
|
|
ws.onclose = () => {
|
|
ws.onmessage = null;
|
|
ws.onclose = null;
|
|
ws.onopen = null;
|
|
channel.opened = false;
|
|
};
|
|
ws.onopen = () => {
|
|
channel.opened = true;
|
|
while (pending.length > 0) {
|
|
const message = pending.shift()
|
|
if (message) ws.send(message)
|
|
}
|
|
};
|
|
|
|
return channel;
|
|
}
|
|
|
|
|
|
export async function cast(url: string): Promise<Status> {
|
|
const response = await fetch(`${BASE_URL}/api/v1/cast`, {
|
|
method: 'POST',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
body: JSON.stringify({ url })
|
|
});
|
|
const result = await response.json();
|
|
const status = result.data as Status;
|
|
return status;
|
|
}
|
|
|
|
export function useCast() {
|
|
const queryClient = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationFn: (params: { url: string }) => cast(params.url),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['playerStatus'] })
|
|
}
|
|
})
|
|
}
|
|
|
|
|
|
export async function reset(): Promise<Status> {
|
|
const response = await fetch(`${BASE_URL}/api/v1/cast`, {
|
|
method: 'DELETE',
|
|
headers: {
|
|
'Content-Type': 'application/json'
|
|
},
|
|
});
|
|
const result = await response.json();
|
|
const status = result.data as Status;
|
|
return status;
|
|
}
|
|
|
|
export function useReset() {
|
|
const queryClient = useQueryClient()
|
|
|
|
return useMutation({
|
|
mutationFn: () => reset(),
|
|
onSuccess: () => {
|
|
queryClient.invalidateQueries({ queryKey: ['playerStatus'] })
|
|
}
|
|
})
|
|
} |