aboutsummaryrefslogtreecommitdiff
path: root/assets
diff options
context:
space:
mode:
Diffstat (limited to 'assets')
-rw-r--r--assets/src/components/RequestPage.svelte (renamed from assets/src/components/Request.svelte)0
-rw-r--r--assets/src/components/SharePage.svelte (renamed from assets/src/components/Share.svelte)4
-rw-r--r--assets/src/components/share/DataPicker.svelte (renamed from assets/src/components/DataPicker.svelte)4
-rw-r--r--assets/src/components/share/Request.svelte31
-rw-r--r--assets/src/components/share/Requests.svelte (renamed from assets/src/components/IncomingRequests.svelte)7
-rw-r--r--assets/src/entries/request.ts4
-rw-r--r--assets/src/entries/share.ts4
-rw-r--r--assets/src/network/channel/connection.ts2
-rw-r--r--assets/src/network/channel/messages/handler.ts49
-rw-r--r--assets/src/network/channel/request.ts10
-rw-r--r--assets/src/network/channel/share.ts28
-rw-r--r--assets/src/network/transfer/transfer.ts82
-rw-r--r--assets/src/stores/requests.ts4
13 files changed, 194 insertions, 35 deletions
diff --git a/assets/src/components/Request.svelte b/assets/src/components/RequestPage.svelte
index 0c0b111..0c0b111 100644
--- a/assets/src/components/Request.svelte
+++ b/assets/src/components/RequestPage.svelte
diff --git a/assets/src/components/Share.svelte b/assets/src/components/SharePage.svelte
index 5ea55b2..d951288 100644
--- a/assets/src/components/Share.svelte
+++ b/assets/src/components/SharePage.svelte
@@ -1,7 +1,7 @@
<script lang="ts">
import data from "../stores/data";
- import DataPicker from "./DataPicker.svelte";
- import IncomingRequests from "./IncomingRequests.svelte";
+ import DataPicker from "./share/DataPicker.svelte";
+ import IncomingRequests from "./share/Requests.svelte";
</script>
<main>
diff --git a/assets/src/components/DataPicker.svelte b/assets/src/components/share/DataPicker.svelte
index 433018d..6e8dbd4 100644
--- a/assets/src/components/DataPicker.svelte
+++ b/assets/src/components/share/DataPicker.svelte
@@ -1,11 +1,13 @@
<script lang="ts">
- import data from "../stores/data";
+ import data from "../../stores/data";
let value = "";
const submit = () => {
data.set(value);
};
+
+ // TODO: Accept data other than text.
</script>
<form on:submit|preventDefault={submit}>
diff --git a/assets/src/components/share/Request.svelte b/assets/src/components/share/Request.svelte
new file mode 100644
index 0000000..26002ae
--- /dev/null
+++ b/assets/src/components/share/Request.svelte
@@ -0,0 +1,31 @@
+<script lang="ts">
+ import { offer } from "../../network/transfer/transfer";
+
+ export let token: string;
+
+ async function accept() {
+ const transfer = await offer(token);
+ }
+
+ function decline() {}
+</script>
+
+<div class="container">
+ <span>{token}</span>
+ <div class="buttons">
+ <button on:click={accept}>Accept</button>
+ <button on:click={decline}>X</button>
+ </div>
+</div>
+
+<style>
+ .container {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ }
+
+ .buttons {
+ display: flex;
+ }
+</style>
diff --git a/assets/src/components/IncomingRequests.svelte b/assets/src/components/share/Requests.svelte
index bf08ffe..509d7be 100644
--- a/assets/src/components/IncomingRequests.svelte
+++ b/assets/src/components/share/Requests.svelte
@@ -1,7 +1,8 @@
<script lang="ts">
- import { getOwnToken, start, Type } from "../network/channel/connection";
+ import { getOwnToken, start, Type } from "../../network/channel/connection";
- import requests from "../stores/requests";
+ import requests from "../../stores/requests";
+ import Request from "./Request.svelte";
const startPromise = start(Type.SHARE);
@@ -14,6 +15,6 @@
<h3>Your token is <b>{getOwnToken()}</b>.</h3>
{#each $requests as request}
- <p>{JSON.stringify(request)}</p>
+ <Request token={request} />
{/each}
{/await}
diff --git a/assets/src/entries/request.ts b/assets/src/entries/request.ts
index 74f84da..6b8a79f 100644
--- a/assets/src/entries/request.ts
+++ b/assets/src/entries/request.ts
@@ -1,6 +1,6 @@
-import Request from "../components/Request.svelte";
+import RequestPage from "../components/RequestPage.svelte";
-const app = new Request({
+const app = new RequestPage({
target: document.getElementById("app"),
props: {},
});
diff --git a/assets/src/entries/share.ts b/assets/src/entries/share.ts
index d0279f1..2704a62 100644
--- a/assets/src/entries/share.ts
+++ b/assets/src/entries/share.ts
@@ -1,6 +1,6 @@
-import Share from "../components/Share.svelte";
+import SharePage from "../components/SharePage.svelte";
-const app = new Share({
+const app = new SharePage({
target: document.getElementById("app"),
props: {},
});
diff --git a/assets/src/network/channel/connection.ts b/assets/src/network/channel/connection.ts
index 59eb633..e1ed2d1 100644
--- a/assets/src/network/channel/connection.ts
+++ b/assets/src/network/channel/connection.ts
@@ -54,6 +54,8 @@ export async function start(type: Type.REQUEST | Type.SHARE) {
type === Type.SHARE
? await startShare(connection)
: await startRequest(connection);
+
+ updateState(ConnectionState.CONNECTED)
}
export function send(event: string, data: any): Push {
diff --git a/assets/src/network/channel/messages/handler.ts b/assets/src/network/channel/messages/handler.ts
index f7a00d2..cc8f005 100644
--- a/assets/src/network/channel/messages/handler.ts
+++ b/assets/src/network/channel/messages/handler.ts
@@ -1,4 +1,4 @@
-import { getChannel } from "../connection";
+import type { Channel } from "phoenix";
import type { AnyMessage } from "./messages";
export type Handlers = {
@@ -14,7 +14,10 @@ export type TokenHandler<Message extends AnyMessage> = {
[token: string]: Handler<Message>;
};
-export type Handler<Message extends AnyMessage> = (message?: Message) => void;
+export type Handler<Message extends AnyMessage> = (
+ message?: Message,
+ unregister?: UnregisterHandler
+) => void;
export type UnregisterHandler = () => void;
@@ -45,17 +48,12 @@ export function registerTokenHandler<Message extends AnyMessage>(
const directHandlers = eventHandler.directHandlers;
directHandlers.push(handler);
- unregister = () => {
- const index = directHandlers.findIndex(h => h === handler);
- directHandlers.splice(index, 1);
- };
+ unregister = makeDirectUnregister(directHandlers, handler);
} else {
const tokenHandler = eventHandler.tokenHandler;
tokenHandler[token] = handler;
- unregister = () => {
- delete tokenHandler[token];
- };
+ unregister = makeTokenUnregister(tokenHandler, token);
}
return unregister;
@@ -80,16 +78,35 @@ function handleEvent<Message extends AnyMessage>(
if (message["token"] !== undefined) {
const token = message["token"];
- const handler: Handler<Message> = eventHandler.tokenHandler[token];
+ const tokenHandler = eventHandler.tokenHandler;
+ const handler: Handler<Message> = tokenHandler[token];
- if (handler === undefined) {
- throw new Error("Received message for an unknown token.");
+ if (handler !== undefined) {
+ handler(message, makeTokenUnregister(tokenHandler, token));
}
-
- handler(message);
}
- for (const handler of eventHandler.directHandlers) {
- handler(message);
+ const directHandlers = eventHandler.directHandlers;
+ for (const handler of directHandlers) {
+ handler(message, makeDirectUnregister(directHandlers, handler));
}
}
+
+function makeDirectUnregister<Message extends AnyMessage>(
+ directHandlers: Handler<Message>[],
+ handler: Handler<Message>
+): UnregisterHandler {
+ return () => {
+ const index = directHandlers.findIndex(h => h === handler);
+ directHandlers.splice(index, 1);
+ };
+}
+
+function makeTokenUnregister<Message extends AnyMessage>(
+ tokenHandler: TokenHandler<Message>,
+ token: string
+): UnregisterHandler {
+ return () => {
+ delete tokenHandler[token];
+ };
+}
diff --git a/assets/src/network/channel/request.ts b/assets/src/network/channel/request.ts
index dd18aab..f5145fb 100644
--- a/assets/src/network/channel/request.ts
+++ b/assets/src/network/channel/request.ts
@@ -1,5 +1,7 @@
import getShareToken from "../../utils/getShareToken";
-import type { Connection } from "./connection";
+import { answer } from "../transfer/transfer";
+import { Connection, on } from "./connection";
+import type { RequestAcceptedMessage } from "./messages/messages";
import { joinRequestChannel } from "./socket";
export async function startRequest(connection: Connection) {
@@ -9,4 +11,10 @@ export async function startRequest(connection: Connection) {
getShareToken()
);
connection.channel = requestChannel;
+
+ on("request_accepted", onRequestAccepted);
+}
+
+async function onRequestAccepted(message: RequestAcceptedMessage) {
+ await answer(message);
}
diff --git a/assets/src/network/channel/share.ts b/assets/src/network/channel/share.ts
index f93e8cb..6dbf0cd 100644
--- a/assets/src/network/channel/share.ts
+++ b/assets/src/network/channel/share.ts
@@ -1,5 +1,10 @@
import requests from "../../stores/requests";
-import type { Connection } from "./connection";
+import { Connection, on, onWithToken } from "./connection";
+import type { UnregisterHandler } from "./messages/handler";
+import type {
+ NewRequestMessage,
+ RequestCancelledMessage,
+} from "./messages/messages";
import { joinShareChannel } from "./socket";
export async function startShare(connection: Connection) {
@@ -8,4 +13,23 @@ export async function startShare(connection: Connection) {
connection.token
);
connection.channel = shareChannel;
-} \ No newline at end of file
+
+ on("new_request", onNewRequest);
+}
+
+function onNewRequest(message: NewRequestMessage) {
+ const token = message.token;
+
+ requests.addRequest(token);
+
+ onWithToken("request_cancelled", token, onRequestCancelled);
+}
+
+function onRequestCancelled(
+ message: RequestCancelledMessage,
+ unregister: UnregisterHandler
+) {
+ const token = message.token;
+ requests.removeRequest(token);
+ unregister();
+}
diff --git a/assets/src/network/transfer/transfer.ts b/assets/src/network/transfer/transfer.ts
index 26d2534..1cc029b 100644
--- a/assets/src/network/transfer/transfer.ts
+++ b/assets/src/network/transfer/transfer.ts
@@ -1,4 +1,10 @@
-import { send } from "../channel/connection";
+import { onWithToken, send } from "../channel/connection";
+import type { UnregisterHandler } from "../channel/messages/handler";
+import type {
+ ShareAcceptedMessage,
+ RequestIceCandidateMessage,
+ ShareIceCandidateMessage,
+} from "../channel/messages/messages";
export enum TransferType {
OFFER,
@@ -11,20 +17,44 @@ export type Transfer = {
type: TransferType;
};
+const servers = {
+ iceServers: [
+ {
+ urls: [
+ "stun:stun1.l.google.com:19302",
+ "stun:stun2.l.google.com:19302",
+ ],
+ },
+ ],
+ iceCandidatePoolSize: 10,
+};
+
export async function offer(request_token: string): Promise<Transfer> {
const transfer = createTransfer(TransferType.OFFER);
const offer = await transfer.pc.createOffer();
transfer.pc.setLocalDescription(offer);
- // TODO: Start waiting for remote answer
+ transfer.pc.onicecandidate = event => {
+ const candidate = event.candidate;
+ if (event.candidate !== null) {
+ send("ice_candidate", { candidate, token: request_token });
+ }
+ };
send("accept_request", {
- request: request_token,
+ token: request_token,
sdp: offer.sdp,
type: offer.type,
});
+ onWithToken(
+ "share_accepted",
+ request_token,
+ (message: ShareAcceptedMessage, unregister) =>
+ onShareAccepted(transfer, message, unregister)
+ );
+
return transfer;
}
@@ -39,6 +69,13 @@ export async function answer(
const answer = await transfer.pc.createAnswer();
transfer.pc.setLocalDescription(answer);
+ transfer.pc.onicecandidate = event => {
+ const candidate = event.candidate;
+ if (event.candidate !== null) {
+ send("ice_candidate", { candidate });
+ }
+ };
+
send("accept_share", {
sdp: offer.sdp,
type: offer.type,
@@ -48,15 +85,50 @@ export async function answer(
}
function createTransfer(type: TransferType): Transfer {
- const pc = new RTCPeerConnection(null);
+ const pc = new RTCPeerConnection(servers);
const channel = pc.createDataChannel("channel", {
negotiated: true,
id: 0,
});
+ channel.onopen = e => console.log("ooooyeeee");
+
return {
pc,
channel,
type,
};
-} \ No newline at end of file
+}
+
+function onShareAccepted(
+ transfer: Transfer,
+ message: ShareAcceptedMessage,
+ unregister: UnregisterHandler
+) {
+ const token = message.token;
+ transfer.pc.setRemoteDescription(message);
+
+ const unregisterIce = onWithToken(
+ "ice_candidate",
+ token,
+ (message: RequestIceCandidateMessage) =>
+ onIncomingIceCandidate(transfer, message)
+ );
+
+ transfer.pc.onicegatheringstatechange = event => {
+ const connection = event.target as any;
+ console.log(connection.iceGatheringState);
+ if (connection.iceGatheringState === "complete") {
+ unregisterIce();
+ }
+ };
+
+ unregister();
+}
+
+function onIncomingIceCandidate(
+ transfer: Transfer,
+ message: ShareIceCandidateMessage | RequestIceCandidateMessage
+) {
+ transfer.pc.addIceCandidate(message.candidate);
+}
diff --git a/assets/src/stores/requests.ts b/assets/src/stores/requests.ts
index e80eb2b..1dc8cb2 100644
--- a/assets/src/stores/requests.ts
+++ b/assets/src/stores/requests.ts
@@ -1,11 +1,13 @@
import { writable } from "svelte/store";
const createRequestStore = () => {
- const { subscribe, update } = writable([]);
+ const { subscribe, update } = writable<string[]>([]);
return {
subscribe,
addRequest: request => update(state => [request, ...state]),
+ removeRequest: request =>
+ update(state => state.filter(r => r !== request)),
};
};