mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-27 10:43:48 +02:00
refactor: Organize Project Structure (#1211)
* refactor: Organize Project Structure * fix * fix * rm security * fix
This commit is contained in:
1108
src/components/dialogs/AvatarDialog/AvatarDialog.vue
Normal file
1108
src/components/dialogs/AvatarDialog/AvatarDialog.vue
Normal file
File diff suppressed because it is too large
Load Diff
130
src/components/dialogs/AvatarDialog/SetAvatarStylesDialog.vue
Normal file
130
src/components/dialogs/AvatarDialog/SetAvatarStylesDialog.vue
Normal file
@@ -0,0 +1,130 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="setAvatarStylesDialog"
|
||||
class="x-dialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="setAvatarStylesDialog.visible"
|
||||
:title="t('dialog.set_avatar_styles.header')"
|
||||
width="400px"
|
||||
append-to-body
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<template v-if="setAvatarStylesDialog.visible">
|
||||
<div>
|
||||
<span>{{ t('dialog.set_avatar_styles.primary_style') }}</span>
|
||||
<el-select
|
||||
v-model="setAvatarStylesDialog.primaryStyle"
|
||||
:placeholder="t('dialog.set_avatar_styles.select_style')"
|
||||
size="small"
|
||||
clearable
|
||||
style="display: inline-block">
|
||||
<el-option
|
||||
v-for="(style, index) in setAvatarStylesDialog.availableAvatarStyles"
|
||||
:key="index"
|
||||
:label="style"
|
||||
:value="style"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
<br />
|
||||
<div>
|
||||
<span>{{ t('dialog.set_avatar_styles.secondary_style') }}</span>
|
||||
<el-select
|
||||
v-model="setAvatarStylesDialog.secondaryStyle"
|
||||
:placeholder="t('dialog.set_avatar_styles.select_style')"
|
||||
size="small"
|
||||
clearable
|
||||
style="display: inline-block">
|
||||
<el-option
|
||||
v-for="(style, index) in setAvatarStylesDialog.availableAvatarStyles"
|
||||
:key="index"
|
||||
:label="style"
|
||||
:value="style"></el-option>
|
||||
</el-select>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button size="small" @click="setAvatarStylesDialog.visible = false">{{
|
||||
t('dialog.set_avatar_styles.cancel')
|
||||
}}</el-button>
|
||||
<el-button type="primary" size="small" @click="saveSetAvatarStylesDialog">{{
|
||||
t('dialog.set_avatar_styles.save')
|
||||
}}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, watch, getCurrentInstance } from 'vue';
|
||||
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { avatarRequest } from '../../../api';
|
||||
|
||||
const beforeDialogClose = inject('beforeDialogClose');
|
||||
const dialogMouseDown = inject('dialogMouseDown');
|
||||
const dialogMouseUp = inject('dialogMouseUp');
|
||||
|
||||
const { t } = useI18n();
|
||||
const instance = getCurrentInstance();
|
||||
const $message = instance.proxy.$message;
|
||||
|
||||
const props = defineProps({
|
||||
setAvatarStylesDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.setAvatarStylesDialog.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
getAvatarStyles();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
async function getAvatarStyles() {
|
||||
const ref = await avatarRequest.getAvailableAvatarStyles();
|
||||
const styles = [];
|
||||
const stylesMap = new Map();
|
||||
for (const style of ref.json) {
|
||||
styles.push(style.styleName);
|
||||
stylesMap.set(style.styleName, style.id);
|
||||
}
|
||||
props.setAvatarStylesDialog.availableAvatarStyles = styles;
|
||||
props.setAvatarStylesDialog.availableAvatarStylesMap = stylesMap;
|
||||
}
|
||||
|
||||
function saveSetAvatarStylesDialog() {
|
||||
if (
|
||||
props.setAvatarStylesDialog.initialPrimaryStyle === props.setAvatarStylesDialog.primaryStyle &&
|
||||
props.setAvatarStylesDialog.initialSecondaryStyle === props.setAvatarStylesDialog.secondaryStyle
|
||||
) {
|
||||
props.setAvatarStylesDialog.visible = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const primaryStyleId =
|
||||
props.setAvatarStylesDialog.availableAvatarStylesMap.get(props.setAvatarStylesDialog.primaryStyle) || '';
|
||||
const secondaryStyleId =
|
||||
props.setAvatarStylesDialog.availableAvatarStylesMap.get(props.setAvatarStylesDialog.secondaryStyle) || '';
|
||||
|
||||
const params = {
|
||||
id: props.setAvatarStylesDialog.avatarId,
|
||||
primaryStyle: primaryStyleId,
|
||||
secondaryStyle: secondaryStyleId
|
||||
};
|
||||
avatarRequest
|
||||
.saveAvatar(params)
|
||||
.then(() => {
|
||||
$message.success(t('dialog.set_avatar_styles.save_success'));
|
||||
props.setAvatarStylesDialog.visible = false;
|
||||
})
|
||||
.catch((error) => {
|
||||
$message.error(t('dialog.set_avatar_styles.save_failed'));
|
||||
console.error('Error saving avatar styles:', error);
|
||||
});
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
289
src/components/dialogs/AvatarDialog/SetAvatarTagsDialog.vue
Normal file
289
src/components/dialogs/AvatarDialog/SetAvatarTagsDialog.vue
Normal file
@@ -0,0 +1,289 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="setAvatarTagsDialog"
|
||||
class="x-dialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="setAvatarTagsDialog.visible"
|
||||
:title="t('dialog.set_avatar_tags.header')"
|
||||
width="770px"
|
||||
append-to-body
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<template v-if="setAvatarTagsDialog.visible">
|
||||
<el-checkbox v-model="setAvatarTagsDialog.contentHorror" @change="updateSelectedAvatarTags">{{
|
||||
t('dialog.set_avatar_tags.content_horror')
|
||||
}}</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setAvatarTagsDialog.contentGore" @change="updateSelectedAvatarTags">{{
|
||||
t('dialog.set_avatar_tags.content_gore')
|
||||
}}</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setAvatarTagsDialog.contentViolence" @change="updateSelectedAvatarTags">{{
|
||||
t('dialog.set_avatar_tags.content_violence')
|
||||
}}</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setAvatarTagsDialog.contentAdult" @change="updateSelectedAvatarTags">{{
|
||||
t('dialog.set_avatar_tags.content_adult')
|
||||
}}</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setAvatarTagsDialog.contentSex" @change="updateSelectedAvatarTags">{{
|
||||
t('dialog.set_avatar_tags.content_sex')
|
||||
}}</el-checkbox>
|
||||
<br />
|
||||
<el-input
|
||||
v-model="setAvatarTagsDialog.selectedTagsCsv"
|
||||
size="mini"
|
||||
:autosize="{ minRows: 2, maxRows: 5 }"
|
||||
:placeholder="t('dialog.set_avatar_tags.custom_tags_placeholder')"
|
||||
style="margin-top: 10px"
|
||||
@input="updateInputAvatarTags"></el-input>
|
||||
<template v-if="setAvatarTagsDialog.ownAvatars.length === setAvatarTagsDialog.selectedCount">
|
||||
<el-button size="small" @click="setAvatarTagsSelectToggle">{{
|
||||
t('dialog.set_avatar_tags.select_none')
|
||||
}}</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button size="small" @click="setAvatarTagsSelectToggle">{{
|
||||
t('dialog.set_avatar_tags.select_all')
|
||||
}}</el-button>
|
||||
</template>
|
||||
<span style="margin-left: 5px"
|
||||
>{{ setAvatarTagsDialog.selectedCount }} / {{ setAvatarTagsDialog.ownAvatars.length }}</span
|
||||
>
|
||||
<span v-if="setAvatarTagsDialog.loading" style="margin-left: 5px">
|
||||
<i class="el-icon-loading"></i>
|
||||
</span>
|
||||
<br />
|
||||
<div class="x-friend-list" style="margin-top: 10px; min-height: 60px; max-height: 280px">
|
||||
<div
|
||||
v-for="avatar in setAvatarTagsDialog.ownAvatars"
|
||||
:key="avatar.id"
|
||||
class="x-friend-item x-friend-item-border"
|
||||
style="width: 350px"
|
||||
@click="showAvatarDialog(avatar.id)">
|
||||
<div class="avatar">
|
||||
<img v-if="avatar.thumbnailImageUrl" v-lazy="avatar.thumbnailImageUrl" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span class="name" v-text="avatar.name"></span>
|
||||
<span
|
||||
v-if="avatar.releaseStatus === 'public'"
|
||||
class="extra"
|
||||
style="color: #67c23a"
|
||||
v-text="avatar.releaseStatus"></span>
|
||||
<span
|
||||
v-else-if="avatar.releaseStatus === 'private'"
|
||||
class="extra"
|
||||
style="color: #f56c6c"
|
||||
v-text="avatar.releaseStatus"></span>
|
||||
<span v-else class="extra" v-text="avatar.releaseStatus"></span>
|
||||
<span class="extra" v-text="avatar.$tagString"></span>
|
||||
</div>
|
||||
<el-button type="text" size="mini" style="margin-left: 5px" @click.stop>
|
||||
<el-checkbox v-model="avatar.$selected" @change="updateAvatarTagsSelection"></el-checkbox>
|
||||
</el-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<template #footer>
|
||||
<el-button size="small" @click="setAvatarTagsDialog.visible = false">{{
|
||||
t('dialog.set_avatar_tags.cancel')
|
||||
}}</el-button>
|
||||
<el-button type="primary" size="small" @click="saveSetAvatarTagsDialog">{{
|
||||
t('dialog.set_avatar_tags.save')
|
||||
}}</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, watch, getCurrentInstance } from 'vue';
|
||||
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import { avatarRequest } from '../../../api';
|
||||
|
||||
const beforeDialogClose = inject('beforeDialogClose');
|
||||
const dialogMouseDown = inject('dialogMouseDown');
|
||||
const dialogMouseUp = inject('dialogMouseUp');
|
||||
const showAvatarDialog = inject('showAvatarDialog');
|
||||
|
||||
const { t } = useI18n();
|
||||
const instance = getCurrentInstance();
|
||||
const $message = instance.proxy.$message;
|
||||
|
||||
const props = defineProps({
|
||||
setAvatarTagsDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
});
|
||||
|
||||
watch(
|
||||
() => props.setAvatarTagsDialog.visible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
updateAvatarTagsSelection();
|
||||
updateSelectedAvatarTags();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
function updateSelectedAvatarTags() {
|
||||
const D = props.setAvatarTagsDialog;
|
||||
if (D.contentHorror) {
|
||||
if (!D.selectedTags.includes('content_horror')) {
|
||||
D.selectedTags.push('content_horror');
|
||||
}
|
||||
} else if (D.selectedTags.includes('content_horror')) {
|
||||
D.selectedTags.splice(D.selectedTags.indexOf('content_horror'), 1);
|
||||
}
|
||||
if (D.contentGore) {
|
||||
if (!D.selectedTags.includes('content_gore')) {
|
||||
D.selectedTags.push('content_gore');
|
||||
}
|
||||
} else if (D.selectedTags.includes('content_gore')) {
|
||||
D.selectedTags.splice(D.selectedTags.indexOf('content_gore'), 1);
|
||||
}
|
||||
if (D.contentViolence) {
|
||||
if (!D.selectedTags.includes('content_violence')) {
|
||||
D.selectedTags.push('content_violence');
|
||||
}
|
||||
} else if (D.selectedTags.includes('content_violence')) {
|
||||
D.selectedTags.splice(D.selectedTags.indexOf('content_violence'), 1);
|
||||
}
|
||||
if (D.contentAdult) {
|
||||
if (!D.selectedTags.includes('content_adult')) {
|
||||
D.selectedTags.push('content_adult');
|
||||
}
|
||||
} else if (D.selectedTags.includes('content_adult')) {
|
||||
D.selectedTags.splice(D.selectedTags.indexOf('content_adult'), 1);
|
||||
}
|
||||
if (D.contentSex) {
|
||||
if (!D.selectedTags.includes('content_sex')) {
|
||||
D.selectedTags.push('content_sex');
|
||||
}
|
||||
} else if (D.selectedTags.includes('content_sex')) {
|
||||
D.selectedTags.splice(D.selectedTags.indexOf('content_sex'), 1);
|
||||
}
|
||||
|
||||
D.selectedTagsCsv = D.selectedTags.join(',').replace(/content_/g, '');
|
||||
}
|
||||
|
||||
function updateAvatarTagsSelection() {
|
||||
const D = props.setAvatarTagsDialog;
|
||||
D.selectedCount = 0;
|
||||
for (const ref of D.ownAvatars) {
|
||||
if (ref.$selected) {
|
||||
D.selectedCount++;
|
||||
}
|
||||
ref.$tagString = '';
|
||||
const contentTags = [];
|
||||
ref.tags.forEach((tag) => {
|
||||
if (tag.startsWith('content_')) {
|
||||
contentTags.push(tag.substring(8));
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < contentTags.length; ++i) {
|
||||
const tag = contentTags[i];
|
||||
if (i < contentTags.length - 1) {
|
||||
ref.$tagString += `${tag}, `;
|
||||
} else {
|
||||
ref.$tagString += tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
// props.setAvatarTagsDialog.forceUpdate++;
|
||||
}
|
||||
|
||||
function setAvatarTagsSelectToggle() {
|
||||
const D = props.setAvatarTagsDialog;
|
||||
const allSelected = D.ownAvatars.length === D.selectedCount;
|
||||
for (const ref of D.ownAvatars) {
|
||||
ref.$selected = !allSelected;
|
||||
}
|
||||
updateAvatarTagsSelection();
|
||||
}
|
||||
|
||||
async function saveSetAvatarTagsDialog() {
|
||||
const D = props.setAvatarTagsDialog;
|
||||
if (D.loading) {
|
||||
return;
|
||||
}
|
||||
D.loading = true;
|
||||
try {
|
||||
for (let i = D.ownAvatars.length - 1; i >= 0; --i) {
|
||||
const ref = D.ownAvatars[i];
|
||||
if (!D.visible) {
|
||||
break;
|
||||
}
|
||||
if (!ref.$selected) {
|
||||
continue;
|
||||
}
|
||||
const tags = [...D.selectedTags];
|
||||
for (const tag of ref.tags) {
|
||||
if (!tag.startsWith('content_')) {
|
||||
tags.push(tag);
|
||||
}
|
||||
}
|
||||
await avatarRequest.saveAvatar({
|
||||
id: ref.id,
|
||||
tags
|
||||
});
|
||||
D.selectedCount--;
|
||||
}
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
$message({
|
||||
message: 'Error saving avatar tags',
|
||||
type: 'error'
|
||||
});
|
||||
} finally {
|
||||
D.loading = false;
|
||||
D.visible = false;
|
||||
}
|
||||
}
|
||||
|
||||
function updateInputAvatarTags() {
|
||||
const D = props.setAvatarTagsDialog;
|
||||
D.contentHorror = false;
|
||||
D.contentGore = false;
|
||||
D.contentViolence = false;
|
||||
D.contentAdult = false;
|
||||
D.contentSex = false;
|
||||
const tags = D.selectedTagsCsv.split(',');
|
||||
D.selectedTags = [];
|
||||
for (const tag of tags) {
|
||||
switch (tag) {
|
||||
case 'horror':
|
||||
D.contentHorror = true;
|
||||
break;
|
||||
case 'gore':
|
||||
D.contentGore = true;
|
||||
break;
|
||||
case 'violence':
|
||||
D.contentViolence = true;
|
||||
break;
|
||||
case 'adult':
|
||||
D.contentAdult = true;
|
||||
break;
|
||||
case 'sex':
|
||||
D.contentSex = true;
|
||||
break;
|
||||
}
|
||||
if (!D.selectedTags.includes(`content_${tag}`)) {
|
||||
D.selectedTags.push(`content_${tag}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// useless
|
||||
// $app.data.avatarContentTags = [
|
||||
// 'content_horror',
|
||||
// 'content_gore',
|
||||
// 'content_violence',
|
||||
// 'content_adult',
|
||||
// 'content_sex'
|
||||
// ];
|
||||
</script>
|
||||
|
||||
<style scoped></style>
|
||||
193
src/components/dialogs/ChooseFavoriteGroupDialog.vue
Normal file
193
src/components/dialogs/ChooseFavoriteGroupDialog.vue
Normal file
@@ -0,0 +1,193 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="favoriteDialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="isVisible"
|
||||
:title="$t('dialog.favorite.header')"
|
||||
width="300px"
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<div v-loading="loading">
|
||||
<span style="display: block; text-align: center">{{ $t('dialog.favorite.vrchat_favorites') }}</span>
|
||||
<template v-if="favoriteDialog.currentGroup && favoriteDialog.currentGroup.key">
|
||||
<el-button
|
||||
style="display: block; width: 100%; margin: 10px 0"
|
||||
@click="deleteFavoriteNoConfirm(favoriteDialog.objectId)">
|
||||
<i class="el-icon-check"></i>
|
||||
{{ favoriteDialog.currentGroup.displayName }} ({{ favoriteDialog.currentGroup.count }} /
|
||||
{{ favoriteDialog.currentGroup.capacity }})
|
||||
</el-button>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button
|
||||
v-for="group in groups"
|
||||
:key="group.key"
|
||||
style="display: block; width: 100%; margin: 10px 0"
|
||||
@click="addFavorite(group)">
|
||||
{{ group.displayName }} ({{ group.count }} / {{ group.capacity }})
|
||||
</el-button>
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="favoriteDialog.type === 'world'" style="margin-top: 20px">
|
||||
<span style="display: block; text-align: center">{{ $t('dialog.favorite.local_favorites') }}</span>
|
||||
<template v-for="group in localWorldFavoriteGroups">
|
||||
<el-button
|
||||
v-if="hasLocalWorldFavorite(favoriteDialog.objectId, group)"
|
||||
:key="group"
|
||||
style="display: block; width: 100%; margin: 10px 0"
|
||||
@click="removeLocalWorldFavorite(favoriteDialog.objectId, group)">
|
||||
<i class="el-icon-check"></i>
|
||||
{{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }})
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
:key="group"
|
||||
style="display: block; width: 100%; margin: 10px 0"
|
||||
@click="addLocalWorldFavorite(favoriteDialog.objectId, group)">
|
||||
{{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }})
|
||||
</el-button>
|
||||
</template>
|
||||
</div>
|
||||
<div v-if="favoriteDialog.type === 'avatar'" style="margin-top: 20px">
|
||||
<span style="display: block; text-align: center">{{ $t('dialog.favorite.local_avatar_favorites') }}</span>
|
||||
<template v-for="group in localAvatarFavoriteGroups">
|
||||
<el-button
|
||||
v-if="hasLocalAvatarFavorite(favoriteDialog.objectId, group)"
|
||||
:key="group"
|
||||
style="display: block; width: 100%; margin: 10px 0"
|
||||
@click="removeLocalAvatarFavorite(favoriteDialog.objectId, group)">
|
||||
<i class="el-icon-check"></i>
|
||||
{{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
|
||||
</el-button>
|
||||
<el-button
|
||||
v-else
|
||||
:key="group"
|
||||
style="display: block; width: 100%; margin: 10px 0"
|
||||
:disabled="!isLocalUserVrcplusSupporter"
|
||||
@click="addLocalAvatarFavorite(favoriteDialog.objectId, group)">
|
||||
{{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
|
||||
</el-button>
|
||||
</template>
|
||||
</div>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { favoriteRequest } from '../../api';
|
||||
import Noty from 'noty';
|
||||
|
||||
export default {
|
||||
name: 'ChooseFavoriteGroupDialog',
|
||||
inject: ['API', 'beforeDialogClose', 'dialogMouseDown', 'dialogMouseUp', 'adjustDialogZ'],
|
||||
props: {
|
||||
favoriteDialog: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
visible: false,
|
||||
type: '',
|
||||
objectId: '',
|
||||
currentGroup: {}
|
||||
})
|
||||
},
|
||||
localWorldFavoriteGroups: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
localAvatarFavoriteGroups: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
hasLocalWorldFavorite: {
|
||||
type: Function,
|
||||
default: () => () => false
|
||||
},
|
||||
getLocalWorldFavoriteGroupLength: {
|
||||
type: Function,
|
||||
default: () => () => 0
|
||||
},
|
||||
hasLocalAvatarFavorite: {
|
||||
type: Function,
|
||||
default: () => () => false
|
||||
},
|
||||
getLocalAvatarFavoriteGroupLength: {
|
||||
type: Function,
|
||||
default: () => () => 0
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
groups: [],
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.favoriteDialog.visible;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:favorite-dialog', { ...this.favoriteDialog, visible: value });
|
||||
}
|
||||
},
|
||||
isLocalUserVrcplusSupporter() {
|
||||
return this.API.currentUser.$isVRCPlus;
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'favoriteDialog.visible'(value) {
|
||||
if (value) {
|
||||
this.initFavoriteDialog();
|
||||
this.$nextTick(() => {
|
||||
this.adjustDialogZ(this.$refs.favoriteDialog.$el);
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initFavoriteDialog() {
|
||||
if (this.favoriteDialog.type === 'friend') {
|
||||
this.groups = this.API.favoriteFriendGroups;
|
||||
} else if (this.favoriteDialog.type === 'world') {
|
||||
this.groups = this.API.favoriteWorldGroups;
|
||||
} else if (this.favoriteDialog.type === 'avatar') {
|
||||
this.groups = this.API.favoriteAvatarGroups;
|
||||
}
|
||||
},
|
||||
addFavorite(group) {
|
||||
const D = this.favoriteDialog;
|
||||
this.loading = true;
|
||||
favoriteRequest
|
||||
.addFavorite({
|
||||
type: D.type,
|
||||
favoriteId: D.objectId,
|
||||
tags: group.name
|
||||
})
|
||||
.then(() => {
|
||||
this.isVisible = false;
|
||||
new Noty({
|
||||
type: 'success',
|
||||
text: 'Favorite added'
|
||||
}).show();
|
||||
})
|
||||
.finally(() => {
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
addLocalWorldFavorite(...args) {
|
||||
this.$emit('add-local-world-favorite', ...args);
|
||||
},
|
||||
removeLocalWorldFavorite(...args) {
|
||||
this.$emit('remove-local-world-favorite', ...args);
|
||||
},
|
||||
addLocalAvatarFavorite(...args) {
|
||||
this.$emit('add-local-avatar-favorite', ...args);
|
||||
},
|
||||
removeLocalAvatarFavorite(...args) {
|
||||
this.$emit('remove-local-avatar-favorite', ...args);
|
||||
},
|
||||
deleteFavoriteNoConfirm(...args) {
|
||||
this.$emit('delete-favorite-no-confirm', ...args);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
1788
src/components/dialogs/GroupDialog/GroupDialog.vue
Normal file
1788
src/components/dialogs/GroupDialog/GroupDialog.vue
Normal file
File diff suppressed because it is too large
Load Diff
1694
src/components/dialogs/GroupDialog/GroupMemberModerationDialog.vue
Normal file
1694
src/components/dialogs/GroupDialog/GroupMemberModerationDialog.vue
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,110 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
class="x-dialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible="isGroupLogsExportDialogVisible"
|
||||
:title="t('dialog.group_member_moderation.export_logs')"
|
||||
width="650px"
|
||||
append-to-body
|
||||
@close="setIsGroupLogsExportDialogVisible"
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<el-checkbox-group
|
||||
v-model="checkedGroupLogsExportLogsOptions"
|
||||
style="margin-bottom: 10px"
|
||||
@change="updateGroupLogsExportContent">
|
||||
<template v-for="option in checkGroupsLogsExportLogsOptions">
|
||||
<el-checkbox :key="option.label" :label="option.label">
|
||||
{{ t(option.text) }}
|
||||
</el-checkbox>
|
||||
</template>
|
||||
</el-checkbox-group>
|
||||
<br />
|
||||
<el-input
|
||||
v-model="groupLogsExportContent"
|
||||
type="textarea"
|
||||
size="mini"
|
||||
rows="15"
|
||||
resize="none"
|
||||
readonly
|
||||
style="margin-top: 15px"
|
||||
@click.native="handleCopyGroupLogsExportContent" />
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import { inject, ref, watch } from 'vue';
|
||||
import { useI18n } from 'vue-i18n-bridge';
|
||||
import utils from '../../../classes/utils';
|
||||
|
||||
const beforeDialogClose = inject('beforeDialogClose');
|
||||
const dialogMouseDown = inject('dialogMouseDown');
|
||||
const dialogMouseUp = inject('dialogMouseUp');
|
||||
const { t } = useI18n();
|
||||
|
||||
const props = defineProps({
|
||||
isGroupLogsExportDialogVisible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
groupLogsModerationTable: {
|
||||
type: Object,
|
||||
default: () => {}
|
||||
}
|
||||
});
|
||||
|
||||
const emit = defineEmits(['update:isGroupLogsExportDialogVisible']);
|
||||
watch(
|
||||
() => props.isGroupLogsExportDialogVisible,
|
||||
(newVal) => {
|
||||
if (newVal) {
|
||||
updateGroupLogsExportContent();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
const groupLogsExportContent = ref('');
|
||||
|
||||
const checkGroupsLogsExportLogsOptions = [
|
||||
{ label: 'created_at', text: 'dialog.group_member_moderation.created_at' },
|
||||
{ label: 'eventType', text: 'dialog.group_member_moderation.type' },
|
||||
{ label: 'actorDisplayName', text: 'dialog.group_member_moderation.display_name' },
|
||||
{ label: 'description', text: 'dialog.group_member_moderation.description' },
|
||||
{ label: 'data', text: 'dialog.group_member_moderation.data' }
|
||||
];
|
||||
const checkedGroupLogsExportLogsOptions = ref([
|
||||
'created_at',
|
||||
'eventType',
|
||||
'actorDisplayName',
|
||||
'description',
|
||||
'data'
|
||||
]);
|
||||
|
||||
function updateGroupLogsExportContent() {
|
||||
const formatter = (str) => (/[\x00-\x1f,"]/.test(str) ? `"${str.replace(/"/g, '""')}"` : str);
|
||||
|
||||
const sortedCheckedOptions = checkGroupsLogsExportLogsOptions
|
||||
.filter((option) => checkedGroupLogsExportLogsOptions.value.includes(option.label))
|
||||
.map((option) => option.label);
|
||||
|
||||
const header = `${sortedCheckedOptions.join(',')}\n`;
|
||||
|
||||
const content = props.groupLogsModerationTable.data
|
||||
.map((item) =>
|
||||
sortedCheckedOptions
|
||||
.map((key) => formatter(key === 'data' ? JSON.stringify(item[key]) : item[key]))
|
||||
.join(',')
|
||||
)
|
||||
.join('\n');
|
||||
|
||||
groupLogsExportContent.value = header + content; // Update ref
|
||||
}
|
||||
|
||||
function handleCopyGroupLogsExportContent() {
|
||||
utils.copyToClipboard(groupLogsExportContent.value);
|
||||
}
|
||||
|
||||
function setIsGroupLogsExportDialogVisible() {
|
||||
emit('update:isGroupLogsExportDialogVisible', false);
|
||||
}
|
||||
</script>
|
||||
200
src/components/dialogs/GroupDialog/GroupPostEditDialog.vue
Normal file
200
src/components/dialogs/GroupDialog/GroupPostEditDialog.vue
Normal file
@@ -0,0 +1,200 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="groupPostEditDialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="groupPostEditDialog.visible"
|
||||
:title="$t('dialog.group_post_edit.header')"
|
||||
width="650px"
|
||||
append-to-body
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<div v-if="groupPostEditDialog.visible">
|
||||
<h3 v-text="groupPostEditDialog.groupRef.name"></h3>
|
||||
<el-form :model="groupPostEditDialog" label-width="150px">
|
||||
<el-form-item :label="$t('dialog.group_post_edit.title')">
|
||||
<el-input v-model="groupPostEditDialog.title" size="mini"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.group_post_edit.message')">
|
||||
<el-input
|
||||
v-model="groupPostEditDialog.text"
|
||||
type="textarea"
|
||||
:rows="4"
|
||||
:autosize="{ minRows: 4, maxRows: 20 }"
|
||||
style="margin-top: 10px"
|
||||
resize="none"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item>
|
||||
<el-checkbox
|
||||
v-if="!groupPostEditDialog.postId"
|
||||
v-model="groupPostEditDialog.sendNotification"
|
||||
size="small">
|
||||
{{ $t('dialog.group_post_edit.send_notification') }}
|
||||
</el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.group_post_edit.post_visibility')">
|
||||
<el-radio-group v-model="groupPostEditDialog.visibility" size="small">
|
||||
<el-radio label="public">
|
||||
{{ $t('dialog.group_post_edit.visibility_public') }}
|
||||
</el-radio>
|
||||
<el-radio label="group">
|
||||
{{ $t('dialog.group_post_edit.visibility_group') }}
|
||||
</el-radio>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="groupPostEditDialog.visibility === 'group'"
|
||||
:label="$t('dialog.new_instance.roles')">
|
||||
<el-select
|
||||
v-model="groupPostEditDialog.roleIds"
|
||||
multiple
|
||||
clearable
|
||||
:placeholder="$t('dialog.new_instance.role_placeholder')"
|
||||
style="width: 100%">
|
||||
<el-option-group :label="$t('dialog.new_instance.role_placeholder')">
|
||||
<el-option
|
||||
v-for="role in groupPostEditDialog.groupRef?.roles"
|
||||
:key="role.id"
|
||||
:label="role.name"
|
||||
:value="role.id"
|
||||
style="height: auto; width: 478px">
|
||||
<div class="detail">
|
||||
<span class="name" v-text="role.name"></span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.group_post_edit.image')">
|
||||
<template v-if="gallerySelectDialog.selectedFileId">
|
||||
<div style="display: inline-block; flex: none; margin-right: 5px">
|
||||
<el-popover placement="right" width="500px" trigger="click">
|
||||
<img
|
||||
slot="reference"
|
||||
v-lazy="gallerySelectDialog.selectedImageUrl"
|
||||
style="
|
||||
flex: none;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
border-radius: 4px;
|
||||
object-fit: cover;
|
||||
" />
|
||||
<img
|
||||
v-lazy="gallerySelectDialog.selectedImageUrl"
|
||||
style="height: 500px"
|
||||
@click="showFullscreenImageDialog(gallerySelectDialog.selectedImageUrl)" />
|
||||
</el-popover>
|
||||
<el-button size="mini" style="vertical-align: top" @click="clearImageGallerySelect">
|
||||
{{ $t('dialog.invite_message.clear_selected_image') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button size="mini" style="margin-right: 5px" @click="showGallerySelectDialog">
|
||||
{{ $t('dialog.invite_message.select_image') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button size="small" @click="groupPostEditDialog.visible = false">
|
||||
{{ $t('dialog.group_post_edit.cancel') }}
|
||||
</el-button>
|
||||
<el-button v-if="groupPostEditDialog.postId" size="small" @click="editGroupPost">
|
||||
{{ $t('dialog.group_post_edit.edit_post') }}
|
||||
</el-button>
|
||||
<el-button v-else size="small" @click="createGroupPost">
|
||||
{{ $t('dialog.group_post_edit.create_post') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { groupRequest } from '../../../api';
|
||||
|
||||
export default {
|
||||
name: 'GroupPostEditDialog',
|
||||
inject: [
|
||||
'beforeDialogClose',
|
||||
'showFullscreenImageDialog',
|
||||
'dialogMouseDown',
|
||||
'dialogMouseUp',
|
||||
'showGallerySelectDialog'
|
||||
],
|
||||
props: {
|
||||
dialogData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
gallerySelectDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
groupPostEditDialog: {
|
||||
get() {
|
||||
return this.dialogData;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:dialog-data', value);
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
editGroupPost() {
|
||||
const D = this.groupPostEditDialog;
|
||||
if (!D.groupId || !D.postId) {
|
||||
return;
|
||||
}
|
||||
const params = {
|
||||
groupId: D.groupId,
|
||||
postId: D.postId,
|
||||
title: D.title,
|
||||
text: D.text,
|
||||
roleIds: D.roleIds,
|
||||
visibility: D.visibility,
|
||||
imageId: null
|
||||
};
|
||||
if (this.gallerySelectDialog.selectedFileId) {
|
||||
params.imageId = this.gallerySelectDialog.selectedFileId;
|
||||
}
|
||||
groupRequest.editGroupPost(params).then((args) => {
|
||||
this.$message({
|
||||
message: 'Group post edited',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
D.visible = false;
|
||||
},
|
||||
createGroupPost() {
|
||||
const D = this.groupPostEditDialog;
|
||||
const params = {
|
||||
groupId: D.groupId,
|
||||
title: D.title,
|
||||
text: D.text,
|
||||
roleIds: D.roleIds,
|
||||
visibility: D.visibility,
|
||||
sendNotification: D.sendNotification,
|
||||
imageId: null
|
||||
};
|
||||
if (this.gallerySelectDialog.selectedFileId) {
|
||||
params.imageId = this.gallerySelectDialog.selectedFileId;
|
||||
}
|
||||
groupRequest.createGroupPost(params).then((args) => {
|
||||
this.$message({
|
||||
message: 'Group post created',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
D.visible = false;
|
||||
},
|
||||
clearImageGallerySelect() {
|
||||
this.$emit('clear-image-gallery-select');
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
307
src/components/dialogs/GroupDialog/InviteGroupDialog.vue
Normal file
307
src/components/dialogs/GroupDialog/InviteGroupDialog.vue
Normal file
@@ -0,0 +1,307 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="inviteGroupDialog"
|
||||
:visible.sync="inviteGroupDialog.visible"
|
||||
:before-close="beforeDialogClose"
|
||||
:title="$t('dialog.invite_to_group.header')"
|
||||
width="450px"
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<div v-if="inviteGroupDialog.visible" v-loading="inviteGroupDialog.loading">
|
||||
<span>{{ $t('dialog.invite_to_group.description') }}</span>
|
||||
<br />
|
||||
<el-select
|
||||
v-model="inviteGroupDialog.groupId"
|
||||
clearable
|
||||
:placeholder="$t('dialog.invite_to_group.choose_group_placeholder')"
|
||||
filterable
|
||||
:disabled="inviteGroupDialog.loading"
|
||||
style="margin-top: 15px"
|
||||
@change="isAllowedToInviteToGroup">
|
||||
<el-option-group
|
||||
v-if="API.currentUserGroups.size"
|
||||
:label="$t('dialog.invite_to_group.groups')"
|
||||
style="width: 410px">
|
||||
<el-option
|
||||
v-for="group in API.currentUserGroups.values()"
|
||||
:key="group.id"
|
||||
:label="group.name"
|
||||
:value="group.id"
|
||||
style="height: auto"
|
||||
class="x-friend-item">
|
||||
<div class="avatar">
|
||||
<img v-lazy="group.iconUrl" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span class="name" v-text="group.name"></span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
<el-select
|
||||
v-model="inviteGroupDialog.userIds"
|
||||
multiple
|
||||
clearable
|
||||
:placeholder="$t('dialog.invite_to_group.choose_friends_placeholder')"
|
||||
filterable
|
||||
:disabled="inviteGroupDialog.loading"
|
||||
style="width: 100%; margin-top: 15px">
|
||||
<el-option-group v-if="inviteGroupDialog.userId" :label="$t('dialog.invite_to_group.selected_users')">
|
||||
<el-option
|
||||
:key="inviteGroupDialog.userObject.id"
|
||||
:label="inviteGroupDialog.userObject.displayName"
|
||||
:value="inviteGroupDialog.userObject.id"
|
||||
class="x-friend-item">
|
||||
<template v-if="inviteGroupDialog.userObject.id">
|
||||
<div class="avatar" :class="userStatusClass(inviteGroupDialog.userObject)">
|
||||
<img v-lazy="userImage(inviteGroupDialog.userObject)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: inviteGroupDialog.userObject.$userColour }"
|
||||
v-text="inviteGroupDialog.userObject.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="inviteGroupDialog.userId"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
<el-option-group v-if="vipFriends.length" :label="$t('side_panel.favorite')">
|
||||
<el-option
|
||||
v-for="friend in vipFriends"
|
||||
:key="friend.id"
|
||||
:label="friend.name"
|
||||
:value="friend.id"
|
||||
style="height: auto"
|
||||
class="x-friend-item">
|
||||
<template v-if="friend.ref">
|
||||
<div class="avatar" :class="userStatusClass(friend.ref)">
|
||||
<img v-lazy="userImage(friend.ref)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: friend.ref.$userColour }"
|
||||
v-text="friend.ref.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="friend.id"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
<el-option-group v-if="onlineFriends.length" :label="$t('side_panel.online')">
|
||||
<el-option
|
||||
v-for="friend in onlineFriends"
|
||||
:key="friend.id"
|
||||
:label="friend.name"
|
||||
:value="friend.id"
|
||||
style="height: auto"
|
||||
class="x-friend-item">
|
||||
<template v-if="friend.ref">
|
||||
<div class="avatar" :class="userStatusClass(friend.ref)">
|
||||
<img v-lazy="userImage(friend.ref)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: friend.ref.$userColour }"
|
||||
v-text="friend.ref.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="friend.id"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
<el-option-group v-if="activeFriends.length" :label="$t('side_panel.active')">
|
||||
<el-option
|
||||
v-for="friend in activeFriends"
|
||||
:key="friend.id"
|
||||
:label="friend.name"
|
||||
:value="friend.id"
|
||||
style="height: auto"
|
||||
class="x-friend-item">
|
||||
<template v-if="friend.ref">
|
||||
<div class="avatar">
|
||||
<img v-lazy="userImage(friend.ref)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: friend.ref.$userColour }"
|
||||
v-text="friend.ref.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="friend.id"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
<el-option-group v-if="offlineFriends.length" :label="$t('side_panel.offline')">
|
||||
<el-option
|
||||
v-for="friend in offlineFriends"
|
||||
:key="friend.id"
|
||||
:label="friend.name"
|
||||
:value="friend.id"
|
||||
style="height: auto"
|
||||
class="x-friend-item">
|
||||
<template v-if="friend.ref">
|
||||
<div class="avatar">
|
||||
<img v-lazy="userImage(friend.ref)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: friend.ref.$userColour }"
|
||||
v-text="friend.ref.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="friend.id"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:disabled="inviteGroupDialog.loading || !inviteGroupDialog.userIds.length"
|
||||
@click="sendGroupInvite">
|
||||
Invite
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { groupRequest, userRequest } from '../../../api';
|
||||
import utils from '../../../classes/utils';
|
||||
|
||||
export default {
|
||||
name: 'InviteGroupDialog',
|
||||
inject: [
|
||||
'API',
|
||||
'dialogMouseDown',
|
||||
'dialogMouseUp',
|
||||
'beforeDialogClose',
|
||||
'userStatusClass',
|
||||
'userImage',
|
||||
'adjustDialogZ'
|
||||
],
|
||||
props: {
|
||||
dialogData: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
vipFriends: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
onlineFriends: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
activeFriends: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
offlineFriends: {
|
||||
type: Array,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
inviteGroupDialog: {
|
||||
get() {
|
||||
return this.dialogData;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:dialog-data', value);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'dialogData.visible'(value) {
|
||||
if (value) {
|
||||
this.initDialog();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
initDialog() {
|
||||
this.$nextTick(() => this.adjustDialogZ(this.$refs.inviteGroupDialog.$el));
|
||||
const D = this.inviteGroupDialog;
|
||||
if (D.groupId) {
|
||||
this.API.getCachedGroup({
|
||||
groupId: D.groupId
|
||||
})
|
||||
.then((args) => {
|
||||
D.groupName = args.ref.name;
|
||||
})
|
||||
.catch(() => {
|
||||
D.groupId = '';
|
||||
});
|
||||
this.isAllowedToInviteToGroup();
|
||||
}
|
||||
|
||||
if (D.userId) {
|
||||
userRequest.getCachedUser({ userId: D.userId }).then((args) => {
|
||||
D.userObject = args.ref;
|
||||
D.userIds = [D.userId];
|
||||
});
|
||||
}
|
||||
},
|
||||
isAllowedToInviteToGroup() {
|
||||
const D = this.inviteGroupDialog;
|
||||
const groupId = D.groupId;
|
||||
if (!groupId) {
|
||||
return;
|
||||
}
|
||||
this.inviteGroupDialog.loading = true;
|
||||
groupRequest
|
||||
.getGroup({ groupId })
|
||||
.then((args) => {
|
||||
if (utils.hasGroupPermission(args.ref, 'group-invites-manage')) {
|
||||
return args;
|
||||
}
|
||||
// not allowed to invite
|
||||
this.inviteGroupDialog.groupId = '';
|
||||
this.$message({
|
||||
type: 'error',
|
||||
message: 'You are not allowed to invite to this group'
|
||||
});
|
||||
return args;
|
||||
})
|
||||
.finally(() => {
|
||||
this.inviteGroupDialog.loading = false;
|
||||
});
|
||||
},
|
||||
sendGroupInvite() {
|
||||
this.$confirm('Continue? Invite User(s) To Group', 'Confirm', {
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'info',
|
||||
callback: (action) => {
|
||||
const D = this.inviteGroupDialog;
|
||||
if (action !== 'confirm' || D.loading === true) {
|
||||
return;
|
||||
}
|
||||
D.loading = true;
|
||||
const inviteLoop = () => {
|
||||
if (D.userIds.length === 0) {
|
||||
D.loading = false;
|
||||
return;
|
||||
}
|
||||
const receiverUserId = D.userIds.shift();
|
||||
groupRequest
|
||||
.sendGroupInvite({
|
||||
groupId: D.groupId,
|
||||
userId: receiverUserId
|
||||
})
|
||||
.then(inviteLoop)
|
||||
.catch(() => {
|
||||
D.loading = false;
|
||||
});
|
||||
};
|
||||
inviteLoop();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
877
src/components/dialogs/NewInstanceDialog.vue
Normal file
877
src/components/dialogs/NewInstanceDialog.vue
Normal file
@@ -0,0 +1,877 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="newInstanceDialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="newInstanceDialog.visible"
|
||||
:title="$t('dialog.new_instance.header')"
|
||||
width="650px"
|
||||
append-to-body
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<el-tabs v-model="newInstanceDialog.selectedTab" type="card" @tab-click="newInstanceTabClick">
|
||||
<el-tab-pane :label="$t('dialog.new_instance.normal')">
|
||||
<el-form :model="newInstanceDialog" label-width="150px">
|
||||
<el-form-item :label="$t('dialog.new_instance.access_type')">
|
||||
<el-radio-group v-model="newInstanceDialog.accessType" size="mini" @change="buildInstance">
|
||||
<el-radio-button label="public">{{
|
||||
$t('dialog.new_instance.access_type_public')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="group">{{
|
||||
$t('dialog.new_instance.access_type_group')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="friends+">{{
|
||||
$t('dialog.new_instance.access_type_friend_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="friends">{{
|
||||
$t('dialog.new_instance.access_type_friend')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="invite+">{{
|
||||
$t('dialog.new_instance.access_type_invite_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="invite">{{
|
||||
$t('dialog.new_instance.access_type_invite')
|
||||
}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="$t('dialog.new_instance.group_access_type')">
|
||||
<el-radio-group v-model="newInstanceDialog.groupAccessType" size="mini" @change="buildInstance">
|
||||
<el-radio-button
|
||||
label="members"
|
||||
:disabled="
|
||||
!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-open-create')
|
||||
"
|
||||
>{{ $t('dialog.new_instance.group_access_type_members') }}</el-radio-button
|
||||
>
|
||||
<el-radio-button
|
||||
label="plus"
|
||||
:disabled="
|
||||
!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-plus-create')
|
||||
"
|
||||
>{{ $t('dialog.new_instance.group_access_type_plus') }}</el-radio-button
|
||||
>
|
||||
<el-radio-button
|
||||
label="public"
|
||||
:disabled="
|
||||
!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-public-create') ||
|
||||
newInstanceDialog.groupRef.privacy === 'private'
|
||||
"
|
||||
>{{ $t('dialog.new_instance.group_access_type_public') }}</el-radio-button
|
||||
>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.region')">
|
||||
<el-radio-group v-model="newInstanceDialog.region" size="mini" @change="buildInstance">
|
||||
<el-radio-button label="US West">{{
|
||||
$t('dialog.new_instance.region_usw')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="US East">{{
|
||||
$t('dialog.new_instance.region_use')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="Europe">{{ $t('dialog.new_instance.region_eu') }}</el-radio-button>
|
||||
<el-radio-button label="Japan">{{ $t('dialog.new_instance.region_jp') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.content_settings')">
|
||||
<el-select
|
||||
v-model="newInstanceDialog.selectedContentSettings"
|
||||
multiple
|
||||
:placeholder="$t('dialog.new_instance.content_placeholder')"
|
||||
style="width: 100%"
|
||||
@change="buildInstance">
|
||||
<el-option-group :label="$t('dialog.new_instance.content_placeholder')">
|
||||
<el-option
|
||||
class="x-friend-item"
|
||||
value="emoji"
|
||||
:label="$t('dialog.new_instance.content_emoji')"></el-option>
|
||||
<el-option
|
||||
class="x-friend-item"
|
||||
value="stickers"
|
||||
:label="$t('dialog.new_instance.content_stickers')"></el-option>
|
||||
<el-option
|
||||
class="x-friend-item"
|
||||
value="pedestals"
|
||||
:label="$t('dialog.new_instance.content_pedestals')"></el-option>
|
||||
<el-option
|
||||
class="x-friend-item"
|
||||
value="prints"
|
||||
:label="$t('dialog.new_instance.content_prints')"></el-option>
|
||||
<el-option
|
||||
class="x-friend-item"
|
||||
value="drones"
|
||||
:label="$t('dialog.new_instance.content_drones')"></el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="$t('dialog.new_instance.queueEnabled')">
|
||||
<el-checkbox v-model="newInstanceDialog.queueEnabled" @change="buildInstance"></el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="$t('dialog.new_instance.ageGate')">
|
||||
<el-checkbox
|
||||
v-model="newInstanceDialog.ageGate"
|
||||
:disabled="
|
||||
!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-age-gated-create')
|
||||
"
|
||||
@change="buildInstance"></el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.world_id')">
|
||||
<el-input
|
||||
v-model="newInstanceDialog.worldId"
|
||||
size="mini"
|
||||
@click.native="$event.target.tagName === 'INPUT' && $event.target.select()"
|
||||
@change="buildInstance"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="$t('dialog.new_instance.group_id')">
|
||||
<el-select
|
||||
v-model="newInstanceDialog.groupId"
|
||||
clearable
|
||||
:placeholder="$t('dialog.new_instance.group_placeholder')"
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@change="buildInstance">
|
||||
<el-option-group :label="$t('dialog.new_instance.group_placeholder')">
|
||||
<el-option
|
||||
v-for="group in API.currentUserGroups.values()"
|
||||
v-if="
|
||||
group &&
|
||||
(hasGroupPermission(group, 'group-instance-public-create') ||
|
||||
hasGroupPermission(group, 'group-instance-plus-create') ||
|
||||
hasGroupPermission(group, 'group-instance-open-create'))
|
||||
"
|
||||
:key="group.id"
|
||||
:label="group.name"
|
||||
:value="group.id"
|
||||
class="x-friend-item"
|
||||
style="height: auto; width: 478px">
|
||||
<div class="avatar">
|
||||
<img v-lazy="group.iconUrl" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span class="name" v-text="group.name"></span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="
|
||||
newInstanceDialog.accessType === 'group' && newInstanceDialog.groupAccessType === 'members'
|
||||
"
|
||||
:label="$t('dialog.new_instance.roles')">
|
||||
<el-select
|
||||
v-model="newInstanceDialog.roleIds"
|
||||
multiple
|
||||
clearable
|
||||
:placeholder="$t('dialog.new_instance.role_placeholder')"
|
||||
style="width: 100%"
|
||||
@change="buildInstance">
|
||||
<el-option-group :label="$t('dialog.new_instance.role_placeholder')">
|
||||
<el-option
|
||||
v-for="role in newInstanceDialog.selectedGroupRoles"
|
||||
:key="role.id"
|
||||
class="x-friend-item"
|
||||
:label="role.name"
|
||||
:value="role.id"
|
||||
style="height: auto; width: 478px">
|
||||
<div class="detail">
|
||||
<span class="name" v-text="role.name"></span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<template v-if="newInstanceDialog.instanceCreated">
|
||||
<el-form-item :label="$t('dialog.new_instance.location')">
|
||||
<el-input
|
||||
v-model="newInstanceDialog.location"
|
||||
size="mini"
|
||||
readonly
|
||||
@click.native="$event.target.tagName === 'INPUT' && $event.target.select()"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.url')">
|
||||
<el-input v-model="newInstanceDialog.url" size="mini" readonly></el-input>
|
||||
</el-form-item>
|
||||
</template>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
<el-tab-pane :label="$t('dialog.new_instance.legacy')">
|
||||
<el-form :model="newInstanceDialog" label-width="150px">
|
||||
<el-form-item :label="$t('dialog.new_instance.access_type')">
|
||||
<el-radio-group
|
||||
v-model="newInstanceDialog.accessType"
|
||||
size="mini"
|
||||
@change="buildLegacyInstance">
|
||||
<el-radio-button label="public">{{
|
||||
$t('dialog.new_instance.access_type_public')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="group">{{
|
||||
$t('dialog.new_instance.access_type_group')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="friends+">{{
|
||||
$t('dialog.new_instance.access_type_friend_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="friends">{{
|
||||
$t('dialog.new_instance.access_type_friend')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="invite+">{{
|
||||
$t('dialog.new_instance.access_type_invite_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="invite">{{
|
||||
$t('dialog.new_instance.access_type_invite')
|
||||
}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="$t('dialog.new_instance.group_access_type')">
|
||||
<el-radio-group
|
||||
v-model="newInstanceDialog.groupAccessType"
|
||||
size="mini"
|
||||
@change="buildLegacyInstance">
|
||||
<el-radio-button label="members">{{
|
||||
$t('dialog.new_instance.group_access_type_members')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="plus">{{
|
||||
$t('dialog.new_instance.group_access_type_plus')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="public">{{
|
||||
$t('dialog.new_instance.group_access_type_public')
|
||||
}}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.region')">
|
||||
<el-radio-group v-model="newInstanceDialog.region" size="mini" @change="buildLegacyInstance">
|
||||
<el-radio-button label="US West">{{
|
||||
$t('dialog.new_instance.region_usw')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="US East">{{
|
||||
$t('dialog.new_instance.region_use')
|
||||
}}</el-radio-button>
|
||||
<el-radio-button label="Europe">{{ $t('dialog.new_instance.region_eu') }}</el-radio-button>
|
||||
<el-radio-button label="Japan">{{ $t('dialog.new_instance.region_jp') }}</el-radio-button>
|
||||
</el-radio-group>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="$t('dialog.new_instance.ageGate')">
|
||||
<el-checkbox v-model="newInstanceDialog.ageGate" @change="buildInstance"></el-checkbox>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.world_id')">
|
||||
<el-input
|
||||
v-model="newInstanceDialog.worldId"
|
||||
size="mini"
|
||||
@click.native="$event.target.tagName === 'INPUT' && $event.target.select()"
|
||||
@change="buildLegacyInstance"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.instance_id')">
|
||||
<el-input
|
||||
v-model="newInstanceDialog.instanceName"
|
||||
:placeholder="$t('dialog.new_instance.instance_id_placeholder')"
|
||||
size="mini"
|
||||
@change="buildLegacyInstance"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType !== 'public' && newInstanceDialog.accessType !== 'group'"
|
||||
:label="$t('dialog.new_instance.instance_creator')">
|
||||
<el-select
|
||||
v-model="newInstanceDialog.userId"
|
||||
clearable
|
||||
:placeholder="$t('dialog.new_instance.instance_creator_placeholder')"
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@change="buildLegacyInstance">
|
||||
<el-option-group v-if="API.currentUser" :label="$t('side_panel.me')">
|
||||
<el-option
|
||||
class="x-friend-item"
|
||||
:label="API.currentUser.displayName"
|
||||
:value="API.currentUser.id"
|
||||
style="height: auto">
|
||||
<div class="avatar" :class="userStatusClass(API.currentUser)">
|
||||
<img v-lazy="userImage(API.currentUser)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span class="name" v-text="API.currentUser.displayName"></span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
<el-option-group v-if="vipFriends.length" :label="$t('side_panel.favorite')">
|
||||
<el-option
|
||||
v-for="friend in vipFriends"
|
||||
:key="friend.id"
|
||||
class="x-friend-item"
|
||||
:label="friend.name"
|
||||
:value="friend.id"
|
||||
style="height: auto">
|
||||
<template v-if="friend.ref">
|
||||
<div class="avatar" :class="userStatusClass(friend.ref)">
|
||||
<img v-lazy="userImage(friend.ref)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: friend.ref.$userColour }"
|
||||
v-text="friend.ref.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="friend.id"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
<el-option-group v-if="onlineFriends.length" :label="$t('side_panel.online')">
|
||||
<el-option
|
||||
v-for="friend in onlineFriends"
|
||||
:key="friend.id"
|
||||
class="x-friend-item"
|
||||
:label="friend.name"
|
||||
:value="friend.id"
|
||||
style="height: auto">
|
||||
<template v-if="friend.ref">
|
||||
<div class="avatar" :class="userStatusClass(friend.ref)">
|
||||
<img v-lazy="userImage(friend.ref)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: friend.ref.$userColour }"
|
||||
v-text="friend.ref.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="friend.id"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
<el-option-group v-if="activeFriends.length" :label="$t('side_panel.active')">
|
||||
<el-option
|
||||
v-for="friend in activeFriends"
|
||||
:key="friend.id"
|
||||
class="x-friend-item"
|
||||
:label="friend.name"
|
||||
:value="friend.id"
|
||||
style="height: auto">
|
||||
<template v-if="friend.ref">
|
||||
<div class="avatar">
|
||||
<img v-lazy="userImage(friend.ref)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: friend.ref.$userColour }"
|
||||
v-text="friend.ref.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="friend.id"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
<el-option-group v-if="offlineFriends.length" :label="$t('side_panel.offline')">
|
||||
<el-option
|
||||
v-for="friend in offlineFriends"
|
||||
:key="friend.id"
|
||||
class="x-friend-item"
|
||||
:label="friend.name"
|
||||
:value="friend.id"
|
||||
style="height: auto">
|
||||
<template v-if="friend.ref">
|
||||
<div class="avatar">
|
||||
<img v-lazy="userImage(friend.ref)" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span
|
||||
class="name"
|
||||
:style="{ color: friend.ref.$userColour }"
|
||||
v-text="friend.ref.displayName"></span>
|
||||
</div>
|
||||
</template>
|
||||
<span v-else v-text="friend.id"></span>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item
|
||||
v-if="newInstanceDialog.accessType === 'group'"
|
||||
:label="$t('dialog.new_instance.group_id')">
|
||||
<el-select
|
||||
v-model="newInstanceDialog.groupId"
|
||||
clearable
|
||||
:placeholder="$t('dialog.new_instance.group_placeholder')"
|
||||
filterable
|
||||
style="width: 100%"
|
||||
@change="buildLegacyInstance">
|
||||
<el-option-group :label="$t('dialog.new_instance.group_placeholder')">
|
||||
<el-option
|
||||
v-for="group in API.currentUserGroups.values()"
|
||||
v-if="group"
|
||||
:key="group.id"
|
||||
class="x-friend-item"
|
||||
:label="group.name"
|
||||
:value="group.id"
|
||||
style="height: auto; width: 478px">
|
||||
<div class="avatar">
|
||||
<img v-lazy="group.iconUrl" />
|
||||
</div>
|
||||
<div class="detail">
|
||||
<span class="name" v-text="group.name"></span>
|
||||
</div>
|
||||
</el-option>
|
||||
</el-option-group>
|
||||
</el-select>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.location')">
|
||||
<el-input
|
||||
v-model="newInstanceDialog.location"
|
||||
size="mini"
|
||||
readonly
|
||||
@click.native="$event.target.tagName === 'INPUT' && $event.target.select()"></el-input>
|
||||
</el-form-item>
|
||||
<el-form-item :label="$t('dialog.new_instance.url')">
|
||||
<el-input v-model="newInstanceDialog.url" size="mini" readonly></el-input>
|
||||
</el-form-item>
|
||||
</el-form>
|
||||
</el-tab-pane>
|
||||
</el-tabs>
|
||||
<template v-if="newInstanceDialog.selectedTab === '0'" #footer>
|
||||
<template v-if="newInstanceDialog.instanceCreated">
|
||||
<el-button size="small" @click="copyInstanceUrl(newInstanceDialog.location)">{{
|
||||
$t('dialog.new_instance.copy_url')
|
||||
}}</el-button>
|
||||
<el-button size="small" @click="selfInvite(newInstanceDialog.location)">{{
|
||||
$t('dialog.new_instance.self_invite')
|
||||
}}</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
:disabled="
|
||||
(newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite') &&
|
||||
newInstanceDialog.userId !== API.currentUser.id
|
||||
"
|
||||
@click="showInviteDialog(newInstanceDialog.location)"
|
||||
>{{ $t('dialog.new_instance.invite') }}</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="showLaunchDialog(newInstanceDialog.location, newInstanceDialog.shortName)"
|
||||
>{{ $t('dialog.new_instance.launch') }}</el-button
|
||||
>
|
||||
</template>
|
||||
<template v-else>
|
||||
<el-button type="primary" size="small" @click="handleCreateNewInstance">{{
|
||||
$t('dialog.new_instance.create_instance')
|
||||
}}</el-button>
|
||||
</template>
|
||||
</template>
|
||||
<template v-else-if="newInstanceDialog.selectedTab === '1'" #footer>
|
||||
<el-button size="small" @click="copyInstanceUrl(newInstanceDialog.location)">{{
|
||||
$t('dialog.new_instance.copy_url')
|
||||
}}</el-button>
|
||||
<el-button size="small" @click="selfInvite(newInstanceDialog.location)">{{
|
||||
$t('dialog.new_instance.self_invite')
|
||||
}}</el-button>
|
||||
<el-button
|
||||
size="small"
|
||||
:disabled="
|
||||
(newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite') &&
|
||||
newInstanceDialog.userId !== API.currentUser.id
|
||||
"
|
||||
@click="showInviteDialog(newInstanceDialog.location)"
|
||||
>{{ $t('dialog.new_instance.invite') }}</el-button
|
||||
>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
@click="showLaunchDialog(newInstanceDialog.location, newInstanceDialog.shortName)"
|
||||
>{{ $t('dialog.new_instance.launch') }}</el-button
|
||||
>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { groupRequest, instanceRequest } from '../../api';
|
||||
import utils from '../../classes/utils';
|
||||
import configRepository from '../../service/config';
|
||||
|
||||
export default {
|
||||
name: 'NewInstanceDialog',
|
||||
inject: [
|
||||
'API',
|
||||
'userImage',
|
||||
'userStatusClass',
|
||||
'beforeDialogClose',
|
||||
'dialogMouseDown',
|
||||
'dialogMouseUp',
|
||||
'showInviteDialog',
|
||||
'showLaunchDialog',
|
||||
'adjustDialogZ'
|
||||
],
|
||||
props: {
|
||||
vipFriends: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
onlineFriends: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
activeFriends: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
offlineFriends: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
instanceContentSettings: {
|
||||
type: Array,
|
||||
required: true
|
||||
},
|
||||
createNewInstance: {
|
||||
type: Function,
|
||||
required: true
|
||||
},
|
||||
newInstanceDialogLocationTag: {
|
||||
type: String,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
newInstanceDialog: {
|
||||
visible: false,
|
||||
// loading: false,
|
||||
selectedTab: '0',
|
||||
instanceCreated: false,
|
||||
queueEnabled: false,
|
||||
worldId: '',
|
||||
instanceId: '',
|
||||
instanceName: '',
|
||||
userId: '',
|
||||
accessType: 'public',
|
||||
region: 'US West',
|
||||
groupRegion: '',
|
||||
groupId: '',
|
||||
groupAccessType: 'plus',
|
||||
ageGate: false,
|
||||
strict: false,
|
||||
location: '',
|
||||
shortName: '',
|
||||
url: '',
|
||||
secureOrShortName: '',
|
||||
lastSelectedGroupId: '',
|
||||
selectedGroupRoles: [],
|
||||
roleIds: [],
|
||||
groupRef: {},
|
||||
contentSettings: this.instanceContentSettings,
|
||||
selectedContentSettings: []
|
||||
}
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
newInstanceDialogLocationTag(value) {
|
||||
this.initNewInstanceDialog(value);
|
||||
}
|
||||
},
|
||||
created() {
|
||||
this.initializeNewInstanceDialog();
|
||||
},
|
||||
methods: {
|
||||
initNewInstanceDialog(tag) {
|
||||
if (!utils.isRealInstance(tag)) {
|
||||
return;
|
||||
}
|
||||
this.$nextTick(() => this.adjustDialogZ(this.$refs.newInstanceDialog.$el));
|
||||
const D = this.newInstanceDialog;
|
||||
const L = utils.parseLocation(tag);
|
||||
if (D.worldId === L.worldId) {
|
||||
// reopening dialog, keep last open instance
|
||||
D.visible = true;
|
||||
return;
|
||||
}
|
||||
D.worldId = L.worldId;
|
||||
D.instanceCreated = false;
|
||||
D.lastSelectedGroupId = '';
|
||||
D.selectedGroupRoles = [];
|
||||
D.groupRef = {};
|
||||
D.roleIds = [];
|
||||
D.strict = false;
|
||||
D.shortName = '';
|
||||
D.secureOrShortName = '';
|
||||
groupRequest.getGroupPermissions({ userId: this.API.currentUser.id });
|
||||
this.buildInstance();
|
||||
this.buildLegacyInstance();
|
||||
this.updateNewInstanceDialog();
|
||||
D.visible = true;
|
||||
},
|
||||
initializeNewInstanceDialog() {
|
||||
configRepository
|
||||
.getBool('instanceDialogQueueEnabled', true)
|
||||
.then((value) => (this.newInstanceDialog.queueEnabled = value));
|
||||
|
||||
configRepository
|
||||
.getString('instanceDialogInstanceName', '')
|
||||
.then((value) => (this.newInstanceDialog.instanceName = value));
|
||||
|
||||
configRepository
|
||||
.getString('instanceDialogUserId', '')
|
||||
.then((value) => (this.newInstanceDialog.userId = value));
|
||||
|
||||
configRepository
|
||||
.getString('instanceDialogAccessType', 'public')
|
||||
.then((value) => (this.newInstanceDialog.accessType = value));
|
||||
|
||||
configRepository
|
||||
.getString('instanceRegion', 'US West')
|
||||
.then((value) => (this.newInstanceDialog.region = value));
|
||||
|
||||
configRepository
|
||||
.getString('instanceDialogGroupId', '')
|
||||
.then((value) => (this.newInstanceDialog.groupId = value));
|
||||
|
||||
configRepository
|
||||
.getString('instanceDialogGroupAccessType', 'plus')
|
||||
.then((value) => (this.newInstanceDialog.groupAccessType = value));
|
||||
|
||||
configRepository
|
||||
.getBool('instanceDialogAgeGate', false)
|
||||
.then((value) => (this.newInstanceDialog.ageGate = value));
|
||||
|
||||
configRepository
|
||||
.getString('instanceDialogSelectedContentSettings', JSON.stringify(this.instanceContentSettings))
|
||||
.then((value) => (this.newInstanceDialog.selectedContentSettings = JSON.parse(value)));
|
||||
},
|
||||
saveNewInstanceDialog() {
|
||||
const {
|
||||
accessType,
|
||||
region,
|
||||
instanceName,
|
||||
userId,
|
||||
groupId,
|
||||
groupAccessType,
|
||||
queueEnabled,
|
||||
ageGate,
|
||||
selectedContentSettings
|
||||
} = this.newInstanceDialog;
|
||||
|
||||
configRepository.setString('instanceDialogAccessType', accessType);
|
||||
configRepository.setString('instanceRegion', region);
|
||||
configRepository.setString('instanceDialogInstanceName', instanceName);
|
||||
configRepository.setString('instanceDialogUserId', userId === this.API.currentUser.id ? '' : userId);
|
||||
configRepository.setString('instanceDialogGroupId', groupId);
|
||||
configRepository.setString('instanceDialogGroupAccessType', groupAccessType);
|
||||
configRepository.setBool('instanceDialogQueueEnabled', queueEnabled);
|
||||
configRepository.setBool('instanceDialogAgeGate', ageGate);
|
||||
configRepository.setString(
|
||||
'instanceDialogSelectedContentSettings',
|
||||
JSON.stringify(selectedContentSettings)
|
||||
);
|
||||
},
|
||||
newInstanceTabClick(tab) {
|
||||
if (tab === '1') {
|
||||
this.buildInstance();
|
||||
} else {
|
||||
this.buildLegacyInstance();
|
||||
}
|
||||
},
|
||||
updateNewInstanceDialog(noChanges) {
|
||||
const D = this.newInstanceDialog;
|
||||
if (D.instanceId) {
|
||||
D.location = `${D.worldId}:${D.instanceId}`;
|
||||
} else {
|
||||
D.location = D.worldId;
|
||||
}
|
||||
const L = utils.parseLocation(D.location);
|
||||
if (noChanges) {
|
||||
L.shortName = D.shortName;
|
||||
} else {
|
||||
D.shortName = '';
|
||||
}
|
||||
D.url = utils.getLaunchURL(L);
|
||||
},
|
||||
selfInvite(location) {
|
||||
const L = utils.parseLocation(location);
|
||||
if (!L.isRealInstance) {
|
||||
return;
|
||||
}
|
||||
instanceRequest
|
||||
.selfInvite({
|
||||
instanceId: L.instanceId,
|
||||
worldId: L.worldId
|
||||
})
|
||||
.then((args) => {
|
||||
this.$message({
|
||||
message: 'Self invite sent',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
},
|
||||
async handleCreateNewInstance() {
|
||||
const args = await this.createNewInstance(this.newInstanceDialog.worldId, this.newInstanceDialog);
|
||||
|
||||
if (args) {
|
||||
this.newInstanceDialog.location = args.json.location;
|
||||
this.newInstanceDialog.instanceId = args.json.instanceId;
|
||||
this.newInstanceDialog.secureOrShortName = args.json.shortName || args.json.secureName;
|
||||
this.newInstanceDialog.instanceCreated = true;
|
||||
this.updateNewInstanceDialog();
|
||||
}
|
||||
},
|
||||
buildInstance() {
|
||||
const D = this.newInstanceDialog;
|
||||
D.instanceCreated = false;
|
||||
D.instanceId = '';
|
||||
D.shortName = '';
|
||||
D.secureOrShortName = '';
|
||||
if (!D.userId) {
|
||||
D.userId = this.API.currentUser.id;
|
||||
}
|
||||
if (D.groupId && D.groupId !== D.lastSelectedGroupId) {
|
||||
D.roleIds = [];
|
||||
const ref = this.API.cachedGroups.get(D.groupId);
|
||||
if (typeof ref !== 'undefined') {
|
||||
D.groupRef = ref;
|
||||
D.selectedGroupRoles = ref.roles;
|
||||
groupRequest
|
||||
.getGroupRoles({
|
||||
groupId: D.groupId
|
||||
})
|
||||
.then((args) => {
|
||||
D.lastSelectedGroupId = D.groupId;
|
||||
D.selectedGroupRoles = args.json;
|
||||
ref.roles = args.json;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!D.groupId) {
|
||||
D.roleIds = [];
|
||||
D.groupRef = {};
|
||||
D.selectedGroupRoles = [];
|
||||
D.lastSelectedGroupId = '';
|
||||
}
|
||||
this.saveNewInstanceDialog();
|
||||
},
|
||||
buildLegacyInstance() {
|
||||
const D = this.newInstanceDialog;
|
||||
D.instanceCreated = false;
|
||||
D.shortName = '';
|
||||
D.secureOrShortName = '';
|
||||
const tags = [];
|
||||
if (D.instanceName) {
|
||||
D.instanceName = D.instanceName.replace(/[^A-Za-z0-9]/g, '');
|
||||
tags.push(D.instanceName);
|
||||
} else {
|
||||
const randValue = (99999 * Math.random() + 1).toFixed(0);
|
||||
tags.push(String(randValue).padStart(5, '0'));
|
||||
}
|
||||
if (!D.userId) {
|
||||
D.userId = this.API.currentUser.id;
|
||||
}
|
||||
const userId = D.userId;
|
||||
if (D.accessType !== 'public') {
|
||||
if (D.accessType === 'friends+') {
|
||||
tags.push(`~hidden(${userId})`);
|
||||
} else if (D.accessType === 'friends') {
|
||||
tags.push(`~friends(${userId})`);
|
||||
} else if (D.accessType === 'group') {
|
||||
tags.push(`~group(${D.groupId})`);
|
||||
tags.push(`~groupAccessType(${D.groupAccessType})`);
|
||||
} else {
|
||||
tags.push(`~private(${userId})`);
|
||||
}
|
||||
if (D.accessType === 'invite+') {
|
||||
tags.push('~canRequestInvite');
|
||||
}
|
||||
}
|
||||
if (D.accessType === 'group' && D.ageGate) {
|
||||
tags.push('~ageGate');
|
||||
}
|
||||
if (D.region === 'US West') {
|
||||
tags.push(`~region(us)`);
|
||||
} else if (D.region === 'US East') {
|
||||
tags.push(`~region(use)`);
|
||||
} else if (D.region === 'Europe') {
|
||||
tags.push(`~region(eu)`);
|
||||
} else if (D.region === 'Japan') {
|
||||
tags.push(`~region(jp)`);
|
||||
}
|
||||
if (D.accessType !== 'invite' && D.accessType !== 'friends') {
|
||||
D.strict = false;
|
||||
}
|
||||
if (D.strict) {
|
||||
tags.push('~strict');
|
||||
}
|
||||
if (D.groupId && D.groupId !== D.lastSelectedGroupId) {
|
||||
D.roleIds = [];
|
||||
const ref = this.API.cachedGroups.get(D.groupId);
|
||||
if (typeof ref !== 'undefined') {
|
||||
D.groupRef = ref;
|
||||
D.selectedGroupRoles = ref.roles;
|
||||
groupRequest
|
||||
.getGroupRoles({
|
||||
groupId: D.groupId
|
||||
})
|
||||
.then((args) => {
|
||||
D.lastSelectedGroupId = D.groupId;
|
||||
D.selectedGroupRoles = args.json;
|
||||
ref.roles = args.json;
|
||||
});
|
||||
}
|
||||
}
|
||||
if (!D.groupId) {
|
||||
D.roleIds = [];
|
||||
D.selectedGroupRoles = [];
|
||||
D.groupRef = {};
|
||||
D.lastSelectedGroupId = '';
|
||||
}
|
||||
D.instanceId = tags.join('');
|
||||
this.updateNewInstanceDialog(false);
|
||||
this.saveNewInstanceDialog();
|
||||
},
|
||||
async copyInstanceUrl(location) {
|
||||
const L = utils.parseLocation(location);
|
||||
const args = await instanceRequest.getInstanceShortName({
|
||||
worldId: L.worldId,
|
||||
instanceId: L.instanceId
|
||||
});
|
||||
if (args.json) {
|
||||
if (args.json.shortName) {
|
||||
L.shortName = args.json.shortName;
|
||||
}
|
||||
// NOTE:
|
||||
// splitting the 'INSTANCE:SHORTNAME' event and put code here
|
||||
const resLocation = `${args.instance.worldId}:${args.instance.instanceId}`;
|
||||
if (resLocation === this.newInstanceDialog.location) {
|
||||
const shortName = args.json.shortName;
|
||||
const secureOrShortName = args.json.shortName || args.json.secureName;
|
||||
this.newInstanceDialog.shortName = shortName;
|
||||
this.newInstanceDialog.secureOrShortName = secureOrShortName;
|
||||
this.updateNewInstanceDialog(true);
|
||||
}
|
||||
}
|
||||
const newUrl = utils.getLaunchURL(L);
|
||||
this.copyToClipboard(newUrl);
|
||||
},
|
||||
async copyToClipboard(newUrl) {
|
||||
try {
|
||||
await navigator.clipboard.writeText(newUrl);
|
||||
this.$message({
|
||||
message: 'Instance copied to clipboard',
|
||||
type: 'success'
|
||||
});
|
||||
} catch (error) {
|
||||
this.$message({
|
||||
message: 'Instance copied failed',
|
||||
type: 'error'
|
||||
});
|
||||
console.error(error.message);
|
||||
}
|
||||
},
|
||||
hasGroupPermission(ref, permission) {
|
||||
return utils.hasGroupPermission(ref, permission);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,163 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="dialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible="visible"
|
||||
:title="$t('dialog.previous_instances.info')"
|
||||
width="800px"
|
||||
:fullscreen="fullscreen"
|
||||
destroy-on-close
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp"
|
||||
@close="$emit('update:visible', false)">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
<location :location="location.tag" style="font-size: 14px"></location>
|
||||
<el-input
|
||||
v-model="dataTable.filters[0].value"
|
||||
:placeholder="$t('dialog.previous_instances.search_placeholder')"
|
||||
style="width: 150px"
|
||||
clearable></el-input>
|
||||
</div>
|
||||
<data-tables v-loading="loading" v-bind="dataTable" style="margin-top: 10px">
|
||||
<el-table-column :label="$t('table.previous_instances.date')" prop="created_at" sortable width="110">
|
||||
<template slot-scope="scope">
|
||||
<el-tooltip placement="left">
|
||||
<template slot="content">
|
||||
<span>{{ scope.row.created_at | formatDate('long') }}</span>
|
||||
</template>
|
||||
<span>{{ scope.row.created_at | formatDate('short') }}</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.gameLog.icon')" prop="isFriend" width="70" align="center">
|
||||
<template slot-scope="scope">
|
||||
<template v-if="gameLogIsFriend(scope.row)">
|
||||
<el-tooltip v-if="gameLogIsFavorite(scope.row)" placement="top" content="Favorite">
|
||||
<span>⭐</span>
|
||||
</el-tooltip>
|
||||
<el-tooltip v-else placement="top" content="Friend">
|
||||
<span>💚</span>
|
||||
</el-tooltip>
|
||||
</template>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.display_name')" prop="displayName" sortable>
|
||||
<template slot-scope="scope">
|
||||
<span class="x-link" @click="lookupUser(scope.row)">{{ scope.row.displayName }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.time')" prop="time" width="100" sortable>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.timer }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.count')" prop="count" width="100" sortable>
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.count }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</data-tables>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import utils from '../../../classes/utils';
|
||||
import database from '../../../service/database';
|
||||
import dayjs from 'dayjs';
|
||||
import Location from '../../Location.vue';
|
||||
|
||||
export default {
|
||||
name: 'PreviousInstancesInfoDialog',
|
||||
components: {
|
||||
Location
|
||||
},
|
||||
inject: ['adjustDialogZ', 'beforeDialogClose', 'dialogMouseDown', 'dialogMouseUp'],
|
||||
props: {
|
||||
visible: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
instanceId: { type: String, required: true },
|
||||
gameLogIsFriend: { type: Function, required: true },
|
||||
gameLogIsFavorite: { type: Function, required: true },
|
||||
lookupUser: { type: Function, required: true },
|
||||
isDarkMode: { type: Boolean, required: true }
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
echarts: null,
|
||||
echartsInstance: null,
|
||||
loading: false,
|
||||
location: {},
|
||||
currentTab: 'table',
|
||||
dataTable: {
|
||||
data: [],
|
||||
filters: [
|
||||
{
|
||||
prop: 'displayName',
|
||||
value: ''
|
||||
}
|
||||
],
|
||||
tableProps: {
|
||||
stripe: true,
|
||||
size: 'mini',
|
||||
defaultSort: {
|
||||
prop: 'created_at',
|
||||
order: 'descending'
|
||||
}
|
||||
},
|
||||
pageSize: 10,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 25, 50, 100]
|
||||
}
|
||||
},
|
||||
fullscreen: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
activityDetailData() {
|
||||
return this.dataTable.data.map((item) => ({
|
||||
displayName: item.displayName,
|
||||
joinTime: dayjs(item.created_at),
|
||||
leaveTime: dayjs(item.created_at).add(item.time, 'ms'),
|
||||
time: item.time,
|
||||
timer: item.timer
|
||||
}));
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
visible(value) {
|
||||
if (value) {
|
||||
this.$nextTick(() => {
|
||||
this.init();
|
||||
this.refreshPreviousInstancesInfoTable();
|
||||
});
|
||||
utils.loadEcharts().then((echarts) => {
|
||||
this.echarts = echarts;
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
init() {
|
||||
this.adjustDialogZ(this.$refs.dialog.$el);
|
||||
this.loading = true;
|
||||
this.location = utils.parseLocation(this.instanceId);
|
||||
},
|
||||
refreshPreviousInstancesInfoTable() {
|
||||
database.getPlayersFromInstance(this.location.tag).then((data) => {
|
||||
const array = [];
|
||||
for (const entry of Array.from(data.values())) {
|
||||
entry.timer = utils.timeToText(entry.time);
|
||||
array.push(entry);
|
||||
}
|
||||
array.sort(utils.compareByCreatedAt);
|
||||
this.dataTable.data = array;
|
||||
this.loading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,214 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="previousInstancesUserDialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="isVisible"
|
||||
:title="$t('dialog.previous_instances.header')"
|
||||
width="1000px"
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="font-size: 14px" v-text="previousInstancesUserDialog.userRef.displayName"></span>
|
||||
<el-input
|
||||
v-model="previousInstancesUserDialogTable.filters[0].value"
|
||||
:placeholder="$t('dialog.previous_instances.search_placeholder')"
|
||||
style="display: block; width: 150px"></el-input>
|
||||
</div>
|
||||
<data-tables v-loading="loading" v-bind="previousInstancesUserDialogTable" style="margin-top: 10px">
|
||||
<el-table-column :label="$t('table.previous_instances.date')" prop="created_at" sortable width="170">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.created_at | formatDate('long') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.world')" prop="name" sortable>
|
||||
<template slot-scope="scope">
|
||||
<location
|
||||
:location="scope.row.location"
|
||||
:hint="scope.row.worldName"
|
||||
:grouphint="scope.row.groupName"></location>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.instance_creator')" prop="location" width="170">
|
||||
<template slot-scope="scope">
|
||||
<display-name
|
||||
:userid="scope.row.$location.userId"
|
||||
:location="scope.row.$location.tag"></display-name>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.time')" prop="time" width="100" sortable>
|
||||
<template slot-scope="scope">
|
||||
<span v-text="scope.row.timer"></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.action')" width="90" align="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="el-icon-switch-button"
|
||||
size="mini"
|
||||
@click="showLaunchDialog(scope.row.location)"></el-button>
|
||||
<el-button
|
||||
type="text"
|
||||
icon="el-icon-s-data"
|
||||
size="mini"
|
||||
@click="showPreviousInstancesInfoDialog(scope.row.location)"></el-button>
|
||||
<el-button
|
||||
v-if="shiftHeld"
|
||||
style="color: #f56c6c"
|
||||
type="text"
|
||||
icon="el-icon-close"
|
||||
size="mini"
|
||||
@click="deleteGameLogUserInstance(scope.row)"></el-button>
|
||||
<el-button
|
||||
v-else
|
||||
type="text"
|
||||
icon="el-icon-close"
|
||||
size="mini"
|
||||
@click="deleteGameLogUserInstancePrompt(scope.row)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</data-tables>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import utils from '../../../classes/utils';
|
||||
import database from '../../../service/database';
|
||||
import Location from '../../Location.vue';
|
||||
|
||||
export default {
|
||||
name: 'PreviousInstancesUserDialog',
|
||||
components: {
|
||||
Location
|
||||
},
|
||||
inject: [
|
||||
'beforeDialogClose',
|
||||
'dialogMouseDown',
|
||||
'dialogMouseUp',
|
||||
'adjustDialogZ',
|
||||
'showLaunchDialog',
|
||||
'showPreviousInstancesInfoDialog'
|
||||
],
|
||||
props: {
|
||||
previousInstancesUserDialog: {
|
||||
type: Object,
|
||||
default: () => ({
|
||||
visible: false,
|
||||
userRef: {},
|
||||
loading: false,
|
||||
forceUpdate: 0,
|
||||
previousInstances: [],
|
||||
previousInstancesTable: {
|
||||
data: [],
|
||||
filters: [
|
||||
{
|
||||
prop: 'displayName',
|
||||
value: ''
|
||||
}
|
||||
],
|
||||
tableProps: {
|
||||
stripe: true,
|
||||
size: 'mini',
|
||||
height: '400px'
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
shiftHeld: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
previousInstancesUserDialogTable: {
|
||||
data: [],
|
||||
filters: [
|
||||
{
|
||||
prop: 'worldName',
|
||||
value: ''
|
||||
}
|
||||
],
|
||||
tableProps: {
|
||||
stripe: true,
|
||||
size: 'mini',
|
||||
defaultSort: {
|
||||
prop: 'created_at',
|
||||
order: 'descending'
|
||||
}
|
||||
},
|
||||
pageSize: 10,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 25, 50, 100]
|
||||
}
|
||||
},
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.previousInstancesUserDialog.visible;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:previous-instances-user-dialog', {
|
||||
...this.previousInstancesUserDialog,
|
||||
visible: value
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'previousInstancesUserDialog.openFlg'() {
|
||||
if (this.previousInstancesUserDialog.visible) {
|
||||
this.$nextTick(() => {
|
||||
this.adjustDialogZ(this.$refs.previousInstancesUserDialog.$el);
|
||||
});
|
||||
this.refreshPreviousInstancesUserTable();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refreshPreviousInstancesUserTable() {
|
||||
this.loading = true;
|
||||
database.getpreviousInstancesByUserId(this.previousInstancesUserDialog.userRef).then((data) => {
|
||||
const array = [];
|
||||
for (const ref of data.values()) {
|
||||
ref.$location = utils.parseLocation(ref.location);
|
||||
if (ref.time > 0) {
|
||||
ref.timer = utils.timeToText(ref.time);
|
||||
} else {
|
||||
ref.timer = '';
|
||||
}
|
||||
array.push(ref);
|
||||
}
|
||||
array.sort(utils.compareByCreatedAt);
|
||||
this.previousInstancesUserDialogTable.data = array;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
deleteGameLogUserInstance(row) {
|
||||
database.deleteGameLogInstance({
|
||||
id: this.previousInstancesUserDialog.userRef.id,
|
||||
displayName: this.previousInstancesUserDialog.userRef.displayName,
|
||||
location: row.location
|
||||
});
|
||||
utils.removeFromArray(this.previousInstancesUserDialogTable.data, row);
|
||||
},
|
||||
deleteGameLogUserInstancePrompt(row) {
|
||||
this.$confirm('Continue? Delete User From GameLog Instance', 'Confirm', {
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'info',
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.deleteGameLogUserInstance(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,186 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
ref="previousInstancesWorldDialog"
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="isVisible"
|
||||
:title="$t('dialog.previous_instances.header')"
|
||||
width="1000px"
|
||||
append-to-body
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<div style="display: flex; align-items: center; justify-content: space-between">
|
||||
<span style="font-size: 14px" v-text="previousInstancesWorldDialog.worldRef.name"></span>
|
||||
<el-input
|
||||
v-model="previousInstancesWorldDialogTable.filters[0].value"
|
||||
:placeholder="$t('dialog.previous_instances.search_placeholder')"
|
||||
style="display: block; width: 150px"></el-input>
|
||||
</div>
|
||||
<data-tables v-loading="loading" v-bind="previousInstancesWorldDialogTable" style="margin-top: 10px">
|
||||
<el-table-column :label="$t('table.previous_instances.date')" prop="created_at" sortable width="170">
|
||||
<template slot-scope="scope">
|
||||
<span>{{ scope.row.created_at | formatDate('long') }}</span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.instance_name')" prop="name">
|
||||
<template slot-scope="scope">
|
||||
<location-world
|
||||
:locationobject="scope.row.$location"
|
||||
:grouphint="scope.row.groupName"
|
||||
:currentuserid="API.currentUser.id"
|
||||
@show-launch-dialog="showLaunchDialog"></location-world>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.instance_creator')" prop="location">
|
||||
<template slot-scope="scope">
|
||||
<display-name
|
||||
:userid="scope.row.$location.userId"
|
||||
:location="scope.row.$location.tag"
|
||||
:force-update-key="previousInstancesWorldDialog.forceUpdate"></display-name>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.time')" prop="time" width="100" sortable>
|
||||
<template slot-scope="scope">
|
||||
<span v-text="scope.row.timer"></span>
|
||||
</template>
|
||||
</el-table-column>
|
||||
<el-table-column :label="$t('table.previous_instances.action')" width="90" align="right">
|
||||
<template slot-scope="scope">
|
||||
<el-button
|
||||
type="text"
|
||||
icon="el-icon-s-data"
|
||||
size="mini"
|
||||
@click="showPreviousInstancesInfoDialog(scope.row.location)"></el-button>
|
||||
<el-button
|
||||
v-if="shiftHeld"
|
||||
style="color: #f56c6c"
|
||||
type="text"
|
||||
icon="el-icon-close"
|
||||
size="mini"
|
||||
@click="deleteGameLogWorldInstance(scope.row)"></el-button>
|
||||
<el-button
|
||||
v-else
|
||||
type="text"
|
||||
icon="el-icon-close"
|
||||
size="mini"
|
||||
@click="deleteGameLogWorldInstancePrompt(scope.row)"></el-button>
|
||||
</template>
|
||||
</el-table-column>
|
||||
</data-tables>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import utils from '../../../classes/utils';
|
||||
import database from '../../../service/database';
|
||||
|
||||
export default {
|
||||
name: 'PreviousInstancesWorldDialog',
|
||||
inject: [
|
||||
'API',
|
||||
'showLaunchDialog',
|
||||
'showPreviousInstancesInfoDialog',
|
||||
'adjustDialogZ',
|
||||
'beforeDialogClose',
|
||||
'dialogMouseDown',
|
||||
'dialogMouseUp'
|
||||
],
|
||||
props: {
|
||||
previousInstancesWorldDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
},
|
||||
shiftHeld: Boolean
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
previousInstancesWorldDialogTable: {
|
||||
data: [],
|
||||
filters: [
|
||||
{
|
||||
prop: 'groupName',
|
||||
value: ''
|
||||
}
|
||||
],
|
||||
tableProps: {
|
||||
stripe: true,
|
||||
size: 'mini',
|
||||
defaultSort: {
|
||||
prop: 'created_at',
|
||||
order: 'descending'
|
||||
}
|
||||
},
|
||||
pageSize: 10,
|
||||
paginationProps: {
|
||||
small: true,
|
||||
layout: 'sizes,prev,pager,next,total',
|
||||
pageSizes: [10, 25, 50, 100]
|
||||
}
|
||||
},
|
||||
loading: false
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.previousInstancesWorldDialog.visible;
|
||||
},
|
||||
set(value) {
|
||||
this.$emit('update:previous-instances-world-dialog', {
|
||||
...this.previousInstancesWorldDialog,
|
||||
visible: value
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'previousInstancesWorldDialog.openFlg'() {
|
||||
if (this.previousInstancesWorldDialog.visible) {
|
||||
this.$nextTick(() => {
|
||||
this.adjustDialogZ(this.$refs.previousInstancesWorldDialog.$el);
|
||||
});
|
||||
this.refreshPreviousInstancesWorldTable();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
refreshPreviousInstancesWorldTable() {
|
||||
this.loading = true;
|
||||
const D = this.previousInstancesWorldDialog;
|
||||
database.getpreviousInstancesByWorldId(D.worldRef).then((data) => {
|
||||
const array = [];
|
||||
for (const ref of data.values()) {
|
||||
ref.$location = utils.parseLocation(ref.location);
|
||||
if (ref.time > 0) {
|
||||
ref.timer = utils.timeToText(ref.time);
|
||||
} else {
|
||||
ref.timer = '';
|
||||
}
|
||||
array.push(ref);
|
||||
}
|
||||
array.sort(utils.compareByCreatedAt);
|
||||
this.previousInstancesWorldDialogTable.data = array;
|
||||
this.loading = false;
|
||||
});
|
||||
},
|
||||
deleteGameLogWorldInstance(row) {
|
||||
database.deleteGameLogInstanceByInstanceId({
|
||||
location: row.location
|
||||
});
|
||||
utils.removeFromArray(this.previousInstancesWorldDialogTable.data, row);
|
||||
},
|
||||
|
||||
deleteGameLogWorldInstancePrompt(row) {
|
||||
this.$confirm('Continue? Delete GameLog Instance', 'Confirm', {
|
||||
confirmButtonText: 'Confirm',
|
||||
cancelButtonText: 'Cancel',
|
||||
type: 'info',
|
||||
callback: (action) => {
|
||||
if (action === 'confirm') {
|
||||
this.deleteGameLogWorldInstance(row);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
297
src/components/dialogs/WorldDialog/SetWorldTagsDialog.vue
Normal file
297
src/components/dialogs/WorldDialog/SetWorldTagsDialog.vue
Normal file
@@ -0,0 +1,297 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="isVisible"
|
||||
:title="$t('dialog.set_world_tags.header')"
|
||||
width="400px"
|
||||
destroy-on-close
|
||||
append-to-body
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<el-checkbox v-model="setWorldTagsDialog.avatarScalingDisabled">
|
||||
{{ $t('dialog.set_world_tags.avatar_scaling_disabled') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.focusViewDisabled">
|
||||
{{ $t('dialog.set_world_tags.focus_view_disabled') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.debugAllowed">
|
||||
{{ $t('dialog.set_world_tags.enable_debugging') }}
|
||||
</el-checkbox>
|
||||
<div style="font-size: 12px; margin-top: 10px">{{ $t('dialog.set_world_tags.author_tags') }}<br /></div>
|
||||
<el-input
|
||||
v-model="setWorldTagsDialog.authorTags"
|
||||
type="textarea"
|
||||
size="mini"
|
||||
show-word-limit
|
||||
:autosize="{ minRows: 2, maxRows: 5 }"
|
||||
placeholder=""
|
||||
style="margin-top: 10px"></el-input>
|
||||
<div style="font-size: 12px; margin-top: 10px">{{ $t('dialog.set_world_tags.content_tags') }}<br /></div>
|
||||
<el-checkbox v-model="setWorldTagsDialog.contentHorror">
|
||||
{{ $t('dialog.set_world_tags.content_horror') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.contentGore">
|
||||
{{ $t('dialog.set_world_tags.content_gore') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.contentViolence">
|
||||
{{ $t('dialog.set_world_tags.content_violence') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.contentAdult">
|
||||
{{ $t('dialog.set_world_tags.content_adult') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.contentSex">
|
||||
{{ $t('dialog.set_world_tags.content_sex') }}
|
||||
</el-checkbox>
|
||||
<div style="font-size: 12px; margin-top: 10px">
|
||||
{{ $t('dialog.set_world_tags.default_content_settings') }}<br />
|
||||
</div>
|
||||
<el-checkbox v-model="setWorldTagsDialog.emoji">
|
||||
{{ $t('dialog.new_instance.content_emoji') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.stickers">
|
||||
{{ $t('dialog.new_instance.content_stickers') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.pedestals">
|
||||
{{ $t('dialog.new_instance.content_pedestals') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.prints">
|
||||
{{ $t('dialog.new_instance.content_prints') }}
|
||||
</el-checkbox>
|
||||
<br />
|
||||
<el-checkbox v-model="setWorldTagsDialog.drones">
|
||||
{{ $t('dialog.new_instance.content_drones') }}
|
||||
</el-checkbox>
|
||||
<template #footer>
|
||||
<div style="display: flex">
|
||||
<el-button size="small" @click="setWorldTagsDialog.visible = false">
|
||||
{{ $t('dialog.set_world_tags.cancel') }}
|
||||
</el-button>
|
||||
<el-button type="primary" size="small" @click="saveSetWorldTagsDialog">
|
||||
{{ $t('dialog.set_world_tags.save') }}
|
||||
</el-button>
|
||||
</div>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { worldRequest } from '../../../api';
|
||||
|
||||
export default {
|
||||
name: 'SetWorldTagsDialog',
|
||||
inject: ['beforeDialogClose', 'dialogMouseDown', 'dialogMouseUp', 'showWorldDialog'],
|
||||
props: {
|
||||
oldTags: {
|
||||
type: Array,
|
||||
default: () => []
|
||||
},
|
||||
isSetWorldTagsDialogVisible: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
},
|
||||
worldId: {
|
||||
type: String,
|
||||
required: true
|
||||
},
|
||||
isWorldDialogVisible: {
|
||||
type: Boolean,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
setWorldTagsDialog: {
|
||||
authorTags: [],
|
||||
contentTags: [],
|
||||
debugAllowed: false,
|
||||
avatarScalingDisabled: false,
|
||||
focusViewDisabled: false,
|
||||
contentHorror: false,
|
||||
contentGore: false,
|
||||
contentViolence: false,
|
||||
contentAdult: false,
|
||||
contentSex: false,
|
||||
emoji: true,
|
||||
stickers: true,
|
||||
pedestals: true,
|
||||
prints: true,
|
||||
drones: true
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.isSetWorldTagsDialogVisible;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:is-set-world-tags-dialog-visible', val);
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
isSetWorldTagsDialogVisible(val) {
|
||||
if (val) {
|
||||
this.showSetWorldTagsDialog();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
showSetWorldTagsDialog() {
|
||||
const D = this.setWorldTagsDialog;
|
||||
D.visible = true;
|
||||
D.debugAllowed = false;
|
||||
D.avatarScalingDisabled = false;
|
||||
D.focusViewDisabled = false;
|
||||
D.contentHorror = false;
|
||||
D.contentGore = false;
|
||||
D.contentViolence = false;
|
||||
D.contentAdult = false;
|
||||
D.contentSex = false;
|
||||
const authorTags = [];
|
||||
const contentTags = [];
|
||||
this.oldTags.forEach((tag) => {
|
||||
if (tag.startsWith('author_tag_')) {
|
||||
authorTags.unshift(tag.substring(11));
|
||||
}
|
||||
if (tag.startsWith('content_')) {
|
||||
contentTags.unshift(tag.substring(8));
|
||||
}
|
||||
switch (tag) {
|
||||
case 'content_horror':
|
||||
D.contentHorror = true;
|
||||
break;
|
||||
case 'content_gore':
|
||||
D.contentGore = true;
|
||||
break;
|
||||
case 'content_violence':
|
||||
D.contentViolence = true;
|
||||
break;
|
||||
case 'content_adult':
|
||||
D.contentAdult = true;
|
||||
break;
|
||||
case 'content_sex':
|
||||
D.contentSex = true;
|
||||
break;
|
||||
case 'debug_allowed':
|
||||
D.debugAllowed = true;
|
||||
break;
|
||||
case 'feature_avatar_scaling_disabled':
|
||||
D.avatarScalingDisabled = true;
|
||||
break;
|
||||
case 'feature_focus_view_disabled':
|
||||
D.focusViewDisabled = true;
|
||||
break;
|
||||
case 'feature_emoji_disabled':
|
||||
D.emoji = false;
|
||||
break;
|
||||
case 'feature_stickers_disabled':
|
||||
D.stickers = false;
|
||||
break;
|
||||
case 'feature_pedestals_disabled':
|
||||
D.pedestals = false;
|
||||
break;
|
||||
case 'feature_prints_disabled':
|
||||
D.prints = false;
|
||||
break;
|
||||
case 'feature_drones_disabled':
|
||||
D.drones = false;
|
||||
break;
|
||||
}
|
||||
});
|
||||
D.authorTags = authorTags.toString();
|
||||
D.contentTags = contentTags.toString();
|
||||
},
|
||||
saveSetWorldTagsDialog() {
|
||||
const D = this.setWorldTagsDialog;
|
||||
const authorTags = D.authorTags.trim().split(',');
|
||||
const contentTags = D.contentTags.trim().split(',');
|
||||
const tags = [];
|
||||
authorTags.forEach((tag) => {
|
||||
if (tag) {
|
||||
tags.unshift(`author_tag_${tag}`);
|
||||
}
|
||||
});
|
||||
// add back custom tags
|
||||
contentTags.forEach((tag) => {
|
||||
switch (tag) {
|
||||
case 'horror':
|
||||
case 'gore':
|
||||
case 'violence':
|
||||
case 'adult':
|
||||
case 'sex':
|
||||
case '':
|
||||
break;
|
||||
default:
|
||||
tags.unshift(`content_${tag}`);
|
||||
break;
|
||||
}
|
||||
});
|
||||
if (D.contentHorror) {
|
||||
tags.unshift('content_horror');
|
||||
}
|
||||
if (D.contentGore) {
|
||||
tags.unshift('content_gore');
|
||||
}
|
||||
if (D.contentViolence) {
|
||||
tags.unshift('content_violence');
|
||||
}
|
||||
if (D.contentAdult) {
|
||||
tags.unshift('content_adult');
|
||||
}
|
||||
if (D.contentSex) {
|
||||
tags.unshift('content_sex');
|
||||
}
|
||||
if (D.debugAllowed) {
|
||||
tags.unshift('debug_allowed');
|
||||
}
|
||||
if (D.avatarScalingDisabled) {
|
||||
tags.unshift('feature_avatar_scaling_disabled');
|
||||
}
|
||||
if (D.focusViewDisabled) {
|
||||
tags.unshift('feature_focus_view_disabled');
|
||||
}
|
||||
if (!D.emoji) {
|
||||
tags.unshift('feature_emoji_disabled');
|
||||
}
|
||||
if (!D.stickers) {
|
||||
tags.unshift('feature_stickers_disabled');
|
||||
}
|
||||
if (!D.pedestals) {
|
||||
tags.unshift('feature_pedestals_disabled');
|
||||
}
|
||||
if (!D.prints) {
|
||||
tags.unshift('feature_prints_disabled');
|
||||
}
|
||||
if (!D.drones) {
|
||||
tags.unshift('feature_drones_disabled');
|
||||
}
|
||||
worldRequest
|
||||
.saveWorld({
|
||||
id: this.worldId,
|
||||
tags
|
||||
})
|
||||
.then((args) => {
|
||||
this.$message({
|
||||
message: 'Tags updated',
|
||||
type: 'success'
|
||||
});
|
||||
this.$emit('update:is-set-world-tags-dialog-visible', false);
|
||||
if (this.isWorldDialogVisible) {
|
||||
this.showWorldDialog(args.json.id);
|
||||
}
|
||||
return args;
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,93 @@
|
||||
<template>
|
||||
<el-dialog
|
||||
:before-close="beforeDialogClose"
|
||||
:visible.sync="isVisible"
|
||||
:title="$t('dialog.allowed_video_player_domains.header')"
|
||||
width="600px"
|
||||
destroy-on-close
|
||||
append-to-body
|
||||
@mousedown.native="dialogMouseDown"
|
||||
@mouseup.native="dialogMouseUp">
|
||||
<div>
|
||||
<el-input
|
||||
v-for="(domain, index) in urlList"
|
||||
:key="index"
|
||||
v-model="urlList[index]"
|
||||
:value="domain"
|
||||
size="small"
|
||||
style="margin-top: 5px">
|
||||
<el-button slot="append" icon="el-icon-delete" @click="urlList.splice(index, 1)"></el-button>
|
||||
</el-input>
|
||||
<el-button size="mini" style="margin-top: 5px" @click="urlList.push('')">
|
||||
{{ $t('dialog.allowed_video_player_domains.add_domain') }}
|
||||
</el-button>
|
||||
</div>
|
||||
<template #footer>
|
||||
<el-button
|
||||
type="primary"
|
||||
size="small"
|
||||
:disabled="!worldAllowedDomainsDialog.worldId"
|
||||
@click="saveWorldAllowedDomains">
|
||||
{{ $t('dialog.allowed_video_player_domains.save') }}
|
||||
</el-button>
|
||||
</template>
|
||||
</el-dialog>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { worldRequest } from '../../../api';
|
||||
|
||||
export default {
|
||||
name: 'WorldAllowedDomainsDialog',
|
||||
inject: ['beforeDialogClose', 'dialogMouseDown', 'dialogMouseUp'],
|
||||
props: {
|
||||
worldAllowedDomainsDialog: {
|
||||
type: Object,
|
||||
required: true
|
||||
}
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
urlList: []
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
isVisible: {
|
||||
get() {
|
||||
return this.worldAllowedDomainsDialog.visible;
|
||||
},
|
||||
set(val) {
|
||||
this.$emit('update:world-allowed-domains-dialog', {
|
||||
...this.worldAllowedDomainsDialog,
|
||||
visible: val
|
||||
});
|
||||
}
|
||||
}
|
||||
},
|
||||
watch: {
|
||||
'worldAllowedDomainsDialog.visible'(val) {
|
||||
if (val) {
|
||||
this.urlList = this.worldAllowedDomainsDialog.urlList;
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
saveWorldAllowedDomains() {
|
||||
const D = this.worldAllowedDomainsDialog;
|
||||
worldRequest
|
||||
.saveWorld({
|
||||
id: D.worldId,
|
||||
urlList: D.urlList
|
||||
})
|
||||
.then((args) => {
|
||||
this.$message({
|
||||
message: 'Allowed Video Player Domains updated',
|
||||
type: 'success'
|
||||
});
|
||||
return args;
|
||||
});
|
||||
D.visible = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
1151
src/components/dialogs/WorldDialog/WorldDialog.vue
Normal file
1151
src/components/dialogs/WorldDialog/WorldDialog.vue
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user