Admin command buttons in the profile modal
This commit is contained in:
parent
b5bbbde784
commit
e70b439cdd
32
src/App.vue
32
src/App.vue
|
@ -653,7 +653,7 @@ export default {
|
||||||
},
|
},
|
||||||
isOp() {
|
isOp() {
|
||||||
// Returns if the current user has operator rights
|
// Returns if the current user has operator rights
|
||||||
return this.jwt.claims.op;
|
return this.jwt.claims.op || this.whoMap[this.username].op;
|
||||||
},
|
},
|
||||||
isVIP() {
|
isVIP() {
|
||||||
// Returns if the current user has VIP rights.
|
// Returns if the current user has VIP rights.
|
||||||
|
@ -933,6 +933,14 @@ export default {
|
||||||
this.messageBox.selectionStart = this.messageBox.selectionEnd = this.messageBox.value.length;
|
this.messageBox.selectionStart = this.messageBox.selectionEnd = this.messageBox.value.length;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
sendCommand(message) {
|
||||||
|
// Automatically send a message to the chat server.
|
||||||
|
// e.g. for the ProfileModal to send a "/kick username" command for easy operator buttons.
|
||||||
|
let origMsg = this.message;
|
||||||
|
this.message = message;
|
||||||
|
this.sendMessage();
|
||||||
|
this.message = origMsg;
|
||||||
|
},
|
||||||
sendMessage() {
|
sendMessage() {
|
||||||
if (!this.message) {
|
if (!this.message) {
|
||||||
return;
|
return;
|
||||||
|
@ -4064,11 +4072,23 @@ export default {
|
||||||
:message="reportModal.message" @accept="doReport" @cancel="reportModal.visible = false"></ReportModal>
|
:message="reportModal.message" @accept="doReport" @cancel="reportModal.visible = false"></ReportModal>
|
||||||
|
|
||||||
<!-- Profile Modal (profile cards popup) -->
|
<!-- Profile Modal (profile cards popup) -->
|
||||||
<ProfileModal :visible="profileModal.visible" :user="profileModal.user" :username="username" :jwt="jwt.token"
|
<ProfileModal
|
||||||
:website-url="config.website" :is-dnd="isUsernameDND(profileModal.username)"
|
:visible="profileModal.visible"
|
||||||
:is-muted="isMutedUser(profileModal.username)" :is-booted="isBooted(profileModal.username)"
|
:user="profileModal.user"
|
||||||
:profile-webhook-enabled="isWebhookEnabled('profile')" :vip-config="config.VIP" @send-dm="openDMs"
|
:username="username"
|
||||||
@mute-user="muteUser" @boot-user="bootUser" @cancel="profileModal.visible = false"></ProfileModal>
|
:is-viewer-op="isOp"
|
||||||
|
:jwt="jwt.token"
|
||||||
|
:website-url="config.website"
|
||||||
|
:is-dnd="isUsernameDND(profileModal.username)"
|
||||||
|
:is-muted="isMutedUser(profileModal.username)"
|
||||||
|
:is-booted="isBooted(profileModal.username)"
|
||||||
|
:profile-webhook-enabled="isWebhookEnabled('profile')"
|
||||||
|
:vip-config="config.VIP"
|
||||||
|
@send-dm="openDMs"
|
||||||
|
@mute-user="muteUser"
|
||||||
|
@boot-user="bootUser"
|
||||||
|
@send-command="sendCommand"
|
||||||
|
@cancel="profileModal.visible = false"></ProfileModal>
|
||||||
|
|
||||||
<div class="chat-container">
|
<div class="chat-container">
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
|
import VideoFlag from '../lib/VideoFlag';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
props: {
|
props: {
|
||||||
visible: Boolean,
|
visible: Boolean,
|
||||||
jwt: String, // caller's JWT token for authorization
|
jwt: String, // caller's JWT token for authorization
|
||||||
user: Object, // the user we are viewing
|
user: Object, // the user we are viewing
|
||||||
username: String, // the local user
|
username: String, // the local user
|
||||||
|
isViewerOp: Boolean, // the viewer is an operator (show buttons)
|
||||||
websiteUrl: String,
|
websiteUrl: String,
|
||||||
isDnd: Boolean,
|
isDnd: Boolean,
|
||||||
isMuted: Boolean,
|
isMuted: Boolean,
|
||||||
|
@ -53,6 +56,13 @@ export default {
|
||||||
}
|
}
|
||||||
return this.user.username;
|
return this.user.username;
|
||||||
},
|
},
|
||||||
|
isOnBlueCam() {
|
||||||
|
// User is broadcasting a cam and is not NSFW.
|
||||||
|
if ((this.user.video & VideoFlag.Active) && !(this.user.video & VideoFlag.NSFW)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
refresh() {
|
refresh() {
|
||||||
|
@ -115,6 +125,29 @@ export default {
|
||||||
this.$emit('boot-user', this.user.username);
|
this.$emit('boot-user', this.user.username);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Operator commands (may be rejected by server if not really Op)
|
||||||
|
markNsfw() {
|
||||||
|
if (!window.confirm("Mark this user's webcam as 'Explicit'?")) return;
|
||||||
|
this.$emit('send-command', `/nsfw ${this.user.username}`);
|
||||||
|
|
||||||
|
// Close the modal immediately: our view of the user's cam data is a copy
|
||||||
|
// and we can't follow the current value.
|
||||||
|
this.cancel();
|
||||||
|
},
|
||||||
|
kickUser() {
|
||||||
|
if (!window.confirm("Really kick this user from the chat room?")) return;
|
||||||
|
this.$emit('send-command', `/kick ${this.user.username}`);
|
||||||
|
},
|
||||||
|
banUser() {
|
||||||
|
let hours = window.prompt(
|
||||||
|
"Ban this user for how many hours? (Default 24)",
|
||||||
|
"24",
|
||||||
|
);
|
||||||
|
if (!/^\d+$/.test(hours)) return;
|
||||||
|
|
||||||
|
this.$emit('send-command', `/ban ${this.user.username} ${hours}`);
|
||||||
|
},
|
||||||
|
|
||||||
urlFor(url) {
|
urlFor(url) {
|
||||||
// Prepend the base websiteUrl if the given URL is relative.
|
// Prepend the base websiteUrl if the given URL is relative.
|
||||||
if (url.match(/^https?:/i)) {
|
if (url.match(/^https?:/i)) {
|
||||||
|
@ -221,6 +254,37 @@ export default {
|
||||||
}"></i>
|
}"></i>
|
||||||
{{ isBooted ? 'Allow to watch my webcam' : "Don't allow to watch my webcam" }}
|
{{ isBooted ? 'Allow to watch my webcam' : "Don't allow to watch my webcam" }}
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
|
<!-- Admin actions -->
|
||||||
|
<div v-if="isViewerOp" class="mt-1">
|
||||||
|
<!-- Mark camera NSFW -->
|
||||||
|
<button v-if="isOnBlueCam"
|
||||||
|
type="button"
|
||||||
|
class="button is-small is-outlined is-danger has-text-dark px-2 mr-1 mb-1"
|
||||||
|
@click="markNsfw()" title="Mark their camera as Explicit (red).">
|
||||||
|
<i class="fa fa-video mr-1" :class="{
|
||||||
|
'has-text-success': isMuted,
|
||||||
|
'has-text-danger': !isMuted
|
||||||
|
}"></i>
|
||||||
|
Mark camera as Explicit
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Kick user -->
|
||||||
|
<button type="button"
|
||||||
|
class="button is-small is-outlined is-danger has-text-dark px-2 mr-1 mb-1"
|
||||||
|
@click="kickUser()" title="Kick this user from the chat room.">
|
||||||
|
<i class="fa fa-shoe-prints mr-1 has-text-danger"></i>
|
||||||
|
Kick from the room
|
||||||
|
</button>
|
||||||
|
|
||||||
|
<!-- Ban user -->
|
||||||
|
<button type="button"
|
||||||
|
class="button is-small is-outlined is-danger has-text-dark px-2 mb-1"
|
||||||
|
@click="banUser()" title="Ban this user from the chat room for 24 hours.">
|
||||||
|
<i class="fa fa-clock mr-1 has-text-danger"></i>
|
||||||
|
Ban user (temporary)
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Profile Fields spinner/error -->
|
<!-- Profile Fields spinner/error -->
|
||||||
|
@ -245,7 +309,6 @@ export default {
|
||||||
{{ field.Value }}
|
{{ field.Value }}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<footer class="card-footer">
|
<footer class="card-footer">
|
||||||
<a :href="profileURL" target="_blank"
|
<a :href="profileURL" target="_blank"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user