Unleash the PUG linter

This commit is contained in:
Natsumi
2025-01-27 12:28:08 +13:00
parent ca6b52c053
commit cc1a1fbd6a
30 changed files with 6904 additions and 3041 deletions

View File

@@ -95,7 +95,11 @@ export default class extends baseClass {
) {
if (LINUX) {
this.nextGameRunningCheck = 1;
$app.updateIsGameRunning(await AppApi.IsGameRunning(), await AppApi.IsSteamVRRunning(), false);
$app.updateIsGameRunning(
await AppApi.IsGameRunning(),
await AppApi.IsSteamVRRunning(),
false
);
} else {
this.nextGameRunningCheck = 3;
AppApi.CheckGameRunning();

View File

@@ -146,12 +146,12 @@ export default class extends baseClass {
fileInput.accept = '.json';
fileInput.style.display = 'none';
document.body.appendChild(fileInput);
fileInput.onchange = function(event) {
fileInput.onchange = function (event) {
const file = event.target.files[0];
if (file) {
const reader = new FileReader();
reader.onload = function() {
reader.onload = function () {
fileInput.remove();
resolve(reader.result);
};
@@ -161,15 +161,19 @@ export default class extends baseClass {
resolve(null);
}
};
fileInput.click();
});
},
async restoreVrcRegistryFromFile() {
if (WINDOWS) {
var filePath = await AppApi.OpenFileSelectorDialog(null, ".json", "JSON Files (*.json)|*.json");
if (filePath === "") {
var filePath = await AppApi.OpenFileSelectorDialog(
null,
'.json',
'JSON Files (*.json)|*.json'
);
if (filePath === '') {
return;
}
}
@@ -180,7 +184,7 @@ export default class extends baseClass {
} else {
json = await AppApi.ReadVrcRegJsonFile(filePath);
}
try {
var data = JSON.parse(json);
if (!data || typeof data !== 'object') {

View File

@@ -185,23 +185,33 @@ export default class extends baseClass {
}
const notiConditions = {
'Always': () => true,
Always: () => true,
'Inside VR': () => this.isSteamVRRunning,
'Outside VR': () => !this.isSteamVRRunning,
'Game Closed': () => !this.isGameRunning, // Also known as "Outside VRChat"
'Game Running': () => this.isGameRunning, // Also known as "Inside VRChat"
'Desktop Mode': () => this.isGameNoVR && this.isGameRunning,
'AFK': () => this.afkDesktopToast && this.isHmdAfk && this.isGameRunning && !this.isGameNoVR,
AFK: () =>
this.afkDesktopToast &&
this.isHmdAfk &&
this.isGameRunning &&
!this.isGameNoVR
};
const playNotificationTTS = notiConditions[this.notificationTTS]?.();
const playDesktopToast = notiConditions[this.desktopToast]?.() || notiConditions['AFK']();
const playNotificationTTS =
notiConditions[this.notificationTTS]?.();
const playDesktopToast =
notiConditions[this.desktopToast]?.() ||
notiConditions['AFK']();
const playOverlayToast = notiConditions[this.overlayToast]?.();
const playOverlayNotification = this.overlayNotifications && playOverlayToast;
const playOverlayNotification =
this.overlayNotifications && playOverlayToast;
const playXSNotification = this.xsNotifications && playOverlayToast;
const playOvrtHudNotifications = this.ovrtHudNotifications && playOverlayToast;
const playOvrtWristNotifications = this.ovrtWristNotifications && playOverlayToast;
const playOvrtHudNotifications =
this.ovrtHudNotifications && playOverlayToast;
const playOvrtWristNotifications =
this.ovrtWristNotifications && playOverlayToast;
var message = '';
if (noty.title) {
@@ -1299,7 +1309,11 @@ export default class extends baseClass {
if (WINDOWS) {
AppApi.DesktopNotification(displayName, message, image);
} else {
window.electron.desktopNotification(displayName, message, image);
window.electron.desktopNotification(
displayName,
message,
image
);
}
},

View File

@@ -1,31 +1,42 @@
doctype html
html
head
meta(http-equiv="Content-Type" content="text/html;charset=utf-8")
meta(http-equiv="Cache-Control" content="no-cache")
meta(http-equiv="referrer" content="no-referrer")
meta(http-equiv="viewport" content="width=device-width,initial-scale=1,user-scalable=no")
meta(http-equiv='Content-Type' content='text/html;charset=utf-8')
meta(http-equiv='Cache-Control' content='no-cache')
meta(http-equiv='referrer' content='no-referrer')
meta(http-equiv='viewport' content='width=device-width,initial-scale=1,user-scalable=no')
title VRCX
link(rel="preconnect" href="https://api.vrchat.cloud")
link(rel="preconnect" href="https://d348imysud55la.cloudfront.net")
link(rel="stylesheet" href="app.css")
link(rel="stylesheet" href="flags.css")
link(rel="stylesheet" href="animated-emoji.css")
link(rel='preconnect' href='https://api.vrchat.cloud')
link(rel='preconnect' href='https://d348imysud55la.cloudfront.net')
link(rel='stylesheet' href='app.css')
link(rel='stylesheet' href='flags.css')
link(rel='stylesheet' href='animated-emoji.css')
body
.x-app#x-app(style="display:none" @dragenter.prevent @dragover.prevent @drop.prevent)
#x-app.x-app(style='display: none' @dragenter.prevent @dragover.prevent @drop.prevent)
//- login
include ./mixins/loginPage.pug
+loginPage()
+loginPage
//- menu
.x-menu-container
//- download progress, update pending
.pending-update(v-if="updateInProgress" @click="showVRCXUpdateDialog")
el-progress(type="circle" width="50" stroke-width="3" :percentage="updateProgress" :format="updateProgressText")
.pending-update(v-else-if="pendingVRCXUpdate || pendingVRCXInstall")
el-button(type="default" @click="showVRCXUpdateDialog" size="mini" icon="el-icon-download" circle style="font-size:14px;height:50px;width:50px")
.pending-update(v-if='updateInProgress' @click='showVRCXUpdateDialog')
el-progress(
type='circle'
width='50'
stroke-width='3'
:percentage='updateProgress'
:format='updateProgressText')
.pending-update(v-else-if='pendingVRCXUpdate || pendingVRCXInstall')
el-button(
type='default'
@click='showVRCXUpdateDialog'
size='mini'
icon='el-icon-download'
circle
style='font-size: 14px; height: 50px; width: 50px')
el-menu(ref="menu" collapse @select="selectMenu")
el-menu(ref='menu' collapse @select='selectMenu')
mixin menuitem(index, name, icon)
el-menu-item(index=index)
i(class=icon)
@@ -44,118 +55,117 @@ html
+menuitem('settings', "{{ $t('nav_tooltip.settings') }}", 'el-icon-s-tools')
//- ### Tabs ###
template(v-if="API.isLoggedIn")
template(v-if='API.isLoggedIn')
//- feed
include ./mixins/tabs/feed.pug
+feedTab()
+feedTab
//- gameLog
include ./mixins/tabs/gameLog.pug
+gameLogTab()
+gameLogTab
//- playerList
include ./mixins/tabs/playerList.pug
+playerListTab()
+playerListTab
//- search
include ./mixins/tabs/search.pug
+searchTab()
+searchTab
//- favorite
include ./mixins/tabs/favorites.pug
+favoritesTab()
+favoritesTab
//- friendLog
include ./mixins/tabs/friendLog.pug
+friendLogTab()
+friendLogTab
//- moderation
moderation-tab(
v-if="$refs.menu?.activeIndex === 'moderation'"
:Api='API'
:table-data='playerModerationTable'
:show-user-dialog='showUserDialog'
:shift-held='shiftHeld')
v-if='$refs.menu?.activeIndex === "moderation"'
:Api='API'
:table-data='playerModerationTable'
:show-user-dialog='showUserDialog'
:shift-held='shiftHeld')
//- notification
include ./mixins/tabs/notifications.pug
+notificationsTab()
+notificationsTab
//- profile
include ./mixins/tabs/profile.pug
+profileTab()
+profileTab
//- friends list
include ./mixins/tabs/friendsList.pug
+friendsListTab()
+friendsListTab
//- settings
include ./mixins/tabs/settings.pug
+settingsTab()
+settingsTab
include ./mixins/friendsListSidebar.pug
+friendsListSidebar()
+friendsListSidebar
//- ## Dialogs ## -\\
include ./mixins/dialogs/userDialog.pug
+userDialog()
+userDialog
include ./mixins/dialogs/worldDialog.pug
+worldDialog()
+worldDialog
include ./mixins/dialogs/avatarDialog.pug
+avatarDialog()
+avatarDialog
include ./mixins/dialogs/groupDialog.pug
+groupDialog()
+groupDialog
include ./mixins/dialogs/favoritesDialog.pug
+favoritesDialog()
+favoritesDialog
include ./mixins/dialogs/images.pug
+images()
+images
include ./mixins/dialogs/newInstance.pug
+newInstance()
+newInstance
include ./mixins/dialogs/feedFilters.pug
+feedFilters()
+feedFilters
include ./mixins/dialogs/openSourceSoftwareNotice.pug
+openSourceSoftwareNotice()
+openSourceSoftwareNotice
include ./mixins/dialogs/groups.pug
+groups()
+groups
include ./mixins/dialogs/currentUser.pug
+currentUser()
+currentUser
include ./mixins/dialogs/invites.pug
+invites()
+invites
include ./mixins/dialogs/launch.pug
+launch()
+launch
include ./mixins/dialogs/screenshotMetadata.pug
+screenshotMetadata()
+screenshotMetadata
include ./mixins/dialogs/vrcx.pug
+vrcx()
+vrcx
include ./mixins/dialogs/settings.pug
+settings()
+settings
include ./mixins/dialogs/previousInstances.pug
+previousInstances()
+previousInstances
include ./mixins/dialogs/tags.pug
+tags()
+tags
include ./mixins/dialogs/boops.pug
+boops()
+boops
//- el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="templateDialog" :visible.sync="templateDialog.visible" :title="$t('dialog.template_dialog.header')" width="450px")
script(src="vendor.js")
script(src="app.js")
script(src='vendor.js')
script(src='app.js')

View File

@@ -1,130 +1,318 @@
mixin avatarDialog()
el-dialog.x-dialog.x-avatar-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="avatarDialog" :visible.sync="avatarDialog.visible" :show-close="false" width="600px")
div(v-loading="avatarDialog.loading")
div(style="display:flex")
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="avatarDialog.ref.thumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:12px")
img.x-link(v-lazy="avatarDialog.ref.imageUrl" style="width:500px;height:375px" @click="showFullscreenImageDialog(avatarDialog.ref.imageUrl)")
div(style="flex:1;display:flex;align-items:center;margin-left:15px")
div(style="flex:1")
mixin avatarDialog
el-dialog.x-dialog.x-avatar-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='avatarDialog'
:visible.sync='avatarDialog.visible'
:show-close='false'
width='600px')
div(v-loading='avatarDialog.loading')
div(style='display: flex')
el-popover(placement='right' width='500px' trigger='click')
img.x-link(
slot='reference'
v-lazy='avatarDialog.ref.thumbnailImageUrl'
style='flex: none; width: 160px; height: 120px; border-radius: 12px')
img.x-link(
v-lazy='avatarDialog.ref.imageUrl'
style='width: 500px; height: 375px'
@click='showFullscreenImageDialog(avatarDialog.ref.imageUrl)')
div(style='flex: 1; display: flex; align-items: center; margin-left: 15px')
div(style='flex: 1')
div
span.dialog-title(v-text="avatarDialog.ref.name")
div(style="margin-top:5px")
span.x-link.x-grey(v-text="avatarDialog.ref.authorName" @click="showUserDialog(avatarDialog.ref.authorId)" style="font-family:monospace")
span.dialog-title(v-text='avatarDialog.ref.name')
div(style='margin-top: 5px')
span.x-link.x-grey(
v-text='avatarDialog.ref.authorName'
@click='showUserDialog(avatarDialog.ref.authorId)'
style='font-family: monospace')
div
el-tag(v-if="avatarDialog.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.avatar.tags.public') }}
el-tag(v-else type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.avatar.tags.private') }}
el-tag.x-tag-platform-pc(v-if="avatarDialog.isPC" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") PC
span.x-grey(v-if="avatarDialog.platformInfo.pc" style=";margin-left:5px;border-left:inherit;padding-left:5px") {{ avatarDialog.platformInfo.pc.performanceRating }}
span.x-grey(v-if="avatarDialog.bundleSizes['standalonewindows']" style=";margin-left:5px;border-left:inherit;padding-left:5px") {{ avatarDialog.bundleSizes['standalonewindows'].fileSize }}
el-tag.x-tag-platform-quest(v-if="avatarDialog.isQuest" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Android
span.x-grey(v-if="avatarDialog.platformInfo.android" style=";margin-left:5px;border-left:inherit;padding-left:5px") {{ avatarDialog.platformInfo.android.performanceRating }}
span.x-grey(v-if="avatarDialog.bundleSizes['android']" style="margin-left:5px;border-left:inherit;padding-left:5px") {{ avatarDialog.bundleSizes['android'].fileSize }}
el-tag.x-tag-platform-ios(v-if="avatarDialog.isIos" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") iOS
span.x-grey(v-if="avatarDialog.platformInfo.ios" style=";margin-left:5px;border-left:inherit;padding-left:5px") {{ avatarDialog.platformInfo.ios.performanceRating }}
span.x-grey(v-if="avatarDialog.bundleSizes['ios']" style="margin-left:5px;border-left:inherit;padding-left:5px") {{ avatarDialog.bundleSizes['ios'].fileSize }}
el-tag.x-link(v-if="avatarDialog.inCache" type="info" effect="plain" size="mini" @click="openFolderGeneric(avatarDialog.cachePath)" style="margin-right:5px;margin-top:5px")
span(v-text="avatarDialog.cacheSize")
| {{ $t('dialog.avatar.tags.cache') }}
el-tag(v-if="avatarDialog.isQuestFallback" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.avatar.tags.fallback') }}
el-tag(v-if="avatarDialog.hasImposter" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.avatar.tags.impostor') }}
span.x-grey(v-if="avatarDialog.imposterVersion" style="margin-left:5px;border-left:inherit;padding-left:5px") v{{ avatarDialog.imposterVersion }}
el-tag(v-if="avatarDialog.ref.unityPackageUrl" type="success" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.avatar.tags.future_proofing') }}
el-tag(
v-if='avatarDialog.ref.releaseStatus === "public"'
type='success'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') {{ $t('dialog.avatar.tags.public') }}
el-tag(
v-else
type='danger'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') {{ $t('dialog.avatar.tags.private') }}
el-tag.x-tag-platform-pc(
v-if='avatarDialog.isPC'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') PC
span.x-grey(
v-if='avatarDialog.platformInfo.pc'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ avatarDialog.platformInfo.pc.performanceRating }}
span.x-grey(
v-if='avatarDialog.bundleSizes["standalonewindows"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ avatarDialog.bundleSizes['standalonewindows'].fileSize }}
el-tag.x-tag-platform-quest(
v-if='avatarDialog.isQuest'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') Android
span.x-grey(
v-if='avatarDialog.platformInfo.android'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ avatarDialog.platformInfo.android.performanceRating }}
span.x-grey(
v-if='avatarDialog.bundleSizes["android"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ avatarDialog.bundleSizes['android'].fileSize }}
el-tag.x-tag-platform-ios(
v-if='avatarDialog.isIos'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') iOS
span.x-grey(
v-if='avatarDialog.platformInfo.ios'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ avatarDialog.platformInfo.ios.performanceRating }}
span.x-grey(
v-if='avatarDialog.bundleSizes["ios"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ avatarDialog.bundleSizes['ios'].fileSize }}
el-tag.x-link(
v-if='avatarDialog.inCache'
type='info'
effect='plain'
size='mini'
@click='openFolderGeneric(avatarDialog.cachePath)'
style='margin-right: 5px; margin-top: 5px')
span(v-text='avatarDialog.cacheSize')
|
| {{ $t('dialog.avatar.tags.cache') }}
el-tag(
v-if='avatarDialog.isQuestFallback'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') {{ $t('dialog.avatar.tags.fallback') }}
el-tag(
v-if='avatarDialog.hasImposter'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') {{ $t('dialog.avatar.tags.impostor') }}
span.x-grey(
v-if='avatarDialog.imposterVersion'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') v{{ avatarDialog.imposterVersion }}
el-tag(
v-if='avatarDialog.ref.unityPackageUrl'
type='success'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') {{ $t('dialog.avatar.tags.future_proofing') }}
div
template(v-for="tag in avatarDialog.ref.tags")
el-tag(v-if="tag.startsWith('content_')" :key="tag" effect="plain" size="mini" style="margin-right:5px;margin-top:5px")
template(v-if="tag === 'content_horror'") {{ $t('dialog.avatar.tags.content_horror') }}
template(v-else-if="tag === 'content_gore'") {{ $t('dialog.avatar.tags.content_gore') }}
template(v-else-if="tag === 'content_violence'") {{ $t('dialog.avatar.tags.content_violence') }}
template(v-else-if="tag === 'content_adult'") {{ $t('dialog.avatar.tags.content_adult') }}
template(v-else-if="tag === 'content_sex'") {{ $t('dialog.avatar.tags.content_sex') }}
template(v-for='tag in avatarDialog.ref.tags')
el-tag(
v-if='tag.startsWith("content_")'
:key='tag'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px')
template(v-if='tag === "content_horror"') {{ $t('dialog.avatar.tags.content_horror') }}
template(v-else-if='tag === "content_gore"') {{ $t('dialog.avatar.tags.content_gore') }}
template(v-else-if='tag === "content_violence"') {{ $t('dialog.avatar.tags.content_violence') }}
template(v-else-if='tag === "content_adult"') {{ $t('dialog.avatar.tags.content_adult') }}
template(v-else-if='tag === "content_sex"') {{ $t('dialog.avatar.tags.content_sex') }}
template(v-else) {{ tag.replace('content_', '') }}
div(style="margin-top:5px")
span(v-show="avatarDialog.ref.name !== avatarDialog.ref.description" v-text="avatarDialog.ref.description" style="font-size:12px")
div(style="flex:none;margin-left:10px")
el-tooltip(v-if="avatarDialog.inCache" placement="top" :content="$t('dialog.avatar.actions.delete_cache_tooltip')" :disabled="hideTooltips")
el-button(icon="el-icon-delete" circle @click="deleteVRChatCache(avatarDialog.ref)" :disabled="isGameRunning && avatarDialog.cacheLocked")
el-tooltip(v-if="avatarDialog.isFavorite" placement="top" :content="$t('dialog.avatar.actions.favorite_tooltip')" :disabled="hideTooltips")
el-button(type="warning" icon="el-icon-star-on" circle @click="avatarDialogCommand('Add Favorite')" style="margin-left:5px")
el-tooltip(v-else placement="top" :content="$t('dialog.avatar.actions.favorite_tooltip')" :disabled="hideTooltips")
el-button(type="default" icon="el-icon-star-off" circle @click="avatarDialogCommand('Add Favorite')" style="margin-left:5px")
el-dropdown(trigger="click" @command="avatarDialogCommand" size="small" style="margin-left:5px")
el-button(:type="avatarDialog.isBlocked ? 'danger' : 'default'" icon="el-icon-more" circle)
el-dropdown-menu(#default="dropdown")
el-dropdown-item(icon="el-icon-refresh" command="Refresh") {{ $t('dialog.avatar.actions.refresh') }}
el-dropdown-item(icon="el-icon-check" :disabled="API.currentUser.currentAvatar === avatarDialog.id" command="Select Avatar") {{ $t('dialog.avatar.actions.select') }}
el-dropdown-item(v-if="/quest/.test(avatarDialog.ref.tags)" icon="el-icon-check" command="Select Fallback Avatar") {{ $t('dialog.avatar.actions.select_fallback') }}
el-dropdown-item(v-if="avatarDialog.isBlocked" icon="el-icon-circle-check" command="Unblock Avatar" style="color:#F56C6C") {{ $t('dialog.avatar.actions.unblock') }}
el-dropdown-item(v-else icon="el-icon-circle-close" command="Block Avatar") {{ $t('dialog.avatar.actions.block') }}
el-dropdown-item(v-if="avatarDialog.ref.authorId !== API.currentUser.id" icon="el-icon-picture-outline" command="Previous Images") {{ $t('dialog.avatar.actions.show_previous_images') }}
template(v-if="avatarDialog.ref.authorId === API.currentUser.id")
el-dropdown-item(v-if="avatarDialog.ref.releaseStatus === 'public'" icon="el-icon-user-solid" command="Make Private" divided) {{ $t('dialog.avatar.actions.make_private') }}
el-dropdown-item(v-else icon="el-icon-user" command="Make Public" divided) {{ $t('dialog.avatar.actions.make_public') }}
el-dropdown-item(icon="el-icon-edit" command="Rename") {{ $t('dialog.avatar.actions.rename') }}
el-dropdown-item(icon="el-icon-edit" command="Change Description") {{ $t('dialog.avatar.actions.change_description') }}
el-dropdown-item(icon="el-icon-edit" command="Change Content Tags") {{ $t('dialog.avatar.actions.change_content_tags') }}
el-dropdown-item(icon="el-icon-picture-outline" command="Change Image") {{ $t('dialog.avatar.actions.change_image') }}
el-dropdown-item(v-if="avatarDialog.ref.unityPackageUrl" icon="el-icon-download" command="Download Unity Package") {{ $t('dialog.avatar.actions.download_package') }}
el-dropdown-item(v-if="avatarDialog.hasImposter" icon="el-icon-refresh" command="Regenerate Imposter" style="color:#F56C6C") {{ $t('dialog.avatar.actions.regenerate_impostor') }}
el-dropdown-item(v-if="avatarDialog.hasImposter" icon="el-icon-delete" command="Delete Imposter" style="color:#F56C6C") {{ $t('dialog.avatar.actions.delete_impostor') }}
el-dropdown-item(v-else icon="el-icon-user" command="Create Imposter") {{ $t('dialog.avatar.actions.create_impostor') }}
el-dropdown-item(icon="el-icon-delete" command="Delete" style="color:#F56C6C" divided) {{ $t('dialog.avatar.actions.delete') }}
div(style='margin-top: 5px')
span(
v-show='avatarDialog.ref.name !== avatarDialog.ref.description'
v-text='avatarDialog.ref.description'
style='font-size: 12px')
div(style='flex: none; margin-left: 10px')
el-tooltip(
v-if='avatarDialog.inCache'
placement='top'
:content='$t("dialog.avatar.actions.delete_cache_tooltip")'
:disabled='hideTooltips')
el-button(
icon='el-icon-delete'
circle
@click='deleteVRChatCache(avatarDialog.ref)'
:disabled='isGameRunning && avatarDialog.cacheLocked')
el-tooltip(
v-if='avatarDialog.isFavorite'
placement='top'
:content='$t("dialog.avatar.actions.favorite_tooltip")'
:disabled='hideTooltips')
el-button(
type='warning'
icon='el-icon-star-on'
circle
@click='avatarDialogCommand("Add Favorite")'
style='margin-left: 5px')
el-tooltip(
v-else
placement='top'
:content='$t("dialog.avatar.actions.favorite_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
icon='el-icon-star-off'
circle
@click='avatarDialogCommand("Add Favorite")'
style='margin-left: 5px')
el-dropdown(
trigger='click'
@command='avatarDialogCommand'
size='small'
style='margin-left: 5px')
el-button(:type='avatarDialog.isBlocked ? "danger" : "default"' icon='el-icon-more' circle)
el-dropdown-menu(#default='dropdown')
el-dropdown-item(icon='el-icon-refresh' command='Refresh') {{ $t('dialog.avatar.actions.refresh') }}
el-dropdown-item(
icon='el-icon-check'
:disabled='API.currentUser.currentAvatar === avatarDialog.id'
command='Select Avatar') {{ $t('dialog.avatar.actions.select') }}
el-dropdown-item(
v-if='/quest/.test(avatarDialog.ref.tags)'
icon='el-icon-check'
command='Select Fallback Avatar') {{ $t('dialog.avatar.actions.select_fallback') }}
el-dropdown-item(
v-if='avatarDialog.isBlocked'
icon='el-icon-circle-check'
command='Unblock Avatar'
style='color: #f56c6c') {{ $t('dialog.avatar.actions.unblock') }}
el-dropdown-item(v-else icon='el-icon-circle-close' command='Block Avatar') {{ $t('dialog.avatar.actions.block') }}
el-dropdown-item(
v-if='avatarDialog.ref.authorId !== API.currentUser.id'
icon='el-icon-picture-outline'
command='Previous Images') {{ $t('dialog.avatar.actions.show_previous_images') }}
template(v-if='avatarDialog.ref.authorId === API.currentUser.id')
el-dropdown-item(
v-if='avatarDialog.ref.releaseStatus === "public"'
icon='el-icon-user-solid'
command='Make Private'
divided) {{ $t('dialog.avatar.actions.make_private') }}
el-dropdown-item(v-else icon='el-icon-user' command='Make Public' divided) {{ $t('dialog.avatar.actions.make_public') }}
el-dropdown-item(icon='el-icon-edit' command='Rename') {{ $t('dialog.avatar.actions.rename') }}
el-dropdown-item(icon='el-icon-edit' command='Change Description') {{ $t('dialog.avatar.actions.change_description') }}
el-dropdown-item(icon='el-icon-edit' command='Change Content Tags') {{ $t('dialog.avatar.actions.change_content_tags') }}
el-dropdown-item(icon='el-icon-picture-outline' command='Change Image') {{ $t('dialog.avatar.actions.change_image') }}
el-dropdown-item(
v-if='avatarDialog.ref.unityPackageUrl'
icon='el-icon-download'
command='Download Unity Package') {{ $t('dialog.avatar.actions.download_package') }}
el-dropdown-item(
v-if='avatarDialog.hasImposter'
icon='el-icon-refresh'
command='Regenerate Imposter'
style='color: #f56c6c') {{ $t('dialog.avatar.actions.regenerate_impostor') }}
el-dropdown-item(
v-if='avatarDialog.hasImposter'
icon='el-icon-delete'
command='Delete Imposter'
style='color: #f56c6c') {{ $t('dialog.avatar.actions.delete_impostor') }}
el-dropdown-item(v-else icon='el-icon-user' command='Create Imposter') {{ $t('dialog.avatar.actions.create_impostor') }}
el-dropdown-item(
icon='el-icon-delete'
command='Delete'
style='color: #f56c6c'
divided) {{ $t('dialog.avatar.actions.delete') }}
el-tabs
el-tab-pane(:label="$t('dialog.avatar.info.header')")
el-tab-pane(:label='$t("dialog.avatar.info.header")')
.x-friend-list
.x-friend-item(style="width:100%;cursor:default")
.detail
span.name(style="margin-bottom:5px") {{ $t('dialog.avatar.info.memo') }}
el-input.extra(v-model="avatarDialog.memo" @change="onAvatarMemoChange" size="mini" type="textarea" :rows="2" :autosize="{minRows: 1, maxRows: 20}" :placeholder="$t('dialog.avatar.info.memo_placeholder')" resize="none")
.x-friend-item(style="width:100%;cursor:default")
.x-friend-item(style='width: 100%; cursor: default')
.detail
span.name(style='margin-bottom: 5px') {{ $t('dialog.avatar.info.memo') }}
el-input.extra(
v-model='avatarDialog.memo'
@change='onAvatarMemoChange'
size='mini'
type='textarea'
:rows='2'
:autosize='{ minRows: 1, maxRows: 20 }'
:placeholder='$t("dialog.avatar.info.memo_placeholder")'
resize='none')
.x-friend-item(style='width: 100%; cursor: default')
.detail
span.name {{ $t('dialog.avatar.info.id') }}
span.extra {{ avatarDialog.id }}
el-tooltip(placement="top" :content="$t('dialog.avatar.info.id_tooltip')" :disabled="hideTooltips")
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
el-button(type="default" icon="el-icon-s-order" size="mini" circle)
el-dropdown-menu(#default="dropdown")
el-dropdown-item(@click.native="copyAvatarId(avatarDialog.id)") {{ $t('dialog.avatar.info.copy_id') }}
el-dropdown-item(@click.native="copyAvatarUrl(avatarDialog.id)") {{ $t('dialog.avatar.info.copy_url') }}
.x-friend-item(style="cursor:default")
el-tooltip(
placement='top'
:content='$t("dialog.avatar.info.id_tooltip")'
:disabled='hideTooltips')
el-dropdown(
trigger='click'
@click.native.stop
size='mini'
style='margin-left: 5px')
el-button(type='default' icon='el-icon-s-order' size='mini' circle)
el-dropdown-menu(#default='dropdown')
el-dropdown-item(@click.native='copyAvatarId(avatarDialog.id)') {{ $t('dialog.avatar.info.copy_id') }}
el-dropdown-item(@click.native='copyAvatarUrl(avatarDialog.id)') {{ $t('dialog.avatar.info.copy_url') }}
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.avatar.info.created_at') }}
span.extra {{ avatarDialog.ref.created_at | formatDate('long') }}
.x-friend-item(style="cursor:default")
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.avatar.info.last_updated') }}
span.extra(v-if="avatarDialog.lastUpdated") {{ avatarDialog.lastUpdated | formatDate('long') }}
span.extra(v-if='avatarDialog.lastUpdated') {{ avatarDialog.lastUpdated | formatDate('long') }}
span.extra(v-else) {{ avatarDialog.ref.updated_at | formatDate('long') }}
.x-friend-item(style="cursor:default")
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.avatar.info.version') }}
span.extra(v-if="avatarDialog.ref.version !== 0" v-text="avatarDialog.ref.version")
span.extra(v-if='avatarDialog.ref.version !== 0' v-text='avatarDialog.ref.version')
span.extra(v-else) -
.x-friend-item(style="cursor:default")
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.avatar.info.time_spent') }}
el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.world.info.accuracy_notice')")
el-tooltip(
v-if='!hideTooltips'
placement='top'
style='margin-left: 5px'
:content='$t("dialog.world.info.accuracy_notice")')
i.el-icon-warning
span.extra(v-if="avatarDialog.timeSpent === 0") -
span.extra(v-if='avatarDialog.timeSpent === 0') -
span.extra(v-else) {{ timeToText(avatarDialog.timeSpent) }}
.x-friend-item(style="width:100%;cursor:default")
.x-friend-item(style='width: 100%; cursor: default')
.detail
span.name {{ $t('dialog.avatar.info.platform') }}
span.extra(v-if="avatarDialogPlatform" v-text="avatarDialogPlatform")
span.extra(v-if='avatarDialogPlatform' v-text='avatarDialogPlatform')
span.extra(v-else) -
el-tab-pane(:label="$t('dialog.avatar.json.header')")
el-button(type="default" @click="refreshAvatarDialogTreeData()" size="mini" icon="el-icon-refresh" circle)
el-tooltip(placement="top" :content="$t('dialog.avatar.json.file_analysis')" :disabled="hideTooltips")
el-button(type="default" @click="getAvatarFileAnalysis" size="mini" icon="el-icon-s-data" circle style="margin-left:5px")
el-button(type="default" @click="downloadAndSaveJson(avatarDialog.id, avatarDialog.ref)" size="mini" icon="el-icon-download" circle style="margin-left:5px")
el-tree(v-if="Object.keys(avatarDialog.fileAnalysis).length > 0" :data="avatarDialog.fileAnalysis" style="margin-top:5px;font-size:12px")
template(#default="scope")
el-tab-pane(:label='$t("dialog.avatar.json.header")')
el-button(
type='default'
@click='refreshAvatarDialogTreeData()'
size='mini'
icon='el-icon-refresh'
circle)
el-tooltip(
placement='top'
:content='$t("dialog.avatar.json.file_analysis")'
:disabled='hideTooltips')
el-button(
type='default'
@click='getAvatarFileAnalysis'
size='mini'
icon='el-icon-s-data'
circle
style='margin-left: 5px')
el-button(
type='default'
@click='downloadAndSaveJson(avatarDialog.id, avatarDialog.ref)'
size='mini'
icon='el-icon-download'
circle
style='margin-left: 5px')
el-tree(
v-if='Object.keys(avatarDialog.fileAnalysis).length > 0'
:data='avatarDialog.fileAnalysis'
style='margin-top: 5px; font-size: 12px')
template(#default='scope')
span
span(v-text="scope.data.key" style="font-weight:bold;margin-right:5px")
span(v-if="!scope.data.children" v-text="scope.data.value")
el-tree(:data="avatarDialog.treeData" style="margin-top:5px;font-size:12px")
template(#default="scope")
span(v-text='scope.data.key' style='font-weight: bold; margin-right: 5px')
span(v-if='!scope.data.children' v-text='scope.data.value')
el-tree(:data='avatarDialog.treeData' style='margin-top: 5px; font-size: 12px')
template(#default='scope')
span
span(v-text="scope.data.key" style="font-weight:bold;margin-right:5px")
span(v-if="!scope.data.children" v-text="scope.data.value")
span(v-text='scope.data.key' style='font-weight: bold; margin-right: 5px')
span(v-if='!scope.data.children' v-text='scope.data.value')

View File

@@ -1,53 +1,104 @@
mixin boops()
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="sendBoopDialog" :visible.sync="sendBoopDialog.visible" :title="$t('dialog.boop_dialog.header')" width="450px")
div(v-if="sendBoopDialog.visible")
el-select(v-model="sendBoopDialog.userId" :placeholder="$t('dialog.new_instance.instance_creator_placeholder')" filterable style="width:100%")
el-option-group(v-if="vipFriends.length" :label="$t('side_panel.favorite')")
el-option.x-friend-item(v-for="friend in vipFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
mixin boops
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='sendBoopDialog'
:visible.sync='sendBoopDialog.visible'
:title='$t("dialog.boop_dialog.header")'
width='450px')
div(v-if='sendBoopDialog.visible')
el-select(
v-model='sendBoopDialog.userId'
:placeholder='$t("dialog.new_instance.instance_creator_placeholder")'
filterable
style='width: 100%')
el-option-group(v-if='vipFriends.length' :label='$t("side_panel.favorite")')
el-option.x-friend-item(
v-for='friend in vipFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar(:class='userStatusClass(friend.ref)')
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="onlineFriends.length" :label="$t('side_panel.online')")
el-option.x-friend-item(v-for="friend in onlineFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
span.name(v-text='friend.ref.displayName' :style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='onlineFriends.length' :label='$t("side_panel.online")')
el-option.x-friend-item(
v-for='friend in onlineFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar(:class='userStatusClass(friend.ref)')
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="activeFriends.length" :label="$t('side_panel.active')")
el-option.x-friend-item(v-for="friend in activeFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
span.name(v-text='friend.ref.displayName' :style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='activeFriends.length' :label='$t("side_panel.active")')
el-option.x-friend-item(
v-for='friend in activeFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar
img(v-lazy="userImage(friend.ref)")
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="offlineFriends.length" :label="$t('side_panel.offline')")
el-option.x-friend-item(v-for="friend in offlineFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
span.name(v-text='friend.ref.displayName' :style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='offlineFriends.length' :label='$t("side_panel.offline")')
el-option.x-friend-item(
v-for='friend in offlineFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar
img(v-lazy="userImage(friend.ref)")
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
span.name(v-text='friend.ref.displayName' :style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
br
br
el-select(v-model="sendBoopDialog.fileId" clearable :placeholder="$t('dialog.boop_dialog.select_emoji')" size="small" style="width:100%" popper-class="max-height-el-select")
el-option-group(:label="$t('dialog.boop_dialog.my_emojis')")
el-option(v-if="image.versions && image.versions.length > 0" v-for="image in emojiTable" :key="image.id" :value="image.id" style="width:100%;height:100%")
.vrcplus-icon(v-if="image.versions[image.versions.length - 1].file.url" style="overflow:hidden;width:200px;height:200px;padding:10px")
template(v-if="image.frames")
.avatar(:style="generateEmojiStyle(image.versions[image.versions.length - 1].file.url, image.framesOverTime, image.frames, image.loopStyle)")
el-select(
v-model='sendBoopDialog.fileId'
clearable
:placeholder='$t("dialog.boop_dialog.select_emoji")'
size='small'
style='width: 100%'
popper-class='max-height-el-select')
el-option-group(:label='$t("dialog.boop_dialog.my_emojis")')
el-option(
v-if='image.versions && image.versions.length > 0'
v-for='image in emojiTable'
:key='image.id'
:value='image.id'
style='width: 100%; height: 100%')
.vrcplus-icon(
v-if='image.versions[image.versions.length - 1].file.url'
style='overflow: hidden; width: 200px; height: 200px; padding: 10px')
template(v-if='image.frames')
.avatar(
:style='generateEmojiStyle(image.versions[image.versions.length - 1].file.url, image.framesOverTime, image.frames, image.loopStyle)')
template(v-else)
img.avatar(v-lazy="image.versions[image.versions.length - 1].file.url" style="width:200px;height:200px")
el-option-group(:label="$t('dialog.boop_dialog.default_emojis')")
el-option(v-for="emojiName in photonEmojis" :key="emojiName" :value="getEmojiValue(emojiName)" style="width:100%;height:100%")
span(v-text="emojiName")
img.avatar(
v-lazy='image.versions[image.versions.length - 1].file.url'
style='width: 200px; height: 200px')
el-option-group(:label='$t("dialog.boop_dialog.default_emojis")')
el-option(
v-for='emojiName in photonEmojis'
:key='emojiName'
:value='getEmojiValue(emojiName)'
style='width: 100%; height: 100%')
span(v-text='emojiName')
template(#footer)
el-button(size="small" @click="showGalleryDialog(2)") {{ $t('dialog.boop_dialog.emoji_manager') }}
el-button(size="small" @click="sendBoopDialog.visible = false") {{ $t('dialog.boop_dialog.cancel') }}
el-button(size="small" @click="sendBoop" :disabled="!sendBoopDialog.userId") {{ $t('dialog.boop_dialog.send') }}
el-button(size='small' @click='showGalleryDialog(2)') {{ $t('dialog.boop_dialog.emoji_manager') }}
el-button(size='small' @click='sendBoopDialog.visible = false') {{ $t('dialog.boop_dialog.cancel') }}
el-button(size='small' @click='sendBoop' :disabled='!sendBoopDialog.userId') {{ $t('dialog.boop_dialog.send') }}

View File

@@ -1,189 +1,445 @@
mixin currentUser()
mixin currentUser
//- dialog: social status
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="socialStatusDialog" :visible.sync="socialStatusDialog.visible" :title="$t('dialog.social_status.header')" width="400px")
div(v-loading="socialStatusDialog.loading")
el-collapse(style="border:0")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='socialStatusDialog'
:visible.sync='socialStatusDialog.visible'
:title='$t("dialog.social_status.header")'
width='400px')
div(v-loading='socialStatusDialog.loading')
el-collapse(style='border: 0')
el-collapse-item
template(slot="title")
span(style="font-size:16px") {{ $t('dialog.social_status.history') }}
data-tables(v-bind="socialStatusHistoryTable" @row-click="setSocialStatusFromHistory" style="cursor:pointer")
el-table-column(:label="$t('table.social_status.no')" prop="no" width="50")
el-table-column(:label="$t('table.social_status.status')" prop="status")
el-select(v-model="socialStatusDialog.status" style="display:block;margin-top:10px")
el-option(:label="$t('dialog.user.status.join_me')" value="join me").
template(slot='title')
span(style='font-size: 16px') {{ $t('dialog.social_status.history') }}
data-tables(
v-bind='socialStatusHistoryTable'
@row-click='setSocialStatusFromHistory'
style='cursor: pointer')
el-table-column(:label='$t("table.social_status.no")' prop='no' width='50')
el-table-column(:label='$t("table.social_status.status")' prop='status')
el-select(v-model='socialStatusDialog.status' style='display: block; margin-top: 10px')
el-option(:label='$t("dialog.user.status.join_me")' value='join me').
#[i.x-user-status.joinme] {{ $t('dialog.user.status.join_me') }}
el-option(:label="$t('dialog.user.status.online')" value="active").
el-option(:label='$t("dialog.user.status.online")' value='active').
#[i.x-user-status.online] {{ $t('dialog.user.status.online') }}
el-option(:label="$t('dialog.user.status.ask_me')" value="ask me").
el-option(:label='$t("dialog.user.status.ask_me")' value='ask me').
#[i.x-user-status.askme] {{ $t('dialog.user.status.ask_me') }}
el-option(:label="$t('dialog.user.status.busy')" value="busy").
el-option(:label='$t("dialog.user.status.busy")' value='busy').
#[i.x-user-status.busy] {{ $t('dialog.user.status.busy') }}
el-option(v-if="API.currentUser.$isModerator" :label="$t('dialog.user.status.offline')" value="offline").
el-option(
v-if='API.currentUser.$isModerator'
:label='$t("dialog.user.status.offline")'
value='offline').
#[i.x-user-status.offline] {{ $t('dialog.user.status.offline') }}
el-input(v-model="socialStatusDialog.statusDescription" :placeholder="$t('dialog.social_status.status_placeholder')" maxlength="32" show-word-limit style="display:block;margin-top:10px")
el-input(
v-model='socialStatusDialog.statusDescription'
:placeholder='$t("dialog.social_status.status_placeholder")'
maxlength='32'
show-word-limit
style='display: block; margin-top: 10px')
template(#footer)
el-button(type="primary" size="small" :disabled="socialStatusDialog.loading" @click="saveSocialStatus") {{ $t('dialog.social_status.update') }}
el-button(type='primary' size='small' :disabled='socialStatusDialog.loading' @click='saveSocialStatus') {{ $t('dialog.social_status.update') }}
//- dialog: language
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="languageDialog" :visible.sync="languageDialog.visible" :title="$t('dialog.language.header')" width="400px")
div(v-loading="languageDialog.loading")
div(style="margin:5px 0")
el-tag(v-for="item in API.currentUser.$languages" :key="item.key" size="small" type="info" effect="plain" closable @close="removeUserLanguage(item.key)" style="margin-right:5px")
span.flags(:class="languageClass(item.key)" style="display:inline-block;margin-right:5px")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='languageDialog'
:visible.sync='languageDialog.visible'
:title='$t("dialog.language.header")'
width='400px')
div(v-loading='languageDialog.loading')
div(style='margin: 5px 0')
el-tag(
v-for='item in API.currentUser.$languages'
:key='item.key'
size='small'
type='info'
effect='plain'
closable
@close='removeUserLanguage(item.key)'
style='margin-right: 5px')
span.flags(:class='languageClass(item.key)' style='display: inline-block; margin-right: 5px')
| {{ item.value }} ({{ item.key }})
div(v-if="languageDialog.languageChoice === true")
el-select(v-model="languageDialog.languageValue" :placeholder="$t('dialog.language.select_language')" size="mini")
el-option(v-for="item in languageDialog.languages" :key="item.key" :value="item.key" :label="item.value")
span.flags(:class="languageClass(item.key)" style="display:inline-block;margin-right:5px")
div(v-if='languageDialog.languageChoice === true')
el-select(
v-model='languageDialog.languageValue'
:placeholder='$t("dialog.language.select_language")'
size='mini')
el-option(
v-for='item in languageDialog.languages'
:key='item.key'
:value='item.key'
:label='item.value')
span.flags(:class='languageClass(item.key)' style='display: inline-block; margin-right: 5px')
| {{ item.value }} ({{ item.key }})
el-button(@click="languageDialog.languageChoice=false; addUserLanguage(languageDialog.languageValue)" size="mini") {{ $t('dialog.language.ok') }}
el-button(@click="languageDialog.languageChoice=false" size="mini" style="margin-left:0") {{ $t('dialog.language.cancel') }}
el-button(
@click='languageDialog.languageChoice = false; addUserLanguage(languageDialog.languageValue)'
size='mini') {{ $t('dialog.language.ok') }}
el-button(@click='languageDialog.languageChoice = false' size='mini' style='margin-left: 0') {{ $t('dialog.language.cancel') }}
div(v-else)
el-button(@click="languageDialog.languageValue='';languageDialog.languageChoice=true" size="mini") {{ $t('dialog.language.add_language') }}
el-button(@click='languageDialog.languageValue = ""; languageDialog.languageChoice = true' size='mini') {{ $t('dialog.language.add_language') }}
//- dialog: bio
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="bioDialog" :visible.sync="bioDialog.visible" :title="$t('dialog.bio.header')" width="600px")
div(v-loading="bioDialog.loading")
el-input(type="textarea" v-model="bioDialog.bio" size="mini" maxlength="512" show-word-limit :autosize="{ minRows:2, maxRows:5 }" :placeholder="$t('dialog.bio.bio_placeholder')")
el-input(v-for="(link, index) in bioDialog.bioLinks" :key="index" :value="link" v-model="bioDialog.bioLinks[index]" size="small" style="margin-top:5px")
img(slot="prepend" :src="getFaviconUrl(link)" style="width:16px;height:16px")
el-button(slot="append" icon="el-icon-delete" @click="bioDialog.bioLinks.splice(index, 1)")
el-button(@click="bioDialog.bioLinks.push('')" :disabled="bioDialog.bioLinks.length >= 3" size="mini" style="margin-top:5px") {{ $t('dialog.bio.add_link') }}
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='bioDialog'
:visible.sync='bioDialog.visible'
:title='$t("dialog.bio.header")'
width='600px')
div(v-loading='bioDialog.loading')
el-input(
type='textarea'
v-model='bioDialog.bio'
size='mini'
maxlength='512'
show-word-limit
:autosize='{ minRows: 2, maxRows: 5 }'
:placeholder='$t("dialog.bio.bio_placeholder")')
el-input(
v-for='(link, index) in bioDialog.bioLinks'
:key='index'
:value='link'
v-model='bioDialog.bioLinks[index]'
size='small'
style='margin-top: 5px')
img(slot='prepend' :src='getFaviconUrl(link)' style='width: 16px; height: 16px')
el-button(slot='append' icon='el-icon-delete' @click='bioDialog.bioLinks.splice(index, 1)')
el-button(
@click='bioDialog.bioLinks.push("")'
:disabled='bioDialog.bioLinks.length >= 3'
size='mini'
style='margin-top: 5px') {{ $t('dialog.bio.add_link') }}
template(#footer)
el-button(type="primary" size="small" :disabled="bioDialog.loading" @click="saveBio") {{ $t('dialog.bio.update') }}
el-button(type='primary' size='small' :disabled='bioDialog.loading' @click='saveBio') {{ $t('dialog.bio.update') }}
//- dialog: pronouns
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="pronounsDialog" :visible.sync="pronounsDialog.visible" :title="$t('dialog.pronouns.header')" width="600px")
div(v-loading="pronounsDialog.loading")
el-input(type="textarea" v-model="pronounsDialog.pronouns" size="mini" maxlength="32" show-word-limit :autosize="{ minRows:2, maxRows:5 }" :placeholder="$t('dialog.pronouns.pronouns_placeholder')")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='pronounsDialog'
:visible.sync='pronounsDialog.visible'
:title='$t("dialog.pronouns.header")'
width='600px')
div(v-loading='pronounsDialog.loading')
el-input(
type='textarea'
v-model='pronounsDialog.pronouns'
size='mini'
maxlength='32'
show-word-limit
:autosize='{ minRows: 2, maxRows: 5 }'
:placeholder='$t("dialog.pronouns.pronouns_placeholder")')
template(#footer)
el-button(type="primary" size="small" :disabled="pronounsDialog.loading" @click="savePronouns") {{ $t('dialog.pronouns.update') }}
el-button(type='primary' size='small' :disabled='pronounsDialog.loading' @click='savePronouns') {{ $t('dialog.pronouns.update') }}
//- dialog: Gallery/VRCPlusIcons
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="galleryDialog" :visible.sync="galleryDialogVisible" :title="$t('dialog.gallery_icons.header')" width="100%")
el-tabs(type="card" ref="galleryTabs")
el-tab-pane(v-if="galleryDialogVisible" v-loading="galleryDialogGalleryLoading")
span(slot="label") {{ $t('dialog.gallery_icons.gallery') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ galleryTable.length }}/64
input(type="file" accept="image/*" @change="onFileChangeGallery" id="GalleryUploadButton" style="display:none")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='galleryDialog'
:visible.sync='galleryDialogVisible'
:title='$t("dialog.gallery_icons.header")'
width='100%')
el-tabs(type='card' ref='galleryTabs')
el-tab-pane(v-if='galleryDialogVisible' v-loading='galleryDialogGalleryLoading')
span(slot='label') {{ $t('dialog.gallery_icons.gallery') }}
span(style='color: #909399; font-size: 12px; margin-left: 5px') {{ galleryTable.length }}/64
input#GalleryUploadButton(
type='file'
accept='image/*'
@change='onFileChangeGallery'
style='display: none')
span {{ $t('dialog.gallery_icons.recommended_image_size') }}: 1200x900px (4:3)
br
br
el-button-group
el-button(type="default" size="small" @click="refreshGalleryTable" icon="el-icon-refresh") {{ $t('dialog.gallery_icons.refresh') }}
el-button(type="default" size="small" @click="displayGalleryUpload" icon="el-icon-upload2" :disabled="!API.currentUser.$isVRCPlus") {{ $t('dialog.gallery_icons.upload') }}
el-button(type="default" size="small" @click="setProfilePicOverride('')" icon="el-icon-close" :disabled="!API.currentUser.profilePicOverride") {{ $t('dialog.gallery_icons.clear') }}
el-button(type='default' size='small' @click='refreshGalleryTable' icon='el-icon-refresh') {{ $t('dialog.gallery_icons.refresh') }}
el-button(
type='default'
size='small'
@click='displayGalleryUpload'
icon='el-icon-upload2'
:disabled='!API.currentUser.$isVRCPlus') {{ $t('dialog.gallery_icons.upload') }}
el-button(
type='default'
size='small'
@click='setProfilePicOverride("")'
icon='el-icon-close'
:disabled='!API.currentUser.profilePicOverride') {{ $t('dialog.gallery_icons.clear') }}
br
.x-friend-item(v-if="image.versions && image.versions.length > 0" v-for="image in galleryTable" :key="image.id" style="display:inline-block;margin-top:10px;width:unset;cursor:default")
.vrcplus-icon(v-if="image.versions[image.versions.length - 1].file.url" @click="setProfilePicOverride(image.id)" :class="{ 'current-vrcplus-icon': compareCurrentProfilePic(image.id) }")
img.avatar(v-lazy="image.versions[image.versions.length - 1].file.url")
div(style="float:right;margin-top:5px")
el-button(type="default" @click="showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url)" size="mini" icon="el-icon-picture-outline" circle)
el-button(type="default" @click="deleteGalleryImage(image.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
el-tab-pane(v-if="galleryDialogVisible" v-loading="galleryDialogIconsLoading")
span(slot="label") {{ $t('dialog.gallery_icons.icons') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ VRCPlusIconsTable.length }}/64
input(type="file" accept="image/*" @change="onFileChangeVRCPlusIcon" id="VRCPlusIconUploadButton" style="display:none")
.x-friend-item(
v-if='image.versions && image.versions.length > 0'
v-for='image in galleryTable'
:key='image.id'
style='display: inline-block; margin-top: 10px; width: unset; cursor: default')
.vrcplus-icon(
v-if='image.versions[image.versions.length - 1].file.url'
@click='setProfilePicOverride(image.id)'
:class='{ "current-vrcplus-icon": compareCurrentProfilePic(image.id) }')
img.avatar(v-lazy='image.versions[image.versions.length - 1].file.url')
div(style='float: right; margin-top: 5px')
el-button(
type='default'
@click='showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url)'
size='mini'
icon='el-icon-picture-outline'
circle)
el-button(
type='default'
@click='deleteGalleryImage(image.id)'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
el-tab-pane(v-if='galleryDialogVisible' v-loading='galleryDialogIconsLoading')
span(slot='label') {{ $t('dialog.gallery_icons.icons') }}
span(style='color: #909399; font-size: 12px; margin-left: 5px') {{ VRCPlusIconsTable.length }}/64
input#VRCPlusIconUploadButton(
type='file'
accept='image/*'
@change='onFileChangeVRCPlusIcon'
style='display: none')
span {{ $t('dialog.gallery_icons.recommended_image_size') }}: 2048x2048px (1:1)
br
br
el-button-group
el-button(type="default" size="small" @click="refreshVRCPlusIconsTable" icon="el-icon-refresh") {{ $t('dialog.gallery_icons.refresh') }}
el-button(type="default" size="small" @click="displayVRCPlusIconUpload" icon="el-icon-upload2" :disabled="!API.currentUser.$isVRCPlus") {{ $t('dialog.gallery_icons.upload') }}
el-button(type="default" size="small" @click="setVRCPlusIcon('')" icon="el-icon-close" :disabled="!API.currentUser.userIcon") {{ $t('dialog.gallery_icons.clear') }}
el-button(type='default' size='small' @click='refreshVRCPlusIconsTable' icon='el-icon-refresh') {{ $t('dialog.gallery_icons.refresh') }}
el-button(
type='default'
size='small'
@click='displayVRCPlusIconUpload'
icon='el-icon-upload2'
:disabled='!API.currentUser.$isVRCPlus') {{ $t('dialog.gallery_icons.upload') }}
el-button(
type='default'
size='small'
@click='setVRCPlusIcon("")'
icon='el-icon-close'
:disabled='!API.currentUser.userIcon') {{ $t('dialog.gallery_icons.clear') }}
br
.x-friend-item(v-if="image.versions && image.versions.length > 0" v-for="image in VRCPlusIconsTable" :key="image.id" style="display:inline-block;margin-top:10px;width:unset;cursor:default")
.vrcplus-icon(v-if="image.versions[image.versions.length - 1].file.url" @click="setVRCPlusIcon(image.id)" :class="{ 'current-vrcplus-icon': compareCurrentVRCPlusIcon(image.id) }")
img.avatar(v-lazy="image.versions[image.versions.length - 1].file.url")
div(style="float:right;margin-top:5px")
el-button(type="default" @click="showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url)" size="mini" icon="el-icon-picture-outline" circle)
el-button(type="default" @click="deleteVRCPlusIcon(image.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
el-tab-pane(v-if="galleryDialogVisible" v-loading="galleryDialogEmojisLoading")
span(slot="label") {{ $t('dialog.gallery_icons.emojis') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ emojiTable.length }}/9
input(type="file" accept="image/*" @change="onFileChangeEmoji" id="EmojiUploadButton" style="display:none")
.x-friend-item(
v-if='image.versions && image.versions.length > 0'
v-for='image in VRCPlusIconsTable'
:key='image.id'
style='display: inline-block; margin-top: 10px; width: unset; cursor: default')
.vrcplus-icon(
v-if='image.versions[image.versions.length - 1].file.url'
@click='setVRCPlusIcon(image.id)'
:class='{ "current-vrcplus-icon": compareCurrentVRCPlusIcon(image.id) }')
img.avatar(v-lazy='image.versions[image.versions.length - 1].file.url')
div(style='float: right; margin-top: 5px')
el-button(
type='default'
@click='showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url)'
size='mini'
icon='el-icon-picture-outline'
circle)
el-button(
type='default'
@click='deleteVRCPlusIcon(image.id)'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
el-tab-pane(v-if='galleryDialogVisible' v-loading='galleryDialogEmojisLoading')
span(slot='label') {{ $t('dialog.gallery_icons.emojis') }}
span(style='color: #909399; font-size: 12px; margin-left: 5px') {{ emojiTable.length }}/9
input#EmojiUploadButton(type='file' accept='image/*' @change='onFileChangeEmoji' style='display: none')
span {{ $t('dialog.gallery_icons.recommended_image_size') }}: 1024x1024px (1:1)
br
br
el-button-group(style="margin-right:10px")
el-button(type="default" size="small" @click="refreshEmojiTable" icon="el-icon-refresh") {{ $t('dialog.gallery_icons.refresh') }}
el-button(type="default" size="small" @click="displayEmojiUpload" icon="el-icon-upload2" :disabled="!API.currentUser.$isVRCPlus") {{ $t('dialog.gallery_icons.upload') }}
el-select(v-model="emojiAnimationStyle" popper-class="max-height-el-select")
el-button-group(style='margin-right: 10px')
el-button(type='default' size='small' @click='refreshEmojiTable' icon='el-icon-refresh') {{ $t('dialog.gallery_icons.refresh') }}
el-button(
type='default'
size='small'
@click='displayEmojiUpload'
icon='el-icon-upload2'
:disabled='!API.currentUser.$isVRCPlus') {{ $t('dialog.gallery_icons.upload') }}
el-select(v-model='emojiAnimationStyle' popper-class='max-height-el-select')
el-option-group {{ $t('dialog.gallery_icons.emoji_animation_styles') }}
el-option.x-friend-item(v-for="(fileName, styleName) in emojiAnimationStyleList" :key="fileName" :label="styleName" :value="styleName" style="height:auto")
.avatar(style="width:200px;height:200px")
img(v-lazy="`${emojiAnimationStyleUrl}${fileName}`")
el-option.x-friend-item(
v-for='(fileName, styleName) in emojiAnimationStyleList'
:key='fileName'
:label='styleName'
:value='styleName'
style='height: auto')
.avatar(style='width: 200px; height: 200px')
img(v-lazy='`${emojiAnimationStyleUrl}${fileName}`')
.detail
span.name(v-text="styleName" style="margin-right:100px")
el-checkbox(v-model="emojiAnimType" style="margin-left:10px;margin-right:10px")
span.name(v-text='styleName' style='margin-right: 100px')
el-checkbox(v-model='emojiAnimType' style='margin-left: 10px; margin-right: 10px')
span {{ $t('dialog.gallery_icons.emoji_animation_type') }}
template(v-if="emojiAnimType")
span(style="margin-right:10px") {{ $t('dialog.gallery_icons.emoji_animation_fps') }}
el-input-number(size="small" v-model="emojiAnimFps" :min="1" :max="64" style="margin-right:10px;width:112px")
span(style="margin-right:10px") {{ $t('dialog.gallery_icons.emoji_animation_frame_count') }}
el-input-number(size="small" v-model="emojiAnimFrameCount" :min="2" :max="64" style="margin-right:10px;width:112px")
el-checkbox(v-model="emojiAnimLoopPingPong" style="margin-left:10px;margin-right:10px")
template(v-if='emojiAnimType')
span(style='margin-right: 10px') {{ $t('dialog.gallery_icons.emoji_animation_fps') }}
el-input-number(
size='small'
v-model='emojiAnimFps'
:min='1'
:max='64'
style='margin-right: 10px; width: 112px')
span(style='margin-right: 10px') {{ $t('dialog.gallery_icons.emoji_animation_frame_count') }}
el-input-number(
size='small'
v-model='emojiAnimFrameCount'
:min='2'
:max='64'
style='margin-right: 10px; width: 112px')
el-checkbox(v-model='emojiAnimLoopPingPong' style='margin-left: 10px; margin-right: 10px')
span {{ $t('dialog.gallery_icons.emoji_loop_pingpong') }}
br
br
span {{ $t('dialog.gallery_icons.flipbook_info') }}
br
.x-friend-item(v-if="image.versions && image.versions.length > 0" v-for="image in emojiTable" :key="image.id" style="display:inline-block;margin-top:10px;width:unset;cursor:default")
.vrcplus-icon(v-if="image.versions[image.versions.length - 1].file.url" style="overflow:hidden" @click="showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url, getEmojiFileName(image))")
template(v-if="image.frames")
.avatar(:style="generateEmojiStyle(image.versions[image.versions.length - 1].file.url, image.framesOverTime, image.frames, image.loopStyle)")
.x-friend-item(
v-if='image.versions && image.versions.length > 0'
v-for='image in emojiTable'
:key='image.id'
style='display: inline-block; margin-top: 10px; width: unset; cursor: default')
.vrcplus-icon(
v-if='image.versions[image.versions.length - 1].file.url'
style='overflow: hidden'
@click='showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url, getEmojiFileName(image))')
template(v-if='image.frames')
.avatar(
:style='generateEmojiStyle(image.versions[image.versions.length - 1].file.url, image.framesOverTime, image.frames, image.loopStyle)')
template(v-else)
img.avatar(v-lazy="image.versions[image.versions.length - 1].file.url")
div(style="display:inline-block;margin:5px")
span(v-if="image.loopStyle === 'pingpong'") #[i.el-icon-refresh.el-icon--left]
span(style="margin-right:5px") {{ image.animationStyle }}
span(v-if="image.framesOverTime" style="margin-right:5px") {{ image.framesOverTime }}fps
span(v-if="image.frames" style="margin-right:5px") {{ image.frames }}frames
img.avatar(v-lazy='image.versions[image.versions.length - 1].file.url')
div(style='display: inline-block; margin: 5px')
span(v-if='image.loopStyle === "pingpong"') #[i.el-icon-refresh.el-icon--left]
span(style='margin-right: 5px') {{ image.animationStyle }}
span(v-if='image.framesOverTime' style='margin-right: 5px') {{ image.framesOverTime }}fps
span(v-if='image.frames' style='margin-right: 5px') {{ image.frames }}frames
br
div(style="float:right;margin-top:5px")
el-button(type="default" @click="showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url, getEmojiFileName(image))" size="mini" icon="el-icon-picture-outline" circle)
el-button(type="default" @click="deleteEmoji(image.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
el-tab-pane(v-if="galleryDialogVisible" v-loading="galleryDialogStickersLoading")
span(slot="label") {{ $t('dialog.gallery_icons.stickers') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ stickerTable.length }}/9
input(type="file" accept="image/*" @change="onFileChangeSticker" id="StickerUploadButton" style="display:none")
div(style='float: right; margin-top: 5px')
el-button(
type='default'
@click='showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url, getEmojiFileName(image))'
size='mini'
icon='el-icon-picture-outline'
circle)
el-button(
type='default'
@click='deleteEmoji(image.id)'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
el-tab-pane(v-if='galleryDialogVisible' v-loading='galleryDialogStickersLoading')
span(slot='label') {{ $t('dialog.gallery_icons.stickers') }}
span(style='color: #909399; font-size: 12px; margin-left: 5px') {{ stickerTable.length }}/9
input#StickerUploadButton(
type='file'
accept='image/*'
@change='onFileChangeSticker'
style='display: none')
span {{ $t('dialog.gallery_icons.recommended_image_size') }}: 1024x1024px (1:1)
br
br
el-button-group
el-button(type="default" size="small" @click="refreshStickerTable" icon="el-icon-refresh") {{ $t('dialog.gallery_icons.refresh') }}
el-button(type="default" size="small" @click="displayStickerUpload" icon="el-icon-upload2" :disabled="!API.currentUser.$isVRCPlus") {{ $t('dialog.gallery_icons.upload') }}
el-button(type='default' size='small' @click='refreshStickerTable' icon='el-icon-refresh') {{ $t('dialog.gallery_icons.refresh') }}
el-button(
type='default'
size='small'
@click='displayStickerUpload'
icon='el-icon-upload2'
:disabled='!API.currentUser.$isVRCPlus') {{ $t('dialog.gallery_icons.upload') }}
br
.x-friend-item(v-if="image.versions && image.versions.length > 0" v-for="image in stickerTable" :key="image.id" style="display:inline-block;margin-top:10px;width:unset;cursor:default")
.vrcplus-icon(v-if="image.versions[image.versions.length - 1].file.url" style="overflow:hidden" @click="showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url)")
img.avatar(v-lazy="image.versions[image.versions.length - 1].file.url")
div(style="float:right;margin-top:5px")
el-button(type="default" @click="showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url)" size="mini" icon="el-icon-picture-outline" circle)
el-button(type="default" @click="deleteSticker(image.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
el-tab-pane(v-if="galleryDialogVisible" v-loading="galleryDialogPrintsLoading")
span(slot="label") {{ $t('dialog.gallery_icons.prints') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ printTable.length }}/64
input(type="file" accept="image/*" @change="onFileChangePrint" id="PrintUploadButton" style="display:none")
.x-friend-item(
v-if='image.versions && image.versions.length > 0'
v-for='image in stickerTable'
:key='image.id'
style='display: inline-block; margin-top: 10px; width: unset; cursor: default')
.vrcplus-icon(
v-if='image.versions[image.versions.length - 1].file.url'
style='overflow: hidden'
@click='showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url)')
img.avatar(v-lazy='image.versions[image.versions.length - 1].file.url')
div(style='float: right; margin-top: 5px')
el-button(
type='default'
@click='showFullscreenImageDialog(image.versions[image.versions.length - 1].file.url)'
size='mini'
icon='el-icon-picture-outline'
circle)
el-button(
type='default'
@click='deleteSticker(image.id)'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
el-tab-pane(v-if='galleryDialogVisible' v-loading='galleryDialogPrintsLoading')
span(slot='label') {{ $t('dialog.gallery_icons.prints') }}
span(style='color: #909399; font-size: 12px; margin-left: 5px') {{ printTable.length }}/64
input#PrintUploadButton(type='file' accept='image/*' @change='onFileChangePrint' style='display: none')
span {{ $t('dialog.gallery_icons.recommended_image_size') }}: 1920x1080px (16:9)
br
br
el-button-group
el-button(type="default" size="small" @click="refreshPrintTable" icon="el-icon-refresh") {{ $t('dialog.gallery_icons.refresh') }}
el-button(type="default" size="small" @click="displayPrintUpload" icon="el-icon-upload2" :disabled="!API.currentUser.$isVRCPlus") {{ $t('dialog.gallery_icons.upload') }}
el-input(type="textarea" v-model="printUploadNote" size="mini" rows="1" resize="none" maxlength="32" style="margin-left:10px;width:300px" :placeholder="$t('dialog.gallery_icons.note')")
el-button(type='default' size='small' @click='refreshPrintTable' icon='el-icon-refresh') {{ $t('dialog.gallery_icons.refresh') }}
el-button(
type='default'
size='small'
@click='displayPrintUpload'
icon='el-icon-upload2'
:disabled='!API.currentUser.$isVRCPlus') {{ $t('dialog.gallery_icons.upload') }}
el-input(
type='textarea'
v-model='printUploadNote'
size='mini'
rows='1'
resize='none'
maxlength='32'
style='margin-left: 10px; width: 300px'
:placeholder='$t("dialog.gallery_icons.note")')
br
.x-friend-item(v-for="image in printTable" :key="image.id" style="display:inline-block;margin-top:10px;width:unset;cursor:default")
.vrcplus-icon(style="overflow:hidden" @click="showFullscreenImageDialog(image.files.image, getPrintFileName(image))")
img.avatar(v-lazy="image.files.image")
div(style="margin-top:5px;width:208px")
span.x-ellipsis(v-if="image.note" v-text="image.note" style="display:block")
span(v-else style="display:block")  
location.x-ellipsis(v-if="image.worldId" :location="image.worldId" :hint="image.worldName" style="display:block")
span(v-else style="display:block")  
display-name.x-ellipsis(v-if="image.authorId" :userid="image.authorId" :hint="image.authorName" style="color:#909399;font-family:monospace;display:block")
span(v-else style="font-family:monospace;display:block")  
span.x-ellipsis(v-if="image.createdAt" style="color:#909399;font-family:monospace;font-size:11px;display:block") {{ image.createdAt | formatDate('long') }}
span(v-else style="display:block")  
div(style="float:right")
el-button(type="default" @click="showFullscreenImageDialog(image.files.image, getPrintFileName(image))" size="mini" icon="el-icon-picture-outline" circle)
el-button(type="default" @click="deletePrint(image.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
.x-friend-item(
v-for='image in printTable'
:key='image.id'
style='display: inline-block; margin-top: 10px; width: unset; cursor: default')
.vrcplus-icon(
style='overflow: hidden'
@click='showFullscreenImageDialog(image.files.image, getPrintFileName(image))')
img.avatar(v-lazy='image.files.image')
div(style='margin-top: 5px; width: 208px')
span.x-ellipsis(v-if='image.note' v-text='image.note' style='display: block')
span(v-else style='display: block')  
location.x-ellipsis(
v-if='image.worldId'
:location='image.worldId'
:hint='image.worldName'
style='display: block')
span(v-else style='display: block')  
display-name.x-ellipsis(
v-if='image.authorId'
:userid='image.authorId'
:hint='image.authorName'
style='color: #909399; font-family: monospace; display: block')
span(v-else style='font-family: monospace; display: block')  
span.x-ellipsis(
v-if='image.createdAt'
style='color: #909399; font-family: monospace; font-size: 11px; display: block') {{ image.createdAt | formatDate('long') }}
span(v-else style='display: block')  
div(style='float: right')
el-button(
type='default'
@click='showFullscreenImageDialog(image.files.image, getPrintFileName(image))'
size='mini'
icon='el-icon-picture-outline'
circle)
el-button(
type='default'
@click='deletePrint(image.id)'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')

View File

@@ -1,241 +1,464 @@
mixin favoritesDialog()
mixin favoritesDialog
//- dialog: favorite
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="favoriteDialog" :visible.sync="favoriteDialog.visible" :title="$t('dialog.favorite.header')" width="300px")
div(v-if="favoriteDialog.visible" v-loading="favoriteDialog.loading")
span(style="display:block;text-align:center") {{ $t('dialog.favorite.vrchat_favorites') }}
template(v-if="favoriteDialog.currentGroup && favoriteDialog.currentGroup.key")
el-button(style="display:block;width:100%;margin:10px 0" @click="deleteFavoriteNoConfirm(favoriteDialog.objectId)") #[i.el-icon-check] {{ favoriteDialog.currentGroup.displayName }} ({{ favoriteDialog.currentGroup.count }} / {{ favoriteDialog.currentGroup.capacity }})
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='favoriteDialog'
:visible.sync='favoriteDialog.visible'
:title='$t("dialog.favorite.header")'
width='300px')
div(v-if='favoriteDialog.visible' v-loading='favoriteDialog.loading')
span(style='display: block; text-align: center') {{ $t('dialog.favorite.vrchat_favorites') }}
template(v-if='favoriteDialog.currentGroup && favoriteDialog.currentGroup.key')
el-button(
style='display: block; width: 100%; margin: 10px 0'
@click='deleteFavoriteNoConfirm(favoriteDialog.objectId)') #[i.el-icon-check] {{ favoriteDialog.currentGroup.displayName }} ({{ favoriteDialog.currentGroup.count }} / {{ favoriteDialog.currentGroup.capacity }})
template(v-else)
el-button(v-for="group in favoriteDialog.groups" :key="group" style="display:block;width:100%;margin:10px 0" @click="addFavorite(group)") {{ group.displayName }} ({{ group.count }} / {{ group.capacity }})
div(v-if="favoriteDialog.visible && favoriteDialog.type === 'world'" style="margin-top:20px")
span(style="display:block;text-align:center") {{ $t('dialog.favorite.local_favorites') }}
template(v-for="group in localWorldFavoriteGroups" :key="group")
el-button(v-if="hasLocalWorldFavorite(favoriteDialog.objectId, group)" style="display:block;width:100%;margin:10px 0" @click="removeLocalWorldFavorite(favoriteDialog.objectId, group)") #[i.el-icon-check] {{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }})
el-button(v-else style="display:block;width:100%;margin:10px 0" @click="addLocalWorldFavorite(favoriteDialog.objectId, group)") {{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }})
div(v-if="favoriteDialog.visible && favoriteDialog.type === 'avatar'" style="margin-top:20px")
span(style="display:block;text-align:center") {{ $t('dialog.favorite.local_avatar_favorites') }}
template(v-for="group in localAvatarFavoriteGroups" :key="group")
el-button(v-if="hasLocalAvatarFavorite(favoriteDialog.objectId, group)" style="display:block;width:100%;margin:10px 0" @click="removeLocalAvatarFavorite(favoriteDialog.objectId, group)") #[i.el-icon-check] {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
el-button(v-else style="display:block;width:100%;margin:10px 0" :disabled="!isLocalUserVrcplusSupporter()" @click="addLocalAvatarFavorite(favoriteDialog.objectId, group)") {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
el-button(
v-for='group in favoriteDialog.groups'
:key='group'
style='display: block; width: 100%; margin: 10px 0'
@click='addFavorite(group)') {{ group.displayName }} ({{ group.count }} / {{ group.capacity }})
div(v-if='favoriteDialog.visible && favoriteDialog.type === "world"' style='margin-top: 20px')
span(style='display: block; text-align: center') {{ $t('dialog.favorite.local_favorites') }}
template(v-for='group in localWorldFavoriteGroups' :key='group')
el-button(
v-if='hasLocalWorldFavorite(favoriteDialog.objectId, group)'
style='display: block; width: 100%; margin: 10px 0'
@click='removeLocalWorldFavorite(favoriteDialog.objectId, group)') #[i.el-icon-check] {{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }})
el-button(
v-else
style='display: block; width: 100%; margin: 10px 0'
@click='addLocalWorldFavorite(favoriteDialog.objectId, group)') {{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }})
div(v-if='favoriteDialog.visible && favoriteDialog.type === "avatar"' style='margin-top: 20px')
span(style='display: block; text-align: center') {{ $t('dialog.favorite.local_avatar_favorites') }}
template(v-for='group in localAvatarFavoriteGroups' :key='group')
el-button(
v-if='hasLocalAvatarFavorite(favoriteDialog.objectId, group)'
style='display: block; width: 100%; margin: 10px 0'
@click='removeLocalAvatarFavorite(favoriteDialog.objectId, group)') #[i.el-icon-check] {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
el-button(
v-else
style='display: block; width: 100%; margin: 10px 0'
:disabled='!isLocalUserVrcplusSupporter()'
@click='addLocalAvatarFavorite(favoriteDialog.objectId, group)') {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
//- dialog: export friends list
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" :visible.sync="exportFriendsListDialog" :title="$t('dialog.export_friends_list.header')" width="650px")
el-tabs(type="card")
el-tab-pane(:label="$t('dialog.export_friends_list.csv')")
el-input(type="textarea" v-if="exportFriendsListDialog" v-model="exportFriendsListCsv" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()")
el-tab-pane(:label="$t('dialog.export_friends_list.json')")
el-input(type="textarea" v-if="exportFriendsListDialog" v-model="exportFriendsListJson" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
:visible.sync='exportFriendsListDialog'
:title='$t("dialog.export_friends_list.header")'
width='650px')
el-tabs(type='card')
el-tab-pane(:label='$t("dialog.export_friends_list.csv")')
el-input(
type='textarea'
v-if='exportFriendsListDialog'
v-model='exportFriendsListCsv'
size='mini'
rows='15'
resize='none'
readonly
style='margin-top: 15px'
@click.native='$event.target.tagName === "TEXTAREA" && $event.target.select()')
el-tab-pane(:label='$t("dialog.export_friends_list.json")')
el-input(
type='textarea'
v-if='exportFriendsListDialog'
v-model='exportFriendsListJson'
size='mini'
rows='15'
resize='none'
readonly
style='margin-top: 15px'
@click.native='$event.target.tagName === "TEXTAREA" && $event.target.select()')
//- dialog: export avatars list
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" :visible.sync="exportAvatarsListDialog" :title="$t('dialog.export_own_avatars.header')" width="650px")
el-input(type="textarea" v-if="exportAvatarsListDialog" v-model="exportAvatarsListCsv" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="$event.target.tagName === 'TEXTAREA' && $event.target.select()")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
:visible.sync='exportAvatarsListDialog'
:title='$t("dialog.export_own_avatars.header")'
width='650px')
el-input(
type='textarea'
v-if='exportAvatarsListDialog'
v-model='exportAvatarsListCsv'
size='mini'
rows='15'
resize='none'
readonly
style='margin-top: 15px'
@click.native='$event.target.tagName === "TEXTAREA" && $event.target.select()')
//- dialog: export world list
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="worldExportDialogRef" :visible.sync="worldExportDialogVisible" :title="$t('dialog.world_export.header')" width="650px")
el-checkbox-group(v-model="exportSelectedOptions" @change="updateWorldExportDialog()" style="margin-bottom:10px")
template(v-for="option in exportSelectOptions" :key="option.value")
el-checkbox(:label="option.label")
el-dropdown(@click.native.stop trigger="click" size="small")
el-button(size="mini")
span(v-if="worldExportFavoriteGroup") {{ worldExportFavoriteGroup.displayName }} ({{ worldExportFavoriteGroup.count }}/{{ worldExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='worldExportDialogRef'
:visible.sync='worldExportDialogVisible'
:title='$t("dialog.world_export.header")'
width='650px')
el-checkbox-group(
v-model='exportSelectedOptions'
@change='updateWorldExportDialog()'
style='margin-bottom: 10px')
template(v-for='option in exportSelectOptions' :key='option.value')
el-checkbox(:label='option.label')
el-dropdown(@click.native.stop trigger='click' size='small')
el-button(size='mini')
span(v-if='worldExportFavoriteGroup') {{ worldExportFavoriteGroup.displayName }} ({{ worldExportFavoriteGroup.count }}/{{ worldExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) All Favorites #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldExportGroup(null)") None
template(v-for="groupAPI in API.favoriteWorldGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldExportGroup(groupAPI)") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown(@click.native.stop trigger="click" size="small" style="margin-left:10px")
el-button(size="mini")
span(v-if="worldExportLocalFavoriteGroup") {{ worldExportLocalFavoriteGroup }} ({{ getLocalWorldFavoriteGroupLength(worldExportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default='dropdown')
el-dropdown-item(style='display: block; margin: 10px 0' @click.native='selectWorldExportGroup(null)') None
template(v-for='groupAPI in API.favoriteWorldGroups' :key='groupAPI.name')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectWorldExportGroup(groupAPI)') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown(@click.native.stop trigger='click' size='small' style='margin-left: 10px')
el-button(size='mini')
span(v-if='worldExportLocalFavoriteGroup') {{ worldExportLocalFavoriteGroup }} ({{ getLocalWorldFavoriteGroupLength(worldExportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) Select Group #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldExportLocalGroup(null)") None
template(v-for="group in localWorldFavoriteGroups" :key="group")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldExportLocalGroup(group)") {{ group }} ({{ localWorldFavorites[group].length }})
el-dropdown-menu(#default='dropdown')
el-dropdown-item(style='display: block; margin: 10px 0' @click.native='selectWorldExportLocalGroup(null)') None
template(v-for='group in localWorldFavoriteGroups' :key='group')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectWorldExportLocalGroup(group)') {{ group }} ({{ localWorldFavorites[group].length }})
br
el-input(type="textarea" v-if="worldExportDialogVisible" v-model="worldExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="handleCopyWorldExportData")
el-input(
type='textarea'
v-if='worldExportDialogVisible'
v-model='worldExportContent'
size='mini'
rows='15'
resize='none'
readonly
style='margin-top: 15px'
@click.native='handleCopyWorldExportData')
//- dialog: World import dialog
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="worldImportDialog" :visible.sync="worldImportDialog.visible" :title="$t('dialog.world_import.header')" width="650px")
div(style="display:flex;align-items:center;justify-content:space-between")
div(style="font-size:12px") {{ $t('dialog.world_import.description') }}
div(style="display:flex;align-items:center;")
div(v-if="worldImportDialog.progress") {{ $t('dialog.world_import.process_progress') }} {{ worldImportDialog.progress }} / {{ worldImportDialog.progressTotal }} #[i.el-icon-loading(style="margin:0 5px")]
el-button(v-if="worldImportDialog.loading" size="small" @click="cancelWorldImport") {{ $t('dialog.world_import.cancel') }}
el-button(v-else size="small" @click="processWorldImportList" :disabled="!worldImportDialog.input") {{ $t('dialog.world_import.process_list') }}
el-input(type="textarea" v-model="worldImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:10px")
div(style="display:flex;align-items:center;justify-content:space-between;margin-top:5px")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='worldImportDialog'
:visible.sync='worldImportDialog.visible'
:title='$t("dialog.world_import.header")'
width='650px')
div(style='display: flex; align-items: center; justify-content: space-between')
div(style='font-size: 12px') {{ $t('dialog.world_import.description') }}
div(style='display: flex; align-items: center')
div(v-if='worldImportDialog.progress') {{ $t('dialog.world_import.process_progress') }} {{ worldImportDialog.progress }} / {{ worldImportDialog.progressTotal }} #[i.el-icon-loading(style='margin: 0 5px')]
el-button(v-if='worldImportDialog.loading' size='small' @click='cancelWorldImport') {{ $t('dialog.world_import.cancel') }}
el-button(v-else size='small' @click='processWorldImportList' :disabled='!worldImportDialog.input') {{ $t('dialog.world_import.process_list') }}
el-input(
type='textarea'
v-model='worldImportDialog.input'
size='mini'
rows='10'
resize='none'
style='margin-top: 10px')
div(style='display: flex; align-items: center; justify-content: space-between; margin-top: 5px')
div
el-dropdown(@click.native.stop trigger="click" size="small" style="margin-right:5px")
el-button(size="mini")
span(v-if="worldImportDialog.worldImportFavoriteGroup") {{ worldImportDialog.worldImportFavoriteGroup.displayName }} ({{ worldImportDialog.worldImportFavoriteGroup.count }}/{{ worldImportDialog.worldImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
el-dropdown(@click.native.stop trigger='click' size='small' style='margin-right: 5px')
el-button(size='mini')
span(v-if='worldImportDialog.worldImportFavoriteGroup') {{ worldImportDialog.worldImportFavoriteGroup.displayName }} ({{ worldImportDialog.worldImportFavoriteGroup.count }}/{{ worldImportDialog.worldImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) {{ $t('dialog.world_import.select_vrchat_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
template(v-for="groupAPI in API.favoriteWorldGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown(@click.native.stop trigger="click" size="small" style="margin:5px")
el-button(size="mini")
span(v-if="worldImportDialog.worldImportLocalFavoriteGroup") {{ worldImportDialog.worldImportLocalFavoriteGroup }} ({{ getLocalWorldFavoriteGroupLength(worldImportDialog.worldImportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default='dropdown')
template(v-for='groupAPI in API.favoriteWorldGroups' :key='groupAPI.name')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectWorldImportGroup(groupAPI)'
:disabled='groupAPI.count >= groupAPI.capacity') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown(@click.native.stop trigger='click' size='small' style='margin: 5px')
el-button(size='mini')
span(v-if='worldImportDialog.worldImportLocalFavoriteGroup') {{ worldImportDialog.worldImportLocalFavoriteGroup }} ({{ getLocalWorldFavoriteGroupLength(worldImportDialog.worldImportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) {{ $t('dialog.world_import.select_local_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
template(v-for="group in localWorldFavoriteGroups" :key="group")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectWorldImportLocalGroup(group)" ) {{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }})
span(v-if="worldImportDialog.worldImportFavoriteGroup" style="margin-left:5px") {{ worldImportTable.data.length }} / {{ worldImportDialog.worldImportFavoriteGroup.capacity - worldImportDialog.worldImportFavoriteGroup.count }}
el-dropdown-menu(#default='dropdown')
template(v-for='group in localWorldFavoriteGroups' :key='group')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectWorldImportLocalGroup(group)') {{ group }} ({{ getLocalWorldFavoriteGroupLength(group) }})
span(v-if='worldImportDialog.worldImportFavoriteGroup' style='margin-left: 5px') {{ worldImportTable.data.length }} / {{ worldImportDialog.worldImportFavoriteGroup.capacity - worldImportDialog.worldImportFavoriteGroup.count }}
div
el-button(size="small" @click="clearWorldImportTable" :disabled="worldImportTable.data.length === 0") {{ $t('dialog.world_import.clear_table') }}
el-button(size="small" type="primary" @click="importWorldImportTable" style="margin:5px" :disabled="worldImportTable.data.length === 0 || (!worldImportDialog.worldImportFavoriteGroup && !worldImportDialog.worldImportLocalFavoriteGroup)") {{ $t('dialog.world_import.import') }}
span(v-if="worldImportDialog.importProgress" style="margin:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.world_import.import_progress') }} {{ worldImportDialog.importProgress }}/{{ worldImportDialog.importProgressTotal }}
el-button(size='small' @click='clearWorldImportTable' :disabled='worldImportTable.data.length === 0') {{ $t('dialog.world_import.clear_table') }}
el-button(
size='small'
type='primary'
@click='importWorldImportTable'
style='margin: 5px'
:disabled='worldImportTable.data.length === 0 || (!worldImportDialog.worldImportFavoriteGroup && !worldImportDialog.worldImportLocalFavoriteGroup)') {{ $t('dialog.world_import.import') }}
span(v-if='worldImportDialog.importProgress' style='margin: 10px') #[i.el-icon-loading(style='margin-right: 5px')] {{ $t('dialog.world_import.import_progress') }} {{ worldImportDialog.importProgress }}/{{ worldImportDialog.importProgressTotal }}
br
template(v-if="worldImportDialog.errors")
el-button(size="small" @click="worldImportDialog.errors = ''") {{ $t('dialog.world_import.clear_errors') }}
h2(style="font-weight:bold;margin:5px 0") {{ $t('dialog.world_import.errors') }}
pre(v-text="worldImportDialog.errors" style="white-space:pre-wrap;font-size:12px")
data-tables(v-if="worldImportDialog.visible" v-bind="worldImportTable" v-loading="worldImportDialog.loading" style="margin-top:10px")
el-table-column(:label="$t('table.import.image')" width="70" prop="thumbnailImageUrl")
template(#default="scope")
el-popover(placement="right" height="500px" trigger="hover")
img.friends-list-avatar(slot="reference" v-lazy="scope.row.thumbnailImageUrl")
img.friends-list-avatar(v-lazy="scope.row.imageUrl" style="height:500px;cursor:pointer" @click="showFullscreenImageDialog(scope.row.imageUrl)")
el-table-column(:label="$t('table.import.name')" prop="name")
template(#default="scope")
span.x-link(v-text="scope.row.name" @click="showWorldDialog(scope.row.id)")
el-table-column(:label="$t('table.import.author')" width="120" prop="authorName")
template(#default="scope")
span.x-link(v-text="scope.row.authorName" @click="showUserDialog(scope.row.authorId)")
el-table-column(:label="$t('table.import.status')" width="70" prop="releaseStatus")
template(#default="scope")
span(v-text="scope.row.releaseStatus.charAt(0).toUpperCase() + scope.row.releaseStatus.slice(1)" :style="{ color: scope.row.releaseStatus === 'public' ? '#67c23a' : scope.row.releaseStatus === 'private' ? '#f56c6c' : undefined }")
el-table-column(:label="$t('table.import.action')" width="90" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-close" size="mini" @click="deleteItemWorldImport(scope.row)")
template(v-if='worldImportDialog.errors')
el-button(size='small' @click='worldImportDialog.errors = ""') {{ $t('dialog.world_import.clear_errors') }}
h2(style='font-weight: bold; margin: 5px 0') {{ $t('dialog.world_import.errors') }}
pre(v-text='worldImportDialog.errors' style='white-space: pre-wrap; font-size: 12px')
data-tables(
v-if='worldImportDialog.visible'
v-bind='worldImportTable'
v-loading='worldImportDialog.loading'
style='margin-top: 10px')
el-table-column(:label='$t("table.import.image")' width='70' prop='thumbnailImageUrl')
template(#default='scope')
el-popover(placement='right' height='500px' trigger='hover')
img.friends-list-avatar(slot='reference' v-lazy='scope.row.thumbnailImageUrl')
img.friends-list-avatar(
v-lazy='scope.row.imageUrl'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(scope.row.imageUrl)')
el-table-column(:label='$t("table.import.name")' prop='name')
template(#default='scope')
span.x-link(v-text='scope.row.name' @click='showWorldDialog(scope.row.id)')
el-table-column(:label='$t("table.import.author")' width='120' prop='authorName')
template(#default='scope')
span.x-link(v-text='scope.row.authorName' @click='showUserDialog(scope.row.authorId)')
el-table-column(:label='$t("table.import.status")' width='70' prop='releaseStatus')
template(#default='scope')
span(
v-text='scope.row.releaseStatus.charAt(0).toUpperCase() + scope.row.releaseStatus.slice(1)'
:style='{ color: scope.row.releaseStatus === "public" ? "#67c23a" : scope.row.releaseStatus === "private" ? "#f56c6c" : undefined }')
el-table-column(:label='$t("table.import.action")' width='90' align='right')
template(#default='scope')
el-button(type='text' icon='el-icon-close' size='mini' @click='deleteItemWorldImport(scope.row)')
//- dialog: export avatar list
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="avatarExportDialogRef" :visible.sync="avatarExportDialogVisible" :title="$t('dialog.avatar_export.header')" width="650px")
el-checkbox-group(v-model="exportSelectedOptions" @change="updateAvatarExportDialog()" style="margin-bottom:10px")
template(v-for="option in exportSelectOptions" :key="option.value")
el-checkbox(:label="option.label")
el-dropdown(@click.native.stop trigger="click" size="small")
el-button(size="mini")
span(v-if="avatarExportFavoriteGroup") {{ avatarExportFavoriteGroup.displayName }} ({{ avatarExportFavoriteGroup.count }}/{{ avatarExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='avatarExportDialogRef'
:visible.sync='avatarExportDialogVisible'
:title='$t("dialog.avatar_export.header")'
width='650px')
el-checkbox-group(
v-model='exportSelectedOptions'
@change='updateAvatarExportDialog()'
style='margin-bottom: 10px')
template(v-for='option in exportSelectOptions' :key='option.value')
el-checkbox(:label='option.label')
el-dropdown(@click.native.stop trigger='click' size='small')
el-button(size='mini')
span(v-if='avatarExportFavoriteGroup') {{ avatarExportFavoriteGroup.displayName }} ({{ avatarExportFavoriteGroup.count }}/{{ avatarExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) All Favorites #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarExportGroup(null)") All Favorites
template(v-for="groupAPI in API.favoriteAvatarGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarExportGroup(groupAPI)") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown(@click.native.stop trigger="click" size="small" style="margin-left:10px")
el-button(size="mini")
span(v-if="avatarExportLocalFavoriteGroup") {{ avatarExportLocalFavoriteGroup }} ({{ getLocalAvatarFavoriteGroupLength(avatarExportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default='dropdown')
el-dropdown-item(style='display: block; margin: 10px 0' @click.native='selectAvatarExportGroup(null)') All Favorites
template(v-for='groupAPI in API.favoriteAvatarGroups' :key='groupAPI.name')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectAvatarExportGroup(groupAPI)') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown(@click.native.stop trigger='click' size='small' style='margin-left: 10px')
el-button(size='mini')
span(v-if='avatarExportLocalFavoriteGroup') {{ avatarExportLocalFavoriteGroup }} ({{ getLocalAvatarFavoriteGroupLength(avatarExportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) Select Group #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarExportLocalGroup(null)") None
template(v-for="group in localAvatarFavoriteGroups" :key="group")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarExportLocalGroup(group)" ) {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
el-dropdown-menu(#default='dropdown')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectAvatarExportLocalGroup(null)') None
template(v-for='group in localAvatarFavoriteGroups' :key='group')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectAvatarExportLocalGroup(group)') {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
br
el-input(type="textarea" v-if="avatarExportDialogVisible" v-model="avatarExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="handleCopyAvatarExportData")
el-input(
type='textarea'
v-if='avatarExportDialogVisible'
v-model='avatarExportContent'
size='mini'
rows='15'
resize='none'
readonly
style='margin-top: 15px'
@click.native='handleCopyAvatarExportData')
//- dialog: Avatar import dialog
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="avatarImportDialog" :visible.sync="avatarImportDialog.visible" :title="$t('dialog.avatar_import.header')" width="650px")
div(style="display:flex;align-items:center;justify-content:space-between")
div(style="font-size:12px") {{ $t('dialog.avatar_import.description') }}
div(style="display:flex;align-items:center;")
div(v-if="avatarImportDialog.progress") {{ $t('dialog.avatar_import.process_progress') }} {{ avatarImportDialog.progress }} / {{ avatarImportDialog.progressTotal }} #[i.el-icon-loading(style="margin:0 5px")]
el-button(v-if="avatarImportDialog.loading" size="small" @click="cancelAvatarImport") {{ $t('dialog.avatar_import.cancel') }}
el-button(v-else size="small" @click="processAvatarImportList" :disabled="!avatarImportDialog.input") {{ $t('dialog.avatar_import.process_list') }}
el-input(type="textarea" v-model="avatarImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:10px")
div(style="display:flex;align-items:center;justify-content:space-between;margin-top:5px")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='avatarImportDialog'
:visible.sync='avatarImportDialog.visible'
:title='$t("dialog.avatar_import.header")'
width='650px')
div(style='display: flex; align-items: center; justify-content: space-between')
div(style='font-size: 12px') {{ $t('dialog.avatar_import.description') }}
div(style='display: flex; align-items: center')
div(v-if='avatarImportDialog.progress') {{ $t('dialog.avatar_import.process_progress') }} {{ avatarImportDialog.progress }} / {{ avatarImportDialog.progressTotal }} #[i.el-icon-loading(style='margin: 0 5px')]
el-button(v-if='avatarImportDialog.loading' size='small' @click='cancelAvatarImport') {{ $t('dialog.avatar_import.cancel') }}
el-button(v-else size='small' @click='processAvatarImportList' :disabled='!avatarImportDialog.input') {{ $t('dialog.avatar_import.process_list') }}
el-input(
type='textarea'
v-model='avatarImportDialog.input'
size='mini'
rows='10'
resize='none'
style='margin-top: 10px')
div(style='display: flex; align-items: center; justify-content: space-between; margin-top: 5px')
div
el-dropdown(@click.native.stop trigger="click" size="small")
el-button(size="mini")
span(v-if="avatarImportDialog.avatarImportFavoriteGroup") {{ avatarImportDialog.avatarImportFavoriteGroup.displayName }} ({{ avatarImportDialog.avatarImportFavoriteGroup.count }}/{{ avatarImportDialog.avatarImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
el-dropdown(@click.native.stop trigger='click' size='small')
el-button(size='mini')
span(v-if='avatarImportDialog.avatarImportFavoriteGroup') {{ avatarImportDialog.avatarImportFavoriteGroup.displayName }} ({{ avatarImportDialog.avatarImportFavoriteGroup.count }}/{{ avatarImportDialog.avatarImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) {{ $t('dialog.avatar_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
template(v-for="groupAPI in API.favoriteAvatarGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown(@click.native.stop trigger="click" size="small" style="margin:5px")
el-button(size="mini")
span(v-if="avatarImportDialog.avatarImportLocalFavoriteGroup") {{ avatarImportDialog.avatarImportLocalFavoriteGroup }} ({{ getLocalAvatarFavoriteGroupLength(avatarImportDialog.avatarImportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default='dropdown')
template(v-for='groupAPI in API.favoriteAvatarGroups' :key='groupAPI.name')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectAvatarImportGroup(groupAPI)'
:disabled='groupAPI.count >= groupAPI.capacity') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown(@click.native.stop trigger='click' size='small' style='margin: 5px')
el-button(size='mini')
span(v-if='avatarImportDialog.avatarImportLocalFavoriteGroup') {{ avatarImportDialog.avatarImportLocalFavoriteGroup }} ({{ getLocalAvatarFavoriteGroupLength(avatarImportDialog.avatarImportLocalFavoriteGroup) }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) {{ $t('dialog.avatar_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
template(v-for="group in localAvatarFavoriteGroups" :key="group")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectAvatarImportLocalGroup(group)" ) {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
span(v-if="avatarImportDialog.avatarImportFavoriteGroup" style="margin-left:5px") {{ avatarImportTable.data.length }} / {{ avatarImportDialog.avatarImportFavoriteGroup.capacity - avatarImportDialog.avatarImportFavoriteGroup.count }}
el-dropdown-menu(#default='dropdown')
template(v-for='group in localAvatarFavoriteGroups' :key='group')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectAvatarImportLocalGroup(group)') {{ group }} ({{ getLocalAvatarFavoriteGroupLength(group) }})
span(v-if='avatarImportDialog.avatarImportFavoriteGroup' style='margin-left: 5px') {{ avatarImportTable.data.length }} / {{ avatarImportDialog.avatarImportFavoriteGroup.capacity - avatarImportDialog.avatarImportFavoriteGroup.count }}
div
el-button(size="small" @click="clearAvatarImportTable") {{ $t('dialog.avatar_import.clear_table') }}
el-button(size="small" type="primary" @click="importAvatarImportTable" style="margin:5px" :disabled="avatarImportTable.data.length === 0 || (!avatarImportDialog.avatarImportFavoriteGroup && !avatarImportDialog.avatarImportLocalFavoriteGroup)") {{ $t('dialog.avatar_import.import') }}
span(v-if="avatarImportDialog.importProgress" style="margin:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.avatar_import.import_progress') }} {{ avatarImportDialog.importProgress }}/{{ avatarImportDialog.importProgressTotal }}
el-button(size='small' @click='clearAvatarImportTable') {{ $t('dialog.avatar_import.clear_table') }}
el-button(
size='small'
type='primary'
@click='importAvatarImportTable'
style='margin: 5px'
:disabled='avatarImportTable.data.length === 0 || (!avatarImportDialog.avatarImportFavoriteGroup && !avatarImportDialog.avatarImportLocalFavoriteGroup)') {{ $t('dialog.avatar_import.import') }}
span(v-if='avatarImportDialog.importProgress' style='margin: 10px') #[i.el-icon-loading(style='margin-right: 5px')] {{ $t('dialog.avatar_import.import_progress') }} {{ avatarImportDialog.importProgress }}/{{ avatarImportDialog.importProgressTotal }}
br
template(v-if="avatarImportDialog.errors")
el-button(size="small" @click="avatarImportDialog.errors = ''") {{ $t('dialog.avatar_import.clear_errors') }}
h2(style="font-weight:bold;margin:5px 0") {{ $t('dialog.avatar_import.errors') }}
pre(v-text="avatarImportDialog.errors" style="white-space:pre-wrap;font-size:12px")
data-tables(v-if="avatarImportDialog.visible" v-bind="avatarImportTable" v-loading="avatarImportDialog.loading" style="margin-top:10px")
el-table-column(:label="$t('table.import.image')" width="70" prop="thumbnailImageUrl")
template(#default="scope")
el-popover(placement="right" height="500px" trigger="hover")
img.friends-list-avatar(slot="reference" v-lazy="scope.row.thumbnailImageUrl")
img.friends-list-avatar(v-lazy="scope.row.imageUrl" style="height:500px;cursor:pointer" @click="showFullscreenImageDialog(scope.row.imageUrl)")
el-table-column(:label="$t('table.import.name')" prop="name")
template(#default="scope")
span.x-link(v-text="scope.row.name" @click="showAvatarDialog(scope.row.id)")
el-table-column(:label="$t('table.import.author')" width="120" prop="authorName")
template(#default="scope")
span.x-link(v-text="scope.row.authorName" @click="showUserDialog(scope.row.authorId)")
el-table-column(:label="$t('table.import.status')" width="70" prop="releaseStatus")
template(#default="scope")
span(v-text="scope.row.releaseStatus.charAt(0).toUpperCase() + scope.row.releaseStatus.slice(1)" :style="{ color: scope.row.releaseStatus === 'public' ? '#67c23a' : scope.row.releaseStatus === 'private' ? '#f56c6c' : undefined }")
el-table-column(:label="$t('table.import.action')" width="90" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-close" size="mini" @click="deleteItemAvatarImport(scope.row)")
template(v-if='avatarImportDialog.errors')
el-button(size='small' @click='avatarImportDialog.errors = ""') {{ $t('dialog.avatar_import.clear_errors') }}
h2(style='font-weight: bold; margin: 5px 0') {{ $t('dialog.avatar_import.errors') }}
pre(v-text='avatarImportDialog.errors' style='white-space: pre-wrap; font-size: 12px')
data-tables(
v-if='avatarImportDialog.visible'
v-bind='avatarImportTable'
v-loading='avatarImportDialog.loading'
style='margin-top: 10px')
el-table-column(:label='$t("table.import.image")' width='70' prop='thumbnailImageUrl')
template(#default='scope')
el-popover(placement='right' height='500px' trigger='hover')
img.friends-list-avatar(slot='reference' v-lazy='scope.row.thumbnailImageUrl')
img.friends-list-avatar(
v-lazy='scope.row.imageUrl'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(scope.row.imageUrl)')
el-table-column(:label='$t("table.import.name")' prop='name')
template(#default='scope')
span.x-link(v-text='scope.row.name' @click='showAvatarDialog(scope.row.id)')
el-table-column(:label='$t("table.import.author")' width='120' prop='authorName')
template(#default='scope')
span.x-link(v-text='scope.row.authorName' @click='showUserDialog(scope.row.authorId)')
el-table-column(:label='$t("table.import.status")' width='70' prop='releaseStatus')
template(#default='scope')
span(
v-text='scope.row.releaseStatus.charAt(0).toUpperCase() + scope.row.releaseStatus.slice(1)'
:style='{ color: scope.row.releaseStatus === "public" ? "#67c23a" : scope.row.releaseStatus === "private" ? "#f56c6c" : undefined }')
el-table-column(:label='$t("table.import.action")' width='90' align='right')
template(#default='scope')
el-button(type='text' icon='el-icon-close' size='mini' @click='deleteItemAvatarImport(scope.row)')
//- dialog: export friend list
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="friendExportDialogRef" :visible.sync="friendExportDialogVisible" :title="$t('dialog.friend_export.header')" width="650px")
el-dropdown(@click.native.stop trigger="click" size="small")
el-button(size="mini")
span(v-if="friendExportFavoriteGroup") {{ friendExportFavoriteGroup.displayName }} ({{ friendExportFavoriteGroup.count }}/{{ friendExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='friendExportDialogRef'
:visible.sync='friendExportDialogVisible'
:title='$t("dialog.friend_export.header")'
width='650px')
el-dropdown(@click.native.stop trigger='click' size='small')
el-button(size='mini')
span(v-if='friendExportFavoriteGroup') {{ friendExportFavoriteGroup.displayName }} ({{ friendExportFavoriteGroup.count }}/{{ friendExportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) All Favorites #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectFriendExportGroup(null)") All Favorites
template(v-for="groupAPI in API.favoriteFriendGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectFriendExportGroup(groupAPI)") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
el-dropdown-menu(#default='dropdown')
el-dropdown-item(style='display: block; margin: 10px 0' @click.native='selectFriendExportGroup(null)') All Favorites
template(v-for='groupAPI in API.favoriteFriendGroups' :key='groupAPI.name')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectFriendExportGroup(groupAPI)') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
br
el-input(type="textarea" v-if="friendExportDialogVisible" v-model="friendExportContent" size="mini" rows="15" resize="none" readonly style="margin-top:15px" @click.native="handleCopyFriendExportData")
el-input(
type='textarea'
v-if='friendExportDialogVisible'
v-model='friendExportContent'
size='mini'
rows='15'
resize='none'
readonly
style='margin-top: 15px'
@click.native='handleCopyFriendExportData')
//- dialog: Friend import dialog
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="friendImportDialog" :visible.sync="friendImportDialog.visible" :title="$t('dialog.friend_import.header')" width="650px")
div(style="display:flex;align-items:center;justify-content:space-between")
div(style="font-size:12px") {{ $t('dialog.friend_import.description') }}
div(style="display:flex;align-items:center;")
div(v-if="friendImportDialog.progress") {{ $t('dialog.friend_import.process_progress') }} {{ friendImportDialog.progress }} / {{ friendImportDialog.progressTotal }} #[i.el-icon-loading(style="margin:0 5px")]
el-button(v-if="friendImportDialog.loading" size="small" @click="cancelFriendImport") {{ $t('dialog.friend_import.cancel') }}
el-button(v-else size="small" @click="processFriendImportList" :disabled="!friendImportDialog.input") {{ $t('dialog.friend_import.process_list') }}
el-input(type="textarea" v-model="friendImportDialog.input" size="mini" rows="10" resize="none" style="margin-top:10px")
div(style="display:flex;align-items:center;justify-content:space-between;margin-top:5px")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='friendImportDialog'
:visible.sync='friendImportDialog.visible'
:title='$t("dialog.friend_import.header")'
width='650px')
div(style='display: flex; align-items: center; justify-content: space-between')
div(style='font-size: 12px') {{ $t('dialog.friend_import.description') }}
div(style='display: flex; align-items: center')
div(v-if='friendImportDialog.progress') {{ $t('dialog.friend_import.process_progress') }} {{ friendImportDialog.progress }} / {{ friendImportDialog.progressTotal }} #[i.el-icon-loading(style='margin: 0 5px')]
el-button(v-if='friendImportDialog.loading' size='small' @click='cancelFriendImport') {{ $t('dialog.friend_import.cancel') }}
el-button(v-else size='small' @click='processFriendImportList' :disabled='!friendImportDialog.input') {{ $t('dialog.friend_import.process_list') }}
el-input(
type='textarea'
v-model='friendImportDialog.input'
size='mini'
rows='10'
resize='none'
style='margin-top: 10px')
div(style='display: flex; align-items: center; justify-content: space-between; margin-top: 5px')
div
el-dropdown(@click.native.stop trigger="click" size="small")
el-button(size="mini")
span(v-if="friendImportDialog.friendImportFavoriteGroup") {{ friendImportDialog.friendImportFavoriteGroup.displayName }} ({{ friendImportDialog.friendImportFavoriteGroup.count }}/{{ friendImportDialog.friendImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
el-dropdown(@click.native.stop trigger='click' size='small')
el-button(size='mini')
span(v-if='friendImportDialog.friendImportFavoriteGroup') {{ friendImportDialog.friendImportFavoriteGroup.displayName }} ({{ friendImportDialog.friendImportFavoriteGroup.count }}/{{ friendImportDialog.friendImportFavoriteGroup.capacity }}) #[i.el-icon-arrow-down.el-icon--right]
span(v-else) {{ $t('dialog.friend_import.select_group_placeholder') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
template(v-for="groupAPI in API.favoriteFriendGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="selectFriendImportGroup(groupAPI)" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
span(v-if="friendImportDialog.friendImportFavoriteGroup" style="margin-left:5px") {{ friendImportTable.data.length }} / {{ friendImportDialog.friendImportFavoriteGroup.capacity - friendImportDialog.friendImportFavoriteGroup.count }}
el-dropdown-menu(#default='dropdown')
template(v-for='groupAPI in API.favoriteFriendGroups' :key='groupAPI.name')
el-dropdown-item(
style='display: block; margin: 10px 0'
@click.native='selectFriendImportGroup(groupAPI)'
:disabled='groupAPI.count >= groupAPI.capacity') {{ groupAPI.displayName }} ({{ groupAPI.count }}/{{ groupAPI.capacity }})
span(v-if='friendImportDialog.friendImportFavoriteGroup' style='margin-left: 5px') {{ friendImportTable.data.length }} / {{ friendImportDialog.friendImportFavoriteGroup.capacity - friendImportDialog.friendImportFavoriteGroup.count }}
div
el-button(size="small" @click="clearFriendImportTable" :disabled="friendImportTable.data.length === 0") {{ $t('dialog.friend_import.clear_table') }}
el-button(size="small" type="primary" @click="importFriendImportTable" style="margin:5px" :disabled="friendImportTable.data.length === 0 || !friendImportDialog.friendImportFavoriteGroup") {{ $t('dialog.friend_import.import') }}
span(v-if="friendImportDialog.importProgress" style="margin:10px") #[i.el-icon-loading(style="margin-right:5px")] {{ $t('dialog.friend_import.import_progress') }} {{ friendImportDialog.importProgress }}/{{ friendImportDialog.importProgressTotal }}
el-button(size='small' @click='clearFriendImportTable' :disabled='friendImportTable.data.length === 0') {{ $t('dialog.friend_import.clear_table') }}
el-button(
size='small'
type='primary'
@click='importFriendImportTable'
style='margin: 5px'
:disabled='friendImportTable.data.length === 0 || !friendImportDialog.friendImportFavoriteGroup') {{ $t('dialog.friend_import.import') }}
span(v-if='friendImportDialog.importProgress' style='margin: 10px') #[i.el-icon-loading(style='margin-right: 5px')] {{ $t('dialog.friend_import.import_progress') }} {{ friendImportDialog.importProgress }}/{{ friendImportDialog.importProgressTotal }}
br
template(v-if="friendImportDialog.errors")
el-button(size="small" @click="friendImportDialog.errors = ''") {{ $t('dialog.friend_import.clear_errors') }}
h2(style="font-weight:bold;margin:5px 0") {{ $t('dialog.friend_import.errors') }}
pre(v-text="friendImportDialog.errors" style="white-space:pre-wrap;font-size:12px")
data-tables(v-if="friendImportDialog.visible" v-bind="friendImportTable" v-loading="friendImportDialog.loading" style="margin-top:10px")
el-table-column(:label="$t('table.import.image')" width="70" prop="currentAvatarThumbnailImageUrl")
template(#default="scope")
el-popover(placement="right" height="500px" trigger="hover")
img.friends-list-avatar(slot="reference" v-lazy="userImage(scope.row)")
img.friends-list-avatar(v-lazy="userImageFull(scope.row)" style="height:500px;cursor:pointer" @click="showFullscreenImageDialog(userImageFull(scope.row))")
el-table-column(:label="$t('table.import.name')" prop="displayName")
template(#default="scope")
span.x-link(v-text="scope.row.displayName" @click="showUserDialog(scope.row.id)")
el-table-column(:label="$t('table.import.action')" width="90" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-close" size="mini" @click="deleteItemFriendImport(scope.row)")
template(v-if='friendImportDialog.errors')
el-button(size='small' @click='friendImportDialog.errors = ""') {{ $t('dialog.friend_import.clear_errors') }}
h2(style='font-weight: bold; margin: 5px 0') {{ $t('dialog.friend_import.errors') }}
pre(v-text='friendImportDialog.errors' style='white-space: pre-wrap; font-size: 12px')
data-tables(
v-if='friendImportDialog.visible'
v-bind='friendImportTable'
v-loading='friendImportDialog.loading'
style='margin-top: 10px')
el-table-column(:label='$t("table.import.image")' width='70' prop='currentAvatarThumbnailImageUrl')
template(#default='scope')
el-popover(placement='right' height='500px' trigger='hover')
img.friends-list-avatar(slot='reference' v-lazy='userImage(scope.row)')
img.friends-list-avatar(
v-lazy='userImageFull(scope.row)'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(userImageFull(scope.row))')
el-table-column(:label='$t("table.import.name")' prop='displayName')
template(#default='scope')
span.x-link(v-text='scope.row.displayName' @click='showUserDialog(scope.row.id)')
el-table-column(:label='$t("table.import.action")' width='90' align='right')
template(#default='scope')
el-button(type='text' icon='el-icon-close' size='mini' @click='deleteItemFriendImport(scope.row)')

View File

@@ -33,11 +33,14 @@ mixin groupDialog
.group-header(style='flex: 1')
span(v-if='groupDialog.ref.ownerId === API.currentUser.id' style='margin-right: 5px') 👑
span.dialog-title(v-text='groupDialog.ref.name' style='margin-right: 5px')
span.group-discriminator.x-grey(style='font-family: monospace; font-size: 12px; margin-right: 5px') {{ groupDialog.ref.shortCode }}.{{ groupDialog.ref.discriminator }}
span.group-discriminator.x-grey(
style='font-family: monospace; font-size: 12px; margin-right: 5px') {{ groupDialog.ref.shortCode }}.{{ groupDialog.ref.discriminator }}
el-tooltip(v-for='item in groupDialog.ref.$languages' :key='item.key' placement='top')
template(#content)
span {{ item.value }} ({{ item.key }})
span.flags(:class='languageClass(item.key)' style='display: inline-block; margin-right: 5px')
span.flags(
:class='languageClass(item.key)'
style='display: inline-block; margin-right: 5px')
div(style='margin-top: 5px')
span.x-link.x-grey(
v-text='groupDialog.ownerDisplayName'
@@ -218,7 +221,11 @@ mixin groupDialog
circle
@click='joinGroup(groupDialog.id)'
style='margin-left: 5px')
el-dropdown(trigger='click' @command='groupDialogCommand' size='small' style='margin-left: 5px')
el-dropdown(
trigger='click'
@command='groupDialogCommand'
size='small'
style='margin-left: 5px')
el-button(
:type='groupDialog.ref.membershipStatus === "userblocked" ? "danger" : "default"'
icon='el-icon-more'
@@ -276,7 +283,9 @@ mixin groupDialog
style='width: 854px; height: 480px'
@click='showFullscreenImageDialog(groupDialog.ref.bannerUrl)')
.x-friend-list(style='max-height: none')
span(v-if='groupDialog.instances.length' style='font-size: 12px; font-weight: bold; margin: 5px') {{ $t('dialog.group.info.instances') }}
span(
v-if='groupDialog.instances.length'
style='font-size: 12px; font-weight: bold; margin: 5px') {{ $t('dialog.group.info.instances') }}
div(v-for='room in groupDialog.instances' :key='room.tag' style='width: 100%')
div(style='margin: 5px 0')
location(:location='room.tag')
@@ -295,7 +304,9 @@ mixin groupDialog
:instance='room.ref'
:friendcount='room.friendCount'
:updateelement='updateInstanceInfo')
.x-friend-list(style='margin: 10px 0; padding: 0; max-height: unset' v-if='room.users.length')
.x-friend-list(
style='margin: 10px 0; padding: 0; max-height: unset'
v-if='room.users.length')
.x-friend-item.x-friend-item-border(
v-for='user in room.users'
:key='user.id'
@@ -560,7 +571,9 @@ mixin groupDialog
v-if='groupDialog.memberSearch.length'
style='font-size: 14px; margin-left: 5px; margin-right: 5px') {{ groupDialog.memberSearchResults.length }}/{{ groupDialog.ref.memberCount }}
span(v-else style='font-size: 14px; margin-left: 5px; margin-right: 5px') {{ groupDialog.members.length }}/{{ groupDialog.ref.memberCount }}
div(v-if='hasGroupPermission(groupDialog.ref, "group-members-manage")' style='float: right')
div(
v-if='hasGroupPermission(groupDialog.ref, "group-members-manage")'
style='float: right')
span(style='margin-right: 5px') {{ $t('dialog.group.members.sort_by') }}
el-dropdown(
@click.native.stop

File diff suppressed because it is too large Load Diff

View File

@@ -1,61 +1,150 @@
mixin images()
mixin images
//- dialog: Change avatar image
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="changeAvatarImageDialog" :visible.sync="changeAvatarImageDialogVisible" :title="$t('dialog.change_content_image.avatar')" width="850px")
div(v-if="changeAvatarImageDialogVisible" v-loading="changeAvatarImageDialogLoading")
input(type="file" accept="image/*" @change="onFileChangeAvatarImage" id="AvatarImageUploadButton" style="display:none")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='changeAvatarImageDialog'
:visible.sync='changeAvatarImageDialogVisible'
:title='$t("dialog.change_content_image.avatar")'
width='850px')
div(v-if='changeAvatarImageDialogVisible' v-loading='changeAvatarImageDialogLoading')
input#AvatarImageUploadButton(
type='file'
accept='image/*'
@change='onFileChangeAvatarImage'
style='display: none')
span {{ $t('dialog.change_content_image.description') }}
br
el-button-group(style="padding-bottom:10px;padding-top:10px")
el-button(type="default" size="small" @click="displayPreviousImages('Avatar', 'Change')" icon="el-icon-refresh") {{ $t('dialog.change_content_image.refresh') }}
el-button(type="default" size="small" @click="uploadAvatarImage" icon="el-icon-upload2") {{ $t('dialog.change_content_image.upload') }}
el-button-group(style='padding-bottom: 10px; padding-top: 10px')
el-button(
type='default'
size='small'
@click='displayPreviousImages("Avatar", "Change")'
icon='el-icon-refresh') {{ $t('dialog.change_content_image.refresh') }}
el-button(type='default' size='small' @click='uploadAvatarImage' icon='el-icon-upload2') {{ $t('dialog.change_content_image.upload') }}
//- el-button(type="default" size="small" @click="deleteAvatarImage" icon="el-icon-delete") Delete Latest Image
br
div(style="display:inline-block" v-for="image in previousImagesTable" :key="image.version" v-if="image.file")
.x-change-image-item(@click="setAvatarImage(image)" style="cursor:pointer" :class="{ 'current-image': compareCurrentImage(image) }")
img.image(v-lazy="image.file.url")
div(
style='display: inline-block'
v-for='image in previousImagesTable'
:key='image.version'
v-if='image.file')
.x-change-image-item(
@click='setAvatarImage(image)'
style='cursor: pointer'
:class='{ "current-image": compareCurrentImage(image) }')
img.image(v-lazy='image.file.url')
//- dialog: Change world image
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="changeWorldImageDialog" :visible.sync="changeWorldImageDialogVisible" :title="$t('dialog.change_content_image.world')" width="850px")
div(v-if="changeWorldImageDialogVisible" v-loading="changeWorldImageDialogLoading")
input(type="file" accept="image/*" @change="onFileChangeWorldImage" id="WorldImageUploadButton" style="display:none")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='changeWorldImageDialog'
:visible.sync='changeWorldImageDialogVisible'
:title='$t("dialog.change_content_image.world")'
width='850px')
div(v-if='changeWorldImageDialogVisible' v-loading='changeWorldImageDialogLoading')
input#WorldImageUploadButton(
type='file'
accept='image/*'
@change='onFileChangeWorldImage'
style='display: none')
span {{ $t('dialog.change_content_image.description') }}
br
el-button-group(style="padding-bottom:10px;padding-top:10px")
el-button(type="default" size="small" @click="displayPreviousImages('World', 'Change')" icon="el-icon-refresh") {{ $t('dialog.change_content_image.refresh') }}
el-button(type="default" size="small" @click="uploadWorldImage" icon="el-icon-upload2") {{ $t('dialog.change_content_image.upload') }}
el-button-group(style='padding-bottom: 10px; padding-top: 10px')
el-button(
type='default'
size='small'
@click='displayPreviousImages("World", "Change")'
icon='el-icon-refresh') {{ $t('dialog.change_content_image.refresh') }}
el-button(type='default' size='small' @click='uploadWorldImage' icon='el-icon-upload2') {{ $t('dialog.change_content_image.upload') }}
//- el-button(type="default" size="small" @click="deleteWorldImage" icon="el-icon-delete") Delete Latest Image
br
div(style="display:inline-block" v-for="image in previousImagesTable" :key="image.version" v-if="image.file")
.x-change-image-item(@click="setWorldImage(image)" style="cursor:pointer" :class="{ 'current-image': compareCurrentImage(image) }")
img.image(v-lazy="image.file.url")
div(
style='display: inline-block'
v-for='image in previousImagesTable'
:key='image.version'
v-if='image.file')
.x-change-image-item(
@click='setWorldImage(image)'
style='cursor: pointer'
:class='{ "current-image": compareCurrentImage(image) }')
img.image(v-lazy='image.file.url')
//- dialog: Display previous avatar/world images
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="previousImagesDialog" :visible.sync="previousImagesDialogVisible" :title="$t('dialog.previous_images.header')" width="800px")
div(v-if="previousImagesDialogVisible")
div(style="display:inline-block" v-for="image in previousImagesTable" :key="image.version" v-if="image.file")
el-popover.x-change-image-item(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="image.file.url")
img.x-link(v-lazy="image.file.url" style="width:500px;height:375px" @click="showFullscreenImageDialog(image.file.url)")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='previousImagesDialog'
:visible.sync='previousImagesDialogVisible'
:title='$t("dialog.previous_images.header")'
width='800px')
div(v-if='previousImagesDialogVisible')
div(
style='display: inline-block'
v-for='image in previousImagesTable'
:key='image.version'
v-if='image.file')
el-popover.x-change-image-item(placement='right' width='500px' trigger='click')
img.x-link(slot='reference' v-lazy='image.file.url')
img.x-link(
v-lazy='image.file.url'
style='width: 500px; height: 375px'
@click='showFullscreenImageDialog(image.file.url)')
//- dialog: gallery select
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="gallerySelectDialog" :visible.sync="gallerySelectDialog.visible" :title="$t('dialog.gallery_select.header')" width="100%")
div(v-if="gallerySelectDialog.visible")
span(slot="label") {{ $t('dialog.gallery_select.gallery') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ galleryTable.length }}/64
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='gallerySelectDialog'
:visible.sync='gallerySelectDialog.visible'
:title='$t("dialog.gallery_select.header")'
width='100%')
div(v-if='gallerySelectDialog.visible')
span(slot='label') {{ $t('dialog.gallery_select.gallery') }}
span(style='color: #909399; font-size: 12px; margin-left: 5px') {{ galleryTable.length }}/64
br
input(type="file" accept="image/*" @change="onFileChangeGallery" id="GalleryUploadButton" style="display:none")
input#GalleryUploadButton(type='file' accept='image/*' @change='onFileChangeGallery' style='display: none')
el-button-group
el-button(type="default" size="small" @click="selectImageGallerySelect('', '')" icon="el-icon-close") {{ $t('dialog.gallery_select.none') }}
el-button(type="default" size="small" @click="refreshGalleryTable" icon="el-icon-refresh") {{ $t('dialog.gallery_select.refresh') }}
el-button(type="default" size="small" @click="displayGalleryUpload" icon="el-icon-upload2" :disabled="!API.currentUser.$isVRCPlus") {{ $t('dialog.gallery_select.upload') }}
el-button(type='default' size='small' @click='selectImageGallerySelect("", "")' icon='el-icon-close') {{ $t('dialog.gallery_select.none') }}
el-button(type='default' size='small' @click='refreshGalleryTable' icon='el-icon-refresh') {{ $t('dialog.gallery_select.refresh') }}
el-button(
type='default'
size='small'
@click='displayGalleryUpload'
icon='el-icon-upload2'
:disabled='!API.currentUser.$isVRCPlus') {{ $t('dialog.gallery_select.upload') }}
br
.x-friend-item(v-if="image.versions && image.versions.length > 0" v-for="image in galleryTable" :key="image.id" style="display:inline-block;margin-top:10px;width:unset;cursor:default")
.vrcplus-icon(v-if="image.versions[image.versions.length - 1].file.url" @click="selectImageGallerySelect(image.versions[image.versions.length - 1].file.url, image.id)")
img.avatar(v-lazy="image.versions[image.versions.length - 1].file.url")
.x-friend-item(
v-if='image.versions && image.versions.length > 0'
v-for='image in galleryTable'
:key='image.id'
style='display: inline-block; margin-top: 10px; width: unset; cursor: default')
.vrcplus-icon(
v-if='image.versions[image.versions.length - 1].file.url'
@click='selectImageGallerySelect(image.versions[image.versions.length - 1].file.url, image.id)')
img.avatar(v-lazy='image.versions[image.versions.length - 1].file.url')
//- dialog: full screen image
el-dialog.x-dialog(ref="fullscreenImageDialog" :before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" :visible.sync="fullscreenImageDialog.visible" top="3vh" width="97vw")
div(style="margin:0 0 5px 5px")
el-button(@click="copyImageUrl(fullscreenImageDialog.imageUrl)" size="mini" icon="el-icon-s-order" circle)
el-button(type="default" size="mini" icon="el-icon-download" circle @click="downloadAndSaveImage(fullscreenImageDialog.imageUrl, fullscreenImageDialog.fileName)" style="margin-left:5px")
img(v-lazy="fullscreenImageDialog.imageUrl" style="width:100%;height:100vh;object-fit:contain")
el-dialog.x-dialog(
ref='fullscreenImageDialog'
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
:visible.sync='fullscreenImageDialog.visible'
top='3vh'
width='97vw')
div(style='margin: 0 0 5px 5px')
el-button(@click='copyImageUrl(fullscreenImageDialog.imageUrl)' size='mini' icon='el-icon-s-order' circle)
el-button(
type='default'
size='mini'
icon='el-icon-download'
circle
@click='downloadAndSaveImage(fullscreenImageDialog.imageUrl, fullscreenImageDialog.fileName)'
style='margin-left: 5px')
img(v-lazy='fullscreenImageDialog.imageUrl' style='width: 100%; height: 100vh; object-fit: contain')

View File

@@ -1,118 +1,262 @@
mixin invites()
mixin invites
//- dialog: invite
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="inviteDialog" :visible.sync="inviteDialog.visible" :title="$t('dialog.invite.header')" width="500px")
div(v-if="inviteDialog.visible" v-loading="inviteDialog.loading")
location(:location="inviteDialog.worldId" :link="false")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='inviteDialog'
:visible.sync='inviteDialog.visible'
:title='$t("dialog.invite.header")'
width='500px')
div(v-if='inviteDialog.visible' v-loading='inviteDialog.loading')
location(:location='inviteDialog.worldId' :link='false')
br
el-button(size="mini" v-text="$t('dialog.invite.add_self')" @click="addSelfToInvite" style="margin-top:10px")
el-button(size="mini" v-text="$t('dialog.invite.add_friends_in_instance')" @click="addFriendsInInstanceToInvite" :disabled="inviteDialog.friendsInInstance.length === 0" style="margin-top:10px")
el-button(size="mini" v-text="$t('dialog.invite.add_favorite_friends')" @click="addFavoriteFriendsToInvite" :disabled="vipFriends.length === 0" style="margin-top:10px")
el-select(v-model="inviteDialog.userIds" multiple clearable :placeholder="$t('dialog.invite.select_placeholder')" filterable :disabled="inviteDialog.loading" style="width:100%;margin-top:15px")
el-option-group(v-if="API.currentUser" :label="$t('side_panel.me')")
el-option.x-friend-item(:label="API.currentUser.displayName" :value="API.currentUser.id" style="height:auto")
.avatar(:class="userStatusClass(API.currentUser)")
img(v-lazy="userImage(API.currentUser)")
el-button(
size='mini'
v-text='$t("dialog.invite.add_self")'
@click='addSelfToInvite'
style='margin-top: 10px')
el-button(
size='mini'
v-text='$t("dialog.invite.add_friends_in_instance")'
@click='addFriendsInInstanceToInvite'
:disabled='inviteDialog.friendsInInstance.length === 0'
style='margin-top: 10px')
el-button(
size='mini'
v-text='$t("dialog.invite.add_favorite_friends")'
@click='addFavoriteFriendsToInvite'
:disabled='vipFriends.length === 0'
style='margin-top: 10px')
el-select(
v-model='inviteDialog.userIds'
multiple
clearable
:placeholder='$t("dialog.invite.select_placeholder")'
filterable
:disabled='inviteDialog.loading'
style='width: 100%; margin-top: 15px')
el-option-group(v-if='API.currentUser' :label='$t("side_panel.me")')
el-option.x-friend-item(
:label='API.currentUser.displayName'
:value='API.currentUser.id'
style='height: auto')
.avatar(:class='userStatusClass(API.currentUser)')
img(v-lazy='userImage(API.currentUser)')
.detail
span.name(v-text="API.currentUser.displayName")
el-option-group(v-if="inviteDialog.friendsInInstance.length" :label="$t('dialog.invite.friends_in_instance')")
el-option.x-friend-item(v-for="friend in inviteDialog.friendsInInstance" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
span.name(v-text='API.currentUser.displayName')
el-option-group(
v-if='inviteDialog.friendsInInstance.length'
:label='$t("dialog.invite.friends_in_instance")')
el-option.x-friend-item(
v-for='friend in inviteDialog.friendsInInstance'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar(:class='userStatusClass(friend.ref)')
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="vipFriends.length" :label="$t('side_panel.favorite')")
el-option.x-friend-item(v-for="friend in vipFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
span.name(v-text='friend.ref.displayName' :style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='vipFriends.length' :label='$t("side_panel.favorite")')
el-option.x-friend-item(
v-for='friend in vipFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar(:class='userStatusClass(friend.ref)')
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="onlineFriends.length" :label="$t('side_panel.online')")
el-option.x-friend-item(v-for="friend in onlineFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
span.name(v-text='friend.ref.displayName' :style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='onlineFriends.length' :label='$t("side_panel.online")')
el-option.x-friend-item(
v-for='friend in onlineFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar(:class='userStatusClass(friend.ref)')
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="activeFriends.length" :label="$t('side_panel.active')")
el-option.x-friend-item(v-for="friend in activeFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
span.name(v-text='friend.ref.displayName' :style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='activeFriends.length' :label='$t("side_panel.active")')
el-option.x-friend-item(
v-for='friend in activeFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar
img(v-lazy="userImage(friend.ref)")
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
span.name(v-text='friend.ref.displayName' :style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
template(#footer)
el-button(size="small" :disabled="inviteDialog.loading || !inviteDialog.userIds.length" @click="showSendInviteDialog()") {{ $t('dialog.invite.invite_with_message') }}
el-button(type="primary" size="small" :disabled="inviteDialog.loading || !inviteDialog.userIds.length" @click="sendInvite()") {{ $t('dialog.invite.invite') }}
el-button(
size='small'
:disabled='inviteDialog.loading || !inviteDialog.userIds.length'
@click='showSendInviteDialog()') {{ $t('dialog.invite.invite_with_message') }}
el-button(
type='primary'
size='small'
:disabled='inviteDialog.loading || !inviteDialog.userIds.length'
@click='sendInvite()') {{ $t('dialog.invite.invite') }}
//- dialog: Edit Invite Message
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="editInviteMessageDialog" :visible.sync="editInviteMessageDialog.visible" :title="$t('dialog.edit_invite_message.header')" width="400px")
div(style='font-size:12px')
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='editInviteMessageDialog'
:visible.sync='editInviteMessageDialog.visible'
:title='$t("dialog.edit_invite_message.header")'
width='400px')
div(style='font-size: 12px')
span {{ $t('dialog.edit_invite_message.description') }}
el-input(type="textarea" v-model="editInviteMessageDialog.newMessage" size="mini" maxlength="64" show-word-limit :autosize="{ minRows:2, maxRows:5 }" placeholder="" style="margin-top:10px")
el-input(
type='textarea'
v-model='editInviteMessageDialog.newMessage'
size='mini'
maxlength='64'
show-word-limit
:autosize='{ minRows: 2, maxRows: 5 }'
placeholder=''
style='margin-top: 10px')
template(#footer)
el-button(type="small" @click="cancelEditInviteMessage") {{ $t('dialog.edit_invite_message.cancel') }}
el-button(type="primary" size="small" @click="saveEditInviteMessage") {{ $t('dialog.edit_invite_message.save') }}
el-button(type='small' @click='cancelEditInviteMessage') {{ $t('dialog.edit_invite_message.cancel') }}
el-button(type='primary' size='small' @click='saveEditInviteMessage') {{ $t('dialog.edit_invite_message.save') }}
//- dialog: Edit And Send Invite Response Message
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="editAndSendInviteResponseDialog" :visible.sync="editAndSendInviteResponseDialog.visible" :title="$t('dialog.edit_send_invite_response_message.header')" width="400px")
div(style='font-size:12px')
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='editAndSendInviteResponseDialog'
:visible.sync='editAndSendInviteResponseDialog.visible'
:title='$t("dialog.edit_send_invite_response_message.header")'
width='400px')
div(style='font-size: 12px')
span {{ $t('dialog.edit_send_invite_response_message.description') }}
el-input(type="textarea" v-model="editAndSendInviteResponseDialog.newMessage" size="mini" maxlength="64" show-word-limit :autosize="{ minRows:2, maxRows:5 }" placeholder="" style="margin-top:10px")
el-input(
type='textarea'
v-model='editAndSendInviteResponseDialog.newMessage'
size='mini'
maxlength='64'
show-word-limit
:autosize='{ minRows: 2, maxRows: 5 }'
placeholder=''
style='margin-top: 10px')
template(#footer)
el-button(type="small" @click="cancelEditAndSendInviteResponse") {{ $t('dialog.edit_send_invite_response_message.cancel') }}
el-button(type="primary" size="small" @click="saveEditAndSendInviteResponse") {{ $t('dialog.edit_send_invite_response_message.send') }}
el-button(type='small' @click='cancelEditAndSendInviteResponse') {{ $t('dialog.edit_send_invite_response_message.cancel') }}
el-button(type='primary' size='small' @click='saveEditAndSendInviteResponse') {{ $t('dialog.edit_send_invite_response_message.send') }}
//- dialog Table: Send Invite Response Message
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="sendInviteResponseDialog" :visible.sync="sendInviteResponseDialogVisible" :title="$t('dialog.invite_response_message.header')" width="800px")
template(v-if="API.currentUser.$isVRCPlus")
input.inviteImageUploadButton(type="file" accept="image/*" @change="inviteImageUpload")
data-tables(v-if="sendInviteResponseDialogVisible" v-bind="inviteResponseMessageTable" @row-click="showSendInviteResponseConfirmDialog" style="margin-top:10px;cursor:pointer")
el-table-column(:label="$t('table.profile.invite_messages.slot')" prop="slot" sortable="custom" width="70")
el-table-column(:label="$t('table.profile.invite_messages.message')" prop="message")
el-table-column(:label="$t('table.profile.invite_messages.cool_down')" prop="updatedAt" sortable="custom" width="110" align="right")
template(#default="scope")
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
el-table-column(:label="$t('table.profile.invite_messages.action')" width="70" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditAndSendInviteResponseDialog('response', scope.row)")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='sendInviteResponseDialog'
:visible.sync='sendInviteResponseDialogVisible'
:title='$t("dialog.invite_response_message.header")'
width='800px')
template(v-if='API.currentUser.$isVRCPlus')
input.inviteImageUploadButton(type='file' accept='image/*' @change='inviteImageUpload')
data-tables(
v-if='sendInviteResponseDialogVisible'
v-bind='inviteResponseMessageTable'
@row-click='showSendInviteResponseConfirmDialog'
style='margin-top: 10px; cursor: pointer')
el-table-column(:label='$t("table.profile.invite_messages.slot")' prop='slot' sortable='custom' width='70')
el-table-column(:label='$t("table.profile.invite_messages.message")' prop='message')
el-table-column(
:label='$t("table.profile.invite_messages.cool_down")'
prop='updatedAt'
sortable='custom'
width='110'
align='right')
template(#default='scope')
countdown-timer(:datetime='scope.row.updatedAt' :hours='1')
el-table-column(:label='$t("table.profile.invite_messages.action")' width='70' align='right')
template(#default='scope')
el-button(
type='text'
icon='el-icon-edit'
size='mini'
@click='showEditAndSendInviteResponseDialog("response", scope.row)')
template(#footer)
el-button(type="small" @click="cancelSendInviteResponse") {{ $t('dialog.invite_response_message.cancel') }}
el-button(type="small" @click="API.refreshInviteMessageTableData('response')") {{ $t('dialog.invite_response_message.refresh') }}
el-button(type='small' @click='cancelSendInviteResponse') {{ $t('dialog.invite_response_message.cancel') }}
el-button(type='small' @click='API.refreshInviteMessageTableData("response")') {{ $t('dialog.invite_response_message.refresh') }}
//- dialog Table: Send Invite Request Response Message
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="sendInviteRequestResponseDialog" :visible.sync="sendInviteRequestResponseDialogVisible" :title="$t('dialog.invite_request_response_message.header')" width="800px")
template(v-if="API.currentUser.$isVRCPlus")
input.inviteImageUploadButton(type="file" accept="image/*" @change="inviteImageUpload")
data-tables(v-if="sendInviteRequestResponseDialogVisible" v-bind="inviteRequestResponseMessageTable" @row-click="showSendInviteResponseConfirmDialog" style="margin-top:10px;cursor:pointer")
el-table-column(:label="$t('table.profile.invite_messages.slot')" prop="slot" sortable="custom" width="70")
el-table-column(:label="$t('table.profile.invite_messages.message')" prop="message")
el-table-column(:label="$t('table.profile.invite_messages.cool_down')" prop="updatedAt" sortable="custom" width="110" align="right")
template(#default="scope")
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
el-table-column(:label="$t('table.profile.invite_messages.action')" width="70" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditAndSendInviteResponseDialog('requestResponse', scope.row)")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='sendInviteRequestResponseDialog'
:visible.sync='sendInviteRequestResponseDialogVisible'
:title='$t("dialog.invite_request_response_message.header")'
width='800px')
template(v-if='API.currentUser.$isVRCPlus')
input.inviteImageUploadButton(type='file' accept='image/*' @change='inviteImageUpload')
data-tables(
v-if='sendInviteRequestResponseDialogVisible'
v-bind='inviteRequestResponseMessageTable'
@row-click='showSendInviteResponseConfirmDialog'
style='margin-top: 10px; cursor: pointer')
el-table-column(:label='$t("table.profile.invite_messages.slot")' prop='slot' sortable='custom' width='70')
el-table-column(:label='$t("table.profile.invite_messages.message")' prop='message')
el-table-column(
:label='$t("table.profile.invite_messages.cool_down")'
prop='updatedAt'
sortable='custom'
width='110'
align='right')
template(#default='scope')
countdown-timer(:datetime='scope.row.updatedAt' :hours='1')
el-table-column(:label='$t("table.profile.invite_messages.action")' width='70' align='right')
template(#default='scope')
el-button(
type='text'
icon='el-icon-edit'
size='mini'
@click='showEditAndSendInviteResponseDialog("requestResponse", scope.row)')
template(#footer)
el-button(type="small" @click="cancelSendInviteRequestResponse") {{ $t('dialog.invite_request_response_message.cancel') }}
el-button(type="small" @click="API.refreshInviteMessageTableData('requestResponse')") {{ $t('dialog.invite_request_response_message.refresh') }}
el-button(type='small' @click='cancelSendInviteRequestResponse') {{ $t('dialog.invite_request_response_message.cancel') }}
el-button(type='small' @click='API.refreshInviteMessageTableData("requestResponse")') {{ $t('dialog.invite_request_response_message.refresh') }}
//- dialog: Send Invite Response Message Confirm
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="sendInviteResponseConfirmDialog" :visible.sync="sendInviteResponseConfirmDialog.visible" :title="$t('dialog.invite_response_message.header')" width="400px")
div(style='font-size:12px')
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='sendInviteResponseConfirmDialog'
:visible.sync='sendInviteResponseConfirmDialog.visible'
:title='$t("dialog.invite_response_message.header")'
width='400px')
div(style='font-size: 12px')
span {{ $t('dialog.invite_response_message.confirmation') }}
template(#footer)
el-button(type="small" @click="cancelInviteResponseConfirm") {{ $t('dialog.invite_response_message.cancel') }}
el-button(type="primary" size="small" @click="sendInviteResponseConfirm") {{ $t('dialog.invite_response_message.confirm') }}
el-button(type='small' @click='cancelInviteResponseConfirm') {{ $t('dialog.invite_response_message.cancel') }}
el-button(type='primary' size='small' @click='sendInviteResponseConfirm') {{ $t('dialog.invite_response_message.confirm') }}
//- dialog Table: Send Invite Message
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="sendInviteDialog" :visible.sync="sendInviteDialogVisible" :title="$t('dialog.invite_message.header')" width="800px")
template(v-if="API.currentUser.$isVRCPlus")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='sendInviteDialog'
:visible.sync='sendInviteDialogVisible'
:title='$t("dialog.invite_message.header")'
width='800px')
template(v-if='API.currentUser.$isVRCPlus')
//- template(v-if="gallerySelectDialog.selectedFileId")
//- div(style="display:inline-block;flex:none;margin-right:5px")
//- el-popover(placement="right" width="500px" trigger="click")
@@ -121,50 +265,105 @@ mixin invites()
//- el-button(size="mini" @click="clearImageGallerySelect" style="vertical-align:top") {{ $t('dialog.invite_message.clear_selected_image') }}
//- template(v-else)
//- el-button(size="mini" @click="showGallerySelectDialog" style="margin-right:5px") {{ $t('dialog.invite_message.select_image') }}
input.inviteImageUploadButton(type="file" accept="image/*" @change="inviteImageUpload")
data-tables(v-if="sendInviteDialogVisible" v-bind="inviteMessageTable" @row-click="showSendInviteConfirmDialog" style="margin-top:10px;cursor:pointer")
el-table-column(:label="$t('table.profile.invite_messages.slot')" prop="slot" sortable="custom" width="70")
el-table-column(:label="$t('table.profile.invite_messages.message')" prop="message")
el-table-column(:label="$t('table.profile.invite_messages.cool_down')" prop="updatedAt" sortable="custom" width="110" align="right")
template(#default="scope")
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
el-table-column(:label="$t('table.profile.invite_messages.action')" width="70" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditAndSendInviteDialog('message', scope.row)")
input.inviteImageUploadButton(type='file' accept='image/*' @change='inviteImageUpload')
data-tables(
v-if='sendInviteDialogVisible'
v-bind='inviteMessageTable'
@row-click='showSendInviteConfirmDialog'
style='margin-top: 10px; cursor: pointer')
el-table-column(:label='$t("table.profile.invite_messages.slot")' prop='slot' sortable='custom' width='70')
el-table-column(:label='$t("table.profile.invite_messages.message")' prop='message')
el-table-column(
:label='$t("table.profile.invite_messages.cool_down")'
prop='updatedAt'
sortable='custom'
width='110'
align='right')
template(#default='scope')
countdown-timer(:datetime='scope.row.updatedAt' :hours='1')
el-table-column(:label='$t("table.profile.invite_messages.action")' width='70' align='right')
template(#default='scope')
el-button(
type='text'
icon='el-icon-edit'
size='mini'
@click='showEditAndSendInviteDialog("message", scope.row)')
template(#footer)
el-button(type="small" @click="cancelSendInvite") {{ $t('dialog.invite_message.cancel') }}
el-button(type="small" @click="API.refreshInviteMessageTableData('message')") {{ $t('dialog.invite_message.refresh') }}
el-button(type='small' @click='cancelSendInvite') {{ $t('dialog.invite_message.cancel') }}
el-button(type='small' @click='API.refreshInviteMessageTableData("message")') {{ $t('dialog.invite_message.refresh') }}
//- dialog Table: Send Invite Request Message
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="sendInviteRequestDialog" :visible.sync="sendInviteRequestDialogVisible" :title="$t('dialog.invite_request_message.header')" width="800px")
template(v-if="API.currentUser.$isVRCPlus")
input.inviteImageUploadButton(type="file" accept="image/*" @change="inviteImageUpload")
data-tables(v-if="sendInviteRequestDialogVisible" v-bind="inviteRequestMessageTable" @row-click="showSendInviteConfirmDialog" style="margin-top:10px;cursor:pointer")
el-table-column(:label="$t('table.profile.invite_messages.slot')" prop="slot" sortable="custom" width="70")
el-table-column(:label="$t('table.profile.invite_messages.message')" prop="message")
el-table-column(:label="$t('table.profile.invite_messages.cool_down')" prop="updatedAt" sortable="custom" width="110" align="right")
template(#default="scope")
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
el-table-column(:label="$t('table.profile.invite_messages.action')" width="70" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditAndSendInviteDialog('request', scope.row)")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='sendInviteRequestDialog'
:visible.sync='sendInviteRequestDialogVisible'
:title='$t("dialog.invite_request_message.header")'
width='800px')
template(v-if='API.currentUser.$isVRCPlus')
input.inviteImageUploadButton(type='file' accept='image/*' @change='inviteImageUpload')
data-tables(
v-if='sendInviteRequestDialogVisible'
v-bind='inviteRequestMessageTable'
@row-click='showSendInviteConfirmDialog'
style='margin-top: 10px; cursor: pointer')
el-table-column(:label='$t("table.profile.invite_messages.slot")' prop='slot' sortable='custom' width='70')
el-table-column(:label='$t("table.profile.invite_messages.message")' prop='message')
el-table-column(
:label='$t("table.profile.invite_messages.cool_down")'
prop='updatedAt'
sortable='custom'
width='110'
align='right')
template(#default='scope')
countdown-timer(:datetime='scope.row.updatedAt' :hours='1')
el-table-column(:label='$t("table.profile.invite_messages.action")' width='70' align='right')
template(#default='scope')
el-button(
type='text'
icon='el-icon-edit'
size='mini'
@click='showEditAndSendInviteDialog("request", scope.row)')
template(#footer)
el-button(type="small" @click="cancelSendInviteRequest") {{ $t('dialog.invite_request_message.cancel') }}
el-button(type="small" @click="API.refreshInviteMessageTableData('request')") {{ $t('dialog.invite_request_message.refresh') }}
el-button(type='small' @click='cancelSendInviteRequest') {{ $t('dialog.invite_request_message.cancel') }}
el-button(type='small' @click='API.refreshInviteMessageTableData("request")') {{ $t('dialog.invite_request_message.refresh') }}
//- dialog: Send Invite Message Confirm
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="sendInviteConfirmDialog" :visible.sync="sendInviteConfirmDialog.visible" :title="$t('dialog.invite_message.header')" width="400px")
div(style='font-size:12px')
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='sendInviteConfirmDialog'
:visible.sync='sendInviteConfirmDialog.visible'
:title='$t("dialog.invite_message.header")'
width='400px')
div(style='font-size: 12px')
span {{ $t('dialog.invite_message.confirmation') }}
template(#footer)
el-button(type="small" @click="cancelInviteConfirm") {{ $t('dialog.invite_message.cancel') }}
el-button(type="primary" size="small" @click="sendInviteConfirm") {{ $t('dialog.invite_message.confirm') }}
el-button(type='small' @click='cancelInviteConfirm') {{ $t('dialog.invite_message.cancel') }}
el-button(type='primary' size='small' @click='sendInviteConfirm') {{ $t('dialog.invite_message.confirm') }}
//- dialog: Edit And Send Invite Message
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="editAndSendInviteDialog" :visible.sync="editAndSendInviteDialog.visible" :title="$t('dialog.edit_send_invite_message.header')" width="400px")
div(style='font-size:12px')
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='editAndSendInviteDialog'
:visible.sync='editAndSendInviteDialog.visible'
:title='$t("dialog.edit_send_invite_message.header")'
width='400px')
div(style='font-size: 12px')
span {{ $t('dialog.edit_send_invite_message.description') }}
el-input(type="textarea" v-model="editAndSendInviteDialog.newMessage" size="mini" maxlength="64" show-word-limit :autosize="{ minRows:2, maxRows:5 }" placeholder="" style="margin-top:10px")
el-input(
type='textarea'
v-model='editAndSendInviteDialog.newMessage'
size='mini'
maxlength='64'
show-word-limit
:autosize='{ minRows: 2, maxRows: 5 }'
placeholder=''
style='margin-top: 10px')
template(#footer)
el-button(type="small" @click="cancelEditAndSendInvite") {{ $t('dialog.edit_send_invite_message.cancel') }}
el-button(type="primary" size="small" @click="saveEditAndSendInvite") {{ $t('dialog.edit_send_invite_message.send') }}
el-button(type='small' @click='cancelEditAndSendInvite') {{ $t('dialog.edit_send_invite_message.cancel') }}
el-button(type='primary' size='small' @click='saveEditAndSendInvite') {{ $t('dialog.edit_send_invite_message.send') }}

View File

@@ -1,38 +1,105 @@
mixin launch()
mixin launch
//- dialog: launch
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="launchDialog" :visible.sync="launchDialog.visible" :title="$t('dialog.launch.header')" width="450px")
el-form(:model="launchDialog" label-width="80px")
el-form-item(:label="$t('dialog.launch.url')")
el-input(v-model="launchDialog.url" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()" style="width:260px")
el-tooltip(placement="right" :content="$t('dialog.launch.copy_tooltip')" :disabled="hideTooltips")
el-button(@click="copyInstanceMessage(launchDialog.url)" size="mini" icon="el-icon-s-order" style="margin-right:5px" circle)
el-form-item(v-if="launchDialog.shortUrl" :label="$t('dialog.launch.short_url')")
el-tooltip(placement="top" style="margin-left:5px" :content="$t('dialog.launch.short_url_notice')")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='launchDialog'
:visible.sync='launchDialog.visible'
:title='$t("dialog.launch.header")'
width='450px')
el-form(:model='launchDialog' label-width='80px')
el-form-item(:label='$t("dialog.launch.url")')
el-input(
v-model='launchDialog.url'
size='mini'
@click.native='$event.target.tagName === "INPUT" && $event.target.select()'
style='width: 260px')
el-tooltip(placement='right' :content='$t("dialog.launch.copy_tooltip")' :disabled='hideTooltips')
el-button(
@click='copyInstanceMessage(launchDialog.url)'
size='mini'
icon='el-icon-s-order'
style='margin-right: 5px'
circle)
el-form-item(v-if='launchDialog.shortUrl' :label='$t("dialog.launch.short_url")')
el-tooltip(placement='top' style='margin-left: 5px' :content='$t("dialog.launch.short_url_notice")')
i.el-icon-warning
el-input(v-model="launchDialog.shortUrl" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()" style="width:241px")
el-tooltip(placement="right" :content="$t('dialog.launch.copy_tooltip')" :disabled="hideTooltips")
el-button(@click="copyInstanceMessage(launchDialog.shortUrl)" size="mini" icon="el-icon-s-order" style="margin-right:5px" circle)
el-form-item(:label="$t('dialog.launch.location')")
el-input(v-model="launchDialog.location" size="mini" @click.native="$event.target.tagName === 'INPUT' && $event.target.select()" style="width:260px")
el-tooltip(placement="right" :content="$t('dialog.launch.copy_tooltip')" :disabled="hideTooltips")
el-button(@click="copyInstanceMessage(launchDialog.location)" size="mini" icon="el-icon-s-order" style="margin-right:5px" circle)
el-input(
v-model='launchDialog.shortUrl'
size='mini'
@click.native='$event.target.tagName === "INPUT" && $event.target.select()'
style='width: 241px')
el-tooltip(placement='right' :content='$t("dialog.launch.copy_tooltip")' :disabled='hideTooltips')
el-button(
@click='copyInstanceMessage(launchDialog.shortUrl)'
size='mini'
icon='el-icon-s-order'
style='margin-right: 5px'
circle)
el-form-item(:label='$t("dialog.launch.location")')
el-input(
v-model='launchDialog.location'
size='mini'
@click.native='$event.target.tagName === "INPUT" && $event.target.select()'
style='width: 260px')
el-tooltip(placement='right' :content='$t("dialog.launch.copy_tooltip")' :disabled='hideTooltips')
el-button(
@click='copyInstanceMessage(launchDialog.location)'
size='mini'
icon='el-icon-s-order'
style='margin-right: 5px'
circle)
template(#footer)
el-checkbox(v-model="launchDialog.desktop" @change="saveLaunchDialog" style="float:left;margin-top:5px") {{ $t('dialog.launch.start_as_desktop') }}
el-button(size="small" @click="showPreviousInstanceInfoDialog(launchDialog.location)") {{ $t('dialog.launch.info') }}
el-button(size="small" @click="showInviteDialog(launchDialog.location)" :disabled="!checkCanInvite(launchDialog.location)") {{ $t('dialog.launch.invite') }}
el-button(type="primary" size="small" @click="launchGame(launchDialog.location, launchDialog.shortName, launchDialog.desktop)" :disabled="!launchDialog.secureOrShortName") {{ $t('dialog.launch.launch') }}
el-checkbox(v-model='launchDialog.desktop' @change='saveLaunchDialog' style='float: left; margin-top: 5px') {{ $t('dialog.launch.start_as_desktop') }}
el-button(size='small' @click='showPreviousInstanceInfoDialog(launchDialog.location)') {{ $t('dialog.launch.info') }}
el-button(
size='small'
@click='showInviteDialog(launchDialog.location)'
:disabled='!checkCanInvite(launchDialog.location)') {{ $t('dialog.launch.invite') }}
el-button(
type='primary'
size='small'
@click='launchGame(launchDialog.location, launchDialog.shortName, launchDialog.desktop)'
:disabled='!launchDialog.secureOrShortName') {{ $t('dialog.launch.launch') }}
//- dialog: launch options
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="launchOptionsDialog" :visible.sync="launchOptionsDialog.visible" :title="$t('dialog.launch_options.header')" width="600px")
div(style="font-size:12px")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='launchOptionsDialog'
:visible.sync='launchOptionsDialog.visible'
:title='$t("dialog.launch_options.header")'
width='600px')
div(style='font-size: 12px')
| {{ $t('dialog.launch_options.description') }} #[br]
| {{ $t('dialog.launch_options.example') }} #[el-tag(size="mini") --fps=144]
el-input(type="textarea" v-model="launchOptionsDialog.launchArguments" size="mini" show-word-limit :autosize="{ minRows:2, maxRows:5 }" placeholder="" style="margin-top:10px")
div(style="font-size:12px;margin-top:10px")
| {{ $t('dialog.launch_options.example') }} #[el-tag(size='mini') --fps=144]
el-input(
type='textarea'
v-model='launchOptionsDialog.launchArguments'
size='mini'
show-word-limit
:autosize='{ minRows: 2, maxRows: 5 }'
placeholder=''
style='margin-top: 10px')
div(style='font-size: 12px; margin-top: 10px')
| {{ $t('dialog.launch_options.path_override') }}
el-input(type="textarea" v-model="launchOptionsDialog.vrcLaunchPathOverride" placeholder="C:\\Program Files (x86)\\Steam\\steamapps\\common\\VRChat" :rows="1" style="display:block;margin-top:10px")
el-input(
type='textarea'
v-model='launchOptionsDialog.vrcLaunchPathOverride'
placeholder='C:\\Program Files (x86)\\Steam\\steamapps\\common\\VRChat'
:rows='1'
style='display: block; margin-top: 10px')
template(#footer)
div(style="display:flex")
el-button(size="small" @click="openExternalLink('https://docs.vrchat.com/docs/launch-options')") {{ $t('dialog.launch_options.vrchat_docs') }}
el-button(size="small" @click="openExternalLink('https://docs.unity3d.com/Manual/CommandLineArguments.html')") {{ $t('dialog.launch_options.unity_manual') }}
el-button(type="primary" size="small" :disabled="launchOptionsDialog.loading" @click="updateLaunchOptions" style="margin-left:auto") {{ $t('dialog.launch_options.save') }}
div(style='display: flex')
el-button(size='small' @click='openExternalLink("https://docs.vrchat.com/docs/launch-options")') {{ $t('dialog.launch_options.vrchat_docs') }}
el-button(
size='small'
@click='openExternalLink("https://docs.unity3d.com/Manual/CommandLineArguments.html")') {{ $t('dialog.launch_options.unity_manual') }}
el-button(
type='primary'
size='small'
:disabled='launchOptionsDialog.loading'
@click='updateLaunchOptions'
style='margin-left: auto') {{ $t('dialog.launch_options.save') }}

View File

@@ -1,143 +1,287 @@
mixin newInstance()
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="newInstanceDialog" :visible.sync="newInstanceDialog.visible" :title="$t('dialog.new_instance.header')" width="650px")
el-tabs(type="card" v-model="newInstanceDialog.selectedTab" @tab-click="newInstanceTabClick")
el-tab-pane(:label="$t('dialog.new_instance.normal')")
el-form(v-if="newInstanceDialog.visible" :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(label="group") {{ $t('dialog.new_instance.access_type_group') }}
el-radio-button(label="friends+") {{ $t('dialog.new_instance.access_type_friend_plus') }}
el-radio-button(label="friends") {{ $t('dialog.new_instance.access_type_friend') }}
el-radio-button(label="invite+") {{ $t('dialog.new_instance.access_type_invite_plus') }}
el-radio-button(label="invite") {{ $t('dialog.new_instance.access_type_invite') }}
el-form-item(:label="$t('dialog.new_instance.group_access_type')" v-if="newInstanceDialog.accessType === 'group'")
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(label="plus" :disabled="!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-plus-create')") {{ $t('dialog.new_instance.group_access_type_plus') }}
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-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(label="US East") {{ $t('dialog.new_instance.region_use') }}
el-radio-button(label="Europe") {{ $t('dialog.new_instance.region_eu') }}
el-radio-button(label="Japan") {{ $t('dialog.new_instance.region_jp') }}
el-form-item(:label="$t('dialog.new_instance.queueEnabled')" v-if="newInstanceDialog.accessType === 'group'")
el-checkbox(v-model="newInstanceDialog.queueEnabled" @change="buildInstance")
el-form-item(:label="$t('dialog.new_instance.ageGate')" v-if="newInstanceDialog.accessType === 'group'")
el-checkbox(v-model="newInstanceDialog.ageGate" @change="buildInstance" :disabled="!hasGroupPermission(newInstanceDialog.groupRef, 'group-instance-age-gated-create')")
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-form-item(:label="$t('dialog.new_instance.group_id')" v-if="newInstanceDialog.accessType === 'group'")
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.x-friend-item(v-if="group && (hasGroupPermission(group, 'group-instance-public-create') || hasGroupPermission(group, 'group-instance-plus-create') || hasGroupPermission(group, 'group-instance-open-create'))" v-for="group in API.currentUserGroups.values()" :key="group.id" :label="group.name" :value="group.id" style="height:auto;width:478px")
mixin newInstance
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='newInstanceDialog'
:visible.sync='newInstanceDialog.visible'
:title='$t("dialog.new_instance.header")'
width='650px')
el-tabs(type='card' v-model='newInstanceDialog.selectedTab' @tab-click='newInstanceTabClick')
el-tab-pane(:label='$t("dialog.new_instance.normal")')
el-form(v-if='newInstanceDialog.visible' :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(label='group') {{ $t('dialog.new_instance.access_type_group') }}
el-radio-button(label='friends+') {{ $t('dialog.new_instance.access_type_friend_plus') }}
el-radio-button(label='friends') {{ $t('dialog.new_instance.access_type_friend') }}
el-radio-button(label='invite+') {{ $t('dialog.new_instance.access_type_invite_plus') }}
el-radio-button(label='invite') {{ $t('dialog.new_instance.access_type_invite') }}
el-form-item(
:label='$t("dialog.new_instance.group_access_type")'
v-if='newInstanceDialog.accessType === "group"')
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(
label='plus'
:disabled='!hasGroupPermission(newInstanceDialog.groupRef, "group-instance-plus-create")') {{ $t('dialog.new_instance.group_access_type_plus') }}
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-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(label='US East') {{ $t('dialog.new_instance.region_use') }}
el-radio-button(label='Europe') {{ $t('dialog.new_instance.region_eu') }}
el-radio-button(label='Japan') {{ $t('dialog.new_instance.region_jp') }}
el-form-item(
:label='$t("dialog.new_instance.queueEnabled")'
v-if='newInstanceDialog.accessType === "group"')
el-checkbox(v-model='newInstanceDialog.queueEnabled' @change='buildInstance')
el-form-item(
:label='$t("dialog.new_instance.ageGate")'
v-if='newInstanceDialog.accessType === "group"')
el-checkbox(
v-model='newInstanceDialog.ageGate'
@change='buildInstance'
:disabled='!hasGroupPermission(newInstanceDialog.groupRef, "group-instance-age-gated-create")')
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-form-item(
:label='$t("dialog.new_instance.group_id")'
v-if='newInstanceDialog.accessType === "group"')
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.x-friend-item(
v-if='group && (hasGroupPermission(group, "group-instance-public-create") || hasGroupPermission(group, "group-instance-plus-create") || hasGroupPermission(group, "group-instance-open-create"))'
v-for='group in API.currentUserGroups.values()'
:key='group.id'
:label='group.name'
:value='group.id'
style='height: auto; width: 478px')
.avatar
img(v-lazy="group.iconUrl")
img(v-lazy='group.iconUrl')
.detail
span.name(v-text="group.name")
el-form-item(:label="$t('dialog.new_instance.roles')" v-if="newInstanceDialog.accessType === 'group' && newInstanceDialog.groupAccessType === 'members'")
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.x-friend-item(v-for="role in newInstanceDialog.selectedGroupRoles" :key="role.id" :label="role.name" :value="role.id" style="height:auto;width:478px")
span.name(v-text='group.name')
el-form-item(
:label='$t("dialog.new_instance.roles")'
v-if='newInstanceDialog.accessType === "group" && newInstanceDialog.groupAccessType === "members"')
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.x-friend-item(
v-for='role in newInstanceDialog.selectedGroupRoles'
:key='role.id'
:label='role.name'
:value='role.id'
style='height: auto; width: 478px')
.detail
span.name(v-text="role.name")
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-form-item(:label="$t('dialog.new_instance.url')")
el-input(v-model="newInstanceDialog.url" size="mini" readonly)
el-tab-pane(:label="$t('dialog.new_instance.legacy')")
el-form(v-if="newInstanceDialog.visible" :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(label="group") {{ $t('dialog.new_instance.access_type_group') }}
el-radio-button(label="friends+") {{ $t('dialog.new_instance.access_type_friend_plus') }}
el-radio-button(label="friends") {{ $t('dialog.new_instance.access_type_friend') }}
el-radio-button(label="invite+") {{ $t('dialog.new_instance.access_type_invite_plus') }}
el-radio-button(label="invite") {{ $t('dialog.new_instance.access_type_invite') }}
el-form-item(:label="$t('dialog.new_instance.group_access_type')" v-if="newInstanceDialog.accessType === 'group'")
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(label="plus") {{ $t('dialog.new_instance.group_access_type_plus') }}
el-radio-button(label="public") {{ $t('dialog.new_instance.group_access_type_public') }}
span.name(v-text='role.name')
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-form-item(:label='$t("dialog.new_instance.url")')
el-input(v-model='newInstanceDialog.url' size='mini' readonly)
el-tab-pane(:label='$t("dialog.new_instance.legacy")')
el-form(v-if='newInstanceDialog.visible' :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(label='group') {{ $t('dialog.new_instance.access_type_group') }}
el-radio-button(label='friends+') {{ $t('dialog.new_instance.access_type_friend_plus') }}
el-radio-button(label='friends') {{ $t('dialog.new_instance.access_type_friend') }}
el-radio-button(label='invite+') {{ $t('dialog.new_instance.access_type_invite_plus') }}
el-radio-button(label='invite') {{ $t('dialog.new_instance.access_type_invite') }}
el-form-item(
:label='$t("dialog.new_instance.group_access_type")'
v-if='newInstanceDialog.accessType === "group"')
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(label='plus') {{ $t('dialog.new_instance.group_access_type_plus') }}
el-radio-button(label='public') {{ $t('dialog.new_instance.group_access_type_public') }}
//- el-form-item(label="Strict" v-if="newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite'")
//- el-checkbox(v-model="newInstanceDialog.strict") Prevent non friends joining via URL/Instance ID
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(label="US East") {{ $t('dialog.new_instance.region_use') }}
el-radio-button(label="Europe") {{ $t('dialog.new_instance.region_eu') }}
el-radio-button(label="Japan") {{ $t('dialog.new_instance.region_jp') }}
el-form-item(:label="$t('dialog.new_instance.ageGate')" v-if="newInstanceDialog.accessType === 'group'")
el-checkbox(v-model="newInstanceDialog.ageGate" @change="buildInstance")
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-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-form-item(:label="$t('dialog.new_instance.instance_creator')" v-if="newInstanceDialog.accessType !== 'public' && newInstanceDialog.accessType !== 'group'")
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.x-friend-item(:label="API.currentUser.displayName" :value="API.currentUser.id" style="height:auto")
.avatar(:class="userStatusClass(API.currentUser)")
img(v-lazy="userImage(API.currentUser)")
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(label='US East') {{ $t('dialog.new_instance.region_use') }}
el-radio-button(label='Europe') {{ $t('dialog.new_instance.region_eu') }}
el-radio-button(label='Japan') {{ $t('dialog.new_instance.region_jp') }}
el-form-item(
:label='$t("dialog.new_instance.ageGate")'
v-if='newInstanceDialog.accessType === "group"')
el-checkbox(v-model='newInstanceDialog.ageGate' @change='buildInstance')
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-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-form-item(
:label='$t("dialog.new_instance.instance_creator")'
v-if='newInstanceDialog.accessType !== "public" && newInstanceDialog.accessType !== "group"')
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.x-friend-item(
:label='API.currentUser.displayName'
:value='API.currentUser.id'
style='height: auto')
.avatar(:class='userStatusClass(API.currentUser)')
img(v-lazy='userImage(API.currentUser)')
.detail
span.name(v-text="API.currentUser.displayName")
el-option-group(v-if="vipFriends.length" :label="$t('side_panel.favorite')")
el-option.x-friend-item(v-for="friend in vipFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
span.name(v-text='API.currentUser.displayName')
el-option-group(v-if='vipFriends.length' :label='$t("side_panel.favorite")')
el-option.x-friend-item(
v-for='friend in vipFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar(:class='userStatusClass(friend.ref)')
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="onlineFriends.length" :label="$t('side_panel.online')")
el-option.x-friend-item(v-for="friend in onlineFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
.avatar(:class="userStatusClass(friend.ref)")
img(v-lazy="userImage(friend.ref)")
span.name(
v-text='friend.ref.displayName'
:style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='onlineFriends.length' :label='$t("side_panel.online")')
el-option.x-friend-item(
v-for='friend in onlineFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar(:class='userStatusClass(friend.ref)')
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="activeFriends.length" :label="$t('side_panel.active')")
el-option.x-friend-item(v-for="friend in activeFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
span.name(
v-text='friend.ref.displayName'
:style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='activeFriends.length' :label='$t("side_panel.active")')
el-option.x-friend-item(
v-for='friend in activeFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar
img(v-lazy="userImage(friend.ref)")
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-option-group(v-if="offlineFriends.length" :label="$t('side_panel.offline')")
el-option.x-friend-item(v-for="friend in offlineFriends" :key="friend.id" :label="friend.name" :value="friend.id" style="height:auto")
template(v-if="friend.ref")
span.name(
v-text='friend.ref.displayName'
:style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-option-group(v-if='offlineFriends.length' :label='$t("side_panel.offline")')
el-option.x-friend-item(
v-for='friend in offlineFriends'
:key='friend.id'
:label='friend.name'
:value='friend.id'
style='height: auto')
template(v-if='friend.ref')
.avatar
img(v-lazy="userImage(friend.ref)")
img(v-lazy='userImage(friend.ref)')
.detail
span.name(v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
span(v-else v-text="friend.id")
el-form-item(:label="$t('dialog.new_instance.group_id')" v-if="newInstanceDialog.accessType === 'group'")
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.x-friend-item(v-if="group" v-for="group in API.currentUserGroups.values()" :key="group.id" :label="group.name" :value="group.id" style="height:auto;width:478px")
span.name(
v-text='friend.ref.displayName'
:style='{ color: friend.ref.$userColour }')
span(v-else v-text='friend.id')
el-form-item(
:label='$t("dialog.new_instance.group_id")'
v-if='newInstanceDialog.accessType === "group"')
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.x-friend-item(
v-if='group'
v-for='group in API.currentUserGroups.values()'
:key='group.id'
:label='group.name'
:value='group.id'
style='height: auto; width: 478px')
.avatar
img(v-lazy="group.iconUrl")
img(v-lazy='group.iconUrl')
.detail
span.name(v-text="group.name")
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-form-item(:label="$t('dialog.new_instance.url')")
el-input(v-model="newInstanceDialog.url" size="mini" readonly)
template(#footer v-if="newInstanceDialog.selectedTab === '0'")
template(v-if="newInstanceDialog.instanceCreated")
el-button(size="small" @click="copyInstanceUrl(newInstanceDialog.location)") {{ $t('dialog.new_instance.copy_url') }}
el-button(size="small" @click="selfInvite(newInstanceDialog.location)") {{ $t('dialog.new_instance.self_invite') }}
el-button(size="small" @click="showInviteDialog(newInstanceDialog.location)" :disabled="(newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite') && newInstanceDialog.userId !== API.currentUser.id") {{ $t('dialog.new_instance.invite') }}
el-button(type="primary" size="small" @click="showLaunchDialog(newInstanceDialog.location, newInstanceDialog.shortName)") {{ $t('dialog.new_instance.launch') }}
span.name(v-text='group.name')
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-form-item(:label='$t("dialog.new_instance.url")')
el-input(v-model='newInstanceDialog.url' size='mini' readonly)
template(#footer v-if='newInstanceDialog.selectedTab === "0"')
template(v-if='newInstanceDialog.instanceCreated')
el-button(size='small' @click='copyInstanceUrl(newInstanceDialog.location)') {{ $t('dialog.new_instance.copy_url') }}
el-button(size='small' @click='selfInvite(newInstanceDialog.location)') {{ $t('dialog.new_instance.self_invite') }}
el-button(
size='small'
@click='showInviteDialog(newInstanceDialog.location)'
:disabled='(newInstanceDialog.accessType === "friends" || newInstanceDialog.accessType === "invite") && newInstanceDialog.userId !== API.currentUser.id') {{ $t('dialog.new_instance.invite') }}
el-button(
type='primary'
size='small'
@click='showLaunchDialog(newInstanceDialog.location, newInstanceDialog.shortName)') {{ $t('dialog.new_instance.launch') }}
template(v-else)
el-button(type="primary" size="small" @click="createNewInstance()") {{ $t('dialog.new_instance.create_instance') }}
template(#footer v-else-if="newInstanceDialog.selectedTab === '1'")
el-button(size="small" @click="copyInstanceUrl(newInstanceDialog.location)") {{ $t('dialog.new_instance.copy_url') }}
el-button(size="small" @click="selfInvite(newInstanceDialog.location)") {{ $t('dialog.new_instance.self_invite') }}
el-button(size="small" @click="showInviteDialog(newInstanceDialog.location)" :disabled="(newInstanceDialog.accessType === 'friends' || newInstanceDialog.accessType === 'invite') && newInstanceDialog.userId !== API.currentUser.id") {{ $t('dialog.new_instance.invite') }}
el-button(type="primary" size="small" @click="showLaunchDialog(newInstanceDialog.location, newInstanceDialog.shortName)") {{ $t('dialog.new_instance.launch') }}
el-button(type='primary' size='small' @click='createNewInstance()') {{ $t('dialog.new_instance.create_instance') }}
template(#footer v-else-if='newInstanceDialog.selectedTab === "1"')
el-button(size='small' @click='copyInstanceUrl(newInstanceDialog.location)') {{ $t('dialog.new_instance.copy_url') }}
el-button(size='small' @click='selfInvite(newInstanceDialog.location)') {{ $t('dialog.new_instance.self_invite') }}
el-button(
size='small'
@click='showInviteDialog(newInstanceDialog.location)'
:disabled='(newInstanceDialog.accessType === "friends" || newInstanceDialog.accessType === "invite") && newInstanceDialog.userId !== API.currentUser.id') {{ $t('dialog.new_instance.invite') }}
el-button(
type='primary'
size='small'
@click='showLaunchDialog(newInstanceDialog.location, newInstanceDialog.shortName)') {{ $t('dialog.new_instance.launch') }}

View File

@@ -1,12 +1,18 @@
mixin openSourceSoftwareNotice()
mixin openSourceSoftwareNotice
//- dialog: open source software notice
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" :visible.sync="ossDialog" :title="$t('dialog.open_source.header')" width="650px")
div(v-if="ossDialog" style="height:350px;overflow:hidden scroll;word-break:break-all")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
:visible.sync='ossDialog'
:title='$t("dialog.open_source.header")'
width='650px')
div(v-if='ossDialog' style='height: 350px; overflow: hidden scroll; word-break: break-all')
div
span {{ $t('dialog.open_source.description') }}
div(style="margin-top:15px")
p(style="font-weight:bold") animate.css
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') animate.css
pre(style='font-size: 12px; white-space: pre-line').
The MIT License (MIT)
Copyright (c) 2019 Daniel Eden
@@ -28,9 +34,9 @@ mixin openSourceSoftwareNotice()
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") CefSharp
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') CefSharp
pre(style='font-size: 12px; white-space: pre-line').
// Copyright © The CefSharp Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
@@ -61,9 +67,9 @@ mixin openSourceSoftwareNotice()
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
div(style="margin-top:15px")
p(style="font-weight:bold") DiscordRichPresence
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') DiscordRichPresence
pre(style='font-size: 12px; white-space: pre-line').
MIT License
Copyright (c) 2018 Lachee
@@ -85,9 +91,9 @@ mixin openSourceSoftwareNotice()
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") element
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') element
pre(style='font-size: 12px; white-space: pre-line').
The MIT License (MIT)
Copyright (c) 2016-present ElemeFE
@@ -109,9 +115,9 @@ mixin openSourceSoftwareNotice()
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") librsync.net
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') librsync.net
pre(style='font-size: 12px; white-space: pre-line').
The MIT License (MIT)
Copyright (c) 2015 Brad Dodson
@@ -133,9 +139,9 @@ mixin openSourceSoftwareNotice()
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") Newtonsoft.Json
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') Newtonsoft.Json
pre(style='font-size: 12px; white-space: pre-line').
The MIT License (MIT)
Copyright (c) 2007 James Newton-King
@@ -145,9 +151,9 @@ mixin openSourceSoftwareNotice()
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") normalize
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') normalize
pre(style='font-size: 12px; white-space: pre-line').
The MIT License (MIT)
Copyright © Nicolas Gallagher and Jonathan Neal
@@ -157,9 +163,9 @@ mixin openSourceSoftwareNotice()
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") noty
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') noty
pre(style='font-size: 12px; white-space: pre-line').
Copyright (c) 2012 Nedim Arabacı
Permission is hereby granted, free of charge, to any person obtaining
@@ -180,9 +186,9 @@ mixin openSourceSoftwareNotice()
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") OpenVR SDK
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') OpenVR SDK
pre(style='font-size: 12px; white-space: pre-line').
Copyright (c) 2015, Valve Corporation
All rights reserved.
@@ -210,9 +216,9 @@ mixin openSourceSoftwareNotice()
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
div(style="margin-top:15px")
p(style="font-weight:bold") Twemoji
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') Twemoji
pre(style='font-size: 12px; white-space: pre-line').
MIT License
Copyright (c) 2021 Twitter
@@ -234,9 +240,9 @@ mixin openSourceSoftwareNotice()
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") SharpDX
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') SharpDX
pre(style='font-size: 12px; white-space: pre-line').
Copyright (c) 2010-2014 SharpDX - Alexandre Mutel
Permission is hereby granted, free of charge, to any person obtaining a copy
@@ -256,9 +262,9 @@ mixin openSourceSoftwareNotice()
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") vue
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') vue
pre(style='font-size: 12px; white-space: pre-line').
The MIT License (MIT)
Copyright (c) 2013-present, Yuxi (Evan) You
@@ -280,9 +286,9 @@ mixin openSourceSoftwareNotice()
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") vue-data-tables
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') vue-data-tables
pre(style='font-size: 12px; white-space: pre-line').
The MIT License (MIT)
Copyright (c) 2018 Leon Zhang
@@ -304,9 +310,9 @@ mixin openSourceSoftwareNotice()
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") vue-lazyload
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') vue-lazyload
pre(style='font-size: 12px; white-space: pre-line').
The MIT License (MIT)
Copyright (c) 2016 Awe
@@ -329,9 +335,9 @@ mixin openSourceSoftwareNotice()
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
div(style="margin-top:15px")
p(style="font-weight:bold") Encode Sans Font (from Dark Vanilla)
pre(style="font-size:12px;white-space:pre-line").
div(style='margin-top: 15px')
p(style='font-weight: bold') Encode Sans Font (from Dark Vanilla)
pre(style='font-size: 12px; white-space: pre-line').
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
Copyright (c) 2020 June 20, Impallari Type, Andres Torresi, Jacques Le Bailly
(https://fonts.google.com/specimen/Encode+Sans),

View File

@@ -1,67 +1,104 @@
mixin tags()
mixin tags
//- dialog: Set World Tags
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="setWorldTagsDialog" :visible.sync="setWorldTagsDialog.visible" :title="$t('dialog.set_world_tags.header')" width="400px")
el-checkbox(v-model="setWorldTagsDialog.avatarScalingDisabled") {{ $t('dialog.set_world_tags.avatar_scaling_disabled') }}
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='setWorldTagsDialog'
:visible.sync='setWorldTagsDialog.visible'
:title='$t("dialog.set_world_tags.header")'
width='400px')
el-checkbox(v-model='setWorldTagsDialog.avatarScalingDisabled') {{ $t('dialog.set_world_tags.avatar_scaling_disabled') }}
br
el-checkbox(v-model="setWorldTagsDialog.focusViewDisabled") {{ $t('dialog.set_world_tags.focus_view_disabled') }}
el-checkbox(v-model='setWorldTagsDialog.focusViewDisabled') {{ $t('dialog.set_world_tags.focus_view_disabled') }}
br
el-checkbox(v-model="setWorldTagsDialog.stickersDisabled") {{ $t('dialog.set_world_tags.stickers_disabled') }}
el-checkbox(v-model='setWorldTagsDialog.stickersDisabled') {{ $t('dialog.set_world_tags.stickers_disabled') }}
br
el-checkbox(v-model="setWorldTagsDialog.debugAllowed") {{ $t('dialog.set_world_tags.enable_debugging') }}
div(style='font-size:12px;margin-top:10px')
el-checkbox(v-model='setWorldTagsDialog.debugAllowed') {{ $t('dialog.set_world_tags.enable_debugging') }}
div(style='font-size: 12px; margin-top: 10px')
| {{ $t('dialog.set_world_tags.author_tags') }} #[br]
el-input(type="textarea" v-model="setWorldTagsDialog.authorTags" size="mini" show-word-limit :autosize="{ minRows:2, maxRows:5 }" placeholder="" style="margin-top:10px")
div(style='font-size:12px;margin-top:10px')
el-input(
type='textarea'
v-model='setWorldTagsDialog.authorTags'
size='mini'
show-word-limit
:autosize='{ minRows: 2, maxRows: 5 }'
placeholder=''
style='margin-top: 10px')
div(style='font-size: 12px; margin-top: 10px')
| {{ $t('dialog.set_world_tags.content_tags') }} #[br]
el-checkbox(v-model="setWorldTagsDialog.contentHorror") {{ $t('dialog.set_world_tags.content_horror') }}
el-checkbox(v-model='setWorldTagsDialog.contentHorror') {{ $t('dialog.set_world_tags.content_horror') }}
br
el-checkbox(v-model="setWorldTagsDialog.contentGore") {{ $t('dialog.set_world_tags.content_gore') }}
el-checkbox(v-model='setWorldTagsDialog.contentGore') {{ $t('dialog.set_world_tags.content_gore') }}
br
el-checkbox(v-model="setWorldTagsDialog.contentViolence") {{ $t('dialog.set_world_tags.content_violence') }}
el-checkbox(v-model='setWorldTagsDialog.contentViolence') {{ $t('dialog.set_world_tags.content_violence') }}
br
el-checkbox(v-model="setWorldTagsDialog.contentAdult") {{ $t('dialog.set_world_tags.content_adult') }}
el-checkbox(v-model='setWorldTagsDialog.contentAdult') {{ $t('dialog.set_world_tags.content_adult') }}
br
el-checkbox(v-model="setWorldTagsDialog.contentSex") {{ $t('dialog.set_world_tags.content_sex') }}
el-checkbox(v-model='setWorldTagsDialog.contentSex') {{ $t('dialog.set_world_tags.content_sex') }}
//- el-input(type="textarea" v-model="setWorldTagsDialog.contentTags" size="mini" show-word-limit :autosize="{ minRows:2, maxRows:5 }" placeholder="" style="margin-top:10px")
template(#footer)
div(style="display:flex")
el-button(size="small" @click="setWorldTagsDialog.visible = false") {{ $t('dialog.set_world_tags.cancel') }}
el-button(type="primary" size="small" @click="saveSetWorldTagsDialog") {{ $t('dialog.set_world_tags.save') }}
div(style='display: flex')
el-button(size='small' @click='setWorldTagsDialog.visible = false') {{ $t('dialog.set_world_tags.cancel') }}
el-button(type='primary' size='small' @click='saveSetWorldTagsDialog') {{ $t('dialog.set_world_tags.save') }}
//- dialog: Set Avatar Tags
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="setAvatarTagsDialog" :visible.sync="setAvatarTagsDialog.visible" :title="$t('dialog.set_avatar_tags.header')" width="770px")
template(v-if="setAvatarTagsDialog.visible")
el-checkbox(v-model="setAvatarTagsDialog.contentHorror" @change="updateSelectedAvatarTags") {{ $t('dialog.set_avatar_tags.content_horror') }}
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='setAvatarTagsDialog'
:visible.sync='setAvatarTagsDialog.visible'
:title='$t("dialog.set_avatar_tags.header")'
width='770px')
template(v-if='setAvatarTagsDialog.visible')
el-checkbox(v-model='setAvatarTagsDialog.contentHorror' @change='updateSelectedAvatarTags') {{ $t('dialog.set_avatar_tags.content_horror') }}
br
el-checkbox(v-model="setAvatarTagsDialog.contentGore" @change="updateSelectedAvatarTags") {{ $t('dialog.set_avatar_tags.content_gore') }}
el-checkbox(v-model='setAvatarTagsDialog.contentGore' @change='updateSelectedAvatarTags') {{ $t('dialog.set_avatar_tags.content_gore') }}
br
el-checkbox(v-model="setAvatarTagsDialog.contentViolence" @change="updateSelectedAvatarTags") {{ $t('dialog.set_avatar_tags.content_violence') }}
el-checkbox(v-model='setAvatarTagsDialog.contentViolence' @change='updateSelectedAvatarTags') {{ $t('dialog.set_avatar_tags.content_violence') }}
br
el-checkbox(v-model="setAvatarTagsDialog.contentAdult" @change="updateSelectedAvatarTags") {{ $t('dialog.set_avatar_tags.content_adult') }}
el-checkbox(v-model='setAvatarTagsDialog.contentAdult' @change='updateSelectedAvatarTags') {{ $t('dialog.set_avatar_tags.content_adult') }}
br
el-checkbox(v-model="setAvatarTagsDialog.contentSex" @change="updateSelectedAvatarTags") {{ $t('dialog.set_avatar_tags.content_sex') }}
el-checkbox(v-model='setAvatarTagsDialog.contentSex' @change='updateSelectedAvatarTags') {{ $t('dialog.set_avatar_tags.content_sex') }}
br
el-input(v-model="setAvatarTagsDialog.selectedTagsCsv" @input="updateInputAvatarTags" size="mini" :autosize="{ minRows:2, maxRows:5 }" :placeholder="$t('dialog.set_avatar_tags.custom_tags_placeholder')" style="margin-top:10px")
template(v-if="setAvatarTagsDialog.ownAvatars.length === setAvatarTagsDialog.selectedCount")
el-button(size="small" @click="setAvatarTagsSelectToggle") {{ $t('dialog.set_avatar_tags.select_none') }}
el-input(
v-model='setAvatarTagsDialog.selectedTagsCsv'
@input='updateInputAvatarTags'
size='mini'
:autosize='{ minRows: 2, maxRows: 5 }'
:placeholder='$t("dialog.set_avatar_tags.custom_tags_placeholder")'
style='margin-top: 10px')
template(v-if='setAvatarTagsDialog.ownAvatars.length === setAvatarTagsDialog.selectedCount')
el-button(size='small' @click='setAvatarTagsSelectToggle') {{ $t('dialog.set_avatar_tags.select_none') }}
template(v-else)
el-button(size="small" @click="setAvatarTagsSelectToggle") {{ $t('dialog.set_avatar_tags.select_all') }}
span(style="margin-left:5px") {{ setAvatarTagsDialog.selectedCount }} / {{ setAvatarTagsDialog.ownAvatars.length }}
span(v-if="setAvatarTagsDialog.loading" style="margin-left:5px")
el-button(size='small' @click='setAvatarTagsSelectToggle') {{ $t('dialog.set_avatar_tags.select_all') }}
span(style='margin-left: 5px') {{ setAvatarTagsDialog.selectedCount }} / {{ setAvatarTagsDialog.ownAvatars.length }}
span(v-if='setAvatarTagsDialog.loading' style='margin-left: 5px')
i.el-icon-loading
br
.x-friend-list(style="margin-top:10px;min-height:60px;max-height:280px")
.x-friend-item(v-for="avatar in setAvatarTagsDialog.ownAvatars" :key="setAvatarTagsDialog.forceUpdate" @click="showAvatarDialog(avatar.id)" class="x-friend-item-border" style="width:350px")
.x-friend-list(style='margin-top: 10px; min-height: 60px; max-height: 280px')
.x-friend-item.x-friend-item-border(
v-for='avatar in setAvatarTagsDialog.ownAvatars'
:key='setAvatarTagsDialog.forceUpdate'
@click='showAvatarDialog(avatar.id)'
style='width: 350px')
.avatar
img(v-if="avatar.thumbnailImageUrl" v-lazy="avatar.thumbnailImageUrl")
img(v-if='avatar.thumbnailImageUrl' v-lazy='avatar.thumbnailImageUrl')
.detail
span.name(v-text="avatar.name")
span.extra(v-text="avatar.releaseStatus" v-if="avatar.releaseStatus === 'public'" style="color: #67c23a;")
span.extra(v-text="avatar.releaseStatus" v-else-if="avatar.releaseStatus === 'private'" style="color: #f56c6c;")
span.extra(v-text="avatar.releaseStatus" v-else)
span.extra(v-text="avatar.$tagString")
el-button(type="text" size="mini" @click.stop style="margin-left:5px")
el-checkbox(v-model="avatar.$selected" @change="updateAvatarTagsSelection")
span.name(v-text='avatar.name')
span.extra(
v-text='avatar.releaseStatus'
v-if='avatar.releaseStatus === "public"'
style='color: #67c23a')
span.extra(
v-text='avatar.releaseStatus'
v-else-if='avatar.releaseStatus === "private"'
style='color: #f56c6c')
span.extra(v-text='avatar.releaseStatus' v-else)
span.extra(v-text='avatar.$tagString')
el-button(type='text' size='mini' @click.stop style='margin-left: 5px')
el-checkbox(v-model='avatar.$selected' @change='updateAvatarTagsSelection')
template(#footer)
el-button(size="small" @click="setAvatarTagsDialog.visible = false") {{ $t('dialog.set_avatar_tags.cancel') }}
el-button(type="primary" size="small" @click="saveSetAvatarTagsDialog") {{ $t('dialog.set_avatar_tags.save') }}
el-button(size='small' @click='setAvatarTagsDialog.visible = false') {{ $t('dialog.set_avatar_tags.cancel') }}
el-button(type='primary' size='small' @click='saveSetAvatarTagsDialog') {{ $t('dialog.set_avatar_tags.save') }}

View File

@@ -917,7 +917,9 @@ mixin userDialog
el-tab-pane
span(slot='label')
span(v-text='list[0]' style='font-weight: bold; font-size: 16px')
i.x-status-icon(style='margin-left: 5px' :class='userFavoriteWorldsStatus(list[1])')
i.x-status-icon(
style='margin-left: 5px'
:class='userFavoriteWorldsStatus(list[1])')
span(style='color: #909399; font-size: 12px; margin-left: 5px') {{ list[2].length }}/{{ API.favoriteLimits.maxFavoritesPerGroup.world }}
.x-friend-list(style='margin-top: 10px; margin-bottom: 15px; min-height: 60px')
.x-friend-item.x-friend-item-border(

View File

@@ -1,33 +1,69 @@
mixin vrcx()
mixin vrcx
//- dialog: update VRCX
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="VRCXUpdateDialog" :visible.sync="VRCXUpdateDialog.visible" :title="$t('dialog.vrcx_updater.header')" width="400px")
div(v-loading="checkingForVRCXUpdate" style="margin-top:15px")
template(v-if="updateInProgress")
el-progress(:percentage="updateProgress" :format="updateProgressText")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='VRCXUpdateDialog'
:visible.sync='VRCXUpdateDialog.visible'
:title='$t("dialog.vrcx_updater.header")'
width='400px')
div(v-loading='checkingForVRCXUpdate' style='margin-top: 15px')
template(v-if='updateInProgress')
el-progress(:percentage='updateProgress' :format='updateProgressText')
br
template(v-else)
div(v-if="VRCXUpdateDialog.updatePending" style="margin-bottom:15px")
span(v-text="pendingVRCXInstall")
div(v-if='VRCXUpdateDialog.updatePending' style='margin-bottom: 15px')
span(v-text='pendingVRCXInstall')
br
span {{ $t('dialog.vrcx_updater.ready_for_update') }}
el-select(v-model="branch" @change="loadBranchVersions" style="display:inline-block;width:150px;margin-right:15px")
el-option(v-for="branch in branches" :key="branch.name" :label="branch.name" :value="branch.name")
el-select(v-model="VRCXUpdateDialog.release" style="display:inline-block;width:150px")
el-option(v-for="item in VRCXUpdateDialog.releases" :key="item.name" :label="item.tag_name" :value="item.name")
div(v-if="!VRCXUpdateDialog.updatePending && VRCXUpdateDialog.release === appVersion" style="margin-top:15px")
el-select(
v-model='branch'
@change='loadBranchVersions'
style='display: inline-block; width: 150px; margin-right: 15px')
el-option(v-for='branch in branches' :key='branch.name' :label='branch.name' :value='branch.name')
el-select(v-model='VRCXUpdateDialog.release' style='display: inline-block; width: 150px')
el-option(
v-for='item in VRCXUpdateDialog.releases'
:key='item.name'
:label='item.tag_name'
:value='item.name')
div(
v-if='!VRCXUpdateDialog.updatePending && VRCXUpdateDialog.release === appVersion'
style='margin-top: 15px')
span {{ $t('dialog.vrcx_updater.latest_version') }}
template(#footer)
el-button(v-if="updateInProgress" type="primary" size="small" @click="cancelUpdate") {{ $t('dialog.vrcx_updater.cancel') }}
el-button(v-if="VRCXUpdateDialog.release !== pendingVRCXInstall" :disabled="updateInProgress" type="primary" size="small" @click="installVRCXUpdate") {{ $t('dialog.vrcx_updater.download') }}
el-button(v-if="!updateInProgress && pendingVRCXInstall" type="primary" size="small" @click="restartVRCX(true)") {{ $t('dialog.vrcx_updater.install') }}
el-button(v-if='updateInProgress' type='primary' size='small' @click='cancelUpdate') {{ $t('dialog.vrcx_updater.cancel') }}
el-button(
v-if='VRCXUpdateDialog.release !== pendingVRCXInstall'
:disabled='updateInProgress'
type='primary'
size='small'
@click='installVRCXUpdate') {{ $t('dialog.vrcx_updater.download') }}
el-button(
v-if='!updateInProgress && pendingVRCXInstall'
type='primary'
size='small'
@click='restartVRCX(true)') {{ $t('dialog.vrcx_updater.install') }}
//- dialog: change log
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="changeLogDialog" :visible.sync="changeLogDialog.visible" :title="$t('dialog.change_log.header')" width="800px" top="5vh")
.changelog-dialog(v-if="changeLogDialog.visible")
h2(v-text="changeLogDialog.buildName")
span {{ $t('dialog.change_log.description') }} #[a.x-link(@click="openExternalLink('https://www.patreon.com/Natsumi_VRCX')") Patreon], #[a.x-link(@click="openExternalLink('https://ko-fi.com/natsumi_sama')") Ko-fi].
vue-markdown(:source="changeLogDialog.changeLog" :linkify="false" style="height:62vh;overflow-y:auto;margin-top:10px")
el-dialog.x-dialog(
:before-close='beforeDialogClose'
@mousedown.native='dialogMouseDown'
@mouseup.native='dialogMouseUp'
ref='changeLogDialog'
:visible.sync='changeLogDialog.visible'
:title='$t("dialog.change_log.header")'
width='800px'
top='5vh')
.changelog-dialog(v-if='changeLogDialog.visible')
h2(v-text='changeLogDialog.buildName')
span {{ $t('dialog.change_log.description') }} #[a.x-link(@click='openExternalLink("https://www.patreon.com/Natsumi_VRCX")') Patreon], #[a.x-link(@click='openExternalLink("https://ko-fi.com/natsumi_sama")') Ko-fi].
vue-markdown(
:source='changeLogDialog.changeLog'
:linkify='false'
style='height: 62vh; overflow-y: auto; margin-top: 10px')
template(#footer)
el-button(type="small" @click="openExternalLink('https://github.com/vrcx-team/VRCX/releases')") {{ $t('dialog.change_log.github') }}
el-button(type="small" @click="openExternalLink('https://patreon.com/Natsumi_VRCX')") {{ $t('dialog.change_log.donate') }}
el-button(type="small" @click="changeLogDialog.visible = false") {{ $t('dialog.change_log.close') }}
el-button(type='small' @click='openExternalLink("https://github.com/vrcx-team/VRCX/releases")') {{ $t('dialog.change_log.github') }}
el-button(type='small' @click='openExternalLink("https://patreon.com/Natsumi_VRCX")') {{ $t('dialog.change_log.donate') }}
el-button(type='small' @click='changeLogDialog.visible = false') {{ $t('dialog.change_log.close') }}

View File

@@ -63,7 +63,7 @@ mixin friendsListSidebar
:traveling='lastLocationDestination'
:link='false')
location.extra(
v-else-if='isRealInstance(API.currentUser.$locationTag) || isRealInstance(API.currentUser.$travelingToLocation)'
v-else-if='isRealInstance(API.currentUser.$locationTag) || isRealInstance(API.currentUser.$travelingToLocation)'
:location='API.currentUser.$locationTag'
:traveling='API.currentUser.$travelingToLocation'
:link='false')

View File

@@ -1,49 +1,104 @@
mixin loginPage()
.x-login-container(v-if="!API.isLoggedIn" v-loading="loginForm.loading")
mixin loginPage
.x-login-container(v-if='!API.isLoggedIn' v-loading='loginForm.loading')
.x-login
div(style="position:fixed; top: 0; left: 0; margin:5px")
el-tooltip(placement="top" :content="$t('view.login.updater')" :disabled="hideTooltips")
el-button(type="default" @click="showVRCXUpdateDialog" size="mini" icon="el-icon-download" circle)
el-tooltip(placement="top" :content="$t('view.login.proxy_settings')" :disabled="hideTooltips")
el-button(type="default" @click="promptProxySettings" size="mini" icon="el-icon-connection" style="margin-left:5px" circle)
div(style='position: fixed; top: 0; left: 0; margin: 5px')
el-tooltip(placement='top' :content='$t("view.login.updater")' :disabled='hideTooltips')
el-button(type='default' @click='showVRCXUpdateDialog' size='mini' icon='el-icon-download' circle)
el-tooltip(placement='top' :content='$t("view.login.proxy_settings")' :disabled='hideTooltips')
el-button(
type='default'
@click='promptProxySettings'
size='mini'
icon='el-icon-connection'
style='margin-left: 5px'
circle)
div.x-login-form-container
.x-login-form-container
div
h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.login") }}
el-form(ref="loginForm" :model="loginForm" :rules="loginForm.rules" @submit.native.prevent="login()")
el-form-item(:label="$t('view.login.field.username')" prop="username" required)
el-input(v-model="loginForm.username" name="username" :placeholder="$t('view.login.field.username')" clearable)
el-form-item(:label="$t('view.login.field.password')" prop="password" required style="margin-top:10px")
el-input(type="password" v-model="loginForm.password" name="password" :placeholder="$t('view.login.field.password')" clearable show-password)
el-checkbox(v-model="loginForm.saveCredentials" style="margin-top:15px") {{ $t("view.login.field.saveCredentials") }}
el-checkbox(v-model="enableCustomEndpoint" @change="toggleCustomEndpoint" style="margin-top:10px") {{ $t("view.login.field.devEndpoint") }}
el-form-item(v-if="enableCustomEndpoint" :label="$t('view.login.field.endpoint')" prop="endpoint" style="margin-top:10px")
el-input(v-model="loginForm.endpoint" name="endpoint" :placeholder="API.endpointDomainVrchat" clearable)
el-form-item(v-if="enableCustomEndpoint" :label="$t('view.login.field.websocket')" prop="endpoint" style="margin-top:10px")
el-input(v-model="loginForm.websocket" name="websocket" :placeholder="API.websocketDomainVrchat" clearable)
el-form-item(style="margin-top:15px")
el-button(native-type="submit" type="primary" style="width:100%") {{ $t("view.login.login") }}
el-button(type="primary" @click="openExternalLink('https://vrchat.com/register')" style="width:100%") {{ $t("view.login.register") }}
hr.x-vertical-divider(v-if="Object.keys(loginForm.savedCredentials).length !== 0")/
h2(style='font-weight: bold; text-align: center; margin: 0') {{ $t('view.login.login') }}
el-form(
ref='loginForm'
:model='loginForm'
:rules='loginForm.rules'
@submit.native.prevent='login()')
el-form-item(:label='$t("view.login.field.username")' prop='username' required)
el-input(
v-model='loginForm.username'
name='username'
:placeholder='$t("view.login.field.username")'
clearable)
el-form-item(
:label='$t("view.login.field.password")'
prop='password'
required
style='margin-top: 10px')
el-input(
type='password'
v-model='loginForm.password'
name='password'
:placeholder='$t("view.login.field.password")'
clearable
show-password)
el-checkbox(v-model='loginForm.saveCredentials' style='margin-top: 15px') {{ $t('view.login.field.saveCredentials') }}
el-checkbox(
v-model='enableCustomEndpoint'
@change='toggleCustomEndpoint'
style='margin-top: 10px') {{ $t('view.login.field.devEndpoint') }}
el-form-item(
v-if='enableCustomEndpoint'
:label='$t("view.login.field.endpoint")'
prop='endpoint'
style='margin-top: 10px')
el-input(
v-model='loginForm.endpoint'
name='endpoint'
:placeholder='API.endpointDomainVrchat'
clearable)
el-form-item(
v-if='enableCustomEndpoint'
:label='$t("view.login.field.websocket")'
prop='endpoint'
style='margin-top: 10px')
el-input(
v-model='loginForm.websocket'
name='websocket'
:placeholder='API.websocketDomainVrchat'
clearable)
el-form-item(style='margin-top: 15px')
el-button(native-type='submit' type='primary' style='width: 100%') {{ $t('view.login.login') }}
el-button(
type='primary'
@click='openExternalLink("https://vrchat.com/register")'
style='width: 100%') {{ $t('view.login.register') }}
div(v-if="Object.keys(loginForm.savedCredentials).length !== 0")
h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.savedAccounts") }}
.x-scroll-wrapper(style="margin-top:10px")
hr.x-vertical-divider(v-if='Object.keys(loginForm.savedCredentials).length !== 0')/
div(v-if='Object.keys(loginForm.savedCredentials).length !== 0')
h2(style='font-weight: bold; text-align: center; margin: 0') {{ $t('view.login.savedAccounts') }}
.x-scroll-wrapper(style='margin-top: 10px')
.x-saved-account-list
.x-friend-item(v-for="user in loginForm.savedCredentials" :key="user.user.id" @click="relogin(user)")
.x-friend-item(
v-for='user in loginForm.savedCredentials'
:key='user.user.id'
@click='relogin(user)')
.avatar
img(v-lazy="userImage(user.user)")
img(v-lazy='userImage(user.user)')
.detail
span.name(v-text="user.user.displayName")
span.extra(v-text="user.user.username")
span.extra(v-text="user.loginParmas.endpoint")
el-button(type="default" @click.stop="deleteSavedLogin(user.user.id)" size="mini" icon="el-icon-delete" style="margin-left:10px" circle)
div.x-legal-notice-container
div(style="text-align:center;font-size:12px")
p #[a.x-link(@click="openExternalLink('https://vrchat.com/home/password')") {{ $t("view.login.forgotPassword") }}]
p © 2019-2024 #[a.x-link(@click="openExternalLink('https://github.com/pypy-vrc')") pypy] & #[a.x-link(@click="openExternalLink('https://github.com/Natsumi-sama')") Natsumi]
p {{ $t("view.settings.general.legal_notice.info") }}
p {{ $t("view.settings.general.legal_notice.disclaimer1") }}
p {{ $t("view.settings.general.legal_notice.disclaimer2") }}
span.name(v-text='user.user.displayName')
span.extra(v-text='user.user.username')
span.extra(v-text='user.loginParmas.endpoint')
el-button(
type='default'
@click.stop='deleteSavedLogin(user.user.id)'
size='mini'
icon='el-icon-delete'
style='margin-left: 10px'
circle)
.x-legal-notice-container
div(style='text-align: center; font-size: 12px')
p #[a.x-link(@click='openExternalLink("https://vrchat.com/home/password")') {{ $t('view.login.forgotPassword') }}]
p © 2019-2024 #[a.x-link(@click='openExternalLink("https://github.com/pypy-vrc")') pypy] & #[a.x-link(@click='openExternalLink("https://github.com/Natsumi-sama")') Natsumi]
p {{ $t('view.settings.general.legal_notice.info') }}
p {{ $t('view.settings.general.legal_notice.disclaimer1') }}
p {{ $t('view.settings.general.legal_notice.disclaimer2') }}

File diff suppressed because it is too large Load Diff

View File

@@ -1,121 +1,189 @@
mixin feedTab()
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'feed'")
data-tables(v-bind="feedTable" v-loading="feedTable.loading")
mixin feedTab
.x-container(v-show='$refs.menu && $refs.menu.activeIndex === \'feed\'')
data-tables(v-bind='feedTable' v-loading='feedTable.loading')
template(#tool)
div(style="margin:0 0 10px;display:flex;align-items:center")
div(style="flex:none;margin-right:10px;display:flex;align-items:center;")
el-tooltip(placement="bottom" :content="$t('view.feed.favorites_only_tooltip')" :disabled="hideTooltips")
el-switch(v-model="feedTable.vip" @change="feedTableLookup" active-color="#13ce66")
el-select(v-model="feedTable.filter" @change="feedTableLookup" multiple clearable style="flex:1;height:40px;" :placeholder="$t('view.feed.filter_placeholder')")
el-option(v-for="type in ['GPS', 'Online', 'Offline', 'Status', 'Avatar', 'Bio']" :key="type" :label="$t('view.feed.filters.' + type)" :value="type")
el-input(v-model="feedTable.search" :placeholder="$t('view.feed.search_placeholder')" @keyup.native.13="feedTableLookup" @change="feedTableLookup" clearable style="flex:none;width:150px;margin:0 10px")
el-table-column(type="expand" width="20")
template(#default="scope")
div(style="position:relative;font-size:14px")
template(v-if="scope.row.type === 'GPS'")
location(v-if="scope.row.previousLocation" :location="scope.row.previousLocation")
el-tag(type="info" effect="plain" size="mini" style="margin-left:5px") {{ timeToText(scope.row.time) }}
div(style='margin: 0 0 10px; display: flex; align-items: center')
div(style='flex: none; margin-right: 10px; display: flex; align-items: center')
el-tooltip(
placement='bottom'
:content='$t("view.feed.favorites_only_tooltip")'
:disabled='hideTooltips')
el-switch(v-model='feedTable.vip' @change='feedTableLookup' active-color='#13ce66')
el-select(
v-model='feedTable.filter'
@change='feedTableLookup'
multiple
clearable
style='flex: 1; height: 40px'
:placeholder='$t("view.feed.filter_placeholder")')
el-option(
v-for='type in ["GPS", "Online", "Offline", "Status", "Avatar", "Bio"]'
:key='type'
:label='$t("view.feed.filters." + type)'
:value='type')
el-input(
v-model='feedTable.search'
:placeholder='$t("view.feed.search_placeholder")'
@keyup.native.13='feedTableLookup'
@change='feedTableLookup'
clearable
style='flex: none; width: 150px; margin: 0 10px')
el-table-column(type='expand' width='20')
template(#default='scope')
div(style='position: relative; font-size: 14px')
template(v-if='scope.row.type === "GPS"')
location(v-if='scope.row.previousLocation' :location='scope.row.previousLocation')
el-tag(type='info' effect='plain' size='mini' style='margin-left: 5px') {{ timeToText(scope.row.time) }}
br
span(style="margin-right:5px")
span(style='margin-right: 5px')
i.el-icon-right
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
template(v-else-if="scope.row.type === 'Offline'")
template(v-if="scope.row.location")
location(:location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
el-tag(type="info" effect="plain" size="mini" style="margin-left:5px") {{ timeToText(scope.row.time) }}
template(v-else-if="scope.row.type === 'Online'")
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
template(v-else-if="scope.row.type === 'Avatar'")
div(style="display:flex;align-items:center")
el-popover(placement="right" width="500px" trigger="click")
div(slot="reference" style="display:inline-block;vertical-align:top;width:160px")
template(v-if="scope.row.previousCurrentAvatarThumbnailImageUrl")
img.x-link(v-lazy="scope.row.previousCurrentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
location(
v-if='scope.row.location'
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName')
template(v-else-if='scope.row.type === "Offline"')
template(v-if='scope.row.location')
location(
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName')
el-tag(type='info' effect='plain' size='mini' style='margin-left: 5px') {{ timeToText(scope.row.time) }}
template(v-else-if='scope.row.type === "Online"')
location(
v-if='scope.row.location'
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName')
template(v-else-if='scope.row.type === "Avatar"')
div(style='display: flex; align-items: center')
el-popover(placement='right' width='500px' trigger='click')
div(slot='reference' style='display: inline-block; vertical-align: top; width: 160px')
template(v-if='scope.row.previousCurrentAvatarThumbnailImageUrl')
img.x-link(
v-lazy='scope.row.previousCurrentAvatarThumbnailImageUrl'
style='flex: none; width: 160px; height: 120px; border-radius: 4px')
br
avatar-info(:imageurl="scope.row.previousCurrentAvatarThumbnailImageUrl" :userid="scope.row.userId" :hintownerid="scope.row.previousOwnerId" :hintavatarname="scope.row.previousAvatarName" :avatartags="scope.row.previousCurrentAvatarTags")
img.x-link(v-lazy="scope.row.previousCurrentAvatarImageUrl" style="width:500px;height:375px" @click="showFullscreenImageDialog(scope.row.previousCurrentAvatarImageUrl)")
span(style="position:relative;margin:0 10px")
avatar-info(
:imageurl='scope.row.previousCurrentAvatarThumbnailImageUrl'
:userid='scope.row.userId'
:hintownerid='scope.row.previousOwnerId'
:hintavatarname='scope.row.previousAvatarName'
:avatartags='scope.row.previousCurrentAvatarTags')
img.x-link(
v-lazy='scope.row.previousCurrentAvatarImageUrl'
style='width: 500px; height: 375px'
@click='showFullscreenImageDialog(scope.row.previousCurrentAvatarImageUrl)')
span(style='position: relative; margin: 0 10px')
i.el-icon-right
el-popover(placement="right" width="500px" trigger="click")
div(slot="reference" style="display:inline-block;vertical-align:top;width:160px")
template(v-if="scope.row.currentAvatarThumbnailImageUrl")
img.x-link(v-lazy="scope.row.currentAvatarThumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
el-popover(placement='right' width='500px' trigger='click')
div(slot='reference' style='display: inline-block; vertical-align: top; width: 160px')
template(v-if='scope.row.currentAvatarThumbnailImageUrl')
img.x-link(
v-lazy='scope.row.currentAvatarThumbnailImageUrl'
style='flex: none; width: 160px; height: 120px; border-radius: 4px')
br
avatar-info(:imageurl="scope.row.currentAvatarThumbnailImageUrl" :userid="scope.row.userId" :hintownerid="scope.row.ownerId" :hintavatarname="scope.row.avatarName" :avatartags="scope.row.currentAvatarTags")
img.x-link(v-lazy="scope.row.currentAvatarImageUrl" style="width:500px;height:375px" @click="showFullscreenImageDialog(scope.row.currentAvatarImageUrl)")
template(v-else-if="scope.row.type === 'Status'")
el-tooltip(placement="top")
avatar-info(
:imageurl='scope.row.currentAvatarThumbnailImageUrl'
:userid='scope.row.userId'
:hintownerid='scope.row.ownerId'
:hintavatarname='scope.row.avatarName'
:avatartags='scope.row.currentAvatarTags')
img.x-link(
v-lazy='scope.row.currentAvatarImageUrl'
style='width: 500px; height: 375px'
@click='showFullscreenImageDialog(scope.row.currentAvatarImageUrl)')
template(v-else-if='scope.row.type === "Status"')
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.previousStatus === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.previousStatus === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.previousStatus === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.previousStatus === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.previousStatus === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.previousStatus === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.previousStatus === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.previousStatus === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.previousStatus)")
span(v-text="scope.row.previousStatusDescription" style="margin-left:5px")
i.x-user-status(:class='statusClass(scope.row.previousStatus)')
span(v-text='scope.row.previousStatusDescription' style='margin-left: 5px')
br
span
i.el-icon-right
el-tooltip(placement="top")
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.status === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.status === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.status === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.status === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.status)" style="margin:0 5px")
span(v-text="scope.row.statusDescription")
template(v-else-if="scope.row.type === 'Bio'")
pre(v-html="formatDifference(scope.row.previousBio, scope.row.bio)" style="font-family:inherit;font-size:12px;white-space:pre-wrap;line-height:25px;line-height: 22px;")
el-table-column(:label="$t('table.feed.date')" prop="created_at" sortable="custom" width="120")
template(#default="scope")
el-tooltip(placement="right")
i.x-user-status(:class='statusClass(scope.row.status)' style='margin: 0 5px')
span(v-text='scope.row.statusDescription')
template(v-else-if='scope.row.type === "Bio"')
pre(
v-html='formatDifference(scope.row.previousBio, scope.row.bio)'
style='font-family: inherit; font-size: 12px; white-space: pre-wrap; line-height: 25px; line-height: 22px')
el-table-column(:label='$t("table.feed.date")' prop='created_at' sortable='custom' width='120')
template(#default='scope')
el-tooltip(placement='right')
template(#content)
span {{ scope.row.created_at | formatDate('long') }}
span {{ scope.row.created_at | formatDate('short') }}
el-table-column(:label="$t('table.feed.type')" prop="type" width="80")
template(#default="scope")
span.x-link(v-text="$t('view.feed.filters.' + scope.row.type)")
el-table-column(:label="$t('table.feed.user')" prop="displayName" width="180")
template(#default="scope")
span.x-link(v-text="scope.row.displayName" @click="showUserDialog(scope.row.userId)" style="padding-right:10px")
el-table-column(:label="$t('table.feed.detail')")
template(#default="scope")
template(v-if="scope.row.type === 'GPS'")
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
template(v-else-if="scope.row.type === 'Offline' || scope.row.type === 'Online'")
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
template(v-else-if="scope.row.type === 'Status'")
template(v-if="scope.row.statusDescription === scope.row.previousStatusDescription")
el-tooltip(placement="top")
el-table-column(:label='$t("table.feed.type")' prop='type' width='80')
template(#default='scope')
span.x-link(v-text='$t("view.feed.filters." + scope.row.type)')
el-table-column(:label='$t("table.feed.user")' prop='displayName' width='180')
template(#default='scope')
span.x-link(
v-text='scope.row.displayName'
@click='showUserDialog(scope.row.userId)'
style='padding-right: 10px')
el-table-column(:label='$t("table.feed.detail")')
template(#default='scope')
template(v-if='scope.row.type === "GPS"')
location(
v-if='scope.row.location'
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName')
template(v-else-if='scope.row.type === "Offline" || scope.row.type === "Online"')
location(
v-if='scope.row.location'
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName')
template(v-else-if='scope.row.type === "Status"')
template(v-if='scope.row.statusDescription === scope.row.previousStatusDescription')
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.previousStatus === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.previousStatus === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.previousStatus === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.previousStatus === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.previousStatus === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.previousStatus === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.previousStatus === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.previousStatus === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.previousStatus)")
span(style="margin:0 5px")
i.x-user-status(:class='statusClass(scope.row.previousStatus)')
span(style='margin: 0 5px')
i.el-icon-right
el-tooltip(placement="top")
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.status === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.status === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.status === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.status === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.status)")
i.x-user-status(:class='statusClass(scope.row.status)')
template(v-else)
el-tooltip(placement="top")
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.status === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.status === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.status === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.status === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.status)" style="margin-right:3px")
span(v-text="scope.row.statusDescription")
template(v-else-if="scope.row.type === 'Avatar'")
avatar-info(:imageurl="scope.row.currentAvatarImageUrl" :userid="scope.row.userId" :hintownerid="scope.row.ownerId" :hintavatarname="scope.row.avatarName" :avatartags="scope.row.currentAvatarTags")
template(v-else-if="scope.row.type === 'Bio'")
span(v-text="scope.row.bio")
i.x-user-status(:class='statusClass(scope.row.status)' style='margin-right: 3px')
span(v-text='scope.row.statusDescription')
template(v-else-if='scope.row.type === "Avatar"')
avatar-info(
:imageurl='scope.row.currentAvatarImageUrl'
:userid='scope.row.userId'
:hintownerid='scope.row.ownerId'
:hintavatarname='scope.row.avatarName'
:avatartags='scope.row.currentAvatarTags')
template(v-else-if='scope.row.type === "Bio"')
span(v-text='scope.row.bio')

View File

@@ -1,85 +1,196 @@
mixin friendsListTab()
.x-container(v-if="$refs.menu && $refs.menu.activeIndex === 'friendsList'")
div.options-container(style="margin-top:0")
mixin friendsListTab
.x-container(v-if='$refs.menu && $refs.menu.activeIndex === "friendsList"')
.options-container(style='margin-top: 0')
span.header {{ $t('view.friend_list.header') }}
div(style="float:right;font-size:13px")
div(v-if="friendsListBulkUnfriendMode" style="display:inline-block;margin-right:10px")
el-button(size="small" @click="showBulkUnfriendSelectionConfirm") {{ $t('view.friend_list.bulk_unfriend_selection') }}
div(style='float: right; font-size: 13px')
div(v-if='friendsListBulkUnfriendMode' style='display: inline-block; margin-right: 10px')
el-button(size='small' @click='showBulkUnfriendSelectionConfirm') {{ $t('view.friend_list.bulk_unfriend_selection') }}
//- el-button(size="small" @click="showBulkUnfriendAllConfirm" style="margin-right:5px") Bulk Unfriend All
div(style="display:inline-block;margin-right:10px")
div(style='display: inline-block; margin-right: 10px')
span.name {{ $t('view.friend_list.bulk_unfriend') }}
el-switch(@change="toggleFriendsListBulkUnfriendMode" v-model="friendsListBulkUnfriendMode" style="margin-left:5px")
el-switch(
@change='toggleFriendsListBulkUnfriendMode'
v-model='friendsListBulkUnfriendMode'
style='margin-left: 5px')
span {{ $t('view.friend_list.load') }}
template(v-if="friendsListLoading")
span(v-text="friendsListLoadingProgress" style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.friend_list.cancel_tooltip')" :disabled="hideTooltips")
el-button(@click="friendsListLoading = false" size="mini" icon="el-icon-loading" circle style="margin-left:5px")
template(v-if='friendsListLoading')
span(v-text='friendsListLoadingProgress' style='margin-left: 5px')
el-tooltip(
placement='top'
:content='$t("view.friend_list.cancel_tooltip")'
:disabled='hideTooltips')
el-button(
@click='friendsListLoading = false'
size='mini'
icon='el-icon-loading'
circle
style='margin-left: 5px')
template(v-else)
el-tooltip(placement="top" :content="$t('view.friend_list.load_tooltip')" :disabled="hideTooltips")
el-button(@click="friendsListLoadUsers" size="mini" icon="el-icon-refresh-left" circle style="margin-left:5px")
div(style="margin:10px 0 0 10px;display:flex;align-items:center")
div(style="flex:none;margin-right:10px;display:flex;align-items:center;")
el-tooltip(placement="bottom" :content="$t('view.friend_list.favorites_only_tooltip')" :disabled="hideTooltips")
el-switch(v-model="friendsListSearchFilterVIP" @change="friendsListSearchChange" active-color="#13ce66")
el-input(v-model="friendsListSearch" :placeholder="$t('view.friend_list.search_placeholder')" @change="friendsListSearchChange" clearable style="flex:1")
el-select(v-model="friendsListSearchFilters" multiple clearable collapse-tags style="flex:none;width:200px;margin:0 10px" @change="friendsListSearchChange" :placeholder="$t('view.friend_list.filter_placeholder')")
el-option(v-for="type in ['Display Name', 'User Name', 'Rank', 'Status', 'Bio', 'Memo']" :key="type" :label="type" :value="type")
el-tooltip(placement="top" :content="$t('view.friend_list.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="friendsListSearchChange" icon="el-icon-refresh" circle style="flex:none")
el-tooltip(placement="top" :content="$t('view.friend_list.clear_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="friendsListTable.data = []" icon="el-icon-delete" circle style="flex:none;margin-left:5px")
data-tables(v-bind="friendsListTable" @row-click="selectFriendsListRow" style="margin-top:10px;cursor:pointer")
el-table-column(width="55" prop="$selected" v-if="friendsListBulkUnfriendMode" :key="friendsListBulkUnfriendForceUpdate")
template(#default="scope")
el-button(type="text" size="mini" @click.stop)
el-checkbox(v-model="scope.row.$selected" @change="friendsListBulkUnfriendForceUpdate++")
el-table-column(:label="$t('table.friendList.no')" width="70" prop="$friendNumber" sortable="custom")
template(#default="scope")
el-tooltip(placement='top' :content='$t("view.friend_list.load_tooltip")' :disabled='hideTooltips')
el-button(
@click='friendsListLoadUsers'
size='mini'
icon='el-icon-refresh-left'
circle
style='margin-left: 5px')
div(style='margin: 10px 0 0 10px; display: flex; align-items: center')
div(style='flex: none; margin-right: 10px; display: flex; align-items: center')
el-tooltip(
placement='bottom'
:content='$t("view.friend_list.favorites_only_tooltip")'
:disabled='hideTooltips')
el-switch(
v-model='friendsListSearchFilterVIP'
@change='friendsListSearchChange'
active-color='#13ce66')
el-input(
v-model='friendsListSearch'
:placeholder='$t("view.friend_list.search_placeholder")'
@change='friendsListSearchChange'
clearable
style='flex: 1')
el-select(
v-model='friendsListSearchFilters'
multiple
clearable
collapse-tags
style='flex: none; width: 200px; margin: 0 10px'
@change='friendsListSearchChange'
:placeholder='$t("view.friend_list.filter_placeholder")')
el-option(
v-for='type in ["Display Name", "User Name", "Rank", "Status", "Bio", "Memo"]'
:key='type'
:label='type'
:value='type')
el-tooltip(placement='top' :content='$t("view.friend_list.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='friendsListSearchChange'
icon='el-icon-refresh'
circle
style='flex: none')
el-tooltip(placement='top' :content='$t("view.friend_list.clear_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='friendsListTable.data = []'
icon='el-icon-delete'
circle
style='flex: none; margin-left: 5px')
data-tables(
v-bind='friendsListTable'
@row-click='selectFriendsListRow'
style='margin-top: 10px; cursor: pointer')
el-table-column(
width='55'
prop='$selected'
v-if='friendsListBulkUnfriendMode'
:key='friendsListBulkUnfriendForceUpdate')
template(#default='scope')
el-button(type='text' size='mini' @click.stop)
el-checkbox(v-model='scope.row.$selected' @change='friendsListBulkUnfriendForceUpdate++')
el-table-column(:label='$t("table.friendList.no")' width='70' prop='$friendNumber' sortable='custom')
template(#default='scope')
span {{ scope.row.$friendNumber ? scope.row.$friendNumber : '' }}
el-table-column(:label="$t('table.friendList.avatar')" width="70" prop="photo")
template(#default="scope")
el-popover(placement="right" height="500px" trigger="hover")
img.friends-list-avatar(slot="reference" v-lazy="userImage(scope.row)")
img.friends-list-avatar(v-lazy="userImageFull(scope.row)" style="height:500px;cursor:pointer" @click="showFullscreenImageDialog(userImageFull(scope.row))")
el-table-column(:label="$t('table.friendList.displayName')" min-width="140" prop="displayName" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'displayName')")
template(#default="scope")
span.name(v-if="randomUserColours" v-text="scope.row.displayName" :style="{'color':scope.row.$userColour}")
span.name(v-else v-text="scope.row.displayName")
el-table-column(:label="$t('table.friendList.rank')" width="110" prop="$trustSortNum" sortable="custom")
template(#default="scope")
span.name(v-if="randomUserColours" v-text="scope.row.$trustLevel" :class="scope.row.$trustClass")
span.name(v-else v-text="scope.row.$trustLevel" :style="{'color':scope.row.$userColour}")
el-table-column(:label="$t('table.friendList.status')" min-width="180" prop="status" sortable :sort-method="(a, b) => sortStatus(a.status, b.status)")
template(#default="scope")
i.x-user-status(v-if="scope.row.status !== 'offline'" :class="statusClass(scope.row.status)")
span
span(v-text="scope.row.statusDescription")
el-table-column(:label="$t('table.friendList.language')" width="110" prop="$languages" sortable :sort-method="(a, b) => sortLanguages(a, b)")
template(#default="scope")
el-tooltip(v-for="item in scope.row.$languages" :key="item.key" placement="top")
el-table-column(:label='$t("table.friendList.avatar")' width='70' prop='photo')
template(#default='scope')
el-popover(placement='right' height='500px' trigger='hover')
img.friends-list-avatar(slot='reference' v-lazy='userImage(scope.row)')
img.friends-list-avatar(
v-lazy='userImageFull(scope.row)'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(userImageFull(scope.row))')
el-table-column(
:label='$t("table.friendList.displayName")'
min-width='140'
prop='displayName'
sortable
:sort-method='(a, b) => sortAlphabetically(a, b, "displayName")')
template(#default='scope')
span.name(
v-if='randomUserColours'
v-text='scope.row.displayName'
:style='{ color: scope.row.$userColour }')
span.name(v-else v-text='scope.row.displayName')
el-table-column(
:label='$t("table.friendList.rank")'
width='110'
prop='$trustSortNum'
sortable='custom')
template(#default='scope')
span.name(
v-if='randomUserColours'
v-text='scope.row.$trustLevel'
:class='scope.row.$trustClass')
span.name(v-else v-text='scope.row.$trustLevel' :style='{ color: scope.row.$userColour }')
el-table-column(
:label='$t("table.friendList.status")'
min-width='180'
prop='status'
sortable
:sort-method='(a, b) => sortStatus(a.status, b.status)')
template(#default='scope')
i.x-user-status(v-if='scope.row.status !== "offline"' :class='statusClass(scope.row.status)')
span
span(v-text='scope.row.statusDescription')
el-table-column(
:label='$t("table.friendList.language")'
width='110'
prop='$languages'
sortable
:sort-method='(a, b) => sortLanguages(a, b)')
template(#default='scope')
el-tooltip(v-for='item in scope.row.$languages' :key='item.key' placement='top')
template(#content)
span {{ item.value }} ({{ item.key }})
span.flags(:class="languageClass(item.key)" style="display:inline-block;margin-right:5px")
el-table-column(:label="$t('table.friendList.bioLink')" width="100" prop="bioLinks")
template(#default="scope")
el-tooltip(v-if="link" v-for="(link, index) in scope.row.bioLinks" :key="index")
span.flags(:class='languageClass(item.key)' style='display: inline-block; margin-right: 5px')
el-table-column(:label='$t("table.friendList.bioLink")' width='100' prop='bioLinks')
template(#default='scope')
el-tooltip(v-if='link' v-for='(link, index) in scope.row.bioLinks' :key='index')
template(#content)
span(v-text="link")
img(:src="getFaviconUrl(link)" style="width:16px;height:16px;vertical-align:middle;margin-right:5px;cursor:pointer" @click.stop="openExternalLink(link)")
el-table-column(:label="$t('table.friendList.joinCount')" width="120" prop="$joinCount" sortable)
el-table-column(:label="$t('table.friendList.timeTogether')" width="140" prop="$timeSpent" sortable)
template(#default="scope")
span(v-if="scope.row.$timeSpent") {{ timeToText(scope.row.$timeSpent) }}
el-table-column(:label="$t('table.friendList.lastSeen')" width="170" prop="$lastSeen" sortable :sort-method="(a, b) => sortAlphabetically(a, b, '$lastSeen')")
template(#default="scope")
span(v-text='link')
img(
:src='getFaviconUrl(link)'
style='width: 16px; height: 16px; vertical-align: middle; margin-right: 5px; cursor: pointer'
@click.stop='openExternalLink(link)')
el-table-column(:label='$t("table.friendList.joinCount")' width='120' prop='$joinCount' sortable)
el-table-column(:label='$t("table.friendList.timeTogether")' width='140' prop='$timeSpent' sortable)
template(#default='scope')
span(v-if='scope.row.$timeSpent') {{ timeToText(scope.row.$timeSpent) }}
el-table-column(
:label='$t("table.friendList.lastSeen")'
width='170'
prop='$lastSeen'
sortable
:sort-method='(a, b) => sortAlphabetically(a, b, "$lastSeen")')
template(#default='scope')
span {{ scope.row.$lastSeen | formatDate('long') }}
el-table-column(:label="$t('table.friendList.lastActivity')" width="170" prop="last_activity" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'last_activity')")
template(#default="scope")
el-table-column(
:label='$t("table.friendList.lastActivity")'
width='170'
prop='last_activity'
sortable
:sort-method='(a, b) => sortAlphabetically(a, b, "last_activity")')
template(#default='scope')
span {{ scope.row.last_activity | formatDate('long') }}
el-table-column(:label="$t('table.friendList.lastLogin')" width="170" prop="last_login" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'last_login')")
template(#default="scope")
el-table-column(
:label='$t("table.friendList.lastLogin")'
width='170'
prop='last_login'
sortable
:sort-method='(a, b) => sortAlphabetically(a, b, "last_login")')
template(#default='scope')
span {{ scope.row.last_login | formatDate('long') }}
el-table-column(:label="$t('table.friendList.dateJoined')" width="120" prop="date_joined" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'date_joined')")
el-table-column(:label="$t('table.friendList.unfriend')" width="100" align="center")
template(#default="scope")
el-button(type="text" icon="el-icon-close" style="color:#f56c6c" size="mini" @click.stop="confirmDeleteFriend(scope.row.id)")
el-table-column(
:label='$t("table.friendList.dateJoined")'
width='120'
prop='date_joined'
sortable
:sort-method='(a, b) => sortAlphabetically(a, b, "date_joined")')
el-table-column(:label='$t("table.friendList.unfriend")' width='100' align='center')
template(#default='scope')
el-button(
type='text'
icon='el-icon-close'
style='color: #f56c6c'
size='mini'
@click.stop='confirmDeleteFriend(scope.row.id)')

View File

@@ -1,57 +1,112 @@
mixin gameLogTab()
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'gameLog'")
data-tables(v-bind="gameLogTable" v-loading="gameLogTable.loading")
mixin gameLogTab
.x-container(v-show='$refs.menu && $refs.menu.activeIndex === \'gameLog\'')
data-tables(v-bind='gameLogTable' v-loading='gameLogTable.loading')
template(#tool)
div(style="margin:0 0 10px;display:flex;align-items:center")
div(style="flex:none;margin-right:10px;display:flex;align-items:center;")
el-tooltip(placement="bottom" :content="$t('view.feed.favorites_only_tooltip')" :disabled="hideTooltips")
el-switch(v-model="gameLogTable.vip" @change="gameLogTableLookup" active-color="#13ce66")
el-select(v-model="gameLogTable.filter" @change="gameLogTableLookup" multiple clearable style="flex:1" :placeholder="$t('view.game_log.filter_placeholder')")
el-option(v-for="type in ['Location', 'OnPlayerJoined', 'OnPlayerLeft', 'PortalSpawn', 'VideoPlay', 'Event', 'External', 'StringLoad', 'ImageLoad']" :key="type" :label="$t('view.game_log.filters.' + type)" :value="type")
el-input(v-model="gameLogTable.search" :placeholder="$t('view.game_log.search_placeholder')" @keyup.native.13="gameLogTableLookup" @change="gameLogTableLookup" clearable style="flex:none;width:150px;margin:0 10px")
el-table-column(:label="$t('table.gameLog.date')" prop="created_at" sortable="custom" width="120")
template(#default="scope")
el-tooltip(placement="right")
div(style='margin: 0 0 10px; display: flex; align-items: center')
div(style='flex: none; margin-right: 10px; display: flex; align-items: center')
el-tooltip(
placement='bottom'
:content='$t("view.feed.favorites_only_tooltip")'
:disabled='hideTooltips')
el-switch(v-model='gameLogTable.vip' @change='gameLogTableLookup' active-color='#13ce66')
el-select(
v-model='gameLogTable.filter'
@change='gameLogTableLookup'
multiple
clearable
style='flex: 1'
:placeholder='$t("view.game_log.filter_placeholder")')
el-option(
v-for='type in ["Location", "OnPlayerJoined", "OnPlayerLeft", "PortalSpawn", "VideoPlay", "Event", "External", "StringLoad", "ImageLoad"]'
:key='type'
:label='$t("view.game_log.filters." + type)'
:value='type')
el-input(
v-model='gameLogTable.search'
:placeholder='$t("view.game_log.search_placeholder")'
@keyup.native.13='gameLogTableLookup'
@change='gameLogTableLookup'
clearable
style='flex: none; width: 150px; margin: 0 10px')
el-table-column(:label='$t("table.gameLog.date")' prop='created_at' sortable='custom' width='120')
template(#default='scope')
el-tooltip(placement='right')
template(#content)
span {{ scope.row.created_at | formatDate('long') }}
span {{ scope.row.created_at | formatDate('short') }}
el-table-column(:label="$t('table.gameLog.type')" prop="type" width="120")
template(#default="scope")
span.x-link(v-if="scope.row.location && scope.row.type !== 'Location'" v-text="$t('view.game_log.filters.' + scope.row.type)" @click="showWorldDialog(scope.row.location)")
span(v-else v-text="$t('view.game_log.filters.' + scope.row.type)")
el-table-column(:label="$t('table.gameLog.icon')" prop="isFriend" width="70" align="center")
template(#default="scope")
template(v-if="gameLogIsFriend(scope.row)")
el-tooltip(v-if="gameLogIsFavorite(scope.row)" placement="top" content="Favorite")
el-table-column(:label='$t("table.gameLog.type")' prop='type' width='120')
template(#default='scope')
span.x-link(
v-if='scope.row.location && scope.row.type !== "Location"'
v-text='$t("view.game_log.filters." + scope.row.type)'
@click='showWorldDialog(scope.row.location)')
span(v-else v-text='$t("view.game_log.filters." + scope.row.type)')
el-table-column(:label='$t("table.gameLog.icon")' prop='isFriend' width='70' align='center')
template(#default='scope')
template(v-if='gameLogIsFriend(scope.row)')
el-tooltip(v-if='gameLogIsFavorite(scope.row)' placement='top' content='Favorite')
span ⭐
el-tooltip(v-else placement="top" content="Friend")
el-tooltip(v-else placement='top' content='Friend')
span 💚
el-table-column(:label="$t('table.gameLog.user')" prop="displayName" width="180")
template(#default="scope")
span.x-link(v-if="scope.row.displayName" v-text="scope.row.displayName" @click="lookupUser(scope.row)" style="padding-right:10px")
el-table-column(:label="$t('table.gameLog.detail')" prop="data")
template(#default="scope")
location(v-if="scope.row.type === 'Location'" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
location(v-else-if="scope.row.type === 'PortalSpawn'" :location="scope.row.instanceId" :hint="scope.row.worldName" :grouphint="scope.row.groupName")
template(v-else-if="scope.row.type === 'Event'")
span(v-text="scope.row.data")
template(v-else-if="scope.row.type === 'External'")
span(v-text="scope.row.message")
template(v-else-if="scope.row.type === 'VideoPlay'")
span(v-if="scope.row.videoId" style="margin-right:5px") {{ scope.row.videoId }}:
span(v-if="scope.row.videoId === 'LSMedia'" v-text="scope.row.videoName")
span.x-link(v-else-if="scope.row.videoName" @click="openExternalLink(scope.row.videoUrl)" v-text="scope.row.videoName")
span.x-link(v-else @click="openExternalLink(scope.row.videoUrl)" v-text="scope.row.videoUrl")
template(v-else-if="scope.row.type === 'ImageLoad'")
span.x-link(@click="openExternalLink(scope.row.resourceUrl)" v-text="scope.row.resourceUrl")
template(v-else-if="scope.row.type === 'StringLoad'")
span.x-link(@click="openExternalLink(scope.row.resourceUrl)" v-text="scope.row.resourceUrl")
template(v-else-if="scope.row.type === 'Notification' || scope.row.type === 'OnPlayerJoined' || scope.row.type === 'OnPlayerLeft'")
span.x-link(v-else v-text="scope.row.data")
el-table-column(:label="$t('table.gameLog.action')" width="80" align="right")
template(#default="scope")
template(v-if="scope.row.type !== 'OnPlayerJoined' && scope.row.type !== 'OnPlayerLeft' && scope.row.type !== 'Location' && scope.row.type !== 'PortalSpawn'")
el-button(v-if="shiftHeld" style="color:#f56c6c" type="text" icon="el-icon-close" size="mini" @click="deleteGameLogEntry(scope.row)")
el-button(v-else type="text" icon="el-icon-delete" size="mini" @click="deleteGameLogEntryPrompt(scope.row)")
el-tooltip(placement="top" content="Open Instance Info" :disabled="hideTooltips")
el-button(v-if="scope.row.type === 'Location'" type="text" icon="el-icon-tickets" size="mini" @click="showPreviousInstanceInfoDialog(scope.row.location)")
el-table-column(:label='$t("table.gameLog.user")' prop='displayName' width='180')
template(#default='scope')
span.x-link(
v-if='scope.row.displayName'
v-text='scope.row.displayName'
@click='lookupUser(scope.row)'
style='padding-right: 10px')
el-table-column(:label='$t("table.gameLog.detail")' prop='data')
template(#default='scope')
location(
v-if='scope.row.type === "Location"'
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName')
location(
v-else-if='scope.row.type === "PortalSpawn"'
:location='scope.row.instanceId'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName')
template(v-else-if='scope.row.type === "Event"')
span(v-text='scope.row.data')
template(v-else-if='scope.row.type === "External"')
span(v-text='scope.row.message')
template(v-else-if='scope.row.type === "VideoPlay"')
span(v-if='scope.row.videoId' style='margin-right: 5px') {{ scope.row.videoId }}:
span(v-if='scope.row.videoId === "LSMedia"' v-text='scope.row.videoName')
span.x-link(
v-else-if='scope.row.videoName'
@click='openExternalLink(scope.row.videoUrl)'
v-text='scope.row.videoName')
span.x-link(v-else @click='openExternalLink(scope.row.videoUrl)' v-text='scope.row.videoUrl')
template(v-else-if='scope.row.type === "ImageLoad"')
span.x-link(@click='openExternalLink(scope.row.resourceUrl)' v-text='scope.row.resourceUrl')
template(v-else-if='scope.row.type === "StringLoad"')
span.x-link(@click='openExternalLink(scope.row.resourceUrl)' v-text='scope.row.resourceUrl')
template(
v-else-if='scope.row.type === "Notification" || scope.row.type === "OnPlayerJoined" || scope.row.type === "OnPlayerLeft"')
span.x-link(v-else v-text='scope.row.data')
el-table-column(:label='$t("table.gameLog.action")' width='80' align='right')
template(#default='scope')
template(
v-if='scope.row.type !== "OnPlayerJoined" && scope.row.type !== "OnPlayerLeft" && scope.row.type !== "Location" && scope.row.type !== "PortalSpawn"')
el-button(
v-if='shiftHeld'
style='color: #f56c6c'
type='text'
icon='el-icon-close'
size='mini'
@click='deleteGameLogEntry(scope.row)')
el-button(
v-else
type='text'
icon='el-icon-delete'
size='mini'
@click='deleteGameLogEntryPrompt(scope.row)')
el-tooltip(placement='top' content='Open Instance Info' :disabled='hideTooltips')
el-button(
v-if='scope.row.type === "Location"'
type='text'
icon='el-icon-tickets'
size='mini'
@click='showPreviousInstanceInfoDialog(scope.row.location)')

View File

@@ -1,95 +1,264 @@
mixin notificationsTab()
.x-container(v-if="$refs.menu && $refs.menu.activeIndex === 'notification'" v-loading="API.isNotificationsLoading")
data-tables(v-bind="notificationTable" ref="notificationTableRef" class="notification-table")
mixin notificationsTab
.x-container(v-if='$refs.menu && $refs.menu.activeIndex === "notification"' v-loading='API.isNotificationsLoading')
data-tables.notification-table(v-bind='notificationTable' ref='notificationTableRef')
template(#tool)
div(style="margin:0 0 10px;display:flex;align-items:center")
el-select(v-model="notificationTable.filters[0].value" @change="saveTableFilters" multiple clearable style="flex:1" :placeholder="$t('view.notification.filter_placeholder')")
el-option(v-for="type in ['requestInvite', 'invite', 'requestInviteResponse', 'inviteResponse', 'friendRequest', 'ignoredFriendRequest', 'message', 'boop', 'groupChange', 'group.announcement', 'group.informative', 'group.invite', 'group.joinRequest', 'group.transfer', 'group.queueReady', 'moderation.warning.group', 'moderation.report.closed', 'instance.closed']" :key="type" :label="$t('view.notification.filters.' + type)" :value="type")
el-input(v-model="notificationTable.filters[1].value" :placeholder="$t('view.notification.search_placeholder')" style="flex:none;width:150px;margin:0 10px")
el-tooltip(placement="bottom" :content="$t('view.notification.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" :loading="API.isNotificationsLoading" @click="API.refreshNotifications()" icon="el-icon-refresh" circle style="flex:none")
el-table-column(:label="$t('table.notification.date')" prop="created_at" sortable="custom" width="120")
template(#default="scope")
el-tooltip(placement="right")
div(style='margin: 0 0 10px; display: flex; align-items: center')
el-select(
v-model='notificationTable.filters[0].value'
@change='saveTableFilters'
multiple
clearable
style='flex: 1'
:placeholder='$t("view.notification.filter_placeholder")')
el-option(
v-for='type in ["requestInvite", "invite", "requestInviteResponse", "inviteResponse", "friendRequest", "ignoredFriendRequest", "message", "boop", "groupChange", "group.announcement", "group.informative", "group.invite", "group.joinRequest", "group.transfer", "group.queueReady", "moderation.warning.group", "moderation.report.closed", "instance.closed"]'
:key='type'
:label='$t("view.notification.filters." + type)'
:value='type')
el-input(
v-model='notificationTable.filters[1].value'
:placeholder='$t("view.notification.search_placeholder")'
style='flex: none; width: 150px; margin: 0 10px')
el-tooltip(
placement='bottom'
:content='$t("view.notification.refresh_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
:loading='API.isNotificationsLoading'
@click='API.refreshNotifications()'
icon='el-icon-refresh'
circle
style='flex: none')
el-table-column(:label='$t("table.notification.date")' prop='created_at' sortable='custom' width='120')
template(#default='scope')
el-tooltip(placement='right')
template(#content)
span {{ scope.row.created_at | formatDate('long') }}
span {{ scope.row.created_at | formatDate('short') }}
el-table-column(:label="$t('table.notification.type')" prop="type" width="180")
template(#default="scope")
el-tooltip(v-if="scope.row.type === 'invite'" placement="top")
el-table-column(:label='$t("table.notification.type")' prop='type' width='180')
template(#default='scope')
el-tooltip(v-if='scope.row.type === "invite"' placement='top')
template(#content)
location(v-if="scope.row.details" :location="scope.row.details.worldId" :hint="scope.row.details.worldName" :grouphint="scope.row.details.groupName" :link="false")
span.x-link(v-text="$t('view.notification.filters.' + scope.row.type)" @click="showWorldDialog(scope.row.details.worldId)")
el-tooltip(v-else-if="scope.row.type === 'group.queueReady' || scope.row.type === 'instance.closed'" placement="top")
location(
v-if='scope.row.details'
:location='scope.row.details.worldId'
:hint='scope.row.details.worldName'
:grouphint='scope.row.details.groupName'
:link='false')
span.x-link(
v-text='$t("view.notification.filters." + scope.row.type)'
@click='showWorldDialog(scope.row.details.worldId)')
el-tooltip(
v-else-if='scope.row.type === "group.queueReady" || scope.row.type === "instance.closed"'
placement='top')
template(#content)
location(v-if="scope.row.location" :location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName" :link="false")
span.x-link(v-text="$t('view.notification.filters.' + scope.row.type)" @click="showWorldDialog(scope.row.location)")
el-tooltip(v-else-if="scope.row.link" placement="top" :content="scope.row.linkText" :disabled="hideTooltips")
span.x-link(v-text="$t('view.notification.filters.' + scope.row.type)" @click="openNotificationLink(scope.row.link)")
span(v-else v-text="$t('view.notification.filters.' + scope.row.type)")
el-table-column(:label="$t('table.notification.user_group')" prop="senderUsername" width="150")
template(#default="scope")
template(v-if="scope.row.type === 'groupChange'")
span.x-link(v-text="scope.row.senderUsername" @click="showGroupDialog(scope.row.senderUserId)")
template(v-else-if="scope.row.senderUserId")
span.x-link(v-text="scope.row.senderUsername" @click="showUserDialog(scope.row.senderUserId)")
template(v-else-if="scope.row.link && scope.row.data?.groupName")
span.x-link(v-text="scope.row.data?.groupName" @click="openNotificationLink(scope.row.link)")
template(v-else-if="scope.row.link")
span.x-link(v-text="scope.row.linkText" @click="openNotificationLink(scope.row.link)")
el-table-column(:label="$t('table.notification.photo')" width="100" prop="photo")
template(#default="scope")
template(v-if="scope.row.details && scope.row.details.imageUrl")
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="scope.row.details.imageUrl" style="flex:none;height:50px;border-radius:4px")
img.x-link(v-lazy="scope.row.details.imageUrl" style="width:500px" @click="showFullscreenImageDialog(scope.row.details.imageUrl)")
template(v-else-if="scope.row.imageUrl")
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="scope.row.imageUrl" style="flex:none;height:50px;border-radius:4px")
img.x-link(v-lazy="scope.row.imageUrl" style="width:500px" @click="showFullscreenImageDialog(scope.row.imageUrl)")
el-table-column(:label="$t('table.notification.message')" prop="message")
template(#default="scope")
span.x-link(v-if="scope.row.type === 'invite'")
location(v-if="scope.row.details" :location="scope.row.details.worldId" :hint="scope.row.details.worldName" :grouphint="scope.row.details.groupName" :link="true")
location(
v-if='scope.row.location'
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName'
:link='false')
span.x-link(
v-text='$t("view.notification.filters." + scope.row.type)'
@click='showWorldDialog(scope.row.location)')
el-tooltip(
v-else-if='scope.row.link'
placement='top'
:content='scope.row.linkText'
:disabled='hideTooltips')
span.x-link(
v-text='$t("view.notification.filters." + scope.row.type)'
@click='openNotificationLink(scope.row.link)')
span(v-else v-text='$t("view.notification.filters." + scope.row.type)')
el-table-column(:label='$t("table.notification.user_group")' prop='senderUsername' width='150')
template(#default='scope')
template(v-if='scope.row.type === "groupChange"')
span.x-link(v-text='scope.row.senderUsername' @click='showGroupDialog(scope.row.senderUserId)')
template(v-else-if='scope.row.senderUserId')
span.x-link(v-text='scope.row.senderUsername' @click='showUserDialog(scope.row.senderUserId)')
template(v-else-if='scope.row.link && scope.row.data?.groupName')
span.x-link(v-text='scope.row.data?.groupName' @click='openNotificationLink(scope.row.link)')
template(v-else-if='scope.row.link')
span.x-link(v-text='scope.row.linkText' @click='openNotificationLink(scope.row.link)')
el-table-column(:label='$t("table.notification.photo")' width='100' prop='photo')
template(#default='scope')
template(v-if='scope.row.details && scope.row.details.imageUrl')
el-popover(placement='right' width='500px' trigger='click')
img.x-link(
slot='reference'
v-lazy='scope.row.details.imageUrl'
style='flex: none; height: 50px; border-radius: 4px')
img.x-link(
v-lazy='scope.row.details.imageUrl'
style='width: 500px'
@click='showFullscreenImageDialog(scope.row.details.imageUrl)')
template(v-else-if='scope.row.imageUrl')
el-popover(placement='right' width='500px' trigger='click')
img.x-link(
slot='reference'
v-lazy='scope.row.imageUrl'
style='flex: none; height: 50px; border-radius: 4px')
img.x-link(
v-lazy='scope.row.imageUrl'
style='width: 500px'
@click='showFullscreenImageDialog(scope.row.imageUrl)')
el-table-column(:label='$t("table.notification.message")' prop='message')
template(#default='scope')
span.x-link(v-if='scope.row.type === "invite"')
location(
v-if='scope.row.details'
:location='scope.row.details.worldId'
:hint='scope.row.details.worldName'
:grouphint='scope.row.details.groupName'
:link='true')
br
span(v-if="scope.row.message && scope.row.message !== `This is a generated invite to ${scope.row.details?.worldName}`" v-text="scope.row.message")
span(v-else-if='scope.row.details && scope.row.details.inviteMessage' v-text="scope.row.details.inviteMessage")
span(v-else-if='scope.row.details && scope.row.details.requestMessage' v-text="scope.row.details.requestMessage")
span(v-else-if='scope.row.details && scope.row.details.responseMessage' v-text="scope.row.details.responseMessage")
el-table-column(:label="$t('table.notification.action')" width="100" align="right")
template(#default="scope")
template(v-if="scope.row.senderUserId !== API.currentUser.id && !scope.row.$isExpired")
template(v-if="scope.row.type === 'friendRequest'")
el-tooltip(placement="top" content="Accept" :disabled="hideTooltips")
el-button(type="text" icon="el-icon-check" style="color:#67c23a" size="mini" @click="acceptFriendRequestNotification(scope.row)")
template(v-else-if="scope.row.type === 'invite'")
el-tooltip(placement="top" content="Decline with message" :disabled="hideTooltips")
el-button(type="text" icon="el-icon-chat-line-square" size="mini" @click="showSendInviteResponseDialog(scope.row)")
template(v-else-if="scope.row.type === 'requestInvite'")
template(v-if="lastLocation.location && isGameRunning && checkCanInvite(lastLocation.location)")
el-tooltip(placement="top" content="Invite" :disabled="hideTooltips")
el-button(type="text" icon="el-icon-check" style="color:#67c23a" size="mini" @click="acceptRequestInvite(scope.row)")
el-tooltip(placement="top" content="Decline with message" :disabled="hideTooltips")
el-button(type="text" icon="el-icon-chat-line-square" size="mini" style="margin-left:5px" @click="showSendInviteRequestResponseDialog(scope.row)")
template(v-if="scope.row.responses")
template(v-for="response in scope.row.responses")
el-tooltip(placement="top" :content="response.text" :disabled="hideTooltips")
el-button(v-if="response.icon === 'check'" type="text" icon="el-icon-check" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, response.type)")
el-button(v-else-if="response.icon === 'cancel'" type="text" icon="el-icon-close" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, response.type)")
el-button(v-else-if="response.icon === 'ban'" type="text" icon="el-icon-circle-close" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, response.type)")
el-button(v-else-if="response.icon === 'bell-slash'" type="text" icon="el-icon-bell" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, response.type)")
el-button(v-else-if="response.icon === 'reply' && scope.row.type === 'boop'" type="text" icon="el-icon-chat-line-square" size="mini" style="margin-left:5px" @click="showSendBoopDialog(scope.row.senderUserId)")
el-button(v-else-if="response.icon === 'reply'" type="text" icon="el-icon-chat-line-square" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, response.type)")
el-button(v-else type="text" icon="el-icon-collection-tag" size="mini" style="margin-left:5px" @click="sendNotificationResponse(scope.row.id, scope.row.responses, response.type)")
template(v-if="scope.row.type !== 'requestInviteResponse' && scope.row.type !== 'inviteResponse' && scope.row.type !== 'message' && scope.row.type !== 'boop' && scope.row.type !== 'groupChange' && !scope.row.type.includes('group.') && !scope.row.type.includes('moderation.') && !scope.row.type.includes('instance.')")
el-tooltip(placement="top" content="Decline" :disabled="hideTooltips")
el-button(v-if="shiftHeld" style="color:#f56c6c;margin-left:5px" type="text" icon="el-icon-close" size="mini" @click="hideNotification(scope.row)")
el-button(v-else type="text" icon="el-icon-close" size="mini" style="margin-left:5px" @click="hideNotificationPrompt(scope.row)")
template(v-if="scope.row.type === 'group.queueReady'")
el-tooltip(placement="top" content="Delete log" :disabled="hideTooltips")
el-button(v-if="shiftHeld" style="color:#f56c6c;margin-left:5px" type="text" icon="el-icon-close" size="mini" @click="deleteNotificationLog(scope.row)")
el-button(v-else type="text" icon="el-icon-delete" size="mini" style="margin-left:5px" @click="deleteNotificationLogPrompt(scope.row)")
template(v-if="scope.row.type !== 'friendRequest' && scope.row.type !== 'ignoredFriendRequest' && !scope.row.type.includes('group.') && !scope.row.type.includes('moderation.')")
el-tooltip(placement="top" content="Delete log" :disabled="hideTooltips")
el-button(v-if="shiftHeld" style="color:#f56c6c;margin-left:5px" type="text" icon="el-icon-close" size="mini" @click="deleteNotificationLog(scope.row)")
el-button(v-else type="text" icon="el-icon-delete" size="mini" style="margin-left:5px" @click="deleteNotificationLogPrompt(scope.row)")
span(
v-if='scope.row.message && scope.row.message !== `This is a generated invite to ${scope.row.details?.worldName}`'
v-text='scope.row.message')
span(
v-else-if='scope.row.details && scope.row.details.inviteMessage'
v-text='scope.row.details.inviteMessage')
span(
v-else-if='scope.row.details && scope.row.details.requestMessage'
v-text='scope.row.details.requestMessage')
span(
v-else-if='scope.row.details && scope.row.details.responseMessage'
v-text='scope.row.details.responseMessage')
el-table-column(:label='$t("table.notification.action")' width='100' align='right')
template(#default='scope')
template(v-if='scope.row.senderUserId !== API.currentUser.id && !scope.row.$isExpired')
template(v-if='scope.row.type === "friendRequest"')
el-tooltip(placement='top' content='Accept' :disabled='hideTooltips')
el-button(
type='text'
icon='el-icon-check'
style='color: #67c23a'
size='mini'
@click='acceptFriendRequestNotification(scope.row)')
template(v-else-if='scope.row.type === "invite"')
el-tooltip(placement='top' content='Decline with message' :disabled='hideTooltips')
el-button(
type='text'
icon='el-icon-chat-line-square'
size='mini'
@click='showSendInviteResponseDialog(scope.row)')
template(v-else-if='scope.row.type === "requestInvite"')
template(
v-if='lastLocation.location && isGameRunning && checkCanInvite(lastLocation.location)')
el-tooltip(placement='top' content='Invite' :disabled='hideTooltips')
el-button(
type='text'
icon='el-icon-check'
style='color: #67c23a'
size='mini'
@click='acceptRequestInvite(scope.row)')
el-tooltip(placement='top' content='Decline with message' :disabled='hideTooltips')
el-button(
type='text'
icon='el-icon-chat-line-square'
size='mini'
style='margin-left: 5px'
@click='showSendInviteRequestResponseDialog(scope.row)')
template(v-if='scope.row.responses')
template(v-for='response in scope.row.responses')
el-tooltip(placement='top' :content='response.text' :disabled='hideTooltips')
el-button(
v-if='response.icon === "check"'
type='text'
icon='el-icon-check'
size='mini'
style='margin-left: 5px'
@click='sendNotificationResponse(scope.row.id, scope.row.responses, response.type)')
el-button(
v-else-if='response.icon === "cancel"'
type='text'
icon='el-icon-close'
size='mini'
style='margin-left: 5px'
@click='sendNotificationResponse(scope.row.id, scope.row.responses, response.type)')
el-button(
v-else-if='response.icon === "ban"'
type='text'
icon='el-icon-circle-close'
size='mini'
style='margin-left: 5px'
@click='sendNotificationResponse(scope.row.id, scope.row.responses, response.type)')
el-button(
v-else-if='response.icon === "bell-slash"'
type='text'
icon='el-icon-bell'
size='mini'
style='margin-left: 5px'
@click='sendNotificationResponse(scope.row.id, scope.row.responses, response.type)')
el-button(
v-else-if='response.icon === "reply" && scope.row.type === "boop"'
type='text'
icon='el-icon-chat-line-square'
size='mini'
style='margin-left: 5px'
@click='showSendBoopDialog(scope.row.senderUserId)')
el-button(
v-else-if='response.icon === "reply"'
type='text'
icon='el-icon-chat-line-square'
size='mini'
style='margin-left: 5px'
@click='sendNotificationResponse(scope.row.id, scope.row.responses, response.type)')
el-button(
v-else
type='text'
icon='el-icon-collection-tag'
size='mini'
style='margin-left: 5px'
@click='sendNotificationResponse(scope.row.id, scope.row.responses, response.type)')
template(
v-if='scope.row.type !== "requestInviteResponse" && scope.row.type !== "inviteResponse" && scope.row.type !== "message" && scope.row.type !== "boop" && scope.row.type !== "groupChange" && !scope.row.type.includes("group.") && !scope.row.type.includes("moderation.") && !scope.row.type.includes("instance.")')
el-tooltip(placement='top' content='Decline' :disabled='hideTooltips')
el-button(
v-if='shiftHeld'
style='color: #f56c6c; margin-left: 5px'
type='text'
icon='el-icon-close'
size='mini'
@click='hideNotification(scope.row)')
el-button(
v-else
type='text'
icon='el-icon-close'
size='mini'
style='margin-left: 5px'
@click='hideNotificationPrompt(scope.row)')
template(v-if='scope.row.type === "group.queueReady"')
el-tooltip(placement='top' content='Delete log' :disabled='hideTooltips')
el-button(
v-if='shiftHeld'
style='color: #f56c6c; margin-left: 5px'
type='text'
icon='el-icon-close'
size='mini'
@click='deleteNotificationLog(scope.row)')
el-button(
v-else
type='text'
icon='el-icon-delete'
size='mini'
style='margin-left: 5px'
@click='deleteNotificationLogPrompt(scope.row)')
template(
v-if='scope.row.type !== "friendRequest" && scope.row.type !== "ignoredFriendRequest" && !scope.row.type.includes("group.") && !scope.row.type.includes("moderation.")')
el-tooltip(placement='top' content='Delete log' :disabled='hideTooltips')
el-button(
v-if='shiftHeld'
style='color: #f56c6c; margin-left: 5px'
type='text'
icon='el-icon-close'
size='mini'
@click='deleteNotificationLog(scope.row)')
el-button(
v-else
type='text'
icon='el-icon-delete'
size='mini'
style='margin-left: 5px'
@click='deleteNotificationLogPrompt(scope.row)')

View File

@@ -1,275 +1,481 @@
mixin playerListTab()
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'playerList'" style="padding-top:5px")
div(style="display:flex;flex-direction:column;height:100%")
div(v-if="currentInstanceWorld.ref.id" style="display:flex")
el-popover(placement="right" width="500px" trigger="click" style="height:120px")
img.x-link(slot="reference" v-lazy="currentInstanceWorld.ref.thumbnailImageUrl" style="flex:none;width:160px;height:120px;border-radius:4px")
img.x-link(v-lazy="currentInstanceWorld.ref.imageUrl" style="width:500px;height:375px" @click="showFullscreenImageDialog(currentInstanceWorld.ref.imageUrl)")
div(style="margin-left:10px;display:flex;flex-direction:column;min-width:320px;width:100%")
mixin playerListTab
.x-container(v-show='$refs.menu && $refs.menu.activeIndex === \'playerList\'' style='padding-top: 5px')
div(style='display: flex; flex-direction: column; height: 100%')
div(v-if='currentInstanceWorld.ref.id' style='display: flex')
el-popover(placement='right' width='500px' trigger='click' style='height: 120px')
img.x-link(
slot='reference'
v-lazy='currentInstanceWorld.ref.thumbnailImageUrl'
style='flex: none; width: 160px; height: 120px; border-radius: 4px')
img.x-link(
v-lazy='currentInstanceWorld.ref.imageUrl'
style='width: 500px; height: 375px'
@click='showFullscreenImageDialog(currentInstanceWorld.ref.imageUrl)')
div(style='margin-left: 10px; display: flex; flex-direction: column; min-width: 320px; width: 100%')
div
span.x-link(@click="showWorldDialog(currentInstanceWorld.ref.id)" style="font-weight:bold;overflow:hidden;text-overflow:ellipsis;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1")
| #[i.el-icon-s-home(v-show="API.currentUser.$homeLocation && API.currentUser.$homeLocation.worldId === currentInstanceWorld.ref.id" style="margin-right:5px")] {{ currentInstanceWorld.ref.name }}
span.x-link(
@click='showWorldDialog(currentInstanceWorld.ref.id)'
style='font-weight: bold; overflow: hidden; text-overflow: ellipsis; display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 1')
|#[i.el-icon-s-home(v-show='API.currentUser.$homeLocation && API.currentUser.$homeLocation.worldId === currentInstanceWorld.ref.id' style='margin-right: 5px')] {{ currentInstanceWorld.ref.name }}
div
span.x-link.x-grey(v-text="currentInstanceWorld.ref.authorName" @click="showUserDialog(currentInstanceWorld.ref.authorId)" style="font-family:monospace")
div(style="margin-top:5px")
el-tag(v-if="currentInstanceWorld.ref.$isLabs" type="primary" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.world.tags.labs') }}
el-tag(v-else-if="currentInstanceWorld.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.world.tags.public') }}
el-tag(v-else-if="currentInstanceWorld.ref.releaseStatus === 'private'" type="danger" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.world.tags.private') }}
el-tag.x-tag-platform-pc(v-if="currentInstanceWorld.isPC" type="info" effect="plain" size="mini" style="margin-right:5px") PC
span.x-grey(v-if="currentInstanceWorld.bundleSizes['standalonewindows']" style="margin-left:5px;border-left:inherit;padding-left:5px") {{ currentInstanceWorld.bundleSizes['standalonewindows'].fileSize }}
el-tag.x-tag-platform-quest(v-if="currentInstanceWorld.isQuest" type="info" effect="plain" size="mini" style="margin-right:5px") Android
span.x-grey(v-if="currentInstanceWorld.bundleSizes['android']" style="margin-left:5px;border-left:inherit;padding-left:5px") {{ currentInstanceWorld.bundleSizes['android'].fileSize }}
el-tag.x-tag-platform-ios(v-if="currentInstanceWorld.isIOS" type="info" effect="plain" size="mini" style="margin-right:5px") iOS
span.x-grey(v-if="currentInstanceWorld.bundleSizes['ios']" style="margin-left:5px;border-left:inherit;padding-left:5px") {{ currentInstanceWorld.bundleSizes['ios'].fileSize }}
el-tag(v-if="currentInstanceWorld.avatarScalingDisabled" type="warning" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.world.tags.avatar_scaling_disabled') }}
el-tag(v-if="currentInstanceWorld.inCache" type="info" effect="plain" size="mini" style="margin-right:5px")
span(v-text="currentInstanceWorld.cacheSize")
| {{ $t('dialog.world.tags.cache') }}
div(style="margin-top:5px")
location-world(:locationobject="currentInstanceLocation" :currentuserid="API.currentUser.id")
span(v-if="lastLocation.playerList.size > 0" style="margin-left:5px")
span.x-link.x-grey(
v-text='currentInstanceWorld.ref.authorName'
@click='showUserDialog(currentInstanceWorld.ref.authorId)'
style='font-family: monospace')
div(style='margin-top: 5px')
el-tag(
v-if='currentInstanceWorld.ref.$isLabs'
type='primary'
effect='plain'
size='mini'
style='margin-right: 5px') {{ $t('dialog.world.tags.labs') }}
el-tag(
v-else-if='currentInstanceWorld.ref.releaseStatus === "public"'
type='success'
effect='plain'
size='mini'
style='margin-right: 5px') {{ $t('dialog.world.tags.public') }}
el-tag(
v-else-if='currentInstanceWorld.ref.releaseStatus === "private"'
type='danger'
effect='plain'
size='mini'
style='margin-right: 5px') {{ $t('dialog.world.tags.private') }}
el-tag.x-tag-platform-pc(
v-if='currentInstanceWorld.isPC'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px') PC
span.x-grey(
v-if='currentInstanceWorld.bundleSizes["standalonewindows"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ currentInstanceWorld.bundleSizes['standalonewindows'].fileSize }}
el-tag.x-tag-platform-quest(
v-if='currentInstanceWorld.isQuest'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px') Android
span.x-grey(
v-if='currentInstanceWorld.bundleSizes["android"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ currentInstanceWorld.bundleSizes['android'].fileSize }}
el-tag.x-tag-platform-ios(
v-if='currentInstanceWorld.isIOS'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px') iOS
span.x-grey(
v-if='currentInstanceWorld.bundleSizes["ios"]'
style='margin-left: 5px; border-left: inherit; padding-left: 5px') {{ currentInstanceWorld.bundleSizes['ios'].fileSize }}
el-tag(
v-if='currentInstanceWorld.avatarScalingDisabled'
type='warning'
effect='plain'
size='mini'
style='margin-right: 5px; margin-top: 5px') {{ $t('dialog.world.tags.avatar_scaling_disabled') }}
el-tag(
v-if='currentInstanceWorld.inCache'
type='info'
effect='plain'
size='mini'
style='margin-right: 5px')
span(v-text='currentInstanceWorld.cacheSize')
|
| {{ $t('dialog.world.tags.cache') }}
div(style='margin-top: 5px')
location-world(
:locationobject='currentInstanceLocation'
:currentuserid='API.currentUser.id')
span(v-if='lastLocation.playerList.size > 0' style='margin-left: 5px')
| {{ lastLocation.playerList.size }}
| #[template(v-if="lastLocation.friendList.size > 0") ({{ lastLocation.friendList.size }})]
|  ― #[timer(v-if="lastLocation.date" :epoch="lastLocation.date")]
div(style="margin-top:5px")
span(v-show="currentInstanceWorld.ref.name !== currentInstanceWorld.ref.description" v-text="currentInstanceWorld.ref.description" :style="{fontSize: '12px', overflow: 'hidden', textOverflow: 'ellipsis', display:'-webkit-box', WebkitBoxOrient: 'vertical', WebkitLineClamp: currentInstanceWorldDescriptionExpanded ? 'none' : '2'}")
div(style="display:flex;justify-content:end")
el-button(v-if="currentInstanceWorld.ref.description.length > 50 && !currentInstanceWorldDescriptionExpanded" type="text" size="mini" @click="currentInstanceWorldDescriptionExpanded = true") {{ !currentInstanceWorldDescriptionExpanded && 'Show more' }}
div(style="display:flex;flex-direction:column;margin-left:20px")
.x-friend-item(style="cursor:default")
| #[template(v-if='lastLocation.friendList.size > 0') ({{ lastLocation.friendList.size }})]
|  ― #[timer(v-if='lastLocation.date' :epoch='lastLocation.date')]
div(style='margin-top: 5px')
span(
v-show='currentInstanceWorld.ref.name !== currentInstanceWorld.ref.description'
v-text='currentInstanceWorld.ref.description'
:style='{ fontSize: "12px", overflow: "hidden", textOverflow: "ellipsis", display: "-webkit-box", WebkitBoxOrient: "vertical", WebkitLineClamp: currentInstanceWorldDescriptionExpanded ? "none" : "2" }')
div(style='display: flex; justify-content: end')
el-button(
v-if='currentInstanceWorld.ref.description.length > 50 && !currentInstanceWorldDescriptionExpanded'
type='text'
size='mini'
@click='currentInstanceWorldDescriptionExpanded = true') {{ !currentInstanceWorldDescriptionExpanded && 'Show more' }}
div(style='display: flex; flex-direction: column; margin-left: 20px')
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.world.info.capacity') }}
span.extra {{ currentInstanceWorld.ref.recommendedCapacity | commaNumber }} ({{ currentInstanceWorld.ref.capacity | commaNumber }})
.x-friend-item(style="cursor:default")
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.world.info.last_updated') }}
span.extra {{ currentInstanceWorld.lastUpdated | formatDate('long') }}
.x-friend-item(style="cursor:default")
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('dialog.world.info.created_at') }}
span.extra {{ currentInstanceWorld.ref.created_at | formatDate('long') }}
div.photon-event-table(v-if="photonLoggingEnabled")
div(style="position:absolute;width:600px;margin-left:215px;z-index:1")
el-select(v-model="photonEventTableTypeFilter" @change="photonEventTableFilterChange" multiple clearable collapse-tags style="flex:1;width:220px" :placeholder="$t('view.player_list.photon.filter_placeholder')")
el-option(v-for="type in photonEventTableTypeFilterList" :key="type" :label="type" :value="type")
el-input(v-model="photonEventTableFilter" @input="photonEventTableFilterChange" :placeholder="$t('view.player_list.photon.search_placeholder')" clearable style="width:150px;margin-left:10px")
el-button(@click="showChatboxBlacklistDialog" style="margin-left:10px") {{ $t('view.player_list.photon.chatbox_blacklist') }}
el-tooltip(placement="bottom" :content="$t('view.player_list.photon.status_tooltip')" :disabled="hideTooltips")
div(style="display:inline-block;margin-left:15px;font-size:14px;vertical-align:text-top;margin-top:1px")
span(v-if="ipcEnabled && !photonEventIcon") 🟢
span(v-else-if="ipcEnabled") ⚪
.photon-event-table(v-if='photonLoggingEnabled')
div(style='position: absolute; width: 600px; margin-left: 215px; z-index: 1')
el-select(
v-model='photonEventTableTypeFilter'
@change='photonEventTableFilterChange'
multiple
clearable
collapse-tags
style='flex: 1; width: 220px'
:placeholder='$t("view.player_list.photon.filter_placeholder")')
el-option(
v-for='type in photonEventTableTypeFilterList'
:key='type'
:label='type'
:value='type')
el-input(
v-model='photonEventTableFilter'
@input='photonEventTableFilterChange'
:placeholder='$t("view.player_list.photon.search_placeholder")'
clearable
style='width: 150px; margin-left: 10px')
el-button(@click='showChatboxBlacklistDialog' style='margin-left: 10px') {{ $t('view.player_list.photon.chatbox_blacklist') }}
el-tooltip(
placement='bottom'
:content='$t("view.player_list.photon.status_tooltip")'
:disabled='hideTooltips')
div(
style='display: inline-block; margin-left: 15px; font-size: 14px; vertical-align: text-top; margin-top: 1px')
span(v-if='ipcEnabled && !photonEventIcon') 🟢
span(v-else-if='ipcEnabled') ⚪
span(v-else) 🔴
el-tabs(type="card")
el-tab-pane(:label="$t('view.player_list.photon.current')")
data-tables(v-bind="photonEventTable" style="margin-bottom:10px")
el-table-column(:label="$t('table.playerList.date')" prop="created_at" width="120")
template(#default="scope")
el-tooltip(placement="right")
el-tabs(type='card')
el-tab-pane(:label='$t("view.player_list.photon.current")')
data-tables(v-bind='photonEventTable' style='margin-bottom: 10px')
el-table-column(:label='$t("table.playerList.date")' prop='created_at' width='120')
template(#default='scope')
el-tooltip(placement='right')
template(#content)
span {{ scope.row.created_at | formatDate('long') }}
span {{ scope.row.created_at | formatDate('short') }}
el-table-column(:label="$t('table.playerList.user')" prop="photonId" width="160")
template(#default="scope")
span.x-link(v-text="scope.row.displayName" @click="showUserFromPhotonId(scope.row.photonId)" style="padding-right:10px")
el-table-column(:label="$t('table.playerList.type')" prop="type" width="140")
el-table-column(:label="$t('table.playerList.detail')" prop="text")
template(#default="scope")
template(v-if="scope.row.type === 'ChangeAvatar'")
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
el-table-column(:label='$t("table.playerList.user")' prop='photonId' width='160')
template(#default='scope')
span.x-link(
v-text='scope.row.displayName'
@click='showUserFromPhotonId(scope.row.photonId)'
style='padding-right: 10px')
el-table-column(:label='$t("table.playerList.type")' prop='type' width='140')
el-table-column(:label='$t("table.playerList.detail")' prop='text')
template(#default='scope')
template(v-if='scope.row.type === "ChangeAvatar"')
span.x-link(
v-text='scope.row.avatar.name'
@click='showAvatarDialog(scope.row.avatar.id)')
|  
span(v-if="!scope.row.inCache" style="color:#aaa") #[i.el-icon-download] 
span.avatar-info-public(v-if="scope.row.avatar.releaseStatus === 'public'") {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if="scope.row.avatar.releaseStatus === 'private'") {{ $t('dialog.avatar.labels.private') }}
template(v-if="scope.row.avatar.description && scope.row.avatar.name !== scope.row.avatar.description")
| - {{ scope.row.avatar.description }}
template(v-else-if="scope.row.type === 'ChangeStatus'")
template(v-if="scope.row.status !== scope.row.previousStatus")
el-tooltip(placement="top")
span(v-if='!scope.row.inCache' style='color: #aaa') #[i.el-icon-download] 
span.avatar-info-public(v-if='scope.row.avatar.releaseStatus === "public"') {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if='scope.row.avatar.releaseStatus === "private"') {{ $t('dialog.avatar.labels.private') }}
template(
v-if='scope.row.avatar.description && scope.row.avatar.name !== scope.row.avatar.description')
|
| - {{ scope.row.avatar.description }}
template(v-else-if='scope.row.type === "ChangeStatus"')
template(v-if='scope.row.status !== scope.row.previousStatus')
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.previousStatus === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.previousStatus === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.previousStatus === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.previousStatus === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.previousStatus === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.previousStatus === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.previousStatus === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.previousStatus === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.previousStatus)")
i.x-user-status(:class='statusClass(scope.row.previousStatus)')
span
i.el-icon-right
el-tooltip(placement="top")
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.status === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.status === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.status === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.status === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.status)" style="margin-right:5px")
span(v-if="scope.row.statusDescription !== scope.row.previousStatusDescription" v-text="scope.row.statusDescription")
template(v-else-if="scope.row.type === 'ChangeGroup'")
span.x-link(v-if="scope.row.previousGroupName" v-text="scope.row.previousGroupName" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
span.x-link(v-else v-text="scope.row.previousGroupId" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
i.x-user-status(
:class='statusClass(scope.row.status)'
style='margin-right: 5px')
span(
v-if='scope.row.statusDescription !== scope.row.previousStatusDescription'
v-text='scope.row.statusDescription')
template(v-else-if='scope.row.type === "ChangeGroup"')
span.x-link(
v-if='scope.row.previousGroupName'
v-text='scope.row.previousGroupName'
@click='showGroupDialog(scope.row.previousGroupId)'
style='margin-right: 5px')
span.x-link(
v-else
v-text='scope.row.previousGroupId'
@click='showGroupDialog(scope.row.previousGroupId)'
style='margin-right: 5px')
span
i.el-icon-right
span.x-link(v-if="scope.row.groupName" v-text="scope.row.groupName" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
span.x-link(v-else v-text="scope.row.groupId" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
span.x-link(v-else-if="scope.row.type === 'PortalSpawn'" @click="showWorldDialog(scope.row.location, scope.row.shortName)")
location(:location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName" :link="false")
span(v-else-if="scope.row.type === 'ChatBoxMessage'" v-text="scope.row.text")
span(v-else-if="scope.row.type === 'OnPlayerJoined'")
span(v-if="scope.row.platform === 'Desktop'" style="color:#409eff") Desktop 
span(v-else-if="scope.row.platform === 'VR'" style="color:#409eff") VR 
span(v-else-if="scope.row.platform === 'Quest'" style="color:#67c23a") Android 
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
span.x-link(
v-if='scope.row.groupName'
v-text='scope.row.groupName'
@click='showGroupDialog(scope.row.groupId)'
style='margin-left: 5px')
span.x-link(
v-else
v-text='scope.row.groupId'
@click='showGroupDialog(scope.row.groupId)'
style='margin-left: 5px')
span.x-link(
v-else-if='scope.row.type === "PortalSpawn"'
@click='showWorldDialog(scope.row.location, scope.row.shortName)')
location(
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName'
:link='false')
span(v-else-if='scope.row.type === "ChatBoxMessage"' v-text='scope.row.text')
span(v-else-if='scope.row.type === "OnPlayerJoined"')
span(v-if='scope.row.platform === "Desktop"' style='color: #409eff') Desktop 
span(v-else-if='scope.row.platform === "VR"' style='color: #409eff') VR 
span(v-else-if='scope.row.platform === "Quest"' style='color: #67c23a') Android 
span.x-link(
v-text='scope.row.avatar.name'
@click='showAvatarDialog(scope.row.avatar.id)')
|  
span(v-if="!scope.row.inCache" style="color:#aaa") #[i.el-icon-download] 
span.avatar-info-public(v-if="scope.row.avatar.releaseStatus === 'public'") {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if="scope.row.avatar.releaseStatus === 'private'") {{ $t('dialog.avatar.labels.private') }}
span(v-else-if="scope.row.type === 'SpawnEmoji'")
span(v-if="scope.row.imageUrl")
el-tooltip(placement="right")
span(v-if='!scope.row.inCache' style='color: #aaa') #[i.el-icon-download] 
span.avatar-info-public(v-if='scope.row.avatar.releaseStatus === "public"') {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if='scope.row.avatar.releaseStatus === "private"') {{ $t('dialog.avatar.labels.private') }}
span(v-else-if='scope.row.type === "SpawnEmoji"')
span(v-if='scope.row.imageUrl')
el-tooltip(placement='right')
template(#content)
img.friends-list-avatar(v-lazy="scope.row.imageUrl" style="height:500px;cursor:pointer" @click="showFullscreenImageDialog(scope.row.imageUrl)")
span(v-text="scope.row.fileId")
span(v-else v-text="scope.row.text")
span(v-else-if="scope.row.color === 'yellow'" v-text="scope.row.text" style="color:yellow")
span(v-else v-text="scope.row.text")
el-tab-pane(:label="$t('view.player_list.photon.previous')")
data-tables(v-bind="photonEventTablePrevious" style="margin-bottom:10px")
el-table-column(:label="$t('table.playerList.date')" prop="created_at" width="120")
template(#default="scope")
el-tooltip(placement="right")
img.friends-list-avatar(
v-lazy='scope.row.imageUrl'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(scope.row.imageUrl)')
span(v-text='scope.row.fileId')
span(v-else v-text='scope.row.text')
span(
v-else-if='scope.row.color === "yellow"'
v-text='scope.row.text'
style='color: yellow')
span(v-else v-text='scope.row.text')
el-tab-pane(:label='$t("view.player_list.photon.previous")')
data-tables(v-bind='photonEventTablePrevious' style='margin-bottom: 10px')
el-table-column(:label='$t("table.playerList.date")' prop='created_at' width='120')
template(#default='scope')
el-tooltip(placement='right')
template(#content)
span {{ scope.row.created_at | formatDate('long') }}
span {{ scope.row.created_at | formatDate('short') }}
el-table-column(:label="$t('table.playerList.user')" prop="photonId" width="160")
template(#default="scope")
span.x-link(v-text="scope.row.displayName" @click="lookupUser(scope.row)" style="padding-right:10px")
el-table-column(:label="$t('table.playerList.type')" prop="type" width="140")
el-table-column(:label="$t('table.playerList.detail')" prop="text")
template(#default="scope")
template(v-if="scope.row.type === 'ChangeAvatar'")
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
el-table-column(:label='$t("table.playerList.user")' prop='photonId' width='160')
template(#default='scope')
span.x-link(
v-text='scope.row.displayName'
@click='lookupUser(scope.row)'
style='padding-right: 10px')
el-table-column(:label='$t("table.playerList.type")' prop='type' width='140')
el-table-column(:label='$t("table.playerList.detail")' prop='text')
template(#default='scope')
template(v-if='scope.row.type === "ChangeAvatar"')
span.x-link(
v-text='scope.row.avatar.name'
@click='showAvatarDialog(scope.row.avatar.id)')
|  
span(v-if="!scope.row.inCache" style="color:#aaa") #[i.el-icon-download] 
span.avatar-info-public(v-if="scope.row.avatar.releaseStatus === 'public'") {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if="scope.row.avatar.releaseStatus === 'private'") {{ $t('dialog.avatar.labels.private') }}
template(v-if="scope.row.avatar.description && scope.row.avatar.name !== scope.row.avatar.description")
| - {{ scope.row.avatar.description }}
template(v-else-if="scope.row.type === 'ChangeStatus'")
template(v-if="scope.row.status !== scope.row.previousStatus")
el-tooltip(placement="top")
span(v-if='!scope.row.inCache' style='color: #aaa') #[i.el-icon-download] 
span.avatar-info-public(v-if='scope.row.avatar.releaseStatus === "public"') {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if='scope.row.avatar.releaseStatus === "private"') {{ $t('dialog.avatar.labels.private') }}
template(
v-if='scope.row.avatar.description && scope.row.avatar.name !== scope.row.avatar.description')
|
| - {{ scope.row.avatar.description }}
template(v-else-if='scope.row.type === "ChangeStatus"')
template(v-if='scope.row.status !== scope.row.previousStatus')
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.previousStatus === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.previousStatus === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.previousStatus === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.previousStatus === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.previousStatus === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.previousStatus === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.previousStatus === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.previousStatus === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.previousStatus)")
i.x-user-status(:class='statusClass(scope.row.previousStatus)')
span
i.el-icon-right
el-tooltip(placement="top")
el-tooltip(placement='top')
template(#content)
span(v-if="scope.row.status === 'active'") {{ $t('dialog.user.status.active') }}
span(v-else-if="scope.row.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
span(v-else-if="scope.row.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
span(v-else-if="scope.row.status === 'busy'") {{ $t('dialog.user.status.busy') }}
span(v-if='scope.row.status === "active"') {{ $t('dialog.user.status.active') }}
span(v-else-if='scope.row.status === "join me"') {{ $t('dialog.user.status.join_me') }}
span(v-else-if='scope.row.status === "ask me"') {{ $t('dialog.user.status.ask_me') }}
span(v-else-if='scope.row.status === "busy"') {{ $t('dialog.user.status.busy') }}
span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="statusClass(scope.row.status)" style="margin-right:5px")
span(v-if="scope.row.statusDescription !== scope.row.previousStatusDescription" v-text="scope.row.statusDescription")
template(v-else-if="scope.row.type === 'ChangeGroup'")
span.x-link(v-if="scope.row.previousGroupName" v-text="scope.row.previousGroupName" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
span.x-link(v-else v-text="scope.row.previousGroupId" @click="showGroupDialog(scope.row.previousGroupId)" style="margin-right:5px")
i.x-user-status(
:class='statusClass(scope.row.status)'
style='margin-right: 5px')
span(
v-if='scope.row.statusDescription !== scope.row.previousStatusDescription'
v-text='scope.row.statusDescription')
template(v-else-if='scope.row.type === "ChangeGroup"')
span.x-link(
v-if='scope.row.previousGroupName'
v-text='scope.row.previousGroupName'
@click='showGroupDialog(scope.row.previousGroupId)'
style='margin-right: 5px')
span.x-link(
v-else
v-text='scope.row.previousGroupId'
@click='showGroupDialog(scope.row.previousGroupId)'
style='margin-right: 5px')
span
i.el-icon-right
span.x-link(v-if="scope.row.groupName" v-text="scope.row.groupName" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
span.x-link(v-else v-text="scope.row.groupId" @click="showGroupDialog(scope.row.groupId)" style="margin-left:5px")
span.x-link(v-else-if="scope.row.type === 'PortalSpawn'" @click="showWorldDialog(scope.row.location, scope.row.shortName)")
location(:location="scope.row.location" :hint="scope.row.worldName" :grouphint="scope.row.groupName" :link="false")
span(v-else-if="scope.row.type === 'ChatBoxMessage'" v-text="scope.row.text")
span(v-else-if="scope.row.type === 'OnPlayerJoined'")
span(v-if="scope.row.platform === 'Desktop'" style="color:#409eff") Desktop 
span(v-else-if="scope.row.platform === 'VR'" style="color:#409eff") VR 
span(v-else-if="scope.row.platform === 'Quest'" style="color:#67c23a") Android 
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
span.x-link(
v-if='scope.row.groupName'
v-text='scope.row.groupName'
@click='showGroupDialog(scope.row.groupId)'
style='margin-left: 5px')
span.x-link(
v-else
v-text='scope.row.groupId'
@click='showGroupDialog(scope.row.groupId)'
style='margin-left: 5px')
span.x-link(
v-else-if='scope.row.type === "PortalSpawn"'
@click='showWorldDialog(scope.row.location, scope.row.shortName)')
location(
:location='scope.row.location'
:hint='scope.row.worldName'
:grouphint='scope.row.groupName'
:link='false')
span(v-else-if='scope.row.type === "ChatBoxMessage"' v-text='scope.row.text')
span(v-else-if='scope.row.type === "OnPlayerJoined"')
span(v-if='scope.row.platform === "Desktop"' style='color: #409eff') Desktop 
span(v-else-if='scope.row.platform === "VR"' style='color: #409eff') VR 
span(v-else-if='scope.row.platform === "Quest"' style='color: #67c23a') Android 
span.x-link(
v-text='scope.row.avatar.name'
@click='showAvatarDialog(scope.row.avatar.id)')
|  
span(v-if="!scope.row.inCache" style="color:#aaa") #[i.el-icon-download] 
span.avatar-info-public(v-if="scope.row.avatar.releaseStatus === 'public'") {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if="scope.row.avatar.releaseStatus === 'private'") {{ $t('dialog.avatar.labels.private') }}
span(v-else-if="scope.row.type === 'SpawnEmoji'")
span(v-if="scope.row.imageUrl")
el-tooltip(placement="right")
span(v-if='!scope.row.inCache' style='color: #aaa') #[i.el-icon-download] 
span.avatar-info-public(v-if='scope.row.avatar.releaseStatus === "public"') {{ $t('dialog.avatar.labels.public') }}
span.avatar-info-own(v-else-if='scope.row.avatar.releaseStatus === "private"') {{ $t('dialog.avatar.labels.private') }}
span(v-else-if='scope.row.type === "SpawnEmoji"')
span(v-if='scope.row.imageUrl')
el-tooltip(placement='right')
template(#content)
img.friends-list-avatar(v-lazy="scope.row.imageUrl" style="height:500px;cursor:pointer" @click="showFullscreenImageDialog(scope.row.imageUrl)")
span(v-text="scope.row.fileId")
span(v-else v-text="scope.row.text")
span(v-else-if="scope.row.color === 'yellow'" v-text="scope.row.text" style="color:yellow")
span(v-else v-text="scope.row.text")
div.current-instance-table
data-tables(v-bind="currentInstanceUserList" @row-click="selectCurrentInstanceRow" style="margin-top:10px;cursor:pointer")
el-table-column(:label="$t('table.playerList.avatar')" width="70" prop="photo")
template(#default="scope")
template(v-if="userImage(scope.row.ref)")
el-popover(placement="right" height="500px" trigger="hover")
img.friends-list-avatar(slot="reference" v-lazy="userImage(scope.row.ref)")
img.friends-list-avatar(v-lazy="userImageFull(scope.row.ref)" style="height:500px;cursor:pointer" @click="showFullscreenImageDialog(userImageFull(scope.row.ref))")
el-table-column(:label="$t('table.playerList.timer')" width="80" prop="timer" sortable)
template(#default="scope")
timer(:epoch="scope.row.timer")
el-table-column(v-if="photonLoggingEnabled" :label="$t('table.playerList.photonId')" width="110" prop="photonId" sortable)
template(#default="scope")
template(v-if="chatboxUserBlacklist.has(scope.row.ref.id)")
el-tooltip(placement="left" content="Unblock chatbox messages")
el-button(type="text" icon="el-icon-turn-off-microphone" size="mini" style="color:red;margin-right:5px" @click.stop="deleteChatboxUserBlacklist(scope.row.ref.id)")
img.friends-list-avatar(
v-lazy='scope.row.imageUrl'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(scope.row.imageUrl)')
span(v-text='scope.row.fileId')
span(v-else v-text='scope.row.text')
span(
v-else-if='scope.row.color === "yellow"'
v-text='scope.row.text'
style='color: yellow')
span(v-else v-text='scope.row.text')
.current-instance-table
data-tables(
v-bind='currentInstanceUserList'
@row-click='selectCurrentInstanceRow'
style='margin-top: 10px; cursor: pointer')
el-table-column(:label='$t("table.playerList.avatar")' width='70' prop='photo')
template(#default='scope')
template(v-if='userImage(scope.row.ref)')
el-popover(placement='right' height='500px' trigger='hover')
img.friends-list-avatar(slot='reference' v-lazy='userImage(scope.row.ref)')
img.friends-list-avatar(
v-lazy='userImageFull(scope.row.ref)'
style='height: 500px; cursor: pointer'
@click='showFullscreenImageDialog(userImageFull(scope.row.ref))')
el-table-column(:label='$t("table.playerList.timer")' width='80' prop='timer' sortable)
template(#default='scope')
timer(:epoch='scope.row.timer')
el-table-column(
v-if='photonLoggingEnabled'
:label='$t("table.playerList.photonId")'
width='110'
prop='photonId'
sortable)
template(#default='scope')
template(v-if='chatboxUserBlacklist.has(scope.row.ref.id)')
el-tooltip(placement='left' content='Unblock chatbox messages')
el-button(
type='text'
icon='el-icon-turn-off-microphone'
size='mini'
style='color: red; margin-right: 5px'
@click.stop='deleteChatboxUserBlacklist(scope.row.ref.id)')
template(v-else)
el-tooltip(placement="left" content="Block chatbox messages")
el-button(type="text" icon="el-icon-microphone" size="mini" style="margin-right:5px" @click.stop="addChatboxUserBlacklist(scope.row.ref)")
span(v-text="scope.row.photonId")
el-table-column(:label="$t('table.playerList.icon')" prop="isMaster" width="70" align="center")
template(#default="scope")
el-tooltip(v-if="scope.row.isMaster" placement="left" content="Instance Master")
el-tooltip(placement='left' content='Block chatbox messages')
el-button(
type='text'
icon='el-icon-microphone'
size='mini'
style='margin-right: 5px'
@click.stop='addChatboxUserBlacklist(scope.row.ref)')
span(v-text='scope.row.photonId')
el-table-column(:label='$t("table.playerList.icon")' prop='isMaster' width='70' align='center')
template(#default='scope')
el-tooltip(v-if='scope.row.isMaster' placement='left' content='Instance Master')
span 👑
el-tooltip(v-if="scope.row.isModerator" placement="left" content="Moderator")
el-tooltip(v-if='scope.row.isModerator' placement='left' content='Moderator')
span ⚔️
el-tooltip(v-if="scope.row.isFriend" placement="left" content="Friend")
el-tooltip(v-if='scope.row.isFriend' placement='left' content='Friend')
span 💚
el-tooltip(v-if="scope.row.timeoutTime" placement="left" content="Timeout")
span(style="color:red") 🔴{{ scope.row.timeoutTime }}s
el-table-column(:label="$t('table.playerList.platform')" prop="inVRMode" width="80")
template(#default="scope")
template(v-if="scope.row.ref.last_platform")
span(v-if="scope.row.ref.last_platform === 'standalonewindows'" style="color:#409eff") PC
span(v-else-if="scope.row.ref.last_platform === 'android'" style="color:#67c23a") A
span(v-else-if="scope.row.ref.last_platform === 'ios'" style="color:#c7c7ce") iOS
el-tooltip(v-if='scope.row.timeoutTime' placement='left' content='Timeout')
span(style='color: red') 🔴{{ scope.row.timeoutTime }}s
el-table-column(:label='$t("table.playerList.platform")' prop='inVRMode' width='80')
template(#default='scope')
template(v-if='scope.row.ref.last_platform')
span(v-if='scope.row.ref.last_platform === "standalonewindows"' style='color: #409eff') PC
span(v-else-if='scope.row.ref.last_platform === "android"' style='color: #67c23a') A
span(v-else-if='scope.row.ref.last_platform === "ios"' style='color: #c7c7ce') iOS
span(v-else) {{ scope.row.ref.last_platform }}
template(v-if="scope.row.inVRMode !== null")
span(v-if="scope.row.inVRMode") VR
span(v-else-if="scope.row.ref.last_platform === 'android' || scope.row.ref.last_platform === 'ios'") M
template(v-if='scope.row.inVRMode !== null')
span(v-if='scope.row.inVRMode') VR
span(
v-else-if='scope.row.ref.last_platform === "android" || scope.row.ref.last_platform === "ios"') M
span(v-else) D
el-table-column(:label="$t('table.playerList.displayName')" min-width="140" prop="displayName" sortable="custom")
template(#default="scope")
span(v-if="randomUserColours" v-text="scope.row.ref.displayName" :style="{'color':scope.row.ref.$userColour}")
span(v-else v-text="scope.row.ref.displayName")
el-table-column(:label="$t('table.playerList.status')" min-width="180" prop="ref.status")
template(#default="scope")
template(v-if="scope.row.ref.status")
i.x-user-status(:class="statusClass(scope.row.ref.status)")
span
span(v-text="scope.row.ref.statusDescription")
el-table-column(
:label='$t("table.playerList.displayName")'
min-width='140'
prop='displayName'
sortable='custom')
template(#default='scope')
span(
v-if='randomUserColours'
v-text='scope.row.ref.displayName'
:style='{ color: scope.row.ref.$userColour }')
span(v-else v-text='scope.row.ref.displayName')
el-table-column(:label='$t("table.playerList.status")' min-width='180' prop='ref.status')
template(#default='scope')
template(v-if='scope.row.ref.status')
i.x-user-status(:class='statusClass(scope.row.ref.status)')
span
span(v-text='scope.row.ref.statusDescription')
//- el-table-column(label="Group" min-width="180" prop="groupOnNameplate" sortable)
//- template(v-once #default="scope")
//- span(v-text="scope.row.groupOnNameplate")
el-table-column(:label="$t('table.playerList.rank')" width="110" prop="$trustSortNum" sortable="custom")
template(#default="scope")
span.name(v-text="scope.row.ref.$trustLevel" :class="scope.row.ref.$trustClass")
el-table-column(:label="$t('table.playerList.language')" width="100" prop="ref.$languages")
template(#default="scope")
el-tooltip(v-for="item in scope.row.ref.$languages" :key="item.key" placement="top")
el-table-column(
:label='$t("table.playerList.rank")'
width='110'
prop='$trustSortNum'
sortable='custom')
template(#default='scope')
span.name(v-text='scope.row.ref.$trustLevel' :class='scope.row.ref.$trustClass')
el-table-column(:label='$t("table.playerList.language")' width='100' prop='ref.$languages')
template(#default='scope')
el-tooltip(v-for='item in scope.row.ref.$languages' :key='item.key' placement='top')
template(#content)
span {{ item.value }} ({{ item.key }})
span.flags(:class="languageClass(item.key)" style="display:inline-block;margin-right:5px")
el-table-column(:label="$t('table.playerList.bioLink')" width="100" prop="ref.bioLinks")
template(#default="scope")
div(style="display:flex;align-items:center")
el-tooltip(v-if="link" v-for="(link, index) in scope.row.ref.bioLinks" :key="index")
span.flags(
:class='languageClass(item.key)'
style='display: inline-block; margin-right: 5px')
el-table-column(:label='$t("table.playerList.bioLink")' width='100' prop='ref.bioLinks')
template(#default='scope')
div(style='display: flex; align-items: center')
el-tooltip(v-if='link' v-for='(link, index) in scope.row.ref.bioLinks' :key='index')
template(#content)
span(v-text="link")
img(:src="getFaviconUrl(link)" style="width:16px;height:16px;vertical-align:middle;margin-right:5px;cursor:pointer" @click.stop="openExternalLink(link)")
span(v-text='link')
img(
:src='getFaviconUrl(link)'
style='width: 16px; height: 16px; vertical-align: middle; margin-right: 5px; cursor: pointer'
@click.stop='openExternalLink(link)')

View File

@@ -1,164 +1,371 @@
mixin profileTab()
.x-container(v-if="$refs.menu && $refs.menu.activeIndex === 'profile'")
div.options-container(style="margin-top:0")
mixin profileTab
.x-container(v-if='$refs.menu && $refs.menu.activeIndex === "profile"')
.options-container(style='margin-top: 0')
span.header {{ $t('view.profile.profile.header') }}
.x-friend-list(style="margin-top:10px")
.x-friend-item(@click="showUserDialog(API.currentUser.id)")
.x-friend-list(style='margin-top: 10px')
.x-friend-item(@click='showUserDialog(API.currentUser.id)')
.avatar
img(v-lazy="userImage(API.currentUser)")
img(v-lazy='userImage(API.currentUser)')
.detail
span.name(v-text="API.currentUser.displayName")
span.extra(v-text="API.currentUser.username")
.x-friend-item(style="cursor:default")
span.name(v-text='API.currentUser.displayName')
span.extra(v-text='API.currentUser.username')
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('view.profile.profile.last_activity') }}
span.extra {{ API.currentUser.last_activity | formatDate('long') }}
.x-friend-item(style="cursor:default")
.x-friend-item(style='cursor: default')
.detail
span.name {{ $t('view.profile.profile.two_factor') }}
span.extra {{ API.currentUser.twoFactorAuthEnabled ? $t('view.profile.profile.two_factor_enabled') : $t('view.profile.profile.two_factor_disabled') }}
.x-friend-item(@click="getVRChatCredits()")
.x-friend-item(@click='getVRChatCredits()')
.detail
span.name {{ $t('view.profile.profile.vrchat_credits') }}
span.extra {{ API.currentUser.$vrchatcredits ?? $t('view.profile.profile.refresh') }}
div(style="margin-top:10px")
el-button(size="small" type="danger" plain icon="el-icon-switch-button" @click="logout()" style="margin-left:0;margin-right:5px;margin-top:10px;") {{ $t('view.profile.profile.logout') }}
el-button(size="small" icon="el-icon-picture-outline" @click="showGalleryDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.manage_gallery_icon') }}
el-button(size="small" icon="el-icon-chat-dot-round" @click="showDiscordNamesDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.discord_names') }}
el-button(size="small" icon="el-icon-printer" @click="showExportFriendsListDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.export_friend_list') }}
el-button(size="small" icon="el-icon-user" @click="showExportAvatarsListDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.export_own_avatars') }}
el-button(size="small" icon="el-icon-document-copy" @click="showNoteExportDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.export_notes') }}
div(style='margin-top: 10px')
el-button(
size='small'
type='danger'
plain
icon='el-icon-switch-button'
@click='logout()'
style='margin-left: 0; margin-right: 5px; margin-top: 10px') {{ $t('view.profile.profile.logout') }}
el-button(
size='small'
icon='el-icon-picture-outline'
@click='showGalleryDialog()'
style='margin-left: 0; margin-right: 5px; margin-top: 10px') {{ $t('view.profile.profile.manage_gallery_icon') }}
el-button(
size='small'
icon='el-icon-chat-dot-round'
@click='showDiscordNamesDialog()'
style='margin-left: 0; margin-right: 5px; margin-top: 10px') {{ $t('view.profile.profile.discord_names') }}
el-button(
size='small'
icon='el-icon-printer'
@click='showExportFriendsListDialog()'
style='margin-left: 0; margin-right: 5px; margin-top: 10px') {{ $t('view.profile.profile.export_friend_list') }}
el-button(
size='small'
icon='el-icon-user'
@click='showExportAvatarsListDialog()'
style='margin-left: 0; margin-right: 5px; margin-top: 10px') {{ $t('view.profile.profile.export_own_avatars') }}
el-button(
size='small'
icon='el-icon-document-copy'
@click='showNoteExportDialog()'
style='margin-left: 0; margin-right: 5px; margin-top: 10px') {{ $t('view.profile.profile.export_notes') }}
div.options-container
.options-container
span.header {{ $t('view.profile.game_info.header') }}
.x-friend-list(style="margin-top:10px")
.x-friend-list(style='margin-top: 10px')
.x-friend-item
.detail(@click="API.getVisits()")
.detail(@click='API.getVisits()')
span.name {{ $t('view.profile.game_info.online_users') }}
span.extra(v-if="visits") {{ $t('view.profile.game_info.user_online', { count: visits }) }}
span.extra(v-if='visits') {{ $t('view.profile.game_info.user_online', { count: visits }) }}
span.extra(v-else) {{ $t('view.profile.game_info.refresh') }}
div.options-container
div.header-bar
.options-container
.header-bar
span.header {{ $t('view.profile.vrc_sdk_downloads.header') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="API.getConfig()" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
.x-friend-list(style="margin-top:10px")
.x-friend-item(v-for="(link, item) in API.cachedConfig.downloadUrls" :key="item" placement="top")
.detail(@click="openExternalLink(link)")
span.name(v-text="item")
span.extra(v-text="link")
div.options-container
el-tooltip(placement='top' :content='$t("view.profile.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='API.getConfig()'
size='mini'
icon='el-icon-refresh'
circle
style='margin-left: 5px')
.x-friend-list(style='margin-top: 10px')
.x-friend-item(v-for='(link, item) in API.cachedConfig.downloadUrls' :key='item' placement='top')
.detail(@click='openExternalLink(link)')
span.name(v-text='item')
span.extra(v-text='link')
.options-container
span.header {{ $t('view.profile.direct_access.header') }}
div(style="margin-top:10px")
div(style='margin-top: 10px')
el-button-group
el-button(size="small" @click="promptUsernameDialog()") {{ $t('view.profile.direct_access.username') }}
el-button(size="small" @click="promptUserIdDialog()") {{ $t('view.profile.direct_access.user_id') }}
el-button(size="small" @click="promptWorldDialog()") {{ $t('view.profile.direct_access.world_instance') }}
el-button(size="small" @click="promptAvatarDialog()") {{ $t('view.profile.direct_access.avatar') }}
div.options-container
div.header-bar
el-button(size='small' @click='promptUsernameDialog()') {{ $t('view.profile.direct_access.username') }}
el-button(size='small' @click='promptUserIdDialog()') {{ $t('view.profile.direct_access.user_id') }}
el-button(size='small' @click='promptWorldDialog()') {{ $t('view.profile.direct_access.world_instance') }}
el-button(size='small' @click='promptAvatarDialog()') {{ $t('view.profile.direct_access.avatar') }}
.options-container
.header-bar
span.header {{ $t('view.profile.invite_messages') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteMessageTable.visible = true; refreshInviteMessageTable('message')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteMessageTable.visible = false" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
data-tables(v-if="inviteMessageTable.visible" v-bind="inviteMessageTable" style="margin-top:10px")
el-table-column(:label="$t('table.profile.invite_messages.slot')" prop="slot" sortable="custom" width="70")
el-table-column(:label="$t('table.profile.invite_messages.message')" prop="message")
el-table-column(:label="$t('table.profile.invite_messages.cool_down')" prop="updatedAt" sortable="custom" width="110" align="right")
template(#default="scope")
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
el-table-column(:label="$t('table.profile.invite_messages.action')" width="60" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('message', scope.row)")
div.options-container
div.header-bar
el-tooltip(placement='top' :content='$t("view.profile.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='inviteMessageTable.visible = true; refreshInviteMessageTable("message")'
size='mini'
icon='el-icon-refresh'
circle
style='margin-left: 5px')
el-tooltip(
placement='top'
:content='$t("view.profile.clear_results_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
@click='inviteMessageTable.visible = false'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
data-tables(v-if='inviteMessageTable.visible' v-bind='inviteMessageTable' style='margin-top: 10px')
el-table-column(
:label='$t("table.profile.invite_messages.slot")'
prop='slot'
sortable='custom'
width='70')
el-table-column(:label='$t("table.profile.invite_messages.message")' prop='message')
el-table-column(
:label='$t("table.profile.invite_messages.cool_down")'
prop='updatedAt'
sortable='custom'
width='110'
align='right')
template(#default='scope')
countdown-timer(:datetime='scope.row.updatedAt' :hours='1')
el-table-column(:label='$t("table.profile.invite_messages.action")' width='60' align='right')
template(#default='scope')
el-button(
type='text'
icon='el-icon-edit'
size='mini'
@click='showEditInviteMessageDialog("message", scope.row)')
.options-container
.header-bar
span.header {{ $t('view.profile.invite_response_messages') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteResponseMessageTable.visible = true; refreshInviteMessageTable('response')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteResponseMessageTable.visible = false" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
data-tables(v-if="inviteResponseMessageTable.visible" v-bind="inviteResponseMessageTable" style="margin-top:10px")
el-table-column(:label="$t('table.profile.invite_messages.slot')" prop="slot" sortable="custom" width="70")
el-table-column(:label="$t('table.profile.invite_messages.message')" prop="message")
el-table-column(:label="$t('table.profile.invite_messages.cool_down')" prop="updatedAt" sortable="custom" width="110" align="right")
template(#default="scope")
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
el-table-column(:label="$t('table.profile.invite_messages.action')" width="60" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('response', scope.row)")
div.options-container
div.header-bar
el-tooltip(placement='top' :content='$t("view.profile.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='inviteResponseMessageTable.visible = true; refreshInviteMessageTable("response")'
size='mini'
icon='el-icon-refresh'
circle
style='margin-left: 5px')
el-tooltip(
placement='top'
:content='$t("view.profile.clear_results_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
@click='inviteResponseMessageTable.visible = false'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
data-tables(
v-if='inviteResponseMessageTable.visible'
v-bind='inviteResponseMessageTable'
style='margin-top: 10px')
el-table-column(
:label='$t("table.profile.invite_messages.slot")'
prop='slot'
sortable='custom'
width='70')
el-table-column(:label='$t("table.profile.invite_messages.message")' prop='message')
el-table-column(
:label='$t("table.profile.invite_messages.cool_down")'
prop='updatedAt'
sortable='custom'
width='110'
align='right')
template(#default='scope')
countdown-timer(:datetime='scope.row.updatedAt' :hours='1')
el-table-column(:label='$t("table.profile.invite_messages.action")' width='60' align='right')
template(#default='scope')
el-button(
type='text'
icon='el-icon-edit'
size='mini'
@click='showEditInviteMessageDialog("response", scope.row)')
.options-container
.header-bar
span.header {{ $t('view.profile.invite_request_messages') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteRequestMessageTable.visible = true; refreshInviteMessageTable('request')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteRequestMessageTable.visible = false" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
data-tables(v-if="inviteRequestMessageTable.visible" v-bind="inviteRequestMessageTable" style="margin-top:10px")
el-table-column(:label="$t('table.profile.invite_messages.slot')" prop="slot" sortable="custom" width="70")
el-table-column(:label="$t('table.profile.invite_messages.message')" prop="message")
el-table-column(:label="$t('table.profile.invite_messages.cool_down')" prop="updatedAt" sortable="custom" width="110" align="right")
template(#default="scope")
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
el-table-column(:label="$t('table.profile.invite_messages.action')" width="60" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('request', scope.row)")
div.options-container
div.header-bar
el-tooltip(placement='top' :content='$t("view.profile.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='inviteRequestMessageTable.visible = true; refreshInviteMessageTable("request")'
size='mini'
icon='el-icon-refresh'
circle
style='margin-left: 5px')
el-tooltip(
placement='top'
:content='$t("view.profile.clear_results_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
@click='inviteRequestMessageTable.visible = false'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
data-tables(
v-if='inviteRequestMessageTable.visible'
v-bind='inviteRequestMessageTable'
style='margin-top: 10px')
el-table-column(
:label='$t("table.profile.invite_messages.slot")'
prop='slot'
sortable='custom'
width='70')
el-table-column(:label='$t("table.profile.invite_messages.message")' prop='message')
el-table-column(
:label='$t("table.profile.invite_messages.cool_down")'
prop='updatedAt'
sortable='custom'
width='110'
align='right')
template(#default='scope')
countdown-timer(:datetime='scope.row.updatedAt' :hours='1')
el-table-column(:label='$t("table.profile.invite_messages.action")' width='60' align='right')
template(#default='scope')
el-button(
type='text'
icon='el-icon-edit'
size='mini'
@click='showEditInviteMessageDialog("request", scope.row)')
.options-container
.header-bar
span.header {{ $t('view.profile.invite_request_response_messages') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteRequestResponseMessageTable.visible = true; refreshInviteMessageTable('requestResponse')" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="inviteRequestResponseMessageTable.visible = false" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
data-tables(v-if="inviteRequestResponseMessageTable.visible" v-bind="inviteRequestResponseMessageTable" style="margin-top:10px")
el-table-column(:label="$t('table.profile.invite_messages.slot')" prop="slot" sortable="custom" width="70")
el-table-column(:label="$t('table.profile.invite_messages.message')" prop="message")
el-table-column(:label="$t('table.profile.invite_messages.cool_down')" prop="updatedAt" sortable="custom" width="110" align="right")
template(#default="scope")
countdown-timer(:datetime="scope.row.updatedAt" :hours="1")
el-table-column(:label="$t('table.profile.invite_messages.action')" width="60" align="right")
template(#default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('requestResponse', scope.row)")
div.options-container
el-tooltip(placement='top' :content='$t("view.profile.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='inviteRequestResponseMessageTable.visible = true; refreshInviteMessageTable("requestResponse")'
size='mini'
icon='el-icon-refresh'
circle
style='margin-left: 5px')
el-tooltip(
placement='top'
:content='$t("view.profile.clear_results_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
@click='inviteRequestResponseMessageTable.visible = false'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
data-tables(
v-if='inviteRequestResponseMessageTable.visible'
v-bind='inviteRequestResponseMessageTable'
style='margin-top: 10px')
el-table-column(
:label='$t("table.profile.invite_messages.slot")'
prop='slot'
sortable='custom'
width='70')
el-table-column(:label='$t("table.profile.invite_messages.message")' prop='message')
el-table-column(
:label='$t("table.profile.invite_messages.cool_down")'
prop='updatedAt'
sortable='custom'
width='110'
align='right')
template(#default='scope')
countdown-timer(:datetime='scope.row.updatedAt' :hours='1')
el-table-column(:label='$t("table.profile.invite_messages.action")' width='60' align='right')
template(#default='scope')
el-button(
type='text'
icon='el-icon-edit'
size='mini'
@click='showEditInviteMessageDialog("requestResponse", scope.row)')
.options-container
span.header {{ $t('view.profile.past_display_names') }}
data-tables(v-bind="pastDisplayNameTable" style="margin-top:10px")
el-table-column(:label="$t('table.profile.previous_display_name.date')" prop="updated_at" sortable="custom")
template(#default="scope")
data-tables(v-bind='pastDisplayNameTable' style='margin-top: 10px')
el-table-column(
:label='$t("table.profile.previous_display_name.date")'
prop='updated_at'
sortable='custom')
template(#default='scope')
span {{ scope.row.updated_at | formatDate('long') }}
el-table-column(:label="$t('table.profile.previous_display_name.name')" prop="displayName")
div.options-container
div.header-bar
el-table-column(:label='$t("table.profile.previous_display_name.name")' prop='displayName')
.options-container
.header-bar
span.header {{ $t('view.profile.config_json') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="refreshConfigTreeData()" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="configTreeData = []" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
el-tree(v-if="configTreeData.length > 0" :data="configTreeData" style="margin-top:10px;font-size:12px")
template(#default="scope")
el-tooltip(placement='top' :content='$t("view.profile.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='refreshConfigTreeData()'
size='mini'
icon='el-icon-refresh'
circle
style='margin-left: 5px')
el-tooltip(
placement='top'
:content='$t("view.profile.clear_results_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
@click='configTreeData = []'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
el-tree(v-if='configTreeData.length > 0' :data='configTreeData' style='margin-top: 10px; font-size: 12px')
template(#default='scope')
span
span(v-text="scope.data.key" style="font-weight:bold;margin-right:5px")
span(v-if="!scope.data.children" v-text="scope.data.value")
div.options-container
div.header-bar
span(v-text='scope.data.key' style='font-weight: bold; margin-right: 5px')
span(v-if='!scope.data.children' v-text='scope.data.value')
.options-container
.header-bar
span.header {{ $t('view.profile.current_user_json') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="refreshCurrentUserTreeData()" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="currentUserTreeData = []" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
el-tree(v-if="currentUserTreeData.length > 0" :data="currentUserTreeData" style="margin-top:10px;font-size:12px")
template(#default="scope")
el-tooltip(placement='top' :content='$t("view.profile.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='refreshCurrentUserTreeData()'
size='mini'
icon='el-icon-refresh'
circle
style='margin-left: 5px')
el-tooltip(
placement='top'
:content='$t("view.profile.clear_results_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
@click='currentUserTreeData = []'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
el-tree(
v-if='currentUserTreeData.length > 0'
:data='currentUserTreeData'
style='margin-top: 10px; font-size: 12px')
template(#default='scope')
span
span(v-text="scope.data.key" style="font-weight:bold;margin-right:5px")
span(v-if="!scope.data.children" v-text="scope.data.value")
div.options-container
div.header-bar
span(v-text='scope.data.key' style='font-weight: bold; margin-right: 5px')
span(v-if='!scope.data.children' v-text='scope.data.value')
.options-container
.header-bar
span.header {{ $t('view.profile.feedback') }}
el-tooltip(placement="top" :content="$t('view.profile.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="getCurrentUserFeedback()" size="mini" icon="el-icon-refresh" circle style="margin-left:5px")
el-tooltip(placement="top" :content="$t('view.profile.clear_results_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="currentUserFeedbackData = []" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
el-tree(v-if="currentUserFeedbackData.length > 0" :data="currentUserFeedbackData" style="margin-top:10px;font-size:12px")
template(#default="scope")
el-tooltip(placement='top' :content='$t("view.profile.refresh_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='getCurrentUserFeedback()'
size='mini'
icon='el-icon-refresh'
circle
style='margin-left: 5px')
el-tooltip(
placement='top'
:content='$t("view.profile.clear_results_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
@click='currentUserFeedbackData = []'
size='mini'
icon='el-icon-delete'
circle
style='margin-left: 5px')
el-tree(
v-if='currentUserFeedbackData.length > 0'
:data='currentUserFeedbackData'
style='margin-top: 10px; font-size: 12px')
template(#default='scope')
span
span(v-text="scope.data.key" style="font-weight:bold;margin-right:5px")
span(v-if="!scope.data.children" v-text="scope.data.value")
span(v-text='scope.data.key' style='font-weight: bold; margin-right: 5px')
span(v-if='!scope.data.children' v-text='scope.data.value')

View File

@@ -1,93 +1,200 @@
mixin searchTab()
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'search'")
div(style="margin:0 0 10px;display:flex;align-items:center")
el-input(v-model="searchText" :placeholder="$t('view.search.search_placeholder')" @keyup.native.13="search()" style="flex:1")
el-tooltip(placement="bottom" :content="$t('view.search.clear_results_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="clearSearch()" icon="el-icon-delete" circle style="flex:none;margin-left:10px")
el-tabs(ref="searchTab" type="card" style="margin-top:15px" @tab-click="searchText = ''")
el-tab-pane(:label="$t('view.search.user.header')" v-loading="isSearchUserLoading" style="min-height:60px")
.x-friend-list(style="min-height:500px")
.x-friend-item(v-for="user in searchUserResults" :key="user.id" @click="showUserDialog(user.id)")
mixin searchTab
.x-container(v-show='$refs.menu && $refs.menu.activeIndex === \'search\'')
div(style='margin: 0 0 10px; display: flex; align-items: center')
el-input(
v-model='searchText'
:placeholder='$t("view.search.search_placeholder")'
@keyup.native.13='search()'
style='flex: 1')
el-tooltip(placement='bottom' :content='$t("view.search.clear_results_tooltip")' :disabled='hideTooltips')
el-button(
type='default'
@click='clearSearch()'
icon='el-icon-delete'
circle
style='flex: none; margin-left: 10px')
el-tabs(ref='searchTab' type='card' style='margin-top: 15px' @tab-click='searchText = ""')
el-tab-pane(:label='$t("view.search.user.header")' v-loading='isSearchUserLoading' style='min-height: 60px')
.x-friend-list(style='min-height: 500px')
.x-friend-item(v-for='user in searchUserResults' :key='user.id' @click='showUserDialog(user.id)')
template
.avatar
img(v-lazy="userImage(user)")
img(v-lazy='userImage(user)')
.detail
span.name(v-text="user.displayName")
span.extra(v-if="randomUserColours" v-text="user.$trustLevel" :class="user.$trustClass")
span.extra(v-else v-text="user.$trustLevel" :style="{'color':user.$userColour}")
el-button-group(style="margin-top:15px" v-if="searchUserResults.length")
el-button(:disabled="!searchUserParams.offset" @click="moreSearchUser(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
el-button(:disabled="searchUserResults.length < 10" @click="moreSearchUser(1)" icon="el-icon-right" size="small") {{ $t('view.search.next_page') }}
el-tab-pane(:label="$t('view.search.world.header')" v-loading="isSearchWorldLoading" style="min-height:60px")
el-dropdown(@command="(row) => searchWorld(row)" size="small" trigger="click" style="margin-bottom:15px")
el-button(size="small") {{ $t('view.search.world.category') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(v-for="row in API.cachedConfig.dynamicWorldRows" :key="row.index" v-text="row.name" :command="row")
el-checkbox(v-model="searchWorldLabs" style="margin-left:10px") {{ $t('view.search.world.community_lab') }}
.x-friend-list(style="min-height:500px")
.x-friend-item(v-for="world in searchWorldResults" :key="world.id" @click="showWorldDialog(world.id)")
span.name(v-text='user.displayName')
span.extra(
v-if='randomUserColours'
v-text='user.$trustLevel'
:class='user.$trustClass')
span.extra(v-else v-text='user.$trustLevel' :style='{ color: user.$userColour }')
el-button-group(style='margin-top: 15px' v-if='searchUserResults.length')
el-button(
:disabled='!searchUserParams.offset'
@click='moreSearchUser(-1)'
icon='el-icon-back'
size='small') {{ $t('view.search.prev_page') }}
el-button(
:disabled='searchUserResults.length < 10'
@click='moreSearchUser(1)'
icon='el-icon-right'
size='small') {{ $t('view.search.next_page') }}
el-tab-pane(
:label='$t("view.search.world.header")'
v-loading='isSearchWorldLoading'
style='min-height: 60px')
el-dropdown(
@command='(row) => searchWorld(row)'
size='small'
trigger='click'
style='margin-bottom: 15px')
el-button(size='small') {{ $t('view.search.world.category') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default='dropdown')
el-dropdown-item(
v-for='row in API.cachedConfig.dynamicWorldRows'
:key='row.index'
v-text='row.name'
:command='row')
el-checkbox(v-model='searchWorldLabs' style='margin-left: 10px') {{ $t('view.search.world.community_lab') }}
.x-friend-list(style='min-height: 500px')
.x-friend-item(
v-for='world in searchWorldResults'
:key='world.id'
@click='showWorldDialog(world.id)')
template
.avatar
img(v-lazy="world.thumbnailImageUrl")
img(v-lazy='world.thumbnailImageUrl')
.detail
span.name(v-text="world.name")
span.extra(v-if="world.occupants") {{ world.authorName }} ({{ world.occupants }})
span.extra(v-else v-text="world.authorName")
el-button-group(style="margin-top:15px" v-if="searchWorldResults.length")
el-button(:disabled="!searchWorldParams.offset" @click="moreSearchWorld(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
el-button(:disabled="searchWorldResults.length < 10" @click="moreSearchWorld(1)" icon="el-icon-right" size="small") {{ $t('view.search.next_page') }}
el-tab-pane(:label="$t('view.search.avatar.header')" v-loading="isSearchAvatarLoading" style="min-height:60px")
div(style="display:flex;align-items:center;justify-content:space-between;")
div(style="display:flex;align-items:center;")
el-dropdown(v-if="avatarRemoteDatabaseProviderList.length > 1" trigger="click" @click.native.stop size="mini" style="margin-right:5px")
el-button(size="small") {{ $t('view.search.avatar.search_provider') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(v-for="provider in avatarRemoteDatabaseProviderList" :key="provider" @click.native="setAvatarProvider(provider)") #[i.el-icon-check.el-icon--left(v-if="provider === avatarRemoteDatabaseProvider")] {{ provider }}
el-tooltip(placement="bottom" :content="$t('view.search.avatar.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" :loading="userDialog.isAvatarsLoading" @click="refreshUserDialogAvatars()" size="mini" icon="el-icon-refresh" circle)
span(style="font-size:14px;margin-left:5px;margin-right:5px") {{ $t("view.search.avatar.result_count", { count: searchAvatarResults.length }) }}
div(style="display:flex;align-items:center;")
el-radio-group(v-model="searchAvatarFilter" size="mini" style="margin:5px;display:block" @change="searchAvatar")
el-radio(label="all") {{ $t('view.search.avatar.all') }}
el-radio(label="public") {{ $t('view.search.avatar.public') }}
el-radio(label="private") {{ $t('view.search.avatar.private') }}
el-divider(direction="vertical")
el-radio-group(v-model="searchAvatarFilterRemote" size="mini" style="margin:5px;display:block" @change="searchAvatar")
el-radio(label="all") {{ $t('view.search.avatar.all') }}
el-radio(label="local") {{ $t('view.search.avatar.local') }}
el-radio(label="remote" :disabled="!avatarRemoteDatabase") {{ $t('view.search.avatar.remote') }}
div(style="display:flex;justify-content:end;")
el-radio-group(:disabled="searchAvatarFilterRemote !== 'local'" v-model="searchAvatarSort" size="mini" style="margin:5px;display:block" @change="searchAvatar")
el-radio(label="name") {{ $t('view.search.avatar.sort_name') }}
el-radio(label="update") {{ $t('view.search.avatar.sort_update') }}
el-radio(label="created") {{ $t('view.search.avatar.sort_created') }}
.x-friend-list(style="margin-top:20px;min-height:500px")
.x-friend-item(v-for="avatar in searchAvatarPage" :key="avatar.id" @click="showAvatarDialog(avatar.id)")
span.name(v-text='world.name')
span.extra(v-if='world.occupants') {{ world.authorName }} ({{ world.occupants }})
span.extra(v-else v-text='world.authorName')
el-button-group(style='margin-top: 15px' v-if='searchWorldResults.length')
el-button(
:disabled='!searchWorldParams.offset'
@click='moreSearchWorld(-1)'
icon='el-icon-back'
size='small') {{ $t('view.search.prev_page') }}
el-button(
:disabled='searchWorldResults.length < 10'
@click='moreSearchWorld(1)'
icon='el-icon-right'
size='small') {{ $t('view.search.next_page') }}
el-tab-pane(
:label='$t("view.search.avatar.header")'
v-loading='isSearchAvatarLoading'
style='min-height: 60px')
div(style='display: flex; align-items: center; justify-content: space-between')
div(style='display: flex; align-items: center')
el-dropdown(
v-if='avatarRemoteDatabaseProviderList.length > 1'
trigger='click'
@click.native.stop
size='mini'
style='margin-right: 5px')
el-button(size='small') {{ $t('view.search.avatar.search_provider') }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default='dropdown')
el-dropdown-item(
v-for='provider in avatarRemoteDatabaseProviderList'
:key='provider'
@click.native='setAvatarProvider(provider)') #[i.el-icon-check.el-icon--left(v-if='provider === avatarRemoteDatabaseProvider')] {{ provider }}
el-tooltip(
placement='bottom'
:content='$t("view.search.avatar.refresh_tooltip")'
:disabled='hideTooltips')
el-button(
type='default'
:loading='userDialog.isAvatarsLoading'
@click='refreshUserDialogAvatars()'
size='mini'
icon='el-icon-refresh'
circle)
span(style='font-size: 14px; margin-left: 5px; margin-right: 5px') {{ $t('view.search.avatar.result_count', { count: searchAvatarResults.length }) }}
div(style='display: flex; align-items: center')
el-radio-group(
v-model='searchAvatarFilter'
size='mini'
style='margin: 5px; display: block'
@change='searchAvatar')
el-radio(label='all') {{ $t('view.search.avatar.all') }}
el-radio(label='public') {{ $t('view.search.avatar.public') }}
el-radio(label='private') {{ $t('view.search.avatar.private') }}
el-divider(direction='vertical')
el-radio-group(
v-model='searchAvatarFilterRemote'
size='mini'
style='margin: 5px; display: block'
@change='searchAvatar')
el-radio(label='all') {{ $t('view.search.avatar.all') }}
el-radio(label='local') {{ $t('view.search.avatar.local') }}
el-radio(label='remote' :disabled='!avatarRemoteDatabase') {{ $t('view.search.avatar.remote') }}
div(style='display: flex; justify-content: end')
el-radio-group(
:disabled='searchAvatarFilterRemote !== "local"'
v-model='searchAvatarSort'
size='mini'
style='margin: 5px; display: block'
@change='searchAvatar')
el-radio(label='name') {{ $t('view.search.avatar.sort_name') }}
el-radio(label='update') {{ $t('view.search.avatar.sort_update') }}
el-radio(label='created') {{ $t('view.search.avatar.sort_created') }}
.x-friend-list(style='margin-top: 20px; min-height: 500px')
.x-friend-item(
v-for='avatar in searchAvatarPage'
:key='avatar.id'
@click='showAvatarDialog(avatar.id)')
template
.avatar
img(v-if="avatar.thumbnailImageUrl" v-lazy="avatar.thumbnailImageUrl")
img(v-else-if="avatar.imageUrl" v-lazy="avatar.imageUrl")
img(v-if='avatar.thumbnailImageUrl' v-lazy='avatar.thumbnailImageUrl')
img(v-else-if='avatar.imageUrl' v-lazy='avatar.imageUrl')
.detail
span.name(v-text="avatar.name")
span.extra(v-text="avatar.releaseStatus" v-if="avatar.releaseStatus === 'public'" style="color: #67c23a;")
span.extra(v-text="avatar.releaseStatus" v-else-if="avatar.releaseStatus === 'private'" style="color: #f56c6c;")
span.extra(v-text="avatar.releaseStatus" v-else)
span.extra(v-text="avatar.authorName")
el-button-group(style="margin-top:15px" v-if="searchAvatarPage.length")
el-button(:disabled="!searchAvatarPageNum" @click="moreSearchAvatar(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
el-button(:disabled="searchAvatarResults.length < 10 || (searchAvatarPageNum + 1) * 10 >= searchAvatarResults.length" @click="moreSearchAvatar(1)" icon="el-icon-right" size="small") {{ $t('view.search.next_page') }}
el-tab-pane(:label="$t('view.search.group.header')" v-loading="isSearchGroupLoading" style="min-height:60px")
.x-friend-list(style="min-height:500px")
.x-friend-item(v-for="group in searchGroupResults" :key="group.id" @click="showGroupDialog(group.id)")
span.name(v-text='avatar.name')
span.extra(
v-text='avatar.releaseStatus'
v-if='avatar.releaseStatus === "public"'
style='color: #67c23a')
span.extra(
v-text='avatar.releaseStatus'
v-else-if='avatar.releaseStatus === "private"'
style='color: #f56c6c')
span.extra(v-text='avatar.releaseStatus' v-else)
span.extra(v-text='avatar.authorName')
el-button-group(style='margin-top: 15px' v-if='searchAvatarPage.length')
el-button(
:disabled='!searchAvatarPageNum'
@click='moreSearchAvatar(-1)'
icon='el-icon-back'
size='small') {{ $t('view.search.prev_page') }}
el-button(
:disabled='searchAvatarResults.length < 10 || (searchAvatarPageNum + 1) * 10 >= searchAvatarResults.length'
@click='moreSearchAvatar(1)'
icon='el-icon-right'
size='small') {{ $t('view.search.next_page') }}
el-tab-pane(
:label='$t("view.search.group.header")'
v-loading='isSearchGroupLoading'
style='min-height: 60px')
.x-friend-list(style='min-height: 500px')
.x-friend-item(
v-for='group in searchGroupResults'
:key='group.id'
@click='showGroupDialog(group.id)')
template
.avatar
img(v-lazy="group.iconUrl")
img(v-lazy='group.iconUrl')
.detail
span.name
span(v-text="group.name")
span(style="margin-left:5px;font-weight:normal") ({{ group.memberCount }})
span(style="margin-left:5px;color:#909399;font-weight:normal;font-family:monospace;font-size:12px") {{ group.shortCode }}.{{ group.discriminator }}
span.extra(v-text="group.description")
el-button-group(style="margin-top:15px" v-if="searchGroupResults.length")
el-button(:disabled="!searchGroupParams.offset" @click="moreSearchGroup(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
el-button(:disabled="searchGroupResults.length < 10" @click="moreSearchGroup(1)" icon="el-icon-right" size="small") {{ $t('view.search.next_page') }}
span(v-text='group.name')
span(style='margin-left: 5px; font-weight: normal') ({{ group.memberCount }})
span(
style='margin-left: 5px; color: #909399; font-weight: normal; font-family: monospace; font-size: 12px') {{ group.shortCode }}.{{ group.discriminator }}
span.extra(v-text='group.description')
el-button-group(style='margin-top: 15px' v-if='searchGroupResults.length')
el-button(
:disabled='!searchGroupParams.offset'
@click='moreSearchGroup(-1)'
icon='el-icon-back'
size='small') {{ $t('view.search.prev_page') }}
el-button(
:disabled='searchGroupResults.length < 10'
@click='moreSearchGroup(1)'
icon='el-icon-right'
size='small') {{ $t('view.search.next_page') }}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff