Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Starting on asset upload. #72

Merged
merged 4 commits into from
Oct 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions client/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ const DocLayout = lazy(() => import("./docs"));
const Config = lazy(() => import("./pages/Config"));

const MainPage = () => {
// const {netSend} = useThorium();

return (
<div className="welcome h-full p-12 grid grid-cols-2 grid-rows-2">
<WelcomeLogo />
Expand Down
4 changes: 2 additions & 2 deletions client/src/components/FlightLobby.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@ import {useClientData} from "../context/useCardData";
import {usePrompt} from "@thorium/ui/AlertDialog";
import {FaSpinner} from "react-icons/fa";
import Button from "@thorium/ui/Button";
import {useNetSend} from "../context/useNetSend";

export function FlightLobby() {
const prompt = usePrompt();
const navigate = useNavigate();
const {netSend} = useThorium();
const clientData = useClientData();

const netSend = useNetSend();
return (
<div className="flex flex-col justify-center items-center h-full filter drop-shadow-lg space-y-8">
<h1 className="text-6xl text-white font-bold">
Expand Down
17 changes: 2 additions & 15 deletions client/src/context/ThoriumContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,6 @@ interface IThoriumContext {
SI: SnapshotInterpolation;
channel: ClientChannel;
socket: ClientSocket;
netSend<
InputName extends AllInputNames,
Params extends AllInputParams[InputName],
Return extends AllInputReturns[InputName]
>(
type: InputName,
params?: Params
): Promise<Return>;
}

const Reconnecting = () => {
Expand Down Expand Up @@ -67,7 +59,7 @@ const Disconnected = () => {

const SI = new SnapshotInterpolation(serverFPS);
export function ThoriumProvider({children}: {children: ReactNode}) {
const {channel, socket, reconnectionState, netSend} = useDataConnection();
const {channel, socket, reconnectionState} = useDataConnection();

useEffect(() => {
channel?.onRaw(snapshot => {
Expand All @@ -81,10 +73,9 @@ export function ThoriumProvider({children}: {children: ReactNode}) {
return {
channel,
socket,
netSend,
SI,
};
}, [channel, socket, netSend]);
}, [channel, socket]);

return (
<ThoriumContext.Provider value={value}>
Expand All @@ -99,7 +90,3 @@ export function useThorium() {
if (!ctx) throw new Error("Thorium Context has not been initialized.");
return ctx;
}

export const useNetSend = () => {
return useThorium().netSend;
};
38 changes: 38 additions & 0 deletions client/src/context/useNetSend.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {AllInputNames, AllInputParams, AllInputReturns} from "@thorium/inputs";
import {getTabId} from "@thorium/tab-id";

export function useNetSend(): <
InputName extends AllInputNames,
Params extends AllInputParams[InputName],
Return extends AllInputReturns[InputName]
>(
type: InputName,
params?: Params
) => Promise<Return> {
return async function netSend(type, params) {
const clientId = await getTabId();
const body = new FormData();
body.append("input", type.toString());
for (const key in params) {
const value = params[key];
if (value instanceof File) {
body.append(key, value);
params[key] = {} as any;
}
if (value instanceof FileList) {
for (let i = 0; i < value.length; i++) {
body.append(`${key}[]`, value[i]);
}
params[key] = [] as any;
}
}
body.append("params", JSON.stringify(params));
const response = await fetch(`/netSend`, {
method: "POST",
headers: {authorization: `Bearer ${clientId}`},
body,
});
const json = await response.json();
return json;
};
}
64 changes: 2 additions & 62 deletions client/src/hooks/useDataConnection.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import {ClientChannel} from "@geckos.io/client";
import {useCallback, useEffect, useRef, useState} from "react";
import {useCallback, useEffect, useState} from "react";
import {loadDataChannel, loadWebSocket} from "../utils/dataChannel";
import uniqid from "@thorium/uniqid";
import {ClientSocket} from "../utils/clientSocket";

export type NetResponseData =
Expand All @@ -16,12 +15,6 @@ export function useDataConnection() {
const [reconnectionState, setReconnectionState] = useState<
"idle" | "connected" | "connecting" | "reconnecting" | "disconnected"
>("idle");
const requestResponses = useRef<
Record<
string,
{resolve: (value: any) => void; reject: (reason?: any) => void}
>
>({});

const startDataConnection = useCallback(async function startDataConnection() {
try {
Expand Down Expand Up @@ -58,58 +51,5 @@ export function useDataConnection() {
startDataConnection();
}, [startDataConnection]);

useEffect(() => {
if (socket) {
const handleNetResponse = (data: NetResponseData) => {
if (typeof data !== "object") {
throw new Error(`netResponse data must be an object. Got "${data}"`);
}

if (!("requestId" in data && "response" in data)) {
const dataString = JSON.stringify(data, null, 2);
throw new Error(
`netResponse data must include a requestId and a response. Got ${dataString}`
);
}

const responseCallback = requestResponses.current[data.requestId];
if (!responseCallback) {
throw new Error(`No response callback for ${data.requestId}`);
}
if (data.error) {
return responseCallback.reject(data.error);
}
responseCallback.resolve(data.response);
delete requestResponses.current[data.requestId];
};
socket.on("netResponse", handleNetResponse);
return () => {
socket.off("netResponse", handleNetResponse);
};
}
}, [socket]);

const netSend = useCallback(
async function netSend(inputName, inputParams) {
const TIMEOUT_MS = 3000;
// This Promise.race means that the server has TIMEOUT_MS to respond to any netSend.
// It results in a rejection which must be handled somehow.
const requestId = uniqid("ns-");
return Promise.race([
new Promise((resolve, reject) => {
socket.send("netSend", {inputName, params: inputParams, requestId});
requestResponses.current[requestId] = {resolve, reject};
}),
new Promise((_, rej) =>
setTimeout(() => {
delete requestResponses.current[requestId];
rej(`Timeout getting response for input: ${inputName}`);
}, TIMEOUT_MS)
),
// Assert `any` to make the AllInputReturns inference work correctly
]) as Promise<any>;
},
[socket]
);
return {channel, reconnectionState, netSend, socket};
return {channel, reconnectionState, socket};
}
2 changes: 1 addition & 1 deletion client/src/pages/Config/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ import Menubar from "@thorium/ui/Menubar";
import SearchableList from "@thorium/ui/SearchableList";
import TagInput from "@thorium/ui/TagInput";
import UploadWell from "@thorium/ui/UploadWell";
import {useNetSend} from "client/src/context/ThoriumContext";
import {useNetRequest} from "client/src/context/useNetRequest";
import {useNetSend} from "client/src/context/useNetSend";
import {useState} from "react";
import {FaEdit} from "react-icons/fa";
import {NavLink, useNavigate, useParams} from "react-router-dom";
Expand Down
3 changes: 3 additions & 0 deletions client/vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ export default defineConfig(async () => {
// Allow serving files from one level up to the project root
allow: [".."],
},
proxy: {
"/netSend": "http://localhost:3001",
},
},
};
});
Loading