Add error modal, trap modal events, and some UI changes

main
idylls 1 year ago
parent 3f94ffccb1
commit 6de6dc5fd1
Signed by: idylls
GPG Key ID: 52D7502B0C319049

@ -0,0 +1 @@
export class WalkyError extends Error {}

@ -9,6 +9,7 @@ import {
import { AcceptDecision, initNetworking } from "./networking.ts";
import { PeerID } from "../common/types.ts";
import { showModal } from "./ui.ts";
import { WalkyError } from "./error.ts";
type LatLng = {
lat: number;
@ -72,7 +73,7 @@ const init = async () => {
const onPeerConnectionRequest = (peerID: PeerID) => {
return new Promise<AcceptDecision>((r) => {
let secondsLeft = 5;
let secondsLeft = 30;
const interval = setInterval(() => {
secondsLeft--;
if (secondsLeft <= 0) {
@ -153,8 +154,23 @@ const init = async () => {
const peersList = swel("div", { id: "peers" });
const lobby = swel("div", { id: "lobby" }, [
peersList,
swel("div", { id: "peerID" }, net.peerID),
swel("div", [peerIDInput, connectButton]),
swel("div", { className: "controls" }, [
swel("div", { id: "peerID" }, [
`Your ID: ${net.peerID}`,
swel(
"button",
{
on: {
click: () => {
navigator.clipboard.writeText(`${net.peerID}`);
},
},
},
"📋",
),
]),
swel("div", [peerIDInput, connectButton]),
]),
]);
const mapContainer = swel("div", { id: "map" });
@ -200,3 +216,8 @@ const init = async () => {
};
(window as unknown as { init: typeof init })["init"] = init;
addEventListener("error", (ev) => {
if (ev.error instanceof WalkyError) {
showModal({ content: `An error occured: ${ev.error}` });
}
});

@ -7,6 +7,7 @@ import {
} from "../common/types.ts";
import { pearServerSocketAddress, rtcConfiguration } from "../ui.config.ts";
import { WalkyError } from "./error.ts";
export type AcceptDecision = true | false;
@ -42,7 +43,7 @@ export const initNetworking = async (p: {
console.debug(data);
if ("error" in data) {
throw new Error(data.error);
throw new WalkyError(data.error);
}
const handler = on[data.kind];
@ -86,14 +87,8 @@ export const initNetworking = async (p: {
pa(msg.answer);
};
const rtcPeerConnection = (peerID: PeerID) => {
const rtcPeerConnection = () => {
const rtc = new RTCPeerConnection(rtcConfiguration);
rtc.addEventListener("icecandidate", (ev) => {
if (ev.candidate) {
send({ kind: "iceCandidate", candidate: ev.candidate, peerID });
}
});
const connected = new Promise((r) => {
rtc.addEventListener("iceconnectionstatechange", (_ev) => {
console.debug(rtc.iceConnectionState);
@ -114,7 +109,7 @@ export const initNetworking = async (p: {
return;
}
const { rtc, connected } = rtcPeerConnection(msg.peerID);
const { rtc, connected } = rtcPeerConnection();
connections.set(msg.peerID, rtc);
const dataChannelP: Promise<RTCDataChannel> = new Promise((r) => {
@ -130,6 +125,15 @@ export const initNetworking = async (p: {
await rtc.setLocalDescription(answer);
send({ kind: "connectAnswer", answer, peerID: msg.peerID });
rtc.addEventListener("icecandidate", (ev) => {
if (ev.candidate) {
send({
kind: "iceCandidate",
candidate: ev.candidate,
peerID: msg.peerID,
});
}
});
const connectedP = (async () => {
const dataChannel = await dataChannelP;
@ -142,7 +146,7 @@ export const initNetworking = async (p: {
};
const connectToPeer = async (peerID: PeerID) => {
const { rtc, connected } = rtcPeerConnection(peerID);
const { rtc, connected } = rtcPeerConnection();
connections.set(peerID, rtc);
const dataChannel = rtc.createDataChannel("data");
@ -151,6 +155,11 @@ export const initNetworking = async (p: {
await rtc.setLocalDescription(offer);
const answer = await sendConnectOffer(peerID, offer);
rtc.addEventListener("icecandidate", (ev) => {
if (ev.candidate) {
send({ kind: "iceCandidate", candidate: ev.candidate, peerID });
}
});
await rtc.setRemoteDescription(answer);
const connectedP = (async () => {

@ -24,6 +24,20 @@ body, main {
height: 20vh;
display: flex;
flex-direction: column;
> * {
padding: 1em;
}
.controls {
display: flex;
flex-direction: row;
justify-content: space-between;
> * {
display: flex;
}
}
}
main {

@ -8,24 +8,33 @@ export const showModal = (p: { content: Renderable; onClose?: () => void }) => {
modal.remove();
};
const modal = swel(
const modalContainer = swel(
"div",
{
className: "modalOverlay",
className: "modalContainer",
on: {
click: () => close(),
click: (e) => e.stopPropagation(),
},
},
[
swel("div", { className: "modalContainer" }, [
swel("div", { className: "modalControls" }, [
swel("button", { on: { click: () => close() } }, "X"),
]),
swel("div", { className: "modalContent" }, p.content),
swel("div", { className: "modalControls" }, [
swel("button", { on: { click: () => close() } }, "X"),
]),
swel("div", { className: "modalContent" }, p.content),
],
);
const modal = swel(
"div",
{
className: "modalOverlay",
on: {
click: () => close(),
},
},
modalContainer,
);
document.body.appendChild(modal);
return close;

Loading…
Cancel
Save