mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-13 20:03:51 +02:00
Refactor moderation tab using Vue SFC (#1084)
* Refactor moderation tab * fix
This commit is contained in:
100
src/app.js
100
src/app.js
@@ -31,6 +31,9 @@ import _apiInit from './classes/apiInit.js';
|
||||
import _apiRequestHandler from './classes/apiRequestHandler.js';
|
||||
import _vrcxJsonStorage from './classes/vrcxJsonStorage.js';
|
||||
|
||||
// tabs
|
||||
import ModerationTab from './views/tabs/Moderation.vue';
|
||||
|
||||
// components
|
||||
import SimpleSwitch from './components/settings/SimpleSwitch.vue';
|
||||
|
||||
@@ -96,7 +99,8 @@ console.log(`isLinux: ${LINUX}`);
|
||||
const i18n = new VueI18n({
|
||||
locale: 'en',
|
||||
fallbackLocale: 'en',
|
||||
messages: localizedStrings
|
||||
messages: localizedStrings,
|
||||
silentTranslationWarn: true
|
||||
});
|
||||
const $t = i18n.t.bind(i18n);
|
||||
Vue.use(ElementUI, {
|
||||
@@ -157,6 +161,11 @@ console.log(`isLinux: ${LINUX}`);
|
||||
},
|
||||
watch: {},
|
||||
components: {
|
||||
// tabs
|
||||
ModerationTab,
|
||||
|
||||
// components
|
||||
// - settings
|
||||
SimpleSwitch
|
||||
},
|
||||
el: '#x-app',
|
||||
@@ -3838,12 +3847,15 @@ console.log(`isLinux: ${LINUX}`);
|
||||
|
||||
workerTimers.setTimeout(() => {
|
||||
// fix some weird sorting bug when disabling data tables
|
||||
if (
|
||||
typeof this.$refs.playerModerationTableRef?.sortData !==
|
||||
'undefined'
|
||||
) {
|
||||
this.$refs.playerModerationTableRef.sortData.prop = 'created';
|
||||
}
|
||||
|
||||
// looks like it's not needed anymore
|
||||
// if (
|
||||
// typeof this.$refs.playerModerationTableRef?.sortData !==
|
||||
// 'undefined'
|
||||
// ) {
|
||||
// this.$refs.playerModerationTableRef.sortData.prop = 'created';
|
||||
// }
|
||||
|
||||
if (
|
||||
typeof this.$refs.notificationTableRef?.sortData !== 'undefined'
|
||||
) {
|
||||
@@ -7511,33 +7523,7 @@ console.log(`isLinux: ${LINUX}`);
|
||||
|
||||
$app.data.playerModerationTable = {
|
||||
data: [],
|
||||
lastRunLength: 0,
|
||||
filters: [
|
||||
{
|
||||
prop: 'type',
|
||||
value: [],
|
||||
filterFn: (row, filter) =>
|
||||
filter.value.some((v) => v === row.type)
|
||||
},
|
||||
{
|
||||
prop: ['sourceDisplayName', 'targetDisplayName'],
|
||||
value: ''
|
||||
}
|
||||
],
|
||||
tableProps: {
|
||||
stripe: true,
|
||||
size: 'mini',
|
||||
defaultSort: {
|
||||
prop: 'created',
|
||||
order: 'descending'
|
||||
}
|
||||
},
|
||||
pageSize: $app.data.tablePageSize,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 25, 50, 100]
|
||||
}
|
||||
pageSize: $app.data.tablePageSize
|
||||
};
|
||||
|
||||
API.$on('LOGIN', function () {
|
||||
@@ -7545,10 +7531,10 @@ console.log(`isLinux: ${LINUX}`);
|
||||
});
|
||||
|
||||
API.$on('PLAYER-MODERATION', function (args) {
|
||||
var { ref } = args;
|
||||
var array = $app.playerModerationTable.data;
|
||||
var { length } = array;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
let { ref } = args;
|
||||
let array = $app.playerModerationTable.data;
|
||||
let { length } = array;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
if (array[i].id === ref.id) {
|
||||
Vue.set(array, i, ref);
|
||||
return;
|
||||
@@ -7558,10 +7544,10 @@ console.log(`isLinux: ${LINUX}`);
|
||||
});
|
||||
|
||||
API.$on('PLAYER-MODERATION:@DELETE', function (args) {
|
||||
var { ref } = args;
|
||||
var array = $app.playerModerationTable.data;
|
||||
var { length } = array;
|
||||
for (var i = 0; i < length; ++i) {
|
||||
let { ref } = args;
|
||||
let array = $app.playerModerationTable.data;
|
||||
let { length } = array;
|
||||
for (let i = 0; i < length; ++i) {
|
||||
if (array[i].id === ref.id) {
|
||||
array.splice(i, 1);
|
||||
return;
|
||||
@@ -7569,26 +7555,6 @@ console.log(`isLinux: ${LINUX}`);
|
||||
}
|
||||
});
|
||||
|
||||
$app.methods.deletePlayerModeration = function (row) {
|
||||
API.deletePlayerModeration({
|
||||
moderated: row.targetUserId,
|
||||
type: row.type
|
||||
});
|
||||
};
|
||||
|
||||
$app.methods.deletePlayerModerationPrompt = function (row) {
|
||||
this.$confirm(`Continue? Delete Moderation ${row.type}`, 'Confirm', {
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'info',
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.deletePlayerModeration(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// #endregion
|
||||
// #region | App: Notification
|
||||
|
||||
@@ -7844,10 +7810,6 @@ console.log(`isLinux: ${LINUX}`);
|
||||
'VRCX_friendLogTableFilters',
|
||||
JSON.stringify(this.friendLogTable.filters[0].value)
|
||||
);
|
||||
await configRepository.setString(
|
||||
'VRCX_playerModerationTableFilters',
|
||||
JSON.stringify(this.playerModerationTable.filters[0].value)
|
||||
);
|
||||
await configRepository.setString(
|
||||
'VRCX_notificationTableFilters',
|
||||
JSON.stringify(this.notificationTable.filters[0].value)
|
||||
@@ -7871,12 +7833,6 @@ console.log(`isLinux: ${LINUX}`);
|
||||
$app.data.friendLogTable.filters[0].value = JSON.parse(
|
||||
await configRepository.getString('VRCX_friendLogTableFilters', '[]')
|
||||
);
|
||||
$app.data.playerModerationTable.filters[0].value = JSON.parse(
|
||||
await configRepository.getString(
|
||||
'VRCX_playerModerationTableFilters',
|
||||
'[]'
|
||||
)
|
||||
);
|
||||
$app.data.notificationTable.filters[0].value = JSON.parse(
|
||||
await configRepository.getString('VRCX_notificationTableFilters', '[]')
|
||||
);
|
||||
|
||||
@@ -71,8 +71,12 @@ html
|
||||
+friendLogTab()
|
||||
|
||||
//- moderation
|
||||
include ./mixins/tabs/moderation.pug
|
||||
+moderationTab()
|
||||
moderation-tab(
|
||||
v-if="$refs.menu?.activeIndex === 'moderation'"
|
||||
:Api='API'
|
||||
:table-data='playerModerationTable'
|
||||
:show-user-dialog='showUserDialog'
|
||||
:shift-held='shiftHeld')
|
||||
|
||||
//- notification
|
||||
include ./mixins/tabs/notifications.pug
|
||||
|
||||
@@ -1,30 +0,0 @@
|
||||
mixin moderationTab()
|
||||
.x-container(v-if="$refs.menu && $refs.menu.activeIndex === 'moderation'")
|
||||
data-tables(v-bind="playerModerationTable" ref="playerModerationTableRef" v-loading="API.isPlayerModerationsLoading")
|
||||
template(#tool)
|
||||
div(style="margin:0 0 10px;display:flex;align-items:center")
|
||||
el-select(v-model="playerModerationTable.filters[0].value" @change="saveTableFilters" multiple clearable style="flex:1" :placeholder="$t('view.moderation.filter_placeholder')")
|
||||
el-option(v-for="type in ['block', 'unblock', 'mute', 'unmute', 'interactOn', 'interactOff', 'muteChat']" :key="type" :label="$t('view.moderation.filters.' + type)" :value="type")
|
||||
el-input(v-model="playerModerationTable.filters[1].value" :placeholder="$t('view.moderation.search_placeholder')" style="flex:none;width:150px;margin:0 10px")
|
||||
el-tooltip(placement="bottom" :content="$t('view.moderation.refresh_tooltip')" :disabled="hideTooltips")
|
||||
el-button(type="default" :loading="API.isPlayerModerationsLoading" @click="API.refreshPlayerModerations()" icon="el-icon-refresh" circle style="flex:none")
|
||||
el-table-column(:label="$t('table.moderation.date')" prop="created" sortable="custom" width="120")
|
||||
template(#default="scope")
|
||||
el-tooltip(placement="right")
|
||||
template(#content)
|
||||
span {{ scope.row.created | formatDate('long') }}
|
||||
span {{ scope.row.created | formatDate('short') }}
|
||||
el-table-column(:label="$t('table.moderation.type')" prop="type" width="100")
|
||||
template(#default="scope")
|
||||
span(v-text="$t('view.moderation.filters.' + scope.row.type)")
|
||||
el-table-column(:label="$t('table.moderation.source')" prop="sourceDisplayName")
|
||||
template(#default="scope")
|
||||
span.x-link(v-text="scope.row.sourceDisplayName" @click="showUserDialog(scope.row.sourceUserId)")
|
||||
el-table-column(:label="$t('table.moderation.target')" prop="targetDisplayName")
|
||||
template(#default="scope")
|
||||
span.x-link(v-text="scope.row.targetDisplayName" @click="showUserDialog(scope.row.targetUserId)")
|
||||
el-table-column(:label="$t('table.moderation.action')" width="80" align="right")
|
||||
template(#default="scope")
|
||||
template(v-if="scope.row.sourceUserId === API.currentUser.id")
|
||||
el-button(v-if="shiftHeld" style="color:#f56c6c" type="text" icon="el-icon-close" size="mini" @click="deletePlayerModeration(scope.row)")
|
||||
el-button(v-else type="text" icon="el-icon-close" size="mini" @click="deletePlayerModerationPrompt(scope.row)")
|
||||
234
src/views/tabs/Moderation.vue
Normal file
234
src/views/tabs/Moderation.vue
Normal file
@@ -0,0 +1,234 @@
|
||||
<template>
|
||||
<div class="x-container">
|
||||
<data-tables
|
||||
:data="tableData.data"
|
||||
:pageSize="tableData.pageSize"
|
||||
:filters="filters"
|
||||
:tableProps="tableProps"
|
||||
:paginationProps="paginationProps"
|
||||
v-loading="Api.isPlayerModerationsLoading"
|
||||
>
|
||||
<template slot="tool">
|
||||
<div class="tool-slot">
|
||||
<el-select
|
||||
v-model="filters[0].value"
|
||||
@change="saveTableFilters()"
|
||||
multiple
|
||||
clearable
|
||||
style="flex: 1"
|
||||
:placeholder="$t('view.moderation.filter_placeholder')"
|
||||
>
|
||||
<el-option
|
||||
v-for="item in moderationTypes"
|
||||
:key="item"
|
||||
:label="$t('view.moderation.filters.' + item)"
|
||||
:value="item"
|
||||
/>
|
||||
</el-select>
|
||||
<el-input
|
||||
v-model="filters[1].value"
|
||||
:placeholder="$t('view.moderation.search_placeholder')"
|
||||
class="filter-input"
|
||||
/>
|
||||
<el-tooltip
|
||||
placement="bottom"
|
||||
:content="$t('view.moderation.refresh_tooltip')"
|
||||
:disabled="hideTooltips"
|
||||
>
|
||||
<el-button
|
||||
type="default"
|
||||
:loading="Api.isPlayerModerationsLoading"
|
||||
@click="Api.refreshPlayerModerations()"
|
||||
icon="el-icon-refresh"
|
||||
circle
|
||||
/>
|
||||
</el-tooltip>
|
||||
</div>
|
||||
</template>
|
||||
<el-table-column
|
||||
:label="$t('table.moderation.date')"
|
||||
prop="created"
|
||||
sortable="custom"
|
||||
width="120"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip placement="right">
|
||||
<template slot="content">
|
||||
<span>{{
|
||||
scope.row.created | formatDate('long')
|
||||
}}</span>
|
||||
</template>
|
||||
<span>{{
|
||||
scope.row.created | formatDate('short')
|
||||
}}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.moderation.type')"
|
||||
prop="type"
|
||||
width="100"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
v-text="$t('view.moderation.filters.' + scope.row.type)"
|
||||
></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.moderation.source')"
|
||||
prop="sourceDisplayName"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
class="x-link"
|
||||
v-text="scope.row.sourceDisplayName"
|
||||
@click="showUserDialog(scope.row.sourceUserId)"
|
||||
></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.moderation.target')"
|
||||
prop="targetDisplayName"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<span
|
||||
class="x-link"
|
||||
v-text="scope.row.targetDisplayName"
|
||||
@click="showUserDialog(scope.row.targetUserId)"
|
||||
></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column
|
||||
:label="$t('table.moderation.action')"
|
||||
width="80"
|
||||
align="right"
|
||||
>
|
||||
<template slot-scope="scope">
|
||||
<template
|
||||
v-if="scope.row.sourceUserId === Api.currentUser.id"
|
||||
>
|
||||
<el-button
|
||||
v-if="shiftHeld"
|
||||
style="color: #f56c6c"
|
||||
type="text"
|
||||
icon="el-icon-close"
|
||||
size="mini"
|
||||
@click="deletePlayerModeration(scope.row)"
|
||||
></el-button>
|
||||
<el-button
|
||||
v-else
|
||||
type="text"
|
||||
icon="el-icon-close"
|
||||
size="mini"
|
||||
@click="deletePlayerModerationPrompt(scope.row)"
|
||||
></el-button>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</data-tables>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import configRepository from '../../repository/config.js';
|
||||
|
||||
export default {
|
||||
name: 'ModerationTab',
|
||||
props: {
|
||||
Api: Object,
|
||||
tableData: Object,
|
||||
showUserDialog: Function,
|
||||
shiftHeld: Boolean
|
||||
},
|
||||
created: async function () {
|
||||
this.filters[0].value = JSON.parse(
|
||||
await configRepository.getString(
|
||||
'VRCX_playerModerationTableFilters',
|
||||
'[]'
|
||||
)
|
||||
);
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
filters: [
|
||||
{
|
||||
prop: 'type',
|
||||
value: [],
|
||||
filterFn: (row, filter) =>
|
||||
filter.value.some((v) => v === row.type)
|
||||
},
|
||||
{
|
||||
prop: ['sourceDisplayName', 'targetDisplayName'],
|
||||
value: ''
|
||||
}
|
||||
],
|
||||
// CONSTANTS
|
||||
moderationTypes: [
|
||||
'block',
|
||||
'unblock',
|
||||
'mute',
|
||||
'unmute',
|
||||
'interactOn',
|
||||
'interactOff',
|
||||
'muteChat'
|
||||
],
|
||||
tableProps: {
|
||||
stripe: true,
|
||||
size: 'mini',
|
||||
defaultSort: {
|
||||
prop: 'created',
|
||||
order: 'descending'
|
||||
}
|
||||
},
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 15, 25, 50, 100]
|
||||
}
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
saveTableFilters() {
|
||||
configRepository.setString(
|
||||
'VRCX_playerModerationTableFilters',
|
||||
JSON.stringify(this.filters[0].value)
|
||||
);
|
||||
},
|
||||
deletePlayerModeration(row) {
|
||||
this.Api.deletePlayerModeration({
|
||||
moderated: row.targetUserId,
|
||||
type: row.type
|
||||
});
|
||||
},
|
||||
deletePlayerModerationPrompt(row) {
|
||||
this.$confirm(
|
||||
`Continue? Delete Moderation ${row.type}`,
|
||||
'Confirm',
|
||||
{
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'info',
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.deletePlayerModeration(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.tool-slot {
|
||||
margin: 0 0 10px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
.filter-input {
|
||||
width: 150px;
|
||||
margin: 0 10px;
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user