diff options
Diffstat (limited to 'client-web/source')
-rw-r--r-- | client-web/source/resource/file.ts | 11 | ||||
-rw-r--r-- | client-web/source/resource/mod.ts | 78 | ||||
-rw-r--r-- | client-web/source/resource/track.ts | 67 | ||||
-rw-r--r-- | client-web/source/user/local.ts | 4 |
4 files changed, 88 insertions, 72 deletions
diff --git a/client-web/source/resource/file.ts b/client-web/source/resource/file.ts new file mode 100644 index 0000000..690c765 --- /dev/null +++ b/client-web/source/resource/file.ts @@ -0,0 +1,11 @@ +import { TrackHandle } from "../track_handle.ts"; +import { Resource } from "./mod.ts"; + +export class FileResource extends Resource { + + on_track(_track: TrackHandle): HTMLElement { + throw new Error("Method not implemented."); + } + + +} diff --git a/client-web/source/resource/mod.ts b/client-web/source/resource/mod.ts index 948ccc2..716d42b 100644 --- a/client-web/source/resource/mod.ts +++ b/client-web/source/resource/mod.ts @@ -6,54 +6,84 @@ /// <reference lib="dom" /> import { ProvideInfo } from "../../../common/packets.d.ts" -import { ediv } from "../helper.ts" -import { log } from "../logger.ts" +import { ediv } from "../helper.ts"; +import { TrackHandle } from "../track_handle.ts"; +import { LocalUser } from "../user/local.ts"; import { User } from "../user/mod.ts" import { RemoteUser } from "../user/remote.ts" -import { TrackResource } from "./track.ts" +import { TrackResource } from "./track.ts"; -export type ChannelState = "running" | "disconnected" - -export abstract class Resource { +export type ChannelState = "enabled" | "await_enable" | "disabled" | "await_disable" +export abstract class Resource extends EventTarget { + local: boolean el: HTMLElement = ediv({ class: ["channel"] }) - on_destroy = () => { } + inner_el?: HTMLElement constructor( public user: User, public info: ProvideInfo, ) { - setTimeout(() => this.update_el(), 0) + super() + this.local = this.user instanceof LocalUser + const button = document.createElement("button") + button.onclick = () => { + this.state == "enabled" ? this.request_stop() : this.request() + } + this.addEventListener("statechange", () => { + if (this.user instanceof LocalUser) button.textContent = "End", button.disabled = false + else if (this.state == "enabled") button.textContent = "Disable", button.disabled = false + else if (this.state == "disabled") button.textContent = `Enable ${this.info.kind}`, button.disabled = false + else button.textContent = "Working…", button.disabled = true; + }) + this.dispatchEvent(new CustomEvent("statechange")) + this.el.append(button) } - private _state: ChannelState = "disconnected" + static create(user: User, info: ProvideInfo): Resource { + if (info.kind == "audio" || info.kind == "video") return new TrackResource(user, info) + else throw new Error("blub"); + } + + private _state: ChannelState = "disabled" get state() { return this._state } set state(value: ChannelState) { const old_value = this._state this._state = value - if (value != old_value) this.update_el() + if (value != old_value) this.dispatchEvent(new CustomEvent("statechange")) } - destroy() { this.on_destroy() } + private _track?: TrackHandle + get track() { return this._track } + set track(value: TrackHandle | undefined) { + const handle_end = () => { + this.track = undefined + this.state = "disabled" + this.inner_el?.remove() + if (this.user instanceof LocalUser) this.destroy() + } + this._track?.removeEventListener("ended", handle_end) + this._track = value + if (value) this.el.append(this.inner_el = this.on_track(value)) + if (value) this.state = "enabled" + else this.state = "disabled" + this._track?.addEventListener("ended", handle_end) + } - abstract create_element(): HTMLElement + abstract on_track(_track: TrackHandle): HTMLElement - static create(user: User, info: ProvideInfo): Resource | undefined { - if (info.kind == "audio" || info.kind == "video") return new TrackResource(user, info) - if (info.kind == "file") throw new Error(""); - log({ scope: "media", warn: true }, "unknown resource kind") - } + destroy() { this.dispatchEvent(new CustomEvent("destroy")) } request() { if (!(this.user instanceof RemoteUser)) return + this.state = "await_enable" this.user.send_to({ request: { id: this.info.id } }) } request_stop() { - if (!(this.user instanceof RemoteUser)) return - this.user.send_to({ request_stop: { id: this.info.id } }) - } - - update_el() { - this.el.innerHTML = "" - this.el.append(this.create_element()) + if (this.user instanceof RemoteUser) { + this.state = "await_disable" + this.user.send_to({ request_stop: { id: this.info.id } }) + } else if (this.user instanceof LocalUser) { + this.destroy() + } } } diff --git a/client-web/source/resource/track.ts b/client-web/source/resource/track.ts index 8cdf6eb..1ae6f94 100644 --- a/client-web/source/resource/track.ts +++ b/client-web/source/resource/track.ts @@ -6,71 +6,46 @@ /// <reference lib="dom" /> import { ProvideInfo } from "../../../common/packets.d.ts"; -import { ebutton } from "../helper.ts"; import { TrackHandle } from "../track_handle.ts"; -import { LocalUser } from "../user/local.ts"; import { User } from "../user/mod.ts"; import { Resource } from "./mod.ts"; export class TrackResource extends Resource { - private _track?: TrackHandle constructor(user: User, info: ProvideInfo, track?: TrackHandle) { super(user, info) this.track = track } - get track() { return this._track } - set track(value: TrackHandle | undefined) { - const handle_end = () => { - this.track = undefined - if (this.user instanceof LocalUser) this.destroy() - } - this._track?.removeEventListener("ended", handle_end) - this._track = value - this._track?.addEventListener("ended", handle_end) - this.update_el() - } - destroy() { this.track?.end() super.destroy() } - create_element() { + on_track(track: TrackHandle): HTMLElement { const el = document.createElement("div") - if (!this.track?.local) { - el.append(ebutton(`${this.track ? "Disable" : "Enable"} ${this.info.kind}`, { - onclick: (e) => { - (e as HTMLButtonElement).disabled = true; - this.track ? this.request_stop() : this.request() - } - })) - } - if (this.track) { - const is_video = this.track.kind == "video" - const media_el = is_video ? document.createElement("video") : document.createElement("audio") - const stream = new MediaStream([this.track.track]) - media_el.srcObject = stream - media_el.classList.add("media") - media_el.autoplay = true - media_el.controls = true - if (this.track.local) media_el.muted = true - el.append(media_el) + const is_video = track.kind == "video" + const media_el = is_video ? document.createElement("video") : document.createElement("audio") + const stream = new MediaStream([track.track]) + media_el.srcObject = stream + media_el.classList.add("media") + media_el.autoplay = true + media_el.controls = true + if (track.local) media_el.muted = true + el.append(media_el) - if (this.track.local) { - const end_button = document.createElement("button") - end_button.textContent = "End" - end_button.addEventListener("click", () => { - this.track?.end() - }) - el.append(end_button) - } - this.el.append(el) - this.track.addEventListener("ended", () => { - media_el.srcObject = null // TODO - el.remove() + if (track.local) { + const end_button = document.createElement("button") + end_button.textContent = "End" + end_button.addEventListener("click", () => { + track?.end() }) + el.append(end_button) } + this.el.append(el) + track.addEventListener("ended", () => { + media_el.srcObject = null // TODO + el.remove() + }) return el } }
\ No newline at end of file diff --git a/client-web/source/user/local.ts b/client-web/source/user/local.ts index 9268a9e..56ff9f0 100644 --- a/client-web/source/user/local.ts +++ b/client-web/source/user/local.ts @@ -77,10 +77,10 @@ export class LocalUser extends User { this.el.append(r.el) const provide: ProvideInfo = r.info this.room.signaling.send_relay({ provide }) - r.on_destroy = () => { + r.addEventListener("destroy", () => { this.el.removeChild(r.el); this.room.signaling.send_relay({ provide_stop: { id: r.info.id } }) - } + }) } async create_camera_res() { |