diff --git a/pkg/commands.go b/pkg/commands.go
index 8cf3b06..7eafd8a 100644
--- a/pkg/commands.go
+++ b/pkg/commands.go
@@ -44,11 +44,15 @@ func (s *Server) ProcessCommand(sub *Subscriber, msg Message) bool {
if err != nil {
sub.ChatServer("/nsfw: username not found: %s", username)
} else {
- other.ChatServer("Your camera has been marked as NSFW by %s", sub.Username)
+ other.ChatServer(
+ "Just a friendly reminder to mark your camera as 'Explicit' by using the button at the top "+
+ "of the page if you are going to be sexual on webcam. Your camera has been marked as Explicit "+
+ "for you by @%s", sub.Username,
+ )
other.VideoStatus |= VideoFlagNSFW
other.SendMe()
s.SendWhoList()
- sub.ChatServer("%s has their camera marked as NSFW", username)
+ sub.ChatServer("%s now has their camera marked as Explicit", username)
}
return true
case "/help":
diff --git a/web/static/js/BareRTC.js b/web/static/js/BareRTC.js
index 491699b..2783e0e 100644
--- a/web/static/js/BareRTC.js
+++ b/web/static/js/BareRTC.js
@@ -175,6 +175,7 @@ const app = Vue.createApp({
historyScrollbox: null,
autoscroll: true, // scroll to bottom on new messages
fontSizeClass: "", // font size magnification
+ scrollback: 1000, // scrollback buffer (messages to keep per channel)
DMs: {},
messageReactions: {
// Will look like:
@@ -204,6 +205,7 @@ const app = Vue.createApp({
settingsModal: {
visible: false,
+ tab: 'prefs', // selected setting tab
},
nsfwModalCast: {
@@ -292,6 +294,9 @@ const app = Vue.createApp({
// Store the setting persistently.
localStorage.fontSizeClass = this.fontSizeClass;
},
+ scrollback() {
+ localStorage.scrollback = this.scrollback;
+ },
status() {
// Send presence updates to the server.
this.sendMe();
@@ -320,6 +325,26 @@ const app = Vue.createApp({
}
return history;
},
+ activeDMs() {
+ // List your currently open DM threads, sorted by most recent.
+ let result = [];
+ for (let channel of Object.keys(this.channels)) {
+ // @mentions only
+ if (channel.indexOf("@") !== 0) {
+ continue;
+ }
+
+ result.push({
+ channel: channel,
+ name: channel.substring(1),
+ updated: this.channels[channel].updated,
+ unread: this.channels[channel].unread,
+ });
+ }
+
+ result.sort((a, b) => b.updated - a.updated);
+ return result;
+ },
channelName() {
// Return a suitable channel title.
if (this.channel.indexOf("@") === 0) {
@@ -366,6 +391,10 @@ const app = Vue.createApp({
this.webcam.videoScale = localStorage.videoScale;
}
+ if (localStorage.scrollback != undefined) {
+ this.scrollback = parseInt(localStorage.scrollback);
+ }
+
// Webcam mutality preferences from last broadcast.
if (localStorage.videoMutual === "true") {
this.webcam.mutual = true;
@@ -944,6 +973,10 @@ const app = Vue.createApp({
username: username,
}));
},
+ isWatchingMe(username) {
+ // Return whether the user is watching your camera
+ return this.webcam.watching[username] === true;
+ },
/**
* Front-end web app concerns.
@@ -1129,28 +1162,6 @@ const app = Vue.createApp({
}
return result;
},
- activeDMs() {
- // List your currently open DM threads, sorted by most recent.
- let result = [];
- for (let channel of Object.keys(this.channels)) {
- // @mentions only
- if (channel.indexOf("@") !== 0) {
- continue;
- }
-
- result.push({
- channel: channel,
- name: channel.substring(1),
- updated: this.channels[channel].updated,
- unread: this.channels[channel].unread,
- });
- }
-
- result.sort((a, b) => {
- return a.updated < b.updated;
- });
- return result;
- },
// Start broadcasting my webcam.
// - force=true to skip the NSFW modal prompt (this param is passed by the button in that modal)
@@ -1632,7 +1643,7 @@ const app = Vue.createApp({
this.initHistory(channel);
// Append the message.
- this.channels[channel].updated = Date.now();
+ this.channels[channel].updated = new Date().getTime();
this.channels[channel].history.push({
action: action,
username: username,
@@ -1642,6 +1653,15 @@ const app = Vue.createApp({
isChatServer,
isChatClient,
});
+
+ // Trim the history per the scrollback buffer.
+ if (this.scrollback > 0 && this.channels[channel].history.length > this.scrollback) {
+ this.channels[channel].history = this.channels[channel].history.slice(
+ -this.scrollback,
+ this.channels[channel].history.length+1,
+ );
+ }
+
this.scrollHistory(channel);
// Mark unread notifiers if this is not our channel.
diff --git a/web/templates/chat.html b/web/templates/chat.html
index 0a592be..18a0d2d 100644
--- a/web/templates/chat.html
+++ b/web/templates/chat.html
@@ -72,227 +72,181 @@
-
-
- Video size
-
-
-
-
-
-
-
- [[ s[1] ]]
-
-
+
+
+
+
+
+
+
+
+
+ Text size
+
+
+
+
+
+
+
+ [[ s[1] ]]
+
+
+
+
+
+
+
+
+
+
Scrollback buffer
+
+
+
+
+ How many chat history messages to keep at once (per channel/DM thread).
+ Older messages will be removed so your web browser doesn't run low on memory.
+ A value of zero (0) will mean "unlimited" and the chat history is never trimmed.
+
+
+
+
+ Webcam Devices
+
+
+
+
+
Video source
+
+
+
+ [[ d.label || `Camera ${i}` ]]
+
+
+
+
+
+
+
Audio source
+
+
+
+ [[ d.label || `Microphone ${i}` ]]
+
+
+
+
+
-
-
-
Text size
+
+
+
+
+
+ DM chat
+
+
+
+
+
+ [[s.name]]
+
+
+
+
+
+
+ Public chat
+
+
+
+
+
+ [[s.name]]
+
+
+
+
-
-
-
-
-
-
- [[ s[1] ]]
-
-
-
+
+
+
+ Room enter
+
+
+
+
+
+ [[s.name]]
+
+
+
+
+
+
+ Room leave
+
+
-
-
-
-
Video source
-
-
-
- [[ d.label || `Camera ${i}` ]]
-
-
-
-
-
-
-
Audio source
-
-
-
- [[ d.label || `Microphone ${i}` ]]
-
-
-
-
-
-
-
Sounds
-
-
-
- DM chat
-
-
-
-
-
- [[s.name]]
-
-
-
-
-
-
- Public chat
-
-
-
-
-
- [[s.name]]
-
-
-
-
-
-
-
-
- Room enter
-
-
-
-
-
- [[s.name]]
-
-
-
-
-
-
- Room leave
-
-
-
-
-
- [[s.name]]
-
-
-
-
-
-
-
-
-
+
@@ -537,7 +491,7 @@