From 368902e801edfcd8bfcd6807678b35cb6e5281f6 Mon Sep 17 00:00:00 2001 From: Noah Petherbridge Date: Mon, 13 Mar 2023 21:26:37 -0700 Subject: [PATCH] Draggable resizable video panels --- README.md | 6 ++- pkg/banned_users.go | 28 ++++++++++++++ pkg/commands.go | 84 ++++++++++++++++++++++++++++++++-------- web/static/css/chat.css | 11 ++++-- web/static/js/BareRTC.js | 12 ++++-- web/templates/chat.html | 21 +++++++--- 6 files changed, 133 insertions(+), 29 deletions(-) create mode 100644 pkg/banned_users.go diff --git a/README.md b/README.md index c1ce2ab..9bdc6a2 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,11 @@ It is very much in the style of the old-school Flash based webcam chat rooms of Some important features still lacking: -* Operator controls (kick/ban users) +* Operator commands + * [x] /kick users + * [x] /nsfw to mark someone's camera + * [ ] /ban users + * [ ] /op users (give temporary mod control) # Configuration diff --git a/pkg/banned_users.go b/pkg/banned_users.go new file mode 100644 index 0000000..662c4bf --- /dev/null +++ b/pkg/banned_users.go @@ -0,0 +1,28 @@ +package barertc + +import "time" + +/* Functions to handle banned users */ + +/* +BanList holds (in memory) knowledge of currently banned users. + +All bans are reset if the chat server is rebooted. Otherwise each ban +comes with a duration - default is 24 hours by the operator can specify +a duration with a ban. If the server is not rebooted, bans will be lifted +after they expire. + +Bans are against usernames and will also block a JWT token from +authenticating if they are currently banned. +*/ +type BanList struct { + Active []Ban +} + +// Ban is an entry on the ban list. +type Ban struct { + Username string + ExpiresAt time.Time +} + +// diff --git a/pkg/commands.go b/pkg/commands.go index ac868e8..279f25b 100644 --- a/pkg/commands.go +++ b/pkg/commands.go @@ -1,6 +1,10 @@ package barertc -import "strings" +import ( + "strconv" + "strings" + "time" +) // ProcessCommand parses a chat message for "/commands" func (s *Server) ProcessCommand(sub *Subscriber, msg Message) bool { @@ -18,21 +22,10 @@ func (s *Server) ProcessCommand(sub *Subscriber, msg Message) bool { if sub.JWTClaims != nil && sub.JWTClaims.IsAdmin { switch words[0] { case "/kick": - if len(words) == 1 { - sub.ChatServer("Usage: `/kick username` to remove the user from the chat room.") - } - username := words[1] - other, err := s.GetSubscriber(username) - if err != nil { - sub.ChatServer("/kick: username not found: %s", username) - } else { - other.ChatServer("You have been kicked from the chat room by %s", sub.Username) - other.SendJSON(Message{ - Action: ActionKick, - }) - s.DeleteSubscriber(other) - sub.ChatServer("%s has been kicked from the room", username) - } + s.KickCommand(words, sub) + return true + case "/ban": + s.BanCommand(words, sub) return true case "/nsfw": if len(words) == 1 { @@ -63,3 +56,62 @@ func (s *Server) ProcessCommand(sub *Subscriber, msg Message) bool { // Not handled. return false } + +// KickCommand handles the `/kick` operator command. +func (s *Server) KickCommand(words []string, sub *Subscriber) { + if len(words) == 1 { + sub.ChatServer("Usage: `/kick username` to remove the user from the chat room.") + } + username := words[1] + other, err := s.GetSubscriber(username) + if err != nil { + sub.ChatServer("/kick: username not found: %s", username) + } else { + other.ChatServer("You have been kicked from the chat room by %s", sub.Username) + other.SendJSON(Message{ + Action: ActionKick, + }) + s.DeleteSubscriber(other) + sub.ChatServer("%s has been kicked from the room", username) + } +} + +// BanCommand handles the `/ban` operator command. +func (s *Server) BanCommand(words []string, sub *Subscriber) { + if len(words) == 1 { + sub.ChatServer( + "Usage: `/ban username` to remove the user from the chat room for 24 hours (default).\n\n" + + "Set another duration (in hours, fractions supported) like: `/ban username 0.5` for a 30-minute ban.", + ) + } + + // Parse the command. + var ( + username = words[1] + duration = 24 * time.Hour + ) + if len(words) >= 3 { + if dur, err := strconv.ParseFloat(words[2], 64); err == nil { + if dur < 1 { + duration = time.Duration(dur*60) * time.Second + } else { + duration = time.Duration(dur) * time.Hour + } + } + } + + // TODO: banning, for now it just kicks. + _ = duration + + other, err := s.GetSubscriber(username) + if err != nil { + sub.ChatServer("/ban: username not found: %s", username) + } else { + other.ChatServer("You have been kicked from the chat room by %s", sub.Username) + other.SendJSON(Message{ + Action: ActionKick, + }) + s.DeleteSubscriber(other) + sub.ChatServer("%s has been kicked from the room", username) + } +} diff --git a/web/static/css/chat.css b/web/static/css/chat.css index 4a9bcfd..2b336af 100644 --- a/web/static/css/chat.css +++ b/web/static/css/chat.css @@ -147,18 +147,21 @@ body { width: 100%; max-width: 100%; - display: flex; + /* display: flex; flex-wrap: wrap; - align-items: left; + align-items: left; */ } .video-feeds > .feed { position: relative; - flex: 0 0 168px; + /* flex: 0 0 168px; */ + float: left; width: 168px; height: 112px; background-color: black; margin: 3px; + overflow: hidden; + resize: both; } .video-feeds.x1 > .feed { @@ -193,7 +196,7 @@ body { .video-feeds > .feed > .controls { position: absolute; background: rgba(0, 0, 0, 0.75); - right: 4px; + left: 4px; bottom: 4px; } diff --git a/web/static/js/BareRTC.js b/web/static/js/BareRTC.js index 9ba6684..0814c8f 100644 --- a/web/static/js/BareRTC.js +++ b/web/static/js/BareRTC.js @@ -188,14 +188,20 @@ const app = Vue.createApp({ history.pushState(null, "", location.href.split("?")[0]); // XX: always show login dialog to test if this helps iOS devices. - this.loginModal.visible = true; - /* + // this.loginModal.visible = true; if (!this.username) { this.loginModal.visible = true; } else { this.signIn(); } - */ + }, + watch: { + "webcam.videoScale": () => { + document.querySelectorAll(".video-feeds > .feed").forEach(node => { + node.style.width = null; + node.style.height = null; + }); + }, }, computed: { chatHistory() { diff --git a/web/templates/chat.html b/web/templates/chat.html index 6f826ae..a89dff4 100644 --- a/web/templates/chat.html +++ b/web/templates/chat.html @@ -463,11 +463,12 @@ - +
+ +
@@ -509,7 +510,17 @@
hi
+
+ hi +
+
+ hi +
+
+ hi +
--> +