Spit and polish
* Add a scrollback buffer option to the chat Settings to trim room history so your browser can manage its memory usage * Update the wording that ChatServer sends to users when the /nsfw command has been used on them * Fix the ordering of active DMs for Chromium browsers so the most recently updated DM thread moves to the top of the list * Show an indicator on videos whether the person you watch also watches you back * Fix the "X" button on the photo modal not functioning correctly
This commit is contained in:
parent
75c7511410
commit
e111899404
|
@ -44,11 +44,15 @@ func (s *Server) ProcessCommand(sub *Subscriber, msg Message) bool {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
sub.ChatServer("/nsfw: username not found: %s", username)
|
sub.ChatServer("/nsfw: username not found: %s", username)
|
||||||
} else {
|
} 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.VideoStatus |= VideoFlagNSFW
|
||||||
other.SendMe()
|
other.SendMe()
|
||||||
s.SendWhoList()
|
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
|
return true
|
||||||
case "/help":
|
case "/help":
|
||||||
|
|
|
@ -175,6 +175,7 @@ const app = Vue.createApp({
|
||||||
historyScrollbox: null,
|
historyScrollbox: null,
|
||||||
autoscroll: true, // scroll to bottom on new messages
|
autoscroll: true, // scroll to bottom on new messages
|
||||||
fontSizeClass: "", // font size magnification
|
fontSizeClass: "", // font size magnification
|
||||||
|
scrollback: 1000, // scrollback buffer (messages to keep per channel)
|
||||||
DMs: {},
|
DMs: {},
|
||||||
messageReactions: {
|
messageReactions: {
|
||||||
// Will look like:
|
// Will look like:
|
||||||
|
@ -204,6 +205,7 @@ const app = Vue.createApp({
|
||||||
|
|
||||||
settingsModal: {
|
settingsModal: {
|
||||||
visible: false,
|
visible: false,
|
||||||
|
tab: 'prefs', // selected setting tab
|
||||||
},
|
},
|
||||||
|
|
||||||
nsfwModalCast: {
|
nsfwModalCast: {
|
||||||
|
@ -292,6 +294,9 @@ const app = Vue.createApp({
|
||||||
// Store the setting persistently.
|
// Store the setting persistently.
|
||||||
localStorage.fontSizeClass = this.fontSizeClass;
|
localStorage.fontSizeClass = this.fontSizeClass;
|
||||||
},
|
},
|
||||||
|
scrollback() {
|
||||||
|
localStorage.scrollback = this.scrollback;
|
||||||
|
},
|
||||||
status() {
|
status() {
|
||||||
// Send presence updates to the server.
|
// Send presence updates to the server.
|
||||||
this.sendMe();
|
this.sendMe();
|
||||||
|
@ -320,6 +325,26 @@ const app = Vue.createApp({
|
||||||
}
|
}
|
||||||
return history;
|
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() {
|
channelName() {
|
||||||
// Return a suitable channel title.
|
// Return a suitable channel title.
|
||||||
if (this.channel.indexOf("@") === 0) {
|
if (this.channel.indexOf("@") === 0) {
|
||||||
|
@ -366,6 +391,10 @@ const app = Vue.createApp({
|
||||||
this.webcam.videoScale = localStorage.videoScale;
|
this.webcam.videoScale = localStorage.videoScale;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (localStorage.scrollback != undefined) {
|
||||||
|
this.scrollback = parseInt(localStorage.scrollback);
|
||||||
|
}
|
||||||
|
|
||||||
// Webcam mutality preferences from last broadcast.
|
// Webcam mutality preferences from last broadcast.
|
||||||
if (localStorage.videoMutual === "true") {
|
if (localStorage.videoMutual === "true") {
|
||||||
this.webcam.mutual = true;
|
this.webcam.mutual = true;
|
||||||
|
@ -944,6 +973,10 @@ const app = Vue.createApp({
|
||||||
username: username,
|
username: username,
|
||||||
}));
|
}));
|
||||||
},
|
},
|
||||||
|
isWatchingMe(username) {
|
||||||
|
// Return whether the user is watching your camera
|
||||||
|
return this.webcam.watching[username] === true;
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Front-end web app concerns.
|
* Front-end web app concerns.
|
||||||
|
@ -1129,28 +1162,6 @@ const app = Vue.createApp({
|
||||||
}
|
}
|
||||||
return result;
|
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.
|
// Start broadcasting my webcam.
|
||||||
// - force=true to skip the NSFW modal prompt (this param is passed by the button in that modal)
|
// - 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);
|
this.initHistory(channel);
|
||||||
|
|
||||||
// Append the message.
|
// Append the message.
|
||||||
this.channels[channel].updated = Date.now();
|
this.channels[channel].updated = new Date().getTime();
|
||||||
this.channels[channel].history.push({
|
this.channels[channel].history.push({
|
||||||
action: action,
|
action: action,
|
||||||
username: username,
|
username: username,
|
||||||
|
@ -1642,6 +1653,15 @@ const app = Vue.createApp({
|
||||||
isChatServer,
|
isChatServer,
|
||||||
isChatClient,
|
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);
|
this.scrollHistory(channel);
|
||||||
|
|
||||||
// Mark unread notifiers if this is not our channel.
|
// Mark unread notifiers if this is not our channel.
|
||||||
|
|
|
@ -72,227 +72,181 @@
|
||||||
</header>
|
</header>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
|
||||||
<div class="field is-horizontal">
|
<!-- Tab bar for the settings -->
|
||||||
<div class="field-label is-normal">
|
<div class="tabs">
|
||||||
<label class="label">Video size</label>
|
<ul>
|
||||||
</div>
|
<li :class="{'is-active': settingsModal.tab==='prefs'}">
|
||||||
<div class="field-body">
|
<a href="#" @click.prevent="settingsModal.tab='prefs'">
|
||||||
<div class="field">
|
Display
|
||||||
<div class="control">
|
</a>
|
||||||
<div class="select is-fullwidth">
|
</li>
|
||||||
<select v-model="webcam.videoScale">
|
<li :class="{'is-active': settingsModal.tab==='sounds'}">
|
||||||
<option v-for="s in webcam.videoScaleOptions"
|
<a href="#" @click.prevent="settingsModal.tab='sounds'">
|
||||||
v-bind:key="s[0]"
|
Sound effects
|
||||||
:value="s[0]">
|
</a>
|
||||||
[[ s[1] ]]
|
</li>
|
||||||
</option>
|
</ul>
|
||||||
</select>
|
</div>
|
||||||
|
|
||||||
|
<!-- Display preferences -->
|
||||||
|
<div v-if="settingsModal.tab==='prefs'">
|
||||||
|
<div class="field is-horizontal">
|
||||||
|
<div class="field-label is-normal">
|
||||||
|
<label class="label">Video size</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select v-model="webcam.videoScale">
|
||||||
|
<option v-for="s in webcam.videoScaleOptions"
|
||||||
|
v-bind:key="s[0]"
|
||||||
|
:value="s[0]">
|
||||||
|
[[ s[1] ]]
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field is-horizontal">
|
||||||
|
<div class="field-label is-normal">
|
||||||
|
<label class="label">Text size</label>
|
||||||
|
</div>
|
||||||
|
<div class="field-body">
|
||||||
|
<div class="field">
|
||||||
|
<div class="control">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select v-model="fontSizeClass">
|
||||||
|
<option v-for="s in config.fontSizeClasses"
|
||||||
|
v-bind:key="s[0]"
|
||||||
|
:value="s[0]">
|
||||||
|
[[ s[1] ]]
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="label">Scrollback buffer</label>
|
||||||
|
<div class="control">
|
||||||
|
<input type="number"
|
||||||
|
class="input"
|
||||||
|
v-model="scrollback"
|
||||||
|
min="0"
|
||||||
|
inputmode="numeric">
|
||||||
|
</div>
|
||||||
|
<p class="help">
|
||||||
|
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.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<h3 class="subtitle mb-2" v-if="webcam.videoDevices.length > 0 || webcam.audioDevices.length > 0">
|
||||||
|
Webcam Devices
|
||||||
|
</h3>
|
||||||
|
<div class="columns is-mobile" v-if="webcam.videoDevices.length > 0 || webcam.audioDevices.length > 0">
|
||||||
|
|
||||||
|
<div class="column">
|
||||||
|
<label class="label">Video source</label>
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select v-model="webcam.videoDeviceID" @change="startVideo({changeCamera: true, force: true})">
|
||||||
|
<option v-for="(d, i) in webcam.videoDevices"
|
||||||
|
:value="d.id">
|
||||||
|
[[ d.label || `Camera ${i}` ]]
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column">
|
||||||
|
<label class="label">Audio source</label>
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select v-model="webcam.audioDeviceID" @change="startVideo({changeCamera: true, force: true})">
|
||||||
|
<option v-for="(d, i) in webcam.audioDevices"
|
||||||
|
:value="d.id">
|
||||||
|
[[ d.label || `Microphone ${i}` ]]
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field is-horizontal">
|
<!-- Sound settings -->
|
||||||
<div class="field-label is-normal">
|
<div v-else-if="settingsModal.tab==='sounds'">
|
||||||
<label class="label">Text size</label>
|
|
||||||
|
<div class="columns is-mobile">
|
||||||
|
<div class="column is-2 pr-1">
|
||||||
|
<label class="label">DM chat</label>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select v-model="config.sounds.settings.DM" @change="setSoundPref('DM')">
|
||||||
|
<option v-for="s in config.sounds.available"
|
||||||
|
v-bind:key="s.name"
|
||||||
|
:value="s.name">
|
||||||
|
[[s.name]]
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column is-2 pr-1">
|
||||||
|
<label class="label">Public chat</label>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select v-model="config.sounds.settings.Chat" @change="setSoundPref('Chat')">
|
||||||
|
<option v-for="s in config.sounds.available"
|
||||||
|
v-bind:key="s.name"
|
||||||
|
:value="s.name">
|
||||||
|
[[s.name]]
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="field-body">
|
|
||||||
<div class="field">
|
<div class="columns is-mobile">
|
||||||
<div class="control">
|
<div class="column is-2 pr-1">
|
||||||
<div class="select is-fullwidth">
|
<label class="label">Room enter</label>
|
||||||
<select v-model="fontSizeClass">
|
</div>
|
||||||
<option v-for="s in config.fontSizeClasses"
|
<div class="column">
|
||||||
v-bind:key="s[0]"
|
<div class="select is-fullwidth">
|
||||||
:value="s[0]">
|
<select v-model="config.sounds.settings.Enter" @change="setSoundPref('Enter')">
|
||||||
[[ s[1] ]]
|
<option v-for="s in config.sounds.available"
|
||||||
</option>
|
v-bind:key="s.name"
|
||||||
</select>
|
:value="s.name">
|
||||||
</div>
|
[[s.name]]
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="column is-2 pr-1">
|
||||||
|
<label class="label">Room leave</label>
|
||||||
|
</div>
|
||||||
|
<div class="column">
|
||||||
|
<div class="select is-fullwidth">
|
||||||
|
<select v-model="config.sounds.settings.Leave" @change="setSoundPref('Leave')">
|
||||||
|
<option v-for="s in config.sounds.available"
|
||||||
|
v-bind:key="s.name"
|
||||||
|
:value="s.name">
|
||||||
|
[[s.name]]
|
||||||
|
</option>
|
||||||
|
</select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="columns is-mobile" v-if="webcam.videoDevices.length > 0 || webcam.audioDevices.length > 0">
|
|
||||||
|
|
||||||
<div class="column">
|
|
||||||
<label class="label">Video source</label>
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="webcam.videoDeviceID" @change="startVideo({changeCamera: true, force: true})">
|
|
||||||
<option v-for="(d, i) in webcam.videoDevices"
|
|
||||||
:value="d.id">
|
|
||||||
[[ d.label || `Camera ${i}` ]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column">
|
|
||||||
<label class="label">Audio source</label>
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="webcam.audioDeviceID" @change="startVideo({changeCamera: true, force: true})">
|
|
||||||
<option v-for="(d, i) in webcam.audioDevices"
|
|
||||||
:value="d.id">
|
|
||||||
[[ d.label || `Microphone ${i}` ]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 class="subtitle mb-2">Sounds</h3>
|
|
||||||
|
|
||||||
<div class="columns is-mobile">
|
|
||||||
<div class="column is-2 pr-1">
|
|
||||||
<label class="label">DM chat</label>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="config.sounds.settings.DM" @change="setSoundPref('DM')">
|
|
||||||
<option v-for="s in config.sounds.available"
|
|
||||||
v-bind:key="s.name"
|
|
||||||
:value="s.name">
|
|
||||||
[[s.name]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column is-2 pr-1">
|
|
||||||
<label class="label">Public chat</label>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="config.sounds.settings.Chat" @change="setSoundPref('Chat')">
|
|
||||||
<option v-for="s in config.sounds.available"
|
|
||||||
v-bind:key="s.name"
|
|
||||||
:value="s.name">
|
|
||||||
[[s.name]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="columns is-mobile">
|
|
||||||
<div class="column is-2 pr-1">
|
|
||||||
<label class="label">Room enter</label>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="config.sounds.settings.Enter" @change="setSoundPref('Enter')">
|
|
||||||
<option v-for="s in config.sounds.available"
|
|
||||||
v-bind:key="s.name"
|
|
||||||
:value="s.name">
|
|
||||||
[[s.name]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="column is-2 pr-1">
|
|
||||||
<label class="label">Room leave</label>
|
|
||||||
</div>
|
|
||||||
<div class="column">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="config.sounds.settings.Leave" @change="setSoundPref('Leave')">
|
|
||||||
<option v-for="s in config.sounds.available"
|
|
||||||
v-bind:key="s.name"
|
|
||||||
:value="s.name">
|
|
||||||
[[s.name]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<!--
|
|
||||||
<div class="field is-horizontal">
|
|
||||||
<div class="field-label is-normal">
|
|
||||||
<label class="label">DM chat</label>
|
|
||||||
</div>
|
|
||||||
<div class="field-body">
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="config.sounds.settings.DM" @change="setSoundPref('DM')">
|
|
||||||
<option v-for="s in config.sounds.available"
|
|
||||||
v-bind:key="s.name"
|
|
||||||
:value="s.name">
|
|
||||||
[[s.name]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field is-horizontal">
|
|
||||||
<div class="field-label is-normal">
|
|
||||||
<label class="label">Public chat</label>
|
|
||||||
</div>
|
|
||||||
<div class="field-body">
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="config.sounds.settings.Chat" @change="setSoundPref('Chat')">
|
|
||||||
<option v-for="s in config.sounds.available"
|
|
||||||
v-bind:key="s.name"
|
|
||||||
:value="s.name">
|
|
||||||
[[s.name]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field is-horizontal">
|
|
||||||
<div class="field-label is-normal">
|
|
||||||
<label class="label">Room enter</label>
|
|
||||||
</div>
|
|
||||||
<div class="field-body">
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="config.sounds.settings.Enter" @change="setSoundPref('Enter')">
|
|
||||||
<option v-for="s in config.sounds.available"
|
|
||||||
v-bind:key="s.name"
|
|
||||||
:value="s.name">
|
|
||||||
[[s.name]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="field is-horizontal">
|
|
||||||
<div class="field-label is-normal">
|
|
||||||
<label class="label">Room leave</label>
|
|
||||||
</div>
|
|
||||||
<div class="field-body">
|
|
||||||
<div class="field">
|
|
||||||
<div class="control">
|
|
||||||
<div class="select is-fullwidth">
|
|
||||||
<select v-model="config.sounds.settings.Leave" @change="setSoundPref('Leave')">
|
|
||||||
<option v-for="s in config.sounds.available"
|
|
||||||
v-bind:key="s.name"
|
|
||||||
:value="s.name">
|
|
||||||
[[s.name]]
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
-->
|
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<footer class="card-footer">
|
<footer class="card-footer">
|
||||||
<div class="card-footer-item">
|
<div class="card-footer-item">
|
||||||
|
@ -417,7 +371,7 @@
|
||||||
<img id="modalImage">
|
<img id="modalImage">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<button class="modal-close is-large" aria-label="close"></button>
|
<button class="modal-close is-large" aria-label="close" onclick="document.querySelector('#photo-modal').classList.remove('is-active')"></button>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="chat-container">
|
<div class="chat-container">
|
||||||
|
@ -537,7 +491,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
<li v-for="c in activeDMs()"
|
<li v-for="c in activeDMs"
|
||||||
v-bind:key="c.channel">
|
v-bind:key="c.channel">
|
||||||
<a :href="'#'+c.channel"
|
<a :href="'#'+c.channel"
|
||||||
@click.prevent="setChannel(c.channel)"
|
@click.prevent="setChannel(c.channel)"
|
||||||
|
@ -681,6 +635,9 @@
|
||||||
<i class="fa fa-microphone-slash mr-1 has-text-grey"
|
<i class="fa fa-microphone-slash mr-1 has-text-grey"
|
||||||
v-if="isSourceMuted(username)"></i>
|
v-if="isSourceMuted(username)"></i>
|
||||||
[[username]]
|
[[username]]
|
||||||
|
<i class="fa fa-people-arrows ml-1 has-text-grey is-size-7"
|
||||||
|
:title="username+' is watching your camera too'"
|
||||||
|
v-if="isWatchingMe(username)"></i>
|
||||||
</div>
|
</div>
|
||||||
<div class="close">
|
<div class="close">
|
||||||
<a href="#"
|
<a href="#"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user