aboutsummaryrefslogtreecommitdiff
path: root/client-web
diff options
context:
space:
mode:
Diffstat (limited to 'client-web')
-rw-r--r--client-web/public/assets/style/chat.css6
-rw-r--r--client-web/source/chat.ts52
-rw-r--r--client-web/source/helper.ts16
-rw-r--r--client-web/source/user/local.ts5
-rw-r--r--client-web/source/user/remote.ts2
5 files changed, 61 insertions, 20 deletions
diff --git a/client-web/public/assets/style/chat.css b/client-web/public/assets/style/chat.css
index 26c1ad5..34e7d63 100644
--- a/client-web/public/assets/style/chat.css
+++ b/client-web/public/assets/style/chat.css
@@ -19,9 +19,13 @@
.chat .author {
font-weight: bold;
}
-.chat .content {
+.chat .text {
color: white;
}
+.chat .image {
+ width: min(20em, 30vw);
+}
+
.chat .messages {
height: calc(100% - 3em);
width: 100%;
diff --git a/client-web/source/chat.ts b/client-web/source/chat.ts
index dfef73f..792a620 100644
--- a/client-web/source/chat.ts
+++ b/client-web/source/chat.ts
@@ -1,4 +1,6 @@
-import { ediv, espan, OverlayUi } from "./helper.ts";
+import { ChatMessage } from "../../common/packets.d.ts";
+import { ediv, espan, image_view, OverlayUi } from "./helper.ts";
+import { log } from "./logger.ts";
import { Room } from "./room.ts";
import { User } from "./user/mod.ts";
@@ -9,13 +11,7 @@ export class Chat extends OverlayUi {
constructor(public room: Room) {
const send = document.createElement("input")
send.type = "text"
- send.onkeydown = (ev) => {
- if (ev.code == "Enter") {
- room.local_user.chat(send.value)
- this.send_message(room.local_user, send.value)
- send.value = ""
- }
- }
+
const messages = ediv({ class: "messages" })
const controls = ediv({ class: "controls" })
controls.append(send)
@@ -23,13 +19,45 @@ export class Chat extends OverlayUi {
super(ediv({ class: "chat" }, messages, controls))
this.messages = messages
this.controls = controls
+
+ send.onkeydown = (ev) => {
+ if (ev.code == "Enter") {
+ if (send.value.trim().length == 0) return // no!
+ this.send({ text: send.value })
+ send.value = ""
+ }
+ }
+ document.onpaste = (pasteEvent) => {
+ // TODO will only work when pasting a single image
+ const item = pasteEvent.clipboardData?.items[0];
+ if (!item) return
+ if (item.type.indexOf("image") === 0) {
+ log("*", "image pasted")
+ const blob = item.getAsFile()
+ if (!blob) return
+ const reader = new FileReader();
+ reader.onload = (event) => {
+ if (!event.target) return
+ if (typeof event.target.result != "string") return
+ this.send({ image: event.target.result })
+ };
+ reader.readAsDataURL(blob);
+ }
+ }
+ }
+
+ send(msg: ChatMessage) {
+ this.room.local_user.chat(msg)
+ this.add_message(this.room.local_user, msg)
}
- send_message(sender: User, message: string) {
+ add_message(sender: User, message: ChatMessage) {
+ const els = []
+ if (message.text) els.push(espan(message.text, { class: "text" }))
+ if (message.image) els.push(image_view(message.image, { class: "image" }))
+
this.messages.append(ediv({ class: "message" },
- espan(sender.display_name, { class: "author" }),
- ": ",
- espan(message, { class: "content" })
+ espan(sender.display_name, { class: "author" }), ": ", ...els
))
}
}
diff --git a/client-web/source/helper.ts b/client-web/source/helper.ts
index 1d75b60..3c5d0ff 100644
--- a/client-web/source/helper.ts
+++ b/client-web/source/helper.ts
@@ -1,14 +1,13 @@
/// <reference lib="dom" />
-
-
const elem = (s: string) => document.createElement(s)
-interface Opts { class?: string[] | string, id?: string }
+interface Opts { class?: string[] | string, id?: string, src?: string, onclick?: () => void }
function apply_opts(e: HTMLElement, o: Opts | undefined) {
if (!o) return
if (o.id) e.id = o.id
+ if (o.onclick) e.onclick = o.onclick
if (typeof o?.class == "string") e.classList.add(o.class)
if (typeof o?.class == "object") e.classList.add(...o.class)
}
@@ -40,7 +39,6 @@ export const elabel = elem_with_content("label")
export const OVERLAYS = ediv({ class: "overlays" })
-
export class OverlayUi {
_shown = false
constructor(public el: HTMLElement, initial = false) {
@@ -54,3 +52,13 @@ export class OverlayUi {
}
}
+export function image_view(url: string, opts?: Opts): HTMLElement {
+ const img = document.createElement("img")
+ apply_opts(img, opts)
+ img.src = url
+ img.alt = `Image (click to open)`
+ img.addEventListener("click", () => {
+ window.open(url, "_blank", "noreferrer=true,noopener=true,popup=true")
+ })
+ return img
+}
diff --git a/client-web/source/user/local.ts b/client-web/source/user/local.ts
index 72d18a4..3fb52ce 100644
--- a/client-web/source/user/local.ts
+++ b/client-web/source/user/local.ts
@@ -9,6 +9,7 @@ import { TrackHandle } from "../track_handle.ts";
import { User } from "./mod.ts";
import { ROOM_CONTAINER } from "../index.ts";
import { ediv } from "../helper.ts";
+import { ChatMessage } from "../../../common/packets.d.ts";
export class LocalUser extends User {
mic_gain?: GainNode
@@ -47,8 +48,8 @@ export class LocalUser extends User {
})
}
- chat(content: string) {
- this.room.signaling.send_relay({ chat: { content } })
+ chat(message: ChatMessage) {
+ this.room.signaling.send_relay({ chat: message })
}
add_initial_to_remote(u: RemoteUser) {
diff --git a/client-web/source/user/remote.ts b/client-web/source/user/remote.ts
index 68dd08f..2ddf2e6 100644
--- a/client-web/source/user/remote.ts
+++ b/client-web/source/user/remote.ts
@@ -43,7 +43,7 @@ export class RemoteUser extends User {
}
on_relay(message: RelayMessage) {
- if (message.chat) this.room.chat.send_message(this, message.chat.content)
+ if (message.chat) this.room.chat.add_message(this, message.chat)
if (message.ice_candidate) this.add_ice_candidate(message.ice_candidate)
if (message.offer) this.on_offer(message.offer)
if (message.answer) this.on_answer(message.answer)