Prefers non-explicit and option to expressly remember closed videos
This commit is contained in:
parent
bdb5e6359b
commit
fea1d1c7b9
|
@ -40,7 +40,7 @@ VideoFlag: {
|
||||||
Active: 1 << 0, // or 00000001 in binary
|
Active: 1 << 0, // or 00000001 in binary
|
||||||
NSFW: 1 << 1, // or 00000010
|
NSFW: 1 << 1, // or 00000010
|
||||||
Muted: 1 << 2, // or 00000100, etc.
|
Muted: 1 << 2, // or 00000100, etc.
|
||||||
IsTalking: 1 << 3,
|
NonExplicit: 1 << 3,
|
||||||
MutualRequired: 1 << 4,
|
MutualRequired: 1 << 4,
|
||||||
MutualOpen: 1 << 5,
|
MutualOpen: 1 << 5,
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,7 +126,7 @@ const (
|
||||||
VideoFlagActive int = 1 << iota // user's camera is enabled/broadcasting
|
VideoFlagActive int = 1 << iota // user's camera is enabled/broadcasting
|
||||||
VideoFlagNSFW // viewer's camera is marked as NSFW
|
VideoFlagNSFW // viewer's camera is marked as NSFW
|
||||||
VideoFlagMuted // user source microphone is muted
|
VideoFlagMuted // user source microphone is muted
|
||||||
VideoFlagIsTalking // broadcaster seems to be talking
|
VideoFlagNonExplicit // viewer prefers not to see NSFW cameras (don't auto-open red cams/auto-close blue cams going red)
|
||||||
VideoFlagMutualRequired // video wants viewers to share their camera too
|
VideoFlagMutualRequired // video wants viewers to share their camera too
|
||||||
VideoFlagMutualOpen // viewer wants to auto-open viewers' cameras
|
VideoFlagMutualOpen // viewer wants to auto-open viewers' cameras
|
||||||
VideoFlagOnlyVIP // can only shows as active to VIP members
|
VideoFlagOnlyVIP // can only shows as active to VIP members
|
||||||
|
|
102
src/App.vue
102
src/App.vue
|
@ -162,7 +162,9 @@ export default {
|
||||||
nsfw: false, // user has flagged their camera to be NSFW
|
nsfw: false, // user has flagged their camera to be NSFW
|
||||||
mutual: false, // user wants viewers to share their own videos
|
mutual: false, // user wants viewers to share their own videos
|
||||||
mutualOpen: false, // user wants to open video mutually
|
mutualOpen: false, // user wants to open video mutually
|
||||||
|
nonExplicit: false, // user prefers not to see explicit cameras
|
||||||
vipOnly: false, // only show camera to fellow VIP users
|
vipOnly: false, // only show camera to fellow VIP users
|
||||||
|
rememberExpresslyClosed: true, // remember cams we expressly closed
|
||||||
|
|
||||||
// Who all is watching me? map of users.
|
// Who all is watching me? map of users.
|
||||||
watching: {},
|
watching: {},
|
||||||
|
@ -422,6 +424,12 @@ export default {
|
||||||
this.sendMe();
|
this.sendMe();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"webcam.nonExplicit": function () {
|
||||||
|
LocalStorage.set('videoNonExplicit', this.webcam.nonExplicit);
|
||||||
|
if (this.webcam.active) {
|
||||||
|
this.sendMe();
|
||||||
|
}
|
||||||
|
},
|
||||||
"webcam.vipOnly": function () {
|
"webcam.vipOnly": function () {
|
||||||
LocalStorage.set('videoVipOnly', this.webcam.vipOnly);
|
LocalStorage.set('videoVipOnly', this.webcam.vipOnly);
|
||||||
if (this.webcam.active) {
|
if (this.webcam.active) {
|
||||||
|
@ -437,6 +445,9 @@ export default {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"webcam.rememberExpresslyClosed": function() {
|
||||||
|
LocalStorage.set('rememberExpresslyClosed', this.webcam.rememberExpresslyClosed);
|
||||||
|
},
|
||||||
|
|
||||||
// Misc preference watches
|
// Misc preference watches
|
||||||
"prefs.joinMessages": function () {
|
"prefs.joinMessages": function () {
|
||||||
|
@ -559,6 +570,7 @@ export default {
|
||||||
if (this.webcam.nsfw) status |= this.VideoFlag.NSFW;
|
if (this.webcam.nsfw) status |= this.VideoFlag.NSFW;
|
||||||
if (this.webcam.mutual) status |= this.VideoFlag.MutualRequired;
|
if (this.webcam.mutual) status |= this.VideoFlag.MutualRequired;
|
||||||
if (this.webcam.mutualOpen) status |= this.VideoFlag.MutualOpen;
|
if (this.webcam.mutualOpen) status |= this.VideoFlag.MutualOpen;
|
||||||
|
if (this.webcam.nonExplicit) status |= this.VideoFlag.NonExplicit;
|
||||||
if (this.webcam.vipOnly && this.isVIP) status |= this.VideoFlag.VipOnly;
|
if (this.webcam.vipOnly && this.isVIP) status |= this.VideoFlag.VipOnly;
|
||||||
return status;
|
return status;
|
||||||
},
|
},
|
||||||
|
@ -749,6 +761,12 @@ export default {
|
||||||
if (settings.videoExplicit === true) {
|
if (settings.videoExplicit === true) {
|
||||||
this.webcam.nsfw = true;
|
this.webcam.nsfw = true;
|
||||||
}
|
}
|
||||||
|
if (settings.videoNonExplicit === true) {
|
||||||
|
this.webcam.nonExplicit = true;
|
||||||
|
}
|
||||||
|
if (settings.rememberExpresslyClosed === false) {
|
||||||
|
this.webcam.rememberExpresslyClosed = false;
|
||||||
|
}
|
||||||
|
|
||||||
// Misc preferences
|
// Misc preferences
|
||||||
if (settings.joinMessages != undefined) {
|
if (settings.joinMessages != undefined) {
|
||||||
|
@ -976,6 +994,15 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let row of this.whoList) {
|
for (let row of this.whoList) {
|
||||||
|
// If we were watching this user's (blue) camera and we prefer non-Explicit,
|
||||||
|
// and their camera is now becoming explicit (red), close it now.
|
||||||
|
if (this.webcam.nonExplicit && this.WebRTC.streams[row.username] != undefined) {
|
||||||
|
if (!(this.whoMap[row.username].video & this.VideoFlag.NSFW)
|
||||||
|
&& (row.video & this.VideoFlag.NSFW)) {
|
||||||
|
this.closeVideo(row.username, "offerer");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
this.whoMap[row.username] = row;
|
this.whoMap[row.username] = row;
|
||||||
this.whoOnline[row.username] = true;
|
this.whoOnline[row.username] = true;
|
||||||
|
|
||||||
|
@ -996,6 +1023,17 @@ export default {
|
||||||
// are already watching them.
|
// are already watching them.
|
||||||
this.unMutualVideo();
|
this.unMutualVideo();
|
||||||
|
|
||||||
|
// If we have any webcams open with users who are no longer in the Who List
|
||||||
|
// (e.g.: can happen during a server reboot when the Who List goes empty),
|
||||||
|
// close those video connections. Note: during normal room exit events this
|
||||||
|
// is done on the onUserExited function - this is an extra safety check especially
|
||||||
|
// in case of unexpected disconnect.
|
||||||
|
for (let username of Object.keys(this.WebRTC.pc)) {
|
||||||
|
if (this.whoOnline[username] == undefined) {
|
||||||
|
this.closeVideo(username);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Has the back-end server forgotten we are on video? This can
|
// Has the back-end server forgotten we are on video? This can
|
||||||
// happen if we disconnect/reconnect while we were streaming.
|
// happen if we disconnect/reconnect while we were streaming.
|
||||||
if (this.webcam.active && !(this.whoMap[this.username]?.video & this.VideoFlag.Active)) {
|
if (this.webcam.active && !(this.whoMap[this.username]?.video & this.VideoFlag.Active)) {
|
||||||
|
@ -1418,7 +1456,7 @@ export default {
|
||||||
// video enabled, and we 'X' out, and they reopen ours - we may be receiving their
|
// video enabled, and we 'X' out, and they reopen ours - we may be receiving their
|
||||||
// video right now. If we had expressly closed it, do not accept their video
|
// video right now. If we had expressly closed it, do not accept their video
|
||||||
// and hang up the connection.
|
// and hang up the connection.
|
||||||
if (this.WebRTC.expresslyClosed[username]) {
|
if (this.WebRTC.expresslyClosed[username] && this.webcam.rememberExpresslyClosed) {
|
||||||
if (!isOfferer) {
|
if (!isOfferer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1496,6 +1534,10 @@ export default {
|
||||||
&& this.webcam.active // Our camera is active (to add it)
|
&& this.webcam.active // Our camera is active (to add it)
|
||||||
&& !this.isBooted(username) // We had not booted them off ours before
|
&& !this.isBooted(username) // We had not booted them off ours before
|
||||||
&& !this.isMutedUser(username) // We had not muted them before
|
&& !this.isMutedUser(username) // We had not muted them before
|
||||||
|
|
||||||
|
// If our webcam is NSFW and the viewer prefers not to see explicit,
|
||||||
|
// do not send our camera on this offer.
|
||||||
|
&& (!this.webcam.nsfw || !(this.whoMap[username].video & this.VideoFlag.NonExplicit))
|
||||||
) {
|
) {
|
||||||
let stream = this.webcam.stream;
|
let stream = this.webcam.stream;
|
||||||
stream.getTracks().forEach(track => {
|
stream.getTracks().forEach(track => {
|
||||||
|
@ -3185,40 +3227,63 @@ export default {
|
||||||
<p class="block mb-1" v-if="config.permitNSFW">
|
<p class="block mb-1" v-if="config.permitNSFW">
|
||||||
<label class="label">Explicit</label>
|
<label class="label">Explicit</label>
|
||||||
</p>
|
</p>
|
||||||
<div class="field" v-if="config.permitNSFW">
|
|
||||||
<label class="checkbox" :class="{ 'cursor-notallowed': !webcam.active }">
|
<div class="field mb-1" v-if="config.permitNSFW">
|
||||||
<input type="checkbox" v-model="webcam.nsfw" :disabled="!webcam.active">
|
<label class="checkbox">
|
||||||
Mark my camera as featuring explicit content
|
<input type="checkbox" v-model="webcam.nsfw">
|
||||||
|
Mark my camera as featuring Explicit content
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" v-model="webcam.nonExplicit">
|
||||||
|
I prefer not to see Explicit cameras from other chatters
|
||||||
|
</label>
|
||||||
|
<p class="help">
|
||||||
|
Don't auto-open explicit cameras when they open mine; and automatically
|
||||||
|
close a camera I am watching if it toggles to become explicit.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<p class="block mb-1">
|
<p class="block mb-1">
|
||||||
<label class="label">Mutual webcam options</label>
|
<label class="label">Mutual webcam options</label>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<div class="field mb-1">
|
<div class="field mb-1">
|
||||||
<label class="checkbox" :class="{ 'cursor-notallowed': !webcam.active }">
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-model="webcam.mutual" :disabled="!webcam.active">
|
<input type="checkbox" v-model="webcam.mutual">
|
||||||
People must be sharing their own camera before they can open mine
|
People must be sharing their own camera before they can open mine
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field mb-1">
|
<div class="field mb-1">
|
||||||
<label class="checkbox" :class="{ 'cursor-notallowed': !webcam.active }">
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-model="webcam.mutualOpen" :disabled="!webcam.active">
|
<input type="checkbox" v-model="webcam.mutualOpen">
|
||||||
When someone opens my camera, I also open their camera automatically
|
When someone opens my camera, I also open their camera automatically
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field" v-if="isVIP">
|
<div class="field mb-1" v-if="isVIP">
|
||||||
<label class="checkbox" :class="{ 'cursor-notallowed': !webcam.active }">
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-model="webcam.vipOnly" :disabled="!webcam.active">
|
<input type="checkbox" v-model="webcam.vipOnly">
|
||||||
Only <span v-html="config.VIP.Branding"></span> <sup class="is-size-7"
|
Only <span v-html="config.VIP.Branding"></span> <sup class="is-size-7"
|
||||||
:class="config.VIP.Icon"></sup>
|
:class="config.VIP.Icon"></sup>
|
||||||
members can see that my camera is broadcasting
|
members can see that my camera is broadcasting
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" v-model="webcam.rememberExpresslyClosed">
|
||||||
|
Don't (automatically) reopen cameras that I have expressly closed
|
||||||
|
</label>
|
||||||
|
<p class="help">
|
||||||
|
If I click the 'X' button to expressly close a webcam, that video won't
|
||||||
|
auto-open again in case that person reopened my camera.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<h3 class="subtitle mb-2" v-if="webcam.videoDevices.length > 0 || webcam.audioDevices.length > 0">
|
<h3 class="subtitle mb-2" v-if="webcam.videoDevices.length > 0 || webcam.audioDevices.length > 0">
|
||||||
Webcam Devices
|
Webcam Devices
|
||||||
<button type="button" class="button is-primary is-small is-outlined ml-2" @click="getDevices()"
|
<button type="button" class="button is-primary is-small is-outlined ml-2" @click="getDevices()"
|
||||||
|
@ -3365,13 +3430,24 @@ export default {
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="field">
|
<div class="field mb-1">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" v-model="webcam.mutualOpen">
|
<input type="checkbox" v-model="webcam.mutualOpen">
|
||||||
When someone opens my camera, I also open their camera automatically
|
When someone opens my camera, I also open their camera automatically
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="field">
|
||||||
|
<label class="checkbox">
|
||||||
|
<input type="checkbox" v-model="webcam.nonExplicit">
|
||||||
|
I prefer not to see Explicit cameras from other chatters
|
||||||
|
</label>
|
||||||
|
<p class="help">
|
||||||
|
Don't auto-open explicit cameras when they open mine; and automatically
|
||||||
|
close a camera I am watching if it toggles to become explicit.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="field" v-if="isVIP">
|
<div class="field" v-if="isVIP">
|
||||||
<label class="checkbox" :class="{ 'cursor-notallowed': !webcam.active }">
|
<label class="checkbox" :class="{ 'cursor-notallowed': !webcam.active }">
|
||||||
<input type="checkbox" v-model="webcam.vipOnly">
|
<input type="checkbox" v-model="webcam.vipOnly">
|
||||||
|
|
|
@ -80,6 +80,10 @@ export default {
|
||||||
parts.push(`${this.vipConfig.Name} only`);
|
parts.push(`${this.vipConfig.Name} only`);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.user.video & VideoFlag.NonExplicit) {
|
||||||
|
parts.push("prefers non-explicit video");
|
||||||
|
}
|
||||||
|
|
||||||
return parts.join("; ");
|
return parts.join("; ");
|
||||||
},
|
},
|
||||||
avatarURL() {
|
avatarURL() {
|
||||||
|
|
|
@ -14,6 +14,8 @@ const keys = {
|
||||||
'videoAutoMute': Boolean,
|
'videoAutoMute': Boolean,
|
||||||
'videoVipOnly': Boolean,
|
'videoVipOnly': Boolean,
|
||||||
'videoExplicit': Boolean, // whether the user turns explicit on by default
|
'videoExplicit': Boolean, // whether the user turns explicit on by default
|
||||||
|
'videoNonExplicit': Boolean, // user prefers not to see explicit
|
||||||
|
'rememberExpresslyClosed': Boolean,
|
||||||
|
|
||||||
// Booleans
|
// Booleans
|
||||||
'joinMessages': Boolean,
|
'joinMessages': Boolean,
|
||||||
|
|
|
@ -3,7 +3,7 @@ const VideoFlag = {
|
||||||
Active: 1 << 0,
|
Active: 1 << 0,
|
||||||
NSFW: 1 << 1,
|
NSFW: 1 << 1,
|
||||||
Muted: 1 << 2,
|
Muted: 1 << 2,
|
||||||
IsTalking: 1 << 3,
|
NonExplicit: 1 << 3,
|
||||||
MutualRequired: 1 << 4,
|
MutualRequired: 1 << 4,
|
||||||
MutualOpen: 1 << 5,
|
MutualOpen: 1 << 5,
|
||||||
VipOnly: 1 << 6,
|
VipOnly: 1 << 6,
|
||||||
|
|
Loading…
Reference in New Issue
Block a user