aboutsummaryrefslogtreecommitdiff
path: root/client-web/source
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2022-10-03 12:45:24 +0200
committermetamuffin <metamuffin@disroot.org>2022-10-03 12:45:24 +0200
commit4d57f2dc4979177f9d074157b0d0767327d5fd67 (patch)
tree18f972626b4586b92f04a7805b3fb0d7d70cba95 /client-web/source
parentd8315a650e3a272d3e57408790bfd879a868c3e1 (diff)
downloadkeks-meet-4d57f2dc4979177f9d074157b0d0767327d5fd67.tar
keks-meet-4d57f2dc4979177f9d074157b0d0767327d5fd67.tar.bz2
keks-meet-4d57f2dc4979177f9d074157b0d0767327d5fd67.tar.zst
first code for file transfer
Diffstat (limited to 'client-web/source')
-rw-r--r--client-web/source/resource/file.ts69
-rw-r--r--client-web/source/resource/mod.ts2
-rw-r--r--client-web/source/user/remote.ts13
3 files changed, 67 insertions, 17 deletions
diff --git a/client-web/source/resource/file.ts b/client-web/source/resource/file.ts
index b6629bc..c54abc8 100644
--- a/client-web/source/resource/file.ts
+++ b/client-web/source/resource/file.ts
@@ -1,18 +1,31 @@
-import { ediv } from "../helper.ts";
+import { ebutton, ediv, espan } from "../helper.ts";
import { LocalResource, ResourceHandlerDecl } from "./mod.ts";
export const resource_file: ResourceHandlerDecl = {
kind: "file",
- new_remote(info, _user, _enable) {
+ new_remote(info, user, enable) {
return {
info,
- el: ediv(),
- on_statechange(_s) { },
- on_enable(_track, _disable) {
- return {
- on_disable() {
-
+ el: ediv({},
+ espan(`File: ${JSON.stringify(info.label)}`),
+ ebutton("Download", {
+ onclick: self => {
+ enable()
+ self.disabled = true
}
+ })
+ ),
+ on_statechange(_s) { },
+ on_enable(channel, _disable) {
+ if (!(channel instanceof RTCDataChannel)) throw new Error("not a data channel");
+ channel.onopen = _ev => {
+ console.log(`${user.display_name}: channel open`);
+ }
+ channel.onerror = _ev => {
+ console.log(`${user.display_name}: channel error`);
+ }
+ channel.onclose = _ev => {
+ console.log(`${user.display_name}: channel closed`);
}
}
}
@@ -28,12 +41,40 @@ export function create_file_res(): Promise<LocalResource> {
if (!picker.files) return reject()
const f = picker.files.item(0)
if (!f) return reject()
- resolve({
- info: { kind: "file", id: Math.random().toString(), label: f.name, size: f.size },
- destroy() { /* TODO */ },
- el: ediv(),
- on_request(_user, _create_channel) { return _create_channel("TODO") }
- })
+ resolve(file_res_inner(f))
})
})
+}
+
+function file_res_inner(file: File): LocalResource {
+ const transfers_el = ediv({})
+ return {
+ info: { kind: "file", id: Math.random().toString(), label: file.name, size: file.size },
+ destroy() { },
+ el: ediv({ class: "file" },
+ espan(`Sharing file: ${JSON.stringify(file.name)}`),
+ transfers_el
+ ),
+ on_request(user, create_channel) {
+ const channel = create_channel()
+ const reader = file.stream().getReader()
+ console.log(`${user.display_name} started requested file`);
+ channel.onbufferedamountlow = async () => {
+ const { value: chunk, done } = await reader.read()
+ console.log(chunk, done);
+ channel.send(chunk)
+ if (!done) console.log("transfer done");
+ }
+ channel.onopen = _ev => {
+ console.log(`${user.display_name}: channel open`);
+ }
+ channel.onerror = _ev => {
+ console.log(`${user.display_name}: channel error`);
+ }
+ channel.onclose = _ev => {
+ console.log(`${user.display_name}: channel closed`);
+ }
+ return channel
+ }
+ }
} \ No newline at end of file
diff --git a/client-web/source/resource/mod.ts b/client-web/source/resource/mod.ts
index f99a252..a213d87 100644
--- a/client-web/source/resource/mod.ts
+++ b/client-web/source/resource/mod.ts
@@ -101,7 +101,7 @@ export interface LocalResource {
el: HTMLElement
info: ProvideInfo,
destroy(): void
- on_request(user: RemoteUser, create_channel: (label: string) => RTCDataChannel): TrackHandle | RTCDataChannel
+ on_request(user: RemoteUser, create_channel: () => RTCDataChannel): TrackHandle | RTCDataChannel
}
const RESOURCE_HANDLERS: ResourceHandlerDecl[] = [resource_file, resource_track]
diff --git a/client-web/source/user/remote.ts b/client-web/source/user/remote.ts
index 677d362..e143625 100644
--- a/client-web/source/user/remote.ts
+++ b/client-web/source/user/remote.ts
@@ -45,10 +45,19 @@ export class RemoteUser extends User {
r.on_enable(new TrackHandle(t), () => {
this.request_resource_stop(r)
})
- // else { ev.transceiver.stop(); return log({ scope: "media", warn: true }, "got a track for a resource that should use data channel") }
log("media", `remote track: ${this.display_name}`, t)
this.update_stats()
}
+ this.pc.ondatachannel = ({ channel }) => {
+ const id = channel.label
+ const r = this.resources.get(id)
+ if (!r) { channel.close(); return log({ scope: "media", warn: true }, "got an unassociated channel") }
+ r.on_enable(channel, () => {
+ this.request_resource_stop(r)
+ })
+ log("media", `remote channel: ${this.display_name}`, channel)
+ this.update_stats()
+ }
this.pc.onnegotiationneeded = () => {
log("webrtc", `negotiation needed: ${this.display_name}`)
if (this.negotiation_busy && this.pc.signalingState == "stable") return
@@ -97,7 +106,7 @@ export class RemoteUser extends User {
if (message.request) {
const r = this.room.local_user.resources.get(message.request.id)
if (!r) return log({ scope: "*", warn: true }, "somebody requested an unknown resource")
- const channel = r.on_request(this, label => this.pc.createDataChannel(label))
+ const channel = r.on_request(this, () => this.pc.createDataChannel(r.info.id))
if (channel instanceof TrackHandle) {
const sender = this.pc.addTrack(channel.track, channel.stream)
this.senders.set(channel.id, sender)