From 98505de0f0c40475029ef21a54e497ba68416907 Mon Sep 17 00:00:00 2001 From: maia tillie arson crimew Date: Sat, 13 Nov 2021 16:21:01 +0100 Subject: [PATCH] Implement a viewer list TODO: - instead of fixing a size make it max-height - when the chat is below the video it would probably be better to put the viewer list next to the chat --- frontend/create.html | 2 +- frontend/index.html | 5 +++-- frontend/lib/chat.mjs | 16 ++++++++++++++++ frontend/lib/join-session.mjs | 2 +- frontend/lib/watch-session.mjs | 5 ++++- frontend/main.mjs | 2 +- frontend/styles.css | 12 +++++++++++- src/events.rs | 1 + src/viewer_connection.rs | 21 +++++++++++++++++++++ 9 files changed, 59 insertions(+), 7 deletions(-) diff --git a/frontend/create.html b/frontend/create.html index f408e3e..66b242a 100644 --- a/frontend/create.html +++ b/frontend/create.html @@ -3,7 +3,7 @@ watch party :D - + diff --git a/frontend/index.html b/frontend/index.html index 41a8707..1aaf712 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -3,7 +3,7 @@ watch party :D - + @@ -46,12 +46,13 @@
+
- + diff --git a/frontend/lib/chat.mjs b/frontend/lib/chat.mjs index bc06473..861fd1b 100644 --- a/frontend/lib/chat.mjs +++ b/frontend/lib/chat.mjs @@ -181,3 +181,19 @@ export const logEventToChat = (event) => { } } }; + +export const updateViewerList = (viewers) => { + const listContainer = document.querySelector("#viewer-list"); + + // empty out the current list + listContainer.innerHTML = ""; + + // display the updated list + for (const viewer of viewers) { + const viewerElem = document.createElement("div"); + const content = document.createElement("strong"); + content.appendChild(document.createTextNode(viewer)); + viewerElem.appendChild(content); + listContainer.appendChild(viewerElem); + } +}; diff --git a/frontend/lib/join-session.mjs b/frontend/lib/join-session.mjs index 2337398..93118c2 100644 --- a/frontend/lib/join-session.mjs +++ b/frontend/lib/join-session.mjs @@ -1,4 +1,4 @@ -import { joinSession } from "./watch-session.mjs?v=3"; +import { joinSession } from "./watch-session.mjs?v=4"; /** * @param {HTMLInputElement} field diff --git a/frontend/lib/watch-session.mjs b/frontend/lib/watch-session.mjs index 762cfee..0ecc2c8 100644 --- a/frontend/lib/watch-session.mjs +++ b/frontend/lib/watch-session.mjs @@ -1,5 +1,5 @@ import { setupVideo } from "./video.mjs?v=2"; -import { setupChat, logEventToChat } from "./chat.mjs?v=2"; +import { setupChat, logEventToChat, updateViewerList } from "./chat.mjs?v=3"; /** * @param {string} sessionId @@ -69,6 +69,9 @@ const setupIncomingEvents = (video, socket) => { setDebounce(); setVideoTime(event.data); break; + case "UpdateViewerList": + updateViewerList(event.data); + break; } } diff --git a/frontend/main.mjs b/frontend/main.mjs index a0bec35..f380e4e 100644 --- a/frontend/main.mjs +++ b/frontend/main.mjs @@ -1,4 +1,4 @@ -import { setupJoinSessionForm } from "./lib/join-session.mjs?v=2"; +import { setupJoinSessionForm } from "./lib/join-session.mjs?v=3"; const main = () => { setupJoinSessionForm(); diff --git a/frontend/styles.css b/frontend/styles.css index 35bf64d..5774f50 100644 --- a/frontend/styles.css +++ b/frontend/styles.css @@ -156,6 +156,16 @@ button.small-button { overflow-y: scroll; } +#viewer-list { + padding: 0.5em 2em; + /* TODO: turn this into max-height instead of fixed height without breaking the chatbox height */ + height: 4em; + overflow-y: scroll; + color: rgb(126, 208, 255); + border-bottom: var(--fg); + border-bottom-style: solid; +} + #chatbox-container { background-color: #222; } @@ -191,6 +201,6 @@ button.small-button { } #chatbox { - height: calc(100vh - 5em) !important; + height: calc(100vh - 5em - 4em) !important; } } diff --git a/src/events.rs b/src/events.rs index 910b3a9..6b0a5b1 100644 --- a/src/events.rs +++ b/src/events.rs @@ -9,6 +9,7 @@ pub enum WatchEventData { UserJoin, UserLeave, ChatMessage(String), + UpdateViewerList(Vec), } #[derive(Clone, Serialize, Deserialize)] diff --git a/src/viewer_connection.rs b/src/viewer_connection.rs index 7ceb490..b93c251 100644 --- a/src/viewer_connection.rs +++ b/src/viewer_connection.rs @@ -65,6 +65,8 @@ pub async fn ws_subscribe(session_uuid: Uuid, nickname: String, ws: WebSocket) { ) .await; + update_viewer_list(session_uuid).await; + while let Some(Ok(message)) = viewer_ws_rx.next().await { let event: WatchEventData = match message .to_str() @@ -97,6 +99,7 @@ pub async fn ws_subscribe(session_uuid: Uuid, nickname: String, ws: WebSocket) { .await; CONNECTED_VIEWERS.write().await.remove(&viewer_id); + update_viewer_list(session_uuid).await; } pub async fn ws_publish(session_uuid: Uuid, skip_viewer_id: Option, event: WatchEvent) { @@ -111,3 +114,21 @@ pub async fn ws_publish(session_uuid: Uuid, skip_viewer_id: Option, event }); } } + +async fn update_viewer_list(session_uuid: Uuid) { + let mut names = Vec::new(); + for viewer in CONNECTED_VIEWERS.read().await.values() { + if viewer.session == session_uuid && viewer.nickname != None { + names.push(viewer.nickname.clone().unwrap()) + } + } + ws_publish( + session_uuid, + None, + WatchEvent::new( + String::from("server"), + WatchEventData::UpdateViewerList(names), + ), + ) + .await; +}