mirror of
https://github.com/MercuryWorkshop/adrift.git
synced 2025-05-12 22:00:02 -04:00
345 lines
9.2 KiB
Svelte
345 lines
9.2 KiB
Svelte
<script lang="ts">
|
|
import {
|
|
BareClient,
|
|
registerRemoteListener,
|
|
setBareClientImplementation,
|
|
} from "bare-client-custom";
|
|
import {
|
|
AdriftBareClient,
|
|
Connection,
|
|
DevWsTransport,
|
|
RTCTransport,
|
|
SignalFirebase,
|
|
} from "client";
|
|
import {
|
|
Button,
|
|
Card,
|
|
CircularProgressIndeterminate,
|
|
StyleFromScheme,
|
|
TextField,
|
|
} from "m3-svelte";
|
|
|
|
import { getAuth, signInWithEmailAndPassword } from "firebase/auth";
|
|
import { getDatabase, onValue, ref, set } from "firebase/database";
|
|
import type { Transport } from "protocol";
|
|
|
|
import Proxy from "./Proxy.svelte";
|
|
import { initializeApp } from "firebase/app";
|
|
|
|
import TrackerList from "tracker-list";
|
|
let transport: Transport;
|
|
|
|
let rtctransport: RTCTransport | undefined;
|
|
|
|
let email = "test@test.com";
|
|
let password = "123456";
|
|
|
|
let connectionState = "";
|
|
|
|
if (!import.meta.env.VITE_ADRIFT_SINGLEFILE) {
|
|
console.log("registering bare-client-custom");
|
|
registerRemoteListener();
|
|
}
|
|
|
|
function onTransportOpen() {
|
|
console.log("Transport opened");
|
|
|
|
let connection = new Connection(transport);
|
|
let bare = new AdriftBareClient(connection);
|
|
console.log(setBareClientImplementation);
|
|
setBareClientImplementation(bare);
|
|
state = ReadyState.Connected;
|
|
}
|
|
|
|
function onTransportClose() {
|
|
console.warn("Transport closed");
|
|
}
|
|
|
|
function createRTCTransport() {
|
|
let transport = new RTCTransport(
|
|
onTransportOpen,
|
|
onTransportClose,
|
|
() => {
|
|
connectionState = `Connection ${transport.peer.connectionState}`;
|
|
},
|
|
() => {
|
|
connectionState = `Signaling ${transport.peer.connectionState}`;
|
|
},
|
|
() => {
|
|
connectionState = `Gathering ${transport.peer.connectionState}`;
|
|
}
|
|
);
|
|
return transport;
|
|
}
|
|
|
|
async function initFirebase() {
|
|
let tracker = TrackerList["us-central-1"];
|
|
initializeApp(tracker.firebase);
|
|
}
|
|
|
|
async function connectAccount() {
|
|
await initFirebase();
|
|
rtctransport = transport = createRTCTransport();
|
|
|
|
let auth = getAuth();
|
|
let creds = await signInWithEmailAndPassword(auth, email, password);
|
|
state = ReadyState.Connecting;
|
|
|
|
const db = getDatabase();
|
|
let peer = ref(db, `/peers/${creds.user.uid}`);
|
|
|
|
let offer = await rtctransport.createOffer();
|
|
|
|
connectionState = "Finding your node...";
|
|
|
|
set(peer, JSON.stringify(offer));
|
|
|
|
onValue(peer, async (snapshot) => {
|
|
const str = snapshot.val();
|
|
if (str) {
|
|
console.log(str);
|
|
let data = JSON.parse(str);
|
|
console.log(data);
|
|
if (data && data.answer && data.candidates) {
|
|
set(peer, null);
|
|
const { answer, candidates } = data;
|
|
connectionState = "Linking to node...";
|
|
await new Promise((r) => {
|
|
setTimeout(r, 1000);
|
|
});
|
|
rtctransport?.answer(answer, candidates);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
async function connectSwarm() {
|
|
await initFirebase();
|
|
|
|
state = ReadyState.Connecting;
|
|
|
|
rtctransport = transport = createRTCTransport();
|
|
|
|
let offer = await rtctransport.createOffer();
|
|
connectionState = "Routing you to an available node...";
|
|
|
|
let answer = await SignalFirebase.signalSwarm(JSON.stringify(offer));
|
|
connectionState = "Linking to node...";
|
|
await new Promise((r) => {
|
|
setTimeout(r, 500);
|
|
});
|
|
|
|
rtctransport.answer(answer.answer, answer.candidates);
|
|
}
|
|
|
|
async function connectDevHttp() {
|
|
rtctransport = transport = createRTCTransport();
|
|
let offer = await rtctransport.createOffer();
|
|
console.log("offer created", offer);
|
|
console.log(JSON.stringify(offer));
|
|
|
|
const r = await fetch("http://localhost:3000/connect", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify(offer),
|
|
});
|
|
if (r.status != 200) {
|
|
throw new Error("connect: " + r.status + " " + r.statusText);
|
|
}
|
|
const { answer, candidates } = await r.json();
|
|
await rtctransport.answer(answer, candidates);
|
|
}
|
|
|
|
async function connectDevWS() {
|
|
transport = new DevWsTransport(onTransportOpen, () =>
|
|
console.log("onclose")
|
|
);
|
|
}
|
|
|
|
(window as any).bare = new BareClient();
|
|
(window as any).myWsTest = () => {
|
|
// const url = "wss://ws.postman-echo.com/raw";
|
|
const url = "ws://127.0.0.1:3002/";
|
|
const ws = ((window as any).ws = (
|
|
(window as any).bare as BareClient
|
|
).createWebSocket(url, ["a", "b"], {}));
|
|
ws.onopen = () => console.log("onopen");
|
|
ws.addEventListener("open", () => console.log("open listener"));
|
|
ws.onclose = () => console.error(new Error("onclose"));
|
|
ws.addEventListener("close", (e) => console.log("close listener", e));
|
|
ws.onmessage = (e) => console.log("message", e);
|
|
};
|
|
|
|
enum ReadyState {
|
|
Idle,
|
|
Connecting,
|
|
Connected,
|
|
}
|
|
let state = ReadyState.Idle;
|
|
</script>
|
|
|
|
{#if state == ReadyState.Connected}
|
|
<Proxy />
|
|
{:else if state == ReadyState.Connecting}
|
|
<CircularProgressIndeterminate />
|
|
<h2>
|
|
{connectionState}
|
|
</h2>
|
|
{:else if !import.meta.env.VITE_ADRIFT_DEV}
|
|
<div id="loginpage">
|
|
<div class="bigcard">
|
|
<h1>Adrift</h1>
|
|
</div>
|
|
|
|
<div class="flex justify-evenly">
|
|
<Card type="filled">basically aero 2</Card>
|
|
<div />
|
|
<Card type="elevated">
|
|
<TextField name="email" bind:value={email} />
|
|
<TextField
|
|
name="password"
|
|
bind:value={password}
|
|
extraOptions={{ type: "password" }}
|
|
/>
|
|
|
|
<Button type="outlined" on:click={connectAccount}
|
|
>Connect with firebase</Button
|
|
>
|
|
|
|
<Button type="filled" on:click={connectSwarm}
|
|
>Connect with the swarm (firebase, webrtc, insecure)
|
|
</Button>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
{:else}
|
|
<div class="flex items-center justify-center h-full">
|
|
<Card type="elevated">
|
|
<div class="flex flex-col h-full">
|
|
<h2 class="m3-font-headline-large m-3">Adrift DEV</h2>
|
|
<div class="flex space-evenly pad-children">
|
|
<Button type="filled" on:click={connectDevHttp}
|
|
>Connect with WebRTC transport over localhost HTTP signaling</Button
|
|
>
|
|
<Button type="filled" on:click={connectDevWS}
|
|
>Connect with localhost websocket transport</Button
|
|
>
|
|
</div>
|
|
</div>
|
|
</Card>
|
|
</div>
|
|
{/if}
|
|
|
|
<StyleFromScheme
|
|
lightScheme={{
|
|
primary: 1284831119,
|
|
onPrimary: 4294967295,
|
|
primaryContainer: 4293516799,
|
|
onPrimaryContainer: 4280291399,
|
|
inversePrimary: 4291804670,
|
|
secondary: 4284636017,
|
|
onSecondary: 4294967295,
|
|
secondaryContainer: 4293451512,
|
|
onSecondaryContainer: 4280162603,
|
|
tertiary: 4286468704,
|
|
onTertiary: 4294967295,
|
|
tertiaryContainer: 4294957539,
|
|
onTertiaryContainer: 4281405469,
|
|
error: 4290386458,
|
|
onError: 4294967295,
|
|
errorContainer: 4294957782,
|
|
onErrorContainer: 4282449922,
|
|
background: 4294834175,
|
|
onBackground: 4280097568,
|
|
surface: 4294834175,
|
|
onSurface: 4280097568,
|
|
surfaceVariant: 4293386475,
|
|
onSurfaceVariant: 4282991950,
|
|
inverseSurface: 4281478965,
|
|
inverseOnSurface: 4294307831,
|
|
outline: 4286215551,
|
|
outlineVariant: 4291478735,
|
|
shadow: 4278190080,
|
|
scrim: 4278190080,
|
|
surfaceDim: 4292794592,
|
|
surfaceBright: 4294834175,
|
|
surfaceContainerLowest: 4294967295,
|
|
surfaceContainerLow: 4294505210,
|
|
surfaceContainer: 4294110452,
|
|
surfaceContainerHigh: 4293715694,
|
|
surfaceContainerHighest: 4293320937,
|
|
surfaceTint: 4284831119,
|
|
}}
|
|
darkScheme={{
|
|
primary: 1291804670,
|
|
onPrimary: 4281739101,
|
|
primaryContainer: 4283252085,
|
|
onPrimaryContainer: 4293516799,
|
|
inversePrimary: 4284831119,
|
|
secondary: 4291543771,
|
|
onSecondary: 4281544001,
|
|
secondaryContainer: 4283057240,
|
|
onSecondaryContainer: 4293451512,
|
|
tertiary: 4293900488,
|
|
onTertiary: 4283049266,
|
|
tertiaryContainer: 4284693320,
|
|
onTertiaryContainer: 4294957539,
|
|
error: 4294948011,
|
|
onError: 4285071365,
|
|
errorContainer: 4287823882,
|
|
onErrorContainer: 4294957782,
|
|
background: 4279505432,
|
|
onBackground: 4293320937,
|
|
surface: 4279505432,
|
|
onSurface: 4293320937,
|
|
surfaceVariant: 4282991950,
|
|
onSurfaceVariant: 4291478735,
|
|
inverseSurface: 4293320937,
|
|
inverseOnSurface: 4281478965,
|
|
outline: 4287926169,
|
|
outlineVariant: 4282991950,
|
|
shadow: 4278190080,
|
|
scrim: 4278190080,
|
|
surfaceDim: 4279505432,
|
|
surfaceBright: 4282071102,
|
|
surfaceContainerLowest: 4279176467,
|
|
surfaceContainerLow: 4280097568,
|
|
surfaceContainer: 4280360740,
|
|
surfaceContainerHigh: 4281018671,
|
|
surfaceContainerHighest: 4281742394,
|
|
surfaceTint: 4291804670,
|
|
}}
|
|
/>
|
|
|
|
<style>
|
|
:global(.pad-children > *) {
|
|
margin: 2rem;
|
|
}
|
|
#loginpage {
|
|
padding: 2.5em;
|
|
}
|
|
.bigcard {
|
|
background-color: rgb(var(--m3-scheme-primary-container));
|
|
color: rgb(var(--m3-scheme-on-primary-container));
|
|
border-radius: 2rem;
|
|
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 2rem;
|
|
text-align: center;
|
|
padding: 8rem 0 6rem 0;
|
|
margin-bottom: 2rem;
|
|
}
|
|
:global(body, html, #app) {
|
|
width: 100vw;
|
|
height: 100vh;
|
|
padding: 0;
|
|
margin: 0;
|
|
background-color: rgb(var(--m3-scheme-background));
|
|
color: rgb(var(--m3-scheme-on-background));
|
|
}
|
|
iframe {
|
|
outline: none;
|
|
border: none;
|
|
}
|
|
</style>
|