diff --git a/html/package-lock.json b/html/package-lock.json
index 217e5a29..1f06e9c2 100644
--- a/html/package-lock.json
+++ b/html/package-lock.json
@@ -5,6 +5,9 @@
"packages": {
"": {
"license": "MIT",
+ "dependencies": {
+ "vue-i18n": "^8.28.2"
+ },
"devDependencies": {
"@fontsource/noto-sans-jp": "^4.5.12",
"@fontsource/noto-sans-kr": "^4.5.12",
@@ -3827,6 +3830,11 @@
"npm": ">= 3.0.0"
}
},
+ "node_modules/vue-i18n": {
+ "version": "8.28.2",
+ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.28.2.tgz",
+ "integrity": "sha512-C5GZjs1tYlAqjwymaaCPDjCyGo10ajUphiwA922jKt9n7KPpqR7oM1PCwYzhB/E7+nT3wfdG3oRre5raIT1rKA=="
+ },
"node_modules/vue-lazyload": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/vue-lazyload/-/vue-lazyload-1.3.4.tgz",
@@ -6948,6 +6956,11 @@
"vue": "^2.5.16"
}
},
+ "vue-i18n": {
+ "version": "8.28.2",
+ "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.28.2.tgz",
+ "integrity": "sha512-C5GZjs1tYlAqjwymaaCPDjCyGo10ajUphiwA922jKt9n7KPpqR7oM1PCwYzhB/E7+nT3wfdG3oRre5raIT1rKA=="
+ },
"vue-lazyload": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/vue-lazyload/-/vue-lazyload-1.3.4.tgz",
diff --git a/html/package.json b/html/package.json
index 482a7123..9bacd175 100644
--- a/html/package.json
+++ b/html/package.json
@@ -49,5 +49,8 @@
"webpack": "^5.75.0",
"webpack-cli": "^5.0.0",
"worker-timers": "^7.0.60"
+ },
+ "dependencies": {
+ "vue-i18n": "^8.28.2"
}
}
diff --git a/html/src/app.js b/html/src/app.js
index 5d79885e..af7abe5a 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -9,6 +9,7 @@ import '@fontsource/noto-sans-jp';
import Noty from 'noty';
import Vue from 'vue';
import VueLazyload from 'vue-lazyload';
+import VueI18n from 'vue-i18n'
import {DataTables} from 'vue-data-tables';
import ElementUI from 'element-ui';
import locale from 'element-ui/lib/locale/lang/en';
@@ -21,6 +22,7 @@ import webApiService from './service/webapi.js';
import gameLogService from './service/gamelog.js';
import security from './security.js';
import database from './repository/database.js';
+import * as localizedStrings from './localization/localizedStrings.js';
speechSynthesis.getVoices();
@@ -205,6 +207,13 @@ speechSynthesis.getVoices();
Vue.use(DataTables);
+ Vue.use(VueI18n);
+
+ var i18n = new VueI18n({
+ locale: 'en',
+ messages: localizedStrings,
+ })
+
var $appDarkStyle = document.createElement('link');
$appDarkStyle.disabled = true;
$appDarkStyle.rel = 'stylesheet';
@@ -4625,6 +4634,7 @@ speechSynthesis.getVoices();
exportFriendsListDialog: false,
exportFriendsListContent: ''
},
+ i18n,
computed: {},
methods: {},
watch: {},
diff --git a/html/src/index.pug b/html/src/index.pug
index 2668560e..8168f289 100644
--- a/html/src/index.pug
+++ b/html/src/index.pug
@@ -18,7 +18,7 @@ html
el-button(type="default" @click="showVRCXUpdateDialog" size="mini" icon="el-icon-download" circle)
div(style="width:300px;margin:auto")
div(style="margin:15px" v-if="Object.keys(loginForm.savedCredentials).length !== 0")
- h2(style="font-weight:bold;text-align:center;margin:0") Saved Accounts
+ h2(style="font-weight:bold;text-align:center;margin:0") {{ $t("view.login.savedAccounts") }}
.x-friend-list(style="margin-top:10px")
.x-friend-item(v-for="user in loginForm.savedCredentials" :key="user.user.id")
.x-friend-item(@click="relogin(user)" style="width:202px;padding:0")
@@ -30,27 +30,27 @@ html
span.extra(v-text="user.loginParmas.endpoint")
el-button(type="default" @click="deleteSavedLogin(user.user.username)" size="mini" icon="el-icon-delete" circle)
div(style="margin:15px")
- h2(style="font-weight:bold;text-align:center;margin:0") Login
+ 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="Username or Email" prop="username" required)
- el-input(v-model="loginForm.username" name="username" placeholder="Username or Email" clearable)
- el-form-item(label="Password" prop="password" required style="margin-top:10px")
- el-input(type="password" v-model="loginForm.password" name="password" placeholder="Password" clearable show-password)
- el-checkbox(v-model="loginForm.saveCredentials" style="margin-top:15px") Save Credentials
- el-checkbox(v-model="enableCustomEndpoint" @change="toggleCustomEndpoint" style="margin-top:10px") Dev Endpoint
- el-form-item(v-if="enableCustomEndpoint" label="Endpont" prop="endpoint" style="margin-top:10px")
+ 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="WebSocket" prop="endpoint" style="margin-top:10px")
+ 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" :loading="loginForm.loading" style="width:100%") Login
- el-button(type="primary" @click="openExternalLink('https://vrchat.com/register')" :loading="loginForm.loading" style="width:100%") Register
+ el-button(native-type="submit" type="primary" :loading="loginForm.loading" style="width:100%") {{ $t("view.login.login") }}
+ el-button(type="primary" @click="openExternalLink('https://vrchat.com/register')" :loading="loginForm.loading" style="width:100%") {{ $t("view.login.register") }}
div(style="text-align:center;font-size:12px")
- p #[a(@click="openExternalLink('https://vrchat.com/home/password')") Forgot password?]
+ p #[a(@click="openExternalLink('https://vrchat.com/home/password')") {{ $t("view.login.forgotPassword") }}]
p © 2019-2022 #[a(@click="openExternalLink('https://github.com/pypy-vrc')") pypy] (mina#5656) & #[a(@click="openExternalLink('https://github.com/Natsumi-sama')") Natsumi]
- p VRCX is an assistant application for provide information about manage friendship. this application uses unofficial VRChat API (VRCSDK).
- p VRCX isn't endorsed by VRChat and doesn't reflect the views or opinions of VRChat or anyone officially involved in producing or managing VRChat. VRChat is trademark of VRChat Inc. VRChat © VRChat Inc.
- p pypy or Natsumi aren't responsible for any problems caused by VRCX. Use at your own risk!
+ p {{ $t("view.settings.general.legal_notice.info") }}
+ p {{ $t("view.settings.general.legal_notice.disclaimer1") }}
+ p {{ $t("view.settings.general.legal_notice.disclaimer2") }}
//- menu
.x-menu-container
@@ -64,17 +64,17 @@ html
i(class=icon)
template(#title)
span= name
- +menuitem('feed', 'Feed', 'el-icon-news')
- +menuitem('gameLog', 'Game Log', 'el-icon-s-data')
- +menuitem('playerList', 'Player List', 'el-icon-tickets')
- +menuitem('search', 'Search', 'el-icon-search')
- +menuitem('favorite', 'Favorites', 'el-icon-star-off')
- +menuitem('friendLog', 'Friend Log', 'el-icon-notebook-2')
- +menuitem('moderation', 'Moderation', 'el-icon-finished')
- +menuitem('notification', 'Notification', 'el-icon-bell')
- +menuitem('friendsList', 'Friends List', 'el-icon-s-management')
- +menuitem('profile', 'Profile', 'el-icon-user')
- +menuitem('settings', 'Settings', 'el-icon-s-tools')
+ +menuitem('feed', "{{ $t('nav_tooltip.feed') }}", 'el-icon-news')
+ +menuitem('gameLog', "{{ $t('nav_tooltip.game_log') }}", 'el-icon-s-data')
+ +menuitem('playerList', "{{ $t('nav_tooltip.player_list') }}", 'el-icon-tickets')
+ +menuitem('search', "{{ $t('nav_tooltip.search') }}", 'el-icon-search')
+ +menuitem('favorite', "{{ $t('nav_tooltip.favorites') }}", 'el-icon-star-off')
+ +menuitem('friendLog', "{{ $t('nav_tooltip.friend_log') }}", 'el-icon-notebook-2')
+ +menuitem('moderation', "{{ $t('nav_tooltip.moderation') }}", 'el-icon-finished')
+ +menuitem('notification', "{{ $t('nav_tooltip.notification') }}", 'el-icon-bell')
+ +menuitem('friendsList', "{{ $t('nav_tooltip.friend_list') }}", 'el-icon-s-management')
+ +menuitem('profile', "{{ $t('nav_tooltip.profile') }}", 'el-icon-user')
+ +menuitem('settings', "{{ $t('nav_tooltip.settings') }}", 'el-icon-s-tools')
//- playerList
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'playerList'")
@@ -134,17 +134,17 @@ html
el-tabs(type="card")
el-tab-pane(label="Current")
data-tables(v-bind="photonEventTable" style="margin-bottom:10px")
- el-table-column(label="Date" prop="created_at" width="120")
+ el-table-column(:label="$t('table.playerList.date')" prop="created_at" width="120")
template(v-once #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="User" prop="photonId" width="160")
+ el-table-column(:label="$t('table.playerList.user')" prop="photonId" width="160")
template(v-once #default="scope")
span.x-link(v-text="scope.row.displayName" @click="showUserFromPhotonId(scope.row.photonId)" style="padding-right:10px")
- el-table-column(label="Type" prop="type" width="140")
- el-table-column(label="Details" prop="text")
+ el-table-column(:label="$t('table.playerList.type')" prop="type" width="140")
+ el-table-column(:label="$t('table.playerList.detail')" prop="text")
template(v-once #default="scope")
template(v-if="scope.row.type === 'ChangeAvatar'")
span.x-link(v-text="scope.row.avatar.name" @click="showAvatarDialog(scope.row.avatar.id)")
@@ -188,7 +188,7 @@ html
span(v-else v-text="scope.row.text")
el-tab-pane(label="Previous")
data-tables(v-bind="photonEventTablePrevious" style="margin-bottom:10px")
- el-table-column(label="Date" prop="created_at" width="120")
+ el-table-column(:label="$t('table.playerList.date')" prop="created_at" width="120")
template(v-once #default="scope")
el-tooltip(placement="right")
template(#content)
@@ -242,16 +242,16 @@ html
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="Avatar" width="70" prop="photo")
+ el-table-column(:label="$t('table.playerList.avatar')" width="70" prop="photo")
template(v-once #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="downloadAndSaveImage(userImageFull(scope.row.ref))")
- el-table-column(label="Timer" width="90" prop="timer" sortable)
+ el-table-column(:label="$t('table.playerList.timer')" width="90" prop="timer" sortable)
template(v-once #default="scope")
timer(:epoch="scope.row.timer")
- el-table-column(v-if="photonLoggingEnabled" label="Photon Id" width="110" prop="photonId" sortable)
+ el-table-column(v-if="photonLoggingEnabled" :label="$t('table.playerList.photonId')" width="110" prop="photonId" sortable)
template(v-once #default="scope")
template(v-if="chatboxUserBlacklist.has(scope.row.ref.id)")
el-tooltip(placement="left" content="Unblock chatbox messages")
@@ -260,7 +260,7 @@ html
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="Icons" prop="isMaster" width="100")
+ el-table-column(:label="$t('table.playerList.icon')" prop="isMaster" width="100")
template(v-once #default="scope")
el-tooltip(v-if="scope.row.isMaster" placement="left" content="Instance Master")
span 👑
@@ -268,7 +268,7 @@ html
span 💚
el-tooltip(v-if="scope.row.timeoutTime" placement="left" content="Timeout")
span(style="color:red") 🔴{{ scope.row.timeoutTime }}s
- el-table-column(label="Platform" prop="inVRMode" width="80")
+ el-table-column(:label="$t('table.playerList.platform')" prop="inVRMode" width="80")
template(v-once #default="scope")
template(v-if="scope.row.ref.last_platform")
span(v-if="scope.row.ref.last_platform === 'standalonewindows'" style="color:#409eff") PC
@@ -277,11 +277,11 @@ html
template(v-if="scope.row.inVRMode !== null")
span(v-if="scope.row.inVRMode") VR
span(v-else) D
- el-table-column(label="Display Name" min-width="140" prop="ref.displayName")
+ el-table-column(:label="$t('table.playerList.displayName')" min-width="140" prop="ref.displayName")
template(v-once #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="Status" min-width="180" prop="ref.status")
+ el-table-column(:label="$t('table.playerList.status')" min-width="180" prop="ref.status")
template(v-once #default="scope")
template(v-if="scope.row.ref.status")
i.x-user-status(:class="statusClass(scope.row.ref.status)")
@@ -290,16 +290,16 @@ html
//- 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="Rank" width="110" prop="$trustSortNum" sortable="custom")
+ el-table-column(:label="$t('table.playerList.rank')" width="110" prop="$trustSortNum" sortable="custom")
template(v-once #default="scope")
span.name(v-text="scope.row.ref.$trustLevel" :class="scope.row.ref.$trustClass")
- el-table-column(label="Language" width="100" prop="ref.$languages")
+ el-table-column(:label="$t('table.playerList.language')" width="100" prop="ref.$languages")
template(v-once #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-left:5px")
- el-table-column(label="Bio Links" width="100" prop="ref.bioLinks")
+ el-table-column(:label="$t('table.playerList.bioLink')" width="100" prop="ref.bioLinks")
template(v-once #default="scope")
el-tooltip(v-if="link" v-for="(link, index) in scope.row.ref.bioLinks" :key="index")
template(#content)
@@ -312,11 +312,11 @@ html
template(#tool)
div(style="margin:0 0 10px;display:flex;align-items:center")
div(style="flex:none;margin-right:10px")
- el-tooltip(placement="bottom" content="Filter VIP only" :disabled="hideTooltips")
+ 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 collapse-tags style="flex:1" placeholder="Filter")
+ el-select(v-model="feedTable.filter" @change="feedTableLookup" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.feed.filter_placeholder')")
el-option(v-once v-for="type in ['GPS', 'Online', 'Offline', 'Status', 'Avatar', 'Bio']" :key="type" :label="type" :value="type")
- el-input(v-model="feedTable.search" placeholder="Search" @keyup.native.13="feedTableLookup" @change="feedTableLookup" clearable style="flex:none;width:150px;margin:0 10px")
+ 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-tooltip(placement="bottom" content="Clear feed" :disabled="hideTooltips")
//- el-button(type="default" @click="clearFeed()" icon="el-icon-delete" circle style="flex:none")
el-table-column(type="expand" width="20")
@@ -371,17 +371,17 @@ html
span
i.el-icon-right
pre(v-text="scope.row.bio" style="font-family:inherit;font-size:12px;white-space:pre-wrap;margin:0 0.5em 0 0")
- el-table-column(label="Date" prop="created_at" sortable="custom" width="120")
+ el-table-column(:label="$t('table.feed.date')" prop="created_at" sortable="custom" width="120")
template(v-once #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="Type" prop="type" width="70")
- el-table-column(label="User" prop="displayName" width="180")
+ el-table-column(:label="$t('table.feed.type')" prop="type" width="70")
+ el-table-column(:label="$t('table.feed.user')" prop="displayName" width="180")
template(v-once #default="scope")
span.x-link(v-text="scope.row.displayName" @click="showUserDialog(scope.row.userId)")
- el-table-column(label="Detail")
+ el-table-column(:label="$t('table.feed.detail')")
template(v-once #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")
@@ -428,32 +428,32 @@ html
data-tables(v-bind="gameLogTable" v-loading="gameLogTable.loading")
template(#tool)
div(style="margin:0 0 10px;display:flex;align-items:center")
- el-select(v-model="gameLogTable.filter" @change="gameLogTableLookup" multiple clearable collapse-tags style="flex:1" placeholder="Filter")
+ el-select(v-model="gameLogTable.filter" @change="gameLogTableLookup" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.game_log.filter_placeholder')")
el-option(v-once v-for="type in ['Location', 'OnPlayerJoined', 'OnPlayerLeft', 'PortalSpawn', 'Event', 'VideoPlay']" :key="type" :label="type" :value="type")
- el-input(v-model="gameLogTable.search" placeholder="Search" @keyup.native.13="gameLogTableLookup" @change="gameLogTableLookup" clearable style="flex:none;width:150px;margin:0 10px")
+ 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-tooltip(placement="bottom" content="Reload game log" :disabled="hideTooltips")
//- el-button(type="default" @click="resetGameLog" icon="el-icon-refresh" circle style="flex:none")
- el-table-column(label="Date" prop="created_at" sortable="custom" width="120")
+ el-table-column(:label="$t('table.gameLog.date')" prop="created_at" sortable="custom" width="120")
template(v-once #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="Type" prop="type" width="120")
+ el-table-column(:label="$t('table.gameLog.type')" prop="type" width="120")
template(v-once #default="scope")
span.x-link(v-if="scope.row.location && scope.row.type !== 'Location'" v-text="scope.row.type" @click="showWorldDialog(scope.row.location)")
span(v-else v-text="scope.row.type")
- el-table-column(label="User" prop="displayName" width="180")
+ el-table-column(:label="$t('table.gameLog.user')" prop="displayName" width="180")
template(v-once #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="Detail" prop="data")
+ el-table-column(:label="$t('table.gameLog.detail')" prop="data")
template(v-once #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 === 'VideoPlay'")
- span(v-if="scope.row.videoId") {{ scope.row.videoId }}:
+ span(v-if="scope.row.videoId") {{ 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")
@@ -463,11 +463,11 @@ html
//- search
.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="Search" @keyup.native.13="search()" style="flex:1")
- el-tooltip(placement="bottom" content="Clear search results" :disabled="hideTooltips")
+ 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")
- el-tab-pane(label="User" v-loading="isSearchUserLoading" style="min-height:60px")
+ el-tab-pane(:label="$t('view.search.user.header')" v-loading="isSearchUserLoading" style="min-height:60px")
.x-friend-list
.x-friend-item(v-for="user in searchUserResults" :key="user.id" @click="showUserDialog(user.id)")
template(v-once)
@@ -478,14 +478,14 @@ html
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")
- el-button(v-if="searchUserParams.offset" @click="moreSearchUser(-1)" icon="el-icon-back" size="small") Prev
- el-button(v-if="searchUserResults.length" @click="moreSearchUser(1)" icon="el-icon-right" size="small") Next
- el-tab-pane(label="World" v-loading="isSearchWorldLoading" style="min-height:60px")
+ el-button(v-if="searchUserParams.offset" @click="moreSearchUser(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
+ el-button(v-if="searchUserResults.length" @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") Search by Category #[i.el-icon-arrow-down.el-icon--right]
+ 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") Include community labs
+ el-checkbox(v-model="searchWorldLabs" style="margin-left:10px") {{ $t('view.search.world.community_lab') }}
.x-friend-list
.x-friend-item(v-for="world in searchWorldResults" :key="world.id" @click="showWorldDialog(world.id)")
template(v-once)
@@ -496,28 +496,28 @@ html
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")
- el-button(v-if="searchWorldParams.offset" @click="moreSearchWorld(-1)" icon="el-icon-back" size="small") Prev
- el-button(v-if="searchWorldResults.length >= 10" @click="moreSearchWorld(1)" icon="el-icon-right" size="small") Next
- el-tab-pane(label="Avatar" v-loading="isSearchAvatarLoading" style="min-height:60px")
+ el-button(v-if="searchWorldParams.offset" @click="moreSearchWorld(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
+ el-button(v-if="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")
el-dropdown(v-if="avatarRemoteDatabaseProviderList.length > 1" trigger="click" @click.native.stop size="mini" style="margin-right:5px")
- el-button(size="small") Search Provider #[i.el-icon-arrow-down.el-icon--right]
+ 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="Refresh own avatars" :disabled="hideTooltips")
+ 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") Results {{ searchAvatarResults.length }}
+ span(style="font-size:14px;margin-left:5px;margin-right:5px") {{ $t("view.search.avatar.result_count", { count: searchAvatarResults.length }) }}
el-radio-group(v-model="searchAvatarFilter" size="mini" style="margin:5px;display:block" @change="searchAvatar")
- el-radio(label="all") all
- el-radio(label="public") public
- el-radio(label="private") private
+ 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-radio-group(v-model="searchAvatarFilterRemote" size="mini" style="margin:5px;display:block" @change="searchAvatar")
- el-radio(label="all") all
- el-radio(label="local") local
- el-radio(label="remote" :disabled="!avatarRemoteDatabase") remote
+ 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') }}
el-radio-group(:disabled="searchAvatarFilterRemote !== 'local'" v-model="searchAvatarSort" size="mini" style="margin:5px;display:block" @change="searchAvatar")
- el-radio(label="name") by name
- el-radio(label="update") by update
- el-radio(label="created") by created
+ 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")
.x-friend-item(v-for="avatar in searchAvatarPage" :key="avatar.id" @click="showAvatarDialog(avatar.id)")
template(v-once)
@@ -531,25 +531,25 @@ html
span.extra(v-text="avatar.releaseStatus" v-else)
span.extra(v-text="avatar.authorName")
el-button-group(style="margin-top:15px")
- el-button(v-if="searchAvatarPageNum" @click="moreSearchAvatar(-1)" icon="el-icon-back" size="small") Prev
- el-button(v-if="searchAvatarResults.length > 10 && (searchAvatarPageNum + 1) * 10 < searchAvatarResults.length" @click="moreSearchAvatar(1)" icon="el-icon-right" size="small") Next
+ el-button(v-if="searchAvatarPageNum" @click="moreSearchAvatar(-1)" icon="el-icon-back" size="small") {{ $t('view.search.prev_page') }}
+ el-button(v-if="searchAvatarResults.length > 10 && (searchAvatarPageNum + 1) * 10 < searchAvatarResults.length" @click="moreSearchAvatar(1)" icon="el-icon-right" size="small") {{ $t('view.search.next_page') }}
//- favorite
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'favorite'")
- el-tooltip(placement="bottom" content="Refresh all favorites" :disabled="hideTooltips")
+ el-tooltip(placement="bottom" :content="$t('view.favorite.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" :loading="API.isFavoriteLoading" @click="API.refreshFavorites(); getLocalWorldFavorites()" size="small" icon="el-icon-refresh" circle style="position:relative;float:right;z-index:1")
el-tabs(ref="favoriteTabRef" type="card" v-loading="API.isFavoriteLoading")
- el-tab-pane(label="Friends")
+ el-tab-pane(:label="$t('view.favorite.friends.header')")
el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '0'" style="border:0")
- el-button(size="small" @click="showFriendExportDialog") Export
- el-button(size="small" @click="showFriendImportDialog") Import
+ el-button(size="small" @click="showFriendExportDialog") {{ $t('view.favorite.export') }}
+ el-button(size="small" @click="showFriendImportDialog") {{ $t('view.favorite.import') }}
el-collapse-item(v-for="group in API.favoriteFriendGroups" :key="group.name")
template(slot="title")
span(v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px")
span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }}
- el-tooltip(placement="top" content="Rename" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px")
- el-tooltip(placement="right" content="Clear" :disabled="hideTooltips")
+ el-tooltip(placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
.x-friend-list(v-if="group.count" style="margin-top:10px")
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteFriends" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showUserDialog(favorite.id)")
@@ -561,35 +561,35 @@ html
span.name(v-text="favorite.ref.displayName" :style="{'color':favorite.ref.$userColour}")
location.extra(v-if="favorite.ref.location !== 'offline'" :location="favorite.ref.location" :traveling="favorite.ref.travelingToLocation" :link="false")
span(v-else v-text="favorite.ref.statusDescription")
- el-tooltip(placement="left" content="Move" :disabled="hideTooltips")
+ el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
el-button(type="default" icon="el-icon-back" size="mini" circle)
el-dropdown-menu(#default="dropdown")
template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteFriendGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'friend')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
- el-tooltip(placement="right" content="Unfavorite" :disabled="hideTooltips")
+ el-tooltip(placement="right" :content="$t('view.favorite.unfavorite_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
template(v-else)
span(v-text="favorite.name || favorite.id")
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px")
- el-tab-pane(label="Worlds")
+ el-tab-pane(:label="$t('view.favorite.worlds.header')")
el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '1'" style="border:0")
- el-button(size="small" @click="showWorldExportDialog") Export
- el-button(size="small" @click="showWorldImportDialog") Import
- span(style="display:block;margin-top:20px") VRChat Favorites
+ el-button(size="small" @click="showWorldExportDialog") {{ $t('view.favorite.export') }}
+ el-button(size="small" @click="showWorldImportDialog") {{ $t('view.favorite.import') }}
+ span(style="display:block;margin-top:20px") {{ $t('view.favorite.worlds.vrchat_favorites') }}
el-collapse-item(v-for="group in API.favoriteWorldGroups" :key="group.name")
template(slot="title")
span(v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px")
i.x-user-status(style="margin-left:5px" :class="userFavoriteWorldsStatus(group.visibility)")
span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }}
- el-tooltip(placement="top" content="Change visibility" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('view.favorite.visibility_tooltip')" :disabled="hideTooltips")
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:10px")
el-button(type="default" icon="el-icon-view" size="mini" circle)
el-dropdown-menu(#default="dropdown")
el-dropdown-item(v-if="group.visibility !== visibility" v-for="visibility in worldGroupVisibilityOptions" :key="visibility" style="display:block;margin:10px 0" v-text="visibility" @click.native="changeWorldGroupVisibility(group.name, visibility)")
- el-tooltip(placement="top" content="Rename" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:5px")
- el-tooltip(placement="right" content="Clear" :disabled="hideTooltips")
+ el-tooltip(placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
.x-friend-list(v-if="group.count" style="margin-top:10px")
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteWorlds" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showWorldDialog(favorite.id)")
@@ -601,26 +601,26 @@ html
span.name(v-text="favorite.ref.name")
span.extra(v-if="favorite.ref.occupants") {{ favorite.ref.authorName }} ({{ favorite.ref.occupants }})
span.extra(v-else v-text="favorite.ref.authorName")
- el-tooltip(placement="left" content="Move" :disabled="hideTooltips")
+ el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
el-button(type="default" icon="el-icon-back" size="mini" circle)
el-dropdown-menu(#default="dropdown")
template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteWorldGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'world')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
- el-tooltip(placement="right" content="Unfavorite" :disabled="hideTooltips")
+ el-tooltip(placement="right" :content="$t('view.favorite.unfavorite_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
template(v-else)
span(v-text="favorite.name || favorite.id")
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="deleteFavorite(favorite.id)" style="margin-left:5px")
- span(style="display:block;margin-top:20px") Local Favorites
- el-button(size="small" @click="promptNewLocalWorldFavoriteGroup" style="display:block;margin-top:10px") New Group
+ span(style="display:block;margin-top:20px") {{ $t('view.favorite.worlds.local_favorites') }}
+ el-button(size="small" @click="promptNewLocalWorldFavoriteGroup" style="display:block;margin-top:10px") {{ $t('view.favorite.worlds.new_group') }}
el-collapse-item(v-for="group in localWorldFavoriteGroups" v-if="localWorldFavorites[group]" :key="group")
template(slot="title")
span(v-text="group" style="font-weight:bold;font-size:14px;margin-left:10px")
span(style="color:#909399;font-size:12px;margin-left:10px") {{ getLocalWorldFavoriteGroupLength(group) }}
- el-tooltip(placement="top" content="Rename" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="promptLocalWorldFavoriteGroupRename(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px")
- el-tooltip(placement="right" content="Delete" :disabled="hideTooltips")
+ el-tooltip(placement="right" :content="$t('view.favorite.delete_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="promptLocalWorldFavoriteGroupDelete(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
.x-friend-list(style="margin-top:10px")
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in localWorldFavorites[group]" :key="favorite.id" @click="showWorldDialog(favorite.id)")
@@ -632,22 +632,22 @@ html
span.name(v-text="favorite.name")
span.extra(v-if="favorite.occupants") {{ favorite.authorName }} ({{ favorite.occupants }})
span.extra(v-else v-text="favorite.authorName")
- el-tooltip(placement="right" content="Unfavorite" :disabled="hideTooltips")
+ el-tooltip(placement="right" :content="$t('view.favorite.unfavorite_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="removeLocalWorldFavorite(favorite.id, group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
template(v-else)
span(v-text="favorite.id")
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="removeLocalWorldFavorite(favorite.id, group)" style="margin-left:5px")
- el-tab-pane(label="Avatars")
+ el-tab-pane(:label="$t('view.favorite.avatars.header')")
el-collapse(v-if="$refs.menu && $refs.menu.activeIndex === 'favorite' && $refs.favoriteTabRef && $refs.favoriteTabRef.currentName === '2'" style="border:0")
- el-button(size="small" @click="showAvatarExportDialog") Export
- el-button(size="small" @click="showAvatarImportDialog") Import
+ el-button(size="small" @click="showAvatarExportDialog") {{ $t('view.favorite.export') }}
+ el-button(size="small" @click="showAvatarImportDialog") {{ $t('view.favorite.import') }}
el-collapse-item(v-for="group in API.favoriteAvatarGroups" :key="group.name")
template(slot="title")
span(v-text="group.displayName" style="font-weight:bold;font-size:14px;margin-left:10px")
span(style="color:#909399;font-size:12px;margin-left:10px") {{ group.count }}/{{ group.capacity }}
- el-tooltip(placement="top" content="Rename" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('view.favorite.rename_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="changeFavoriteGroupName(group)" size="mini" icon="el-icon-edit" circle style="margin-left:10px")
- el-tooltip(placement="right" content="Clear" :disabled="hideTooltips")
+ el-tooltip(placement="right" :content="$t('view.favorite.clear_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="clearFavoriteGroup(group)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
.x-friend-list(v-if="group.count" style="margin-top:10px")
div(style="display:inline-block;width:300px;margin-right:15px" v-for="favorite in favoriteAvatars" v-if="favorite.groupKey === group.key" :key="favorite.id" @click="showAvatarDialog(favorite.id)")
@@ -658,13 +658,13 @@ html
.detail
span.name(v-text="favorite.ref.name")
span.extra(v-text="favorite.ref.authorName")
- el-tooltip(placement="left" content="Move" :disabled="hideTooltips")
+ el-tooltip(placement="left" :content="$t('view.favorite.move_tooltip')" :disabled="hideTooltips")
el-dropdown(trigger="click" @click.native.stop size="mini" style="margin-left:5px")
el-button(type="default" icon="el-icon-back" size="mini" circle)
el-dropdown-menu(#default="dropdown")
template(v-if="groupAPI.name !== group.name" v-for="groupAPI in API.favoriteAvatarGroups" :key="groupAPI.name")
el-dropdown-item(style="display:block;margin:10px 0" @click.native="moveFavorite(favorite.ref, groupAPI, 'avatar')" :disabled="groupAPI.count >= groupAPI.capacity") {{ groupAPI.displayName }} ({{ groupAPI.count }} / {{ groupAPI.capacity }})
- el-tooltip(placement="right" content="Unfavorite" :disabled="hideTooltips")
+ el-tooltip(placement="right" :content="$t('view.favorite.unfavorite_tooltip')" :disabled="hideTooltips")
el-button(@click.stop="deleteFavorite(favorite.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
template(v-else)
.detail
@@ -696,23 +696,23 @@ html
data-tables(v-bind="friendLogTable")
template(#tool)
div(style="margin:0 0 10px;display:flex;align-items:center")
- el-select(v-model="friendLogTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" placeholder="Filter")
+ el-select(v-model="friendLogTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.friend_log.filter_placeholder')")
el-option(v-once v-for="type in ['Friend', 'Unfriend', 'FriendRequest', 'CancelFriendRequest', 'DisplayName', 'TrustLevel']" :key="type" :label="type" :value="type")
- el-input(v-model="friendLogTable.filters[1].value" placeholder="Search" style="flex:none;width:150px;margin-left:10px")
- el-table-column(label="Date" prop="created_at" sortable="custom" width="120")
+ el-input(v-model="friendLogTable.filters[1].value" :placeholder="$t('view.friend_log.search_placeholder')" style="flex:none;width:150px;margin-left:10px")
+ el-table-column(:label="$t('table.friendLog.date')" prop="created_at" sortable="custom" width="120")
template(v-once #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="Type" prop="type" width="150")
- el-table-column(label="User" prop="displayName")
+ el-table-column(:label="$t('table.friendLog.type')" prop="type" width="150")
+ el-table-column(:label="$t('table.friendLog.user')" prop="displayName")
template(v-once #default="scope")
- span(v-if="scope.row.type === 'DisplayName'") {{ scope.row.previousDisplayName }} #[i.el-icon-right]
+ span(v-if="scope.row.type === 'DisplayName'") {{ scope.row.previousDisplayName }} #[i.el-icon-right]
span.x-link(v-text="scope.row.displayName || scope.row.userId" @click="showUserDialog(scope.row.userId)")
template(v-if="scope.row.type === 'TrustLevel'")
span ({{ scope.row.previousTrustLevel }} #[i.el-icon-right] {{ scope.row.trustLevel }})
- el-table-column(label="Action" width="80" align="right")
+ el-table-column(:label="$t('table.friendLog.action')" width="80" align="right")
template(v-once #default="scope")
el-button(type="text" icon="el-icon-close" size="mini" @click="deleteFriendLog(scope.row)")
@@ -721,25 +721,25 @@ html
data-tables(v-bind="playerModerationTable" v-loading="API.isPlayerModerationsLoading")
template(#tool)
div(style="margin:0 0 10px;display:flex;align-items:center")
- el-select(v-model="playerModerationTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" placeholder="Filter")
+ el-select(v-model="playerModerationTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.moderation.filter_placeholder')")
el-option(v-once v-for="type in ['block', 'unblock', 'mute', 'unmute', 'interactOn', 'interactOff']" :key="type" :label="type" :value="type")
- el-input(v-model="playerModerationTable.filters[1].value" placeholder="Search" style="flex:none;width:150px;margin:0 10px")
- el-tooltip(placement="bottom" content="Refresh" :disabled="hideTooltips")
+ el-input(v-model="playerModerationTable.filters[1].value" :placeholder="$t('view.moderation.search_placeholder')" style="flex:none;width:150px;margin:0 10px")
+ el-tooltip(placement="bottom" :content="$t('view.moderation.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" :loading="API.isPlayerModerationsLoading" @click="API.refreshPlayerModerations()" icon="el-icon-refresh" circle style="flex:none")
- el-table-column(label="Date" prop="created" sortable="custom" width="120")
+ el-table-column(:label="$t('table.moderation.date')" prop="created" sortable="custom" width="120")
template(v-once #default="scope")
el-tooltip(placement="right")
template(#content)
span {{ scope.row.created | formatDate('long') }}
span {{ scope.row.created | formatDate('short') }}
- el-table-column(label="Type" prop="type" width="100")
- el-table-column(label="Source" prop="sourceDisplayName")
+ el-table-column(:label="$t('table.moderation.type')" prop="type" width="100")
+ el-table-column(:label="$t('table.moderation.source')" prop="sourceDisplayName")
template(v-once #default="scope")
span.x-link(v-text="scope.row.sourceDisplayName" @click="showUserDialog(scope.row.sourceUserId)")
- el-table-column(label="Target" prop="targetDisplayName")
+ el-table-column(:label="$t('table.moderation.target')" prop="targetDisplayName")
template(v-once #default="scope")
span.x-link(v-text="scope.row.targetDisplayName" @click="showUserDialog(scope.row.targetUserId)")
- el-table-column(label="Action" width="80" align="right")
+ el-table-column(:label="$t('table.moderation.action')" width="80" align="right")
template(v-once #default="scope")
el-button(v-if="scope.row.sourceUserId === API.currentUser.id" type="text" icon="el-icon-close" size="mini" @click="deletePlayerModeration(scope.row)")
@@ -748,18 +748,18 @@ html
data-tables(v-bind="notificationTable")
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 collapse-tags style="flex:1" placeholder="Filter")
+ el-select(v-model="notificationTable.filters[0].value" @change="saveTableFilters" multiple clearable collapse-tags style="flex:1" :placeholder="$t('view.notification.filter_placeholder')")
el-option(v-once v-for="type in ['requestInvite', 'invite', 'requestInviteResponse', 'inviteResponse', 'friendRequest', 'hiddenFriendRequest', 'message', 'group.announcement', 'group.informative', 'group.invite', 'group.joinRequest', 'moderation.warning.group']" :key="type" :label="type" :value="type")
- el-input(v-model="notificationTable.filters[1].value" placeholder="Search" style="flex:none;width:150px;margin:0 10px")
- el-tooltip(placement="bottom" content="Refresh" :disabled="hideTooltips")
+ 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="Date" prop="created_at" sortable="custom" width="120")
+ el-table-column(:label="$t('table.notification.date')" prop="created_at" sortable="custom" width="120")
template(v-once #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="Type" prop="type" width="160")
+ el-table-column(:label="$t('table.notification.type')" prop="type" width="160")
template(v-once #default="scope")
el-tooltip(v-if="scope.row.type === 'invite'" placement="top")
template(#content)
@@ -769,10 +769,10 @@ html
el-tooltip(placement="top" :content="scope.row.linkText" :disabled="hideTooltips")
span.x-link(v-text="scope.row.type" @click="openNotificationLink(scope.row.link)")
span(v-else v-text="scope.row.type")
- el-table-column(label="User" prop="senderUsername" width="150")
+ el-table-column(:label="$t('table.notification.user')" prop="senderUsername" width="150")
template(v-once #default="scope")
span.x-link(v-text="scope.row.senderUsername" @click="showUserDialog(scope.row.senderUserId)")
- el-table-column(label="Photo" width="100" prop="photo")
+ el-table-column(:label="$t('table.notification.photo')" width="100" prop="photo")
template(v-once #default="scope")
template(v-if="scope.row.details && scope.row.details.imageUrl")
el-popover(placement="right" width="500px" trigger="click")
@@ -782,14 +782,14 @@ html
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="scope.row.imageUrl" style="flex:none;width:90px;border-radius:4px")
img.x-link(v-lazy="scope.row.imageUrl" style="width:500px" @click="downloadAndSaveImage(scope.row.imageUrl)")
- el-table-column(label="Message" prop="message")
+ el-table-column(:label="$t('table.notification.message')" prop="message")
template(v-once #default="scope")
span(v-if="scope.row.title") {{ scope.row.title }}, {{ scope.row.message }}
span(v-else-if="scope.row.message" 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="Action" width="100" align="right")
+ el-table-column(:label="$t('table.notification.action')" width="100" align="right")
template(v-once #default="scope")
template(v-if="scope.row.senderUserId !== API.currentUser.id && !scope.row.$isExpired")
template(v-if="scope.row.type === 'friendRequest'")
@@ -836,7 +836,7 @@ html
//- profile
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'profile'")
div.options-container(style="margin-top:0")
- span.header Profile
+ span.header {{ $t('view.profile.profile.header') }}
.x-friend-list(style="margin-top:10px")
.x-friend-item(@click="showUserDialog(API.currentUser.id)")
.avatar
@@ -846,29 +846,29 @@ html
span.extra(v-text="API.currentUser.username")
.x-friend-item(style="cursor:default")
.detail
- span.name Last Activity
+ span.name {{ $t('view.profile.profile.last_activity') }}
span.extra {{ API.currentUser.last_activity | formatDate('long') }}
.x-friend-item(style="cursor:default")
.detail
- span.name Two-Factor Auth (2FA)
- span.extra {{ API.currentUser.twoFactorAuthEnabled ? 'Enabled' : 'Disabled' }}
+ 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') }}
div
- el-button(size="small" icon="el-icon-switch-button" @click="logout()" style="margin-left:0;margin-right:5px;margin-top:10px") Logout
- el-button(size="small" icon="el-icon-printer" @click="showExportFriendsListDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") Export Friends List
- el-button(size="small" icon="el-icon-user" @click="showExportAvatarsListDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") Export Own Avatars
- el-button(size="small" icon="el-icon-chat-dot-round" @click="showDiscordNamesDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") Discord Names
- el-button(size="small" icon="el-icon-document-copy" @click="showNoteExportDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") Export Notes
+ el-button(size="small" 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-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-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-document-copy" @click="showNoteExportDialog()" style="margin-left:0;margin-right:5px;margin-top:10px") {{ $t('view.profile.profile.export_notes') }}
div.options-container
- span.header Game Info
+ span.header {{ $t('view.profile.game_info.header') }}
.x-friend-list(style="margin-top:10px")
.x-friend-item
.detail(@click="API.getVisits()")
- span.name Online Users
- span.extra(v-if="visits") {{visits}} users online.
- span.extra(v-else) Click to refresh
+ 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-else) {{ $t('view.profile.game_info.refresh') }}
div.options-container
- span.header VRC SDK Downloads
- el-tooltip(placement="top" content="Refresh" :disabled="hideTooltips")
+ 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")
@@ -876,18 +876,18 @@ html
span.name(v-text="item")
span.extra(v-text="link")
div.options-container
- span.header Direct Access
+ span.header {{ $t('view.profile.direct_access.header') }}
div(style="margin-top:10px")
el-button-group
- el-button(size="small" @click="promptUsernameDialog()") Username
- el-button(size="small" @click="promptUserIdDialog()") User ID
- el-button(size="small" @click="promptWorldDialog()") World/Instance
- el-button(size="small" @click="promptAvatarDialog()") Avatar
+ 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
- span.header Invite Messages
- el-tooltip(placement="top" content="Refresh" :disabled="hideTooltips")
+ 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="Clear results" :disabled="hideTooltips")
+ 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="Slot" prop="slot" sortable="custom" width="70")
@@ -899,10 +899,10 @@ html
template(v-once #default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('message', scope.row)")
div.options-container
- span.header Invite Response Messages
- el-tooltip(placement="top" content="Refresh" :disabled="hideTooltips")
+ 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="Clear results" :disabled="hideTooltips")
+ 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="Slot" prop="slot" sortable="custom" width="70")
@@ -914,10 +914,10 @@ html
template(v-once #default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('response', scope.row)")
div.options-container
- span.header Invite Request Messages
- el-tooltip(placement="top" content="Refresh" :disabled="hideTooltips")
+ 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="Clear results" :disabled="hideTooltips")
+ 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="Slot" prop="slot" sortable="custom" width="70")
@@ -929,10 +929,10 @@ html
template(v-once #default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('request', scope.row)")
div.options-container
- span.header Invite Request Response Messages
- el-tooltip(placement="top" content="Refresh" :disabled="hideTooltips")
+ 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="Clear results" :disabled="hideTooltips")
+ 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="Slot" prop="slot" sortable="custom" width="70")
@@ -944,17 +944,17 @@ html
template(v-once #default="scope")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showEditInviteMessageDialog('requestResponse', scope.row)")
div.options-container
- span.header Past Display Names
+ span.header {{ $t('view.profile.past_display_names') }}
data-tables(v-bind="pastDisplayNameTable" style="margin-top:10px")
el-table-column(label="Date" prop="updated_at" sortable="custom")
template(v-once #default="scope")
span {{ scope.row.updated_at | formatDate('long') }}
el-table-column(label="Name" prop="displayName")
div.options-container
- span.header Config JSON
- el-tooltip(placement="top" content="Refresh" :disabled="hideTooltips")
+ 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="Clear results" :disabled="hideTooltips")
+ 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")
@@ -962,10 +962,10 @@ html
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
- span.header Current User JSON
- el-tooltip(placement="top" content="Refresh" :disabled="hideTooltips")
+ 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="Clear results" :disabled="hideTooltips")
+ 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")
@@ -976,230 +976,230 @@ html
//- friends list
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'friendsList'" v-if="$refs.menu && $refs.menu.activeIndex === 'friendsList'")
div.options-container(style="margin-top:0")
- span.header Friends List
+ 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") Bulk Unfriend Selection
+ 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")
- span.name Bulk Unfriend Mode
+ span.name {{ $t('view.friend_list.bulk_unfriend') }}
el-switch(v-model="friendsListBulkUnfriendMode" style="margin-left:5px")
- span Load missing entries
- el-tooltip(placement="top" style="margin-left:5px" content="This takes a lot of API requests so use it sparingly")
+ span {{ $t('view.friend_list.load') }}
+ el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.friend_list.load_notice')")
i.el-icon-warning
template(v-if="friendsListLoading")
span(v-text="friendsListLoadingProgress" style="margin-left:5px")
- el-tooltip(placement="top" content="Cancel" :disabled="hideTooltips")
+ 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="Load" :disabled="hideTooltips")
+ 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")
- el-tooltip(placement="bottom" content="Filter VIP only" :disabled="hideTooltips")
+ 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="Search" @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="Filter")
+ 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-once v-for="type in ['Display Name', 'User Name', 'Rank', 'Status', 'Bio', 'Memo']" :key="type" :label="type" :value="type")
- el-tooltip(placement="top" content="Refresh" :disabled="hideTooltips")
+ 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="Clear results" :disabled="hideTooltips")
+ 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(v-if="friendsListBulkUnfriendMode" width="55" prop="$selected")
template(v-once #default="scope")
el-button(type="text" size="mini" @click.stop)
el-checkbox(v-model="scope.row.$selected")
- el-table-column(label="No." width="70" prop="$friendNum" sortable="custom")
- el-table-column(label="Avatar" width="70" prop="photo")
+ el-table-column(:label="$t('table.friendList.no')" width="70" prop="$friendNum" sortable="custom")
+ el-table-column(:label="$t('table.friendList.avatar')" width="70" prop="photo")
template(v-once #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="downloadAndSaveImage(userImageFull(scope.row))")
- el-table-column(label="Display Name" min-width="140" prop="displayName" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'displayName')")
+ el-table-column(:label="$t('table.friendList.displayName')" min-width="140" prop="displayName" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'displayName')")
template(v-once #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="Rank" width="110" prop="$trustSortNum" sortable="custom")
+ el-table-column(:label="$t('table.friendList.rank')" width="110" prop="$trustSortNum" sortable="custom")
template(v-once #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="Status" min-width="180" prop="status" sortable :sort-method="(a, b) => sortStatus(a.status, b.status)")
+ el-table-column(:label="$t('table.friendList.status')" min-width="180" prop="status" sortable :sort-method="(a, b) => sortStatus(a.status, b.status)")
template(v-once #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="Language" width="110" prop="$languages" sortable :sort-method="(a, b) => sortLanguages(a, b)")
+ el-table-column(:label="$t('table.friendList.language')" width="110" prop="$languages" sortable :sort-method="(a, b) => sortLanguages(a, b)")
template(v-once #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-left:5px")
- el-table-column(label="Bio Links" width="100" prop="bioLinks")
+ el-table-column(:label="$t('table.friendList.bioLink')" width="100" prop="bioLinks")
template(v-once #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="Join Count" width="120" prop="$joinCount" sortable)
- el-table-column(label="Time Together" width="140" prop="$timeSpent" sortable)
+ 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(v-once #default="scope")
span(v-if="scope.row.$timeSpent") {{ scope.row.$timeSpent | timeToText }}
- el-table-column(label="Last Seen" width="170" prop="$lastSeen" sortable :sort-method="(a, b) => sortAlphabetically(a, b, '$lastSeen')")
+ el-table-column(:label="$t('table.friendList.lastSeen')" width="170" prop="$lastSeen" sortable :sort-method="(a, b) => sortAlphabetically(a, b, '$lastSeen')")
template(v-once #default="scope")
span {{ scope.row.$lastSeen | formatDate('long') }}
- el-table-column(label="Last Activity" width="170" prop="last_activity" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'last_activity')")
+ el-table-column(:label="$t('table.friendList.lastActivity')" width="170" prop="last_activity" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'last_activity')")
template(v-once #default="scope")
span {{ scope.row.last_activity | formatDate('long') }}
- el-table-column(label="Last Login" width="170" prop="last_login" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'last_login')")
+ el-table-column(:label="$t('table.friendList.lastLogin')" width="170" prop="last_login" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'last_login')")
template(v-once #default="scope")
span {{ scope.row.last_login | formatDate('long') }}
- el-table-column(label="Date Joined" width="120" prop="date_joined" sortable :sort-method="(a, b) => sortAlphabetically(a, b, 'date_joined')")
- el-table-column(label="Unfriend" width="80")
+ 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="80")
template(v-once #default="scope")
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(scope.row.id)")
//- settings
.x-container(v-show="$refs.menu && $refs.menu.activeIndex === 'settings'")
- div.options-container(style="margin-top:0")
- span.header Settings
+ div.options-container(style="margin-top:0")
+ span.header {{ $t("view.settings.header") }}
el-tabs(type="card" style="margin-top:10px")
- el-tab-pane(label="General")
+ el-tab-pane(:label="$t('view.settings.category.general')")
div.options-container(style="margin-top:0")
- span.header General
+ span.header {{ $t("view.settings.general.general.header") }}
.x-friend-list(style="margin-top:10px")
.x-friend-item(style="cursor:default")
.detail
- span.name Version
+ span.name {{ $t("view.settings.general.general.version") }}
span.extra(v-text="appVersion")
.x-friend-item(@click="checkForVRCXUpdate")
.detail
- span.name Latest Version
+ span.name {{ $t("view.settings.general.general.latest_app_version") }}
span.extra(v-if="latestAppVersion" v-text="latestAppVersion")
- span.extra(v-else) Click to refresh
+ span.extra(v-else) {{ $t("view.settings.general.general.latest_app_version_refresh") }}
.x-friend-item(@click="openExternalLink('https://github.com/pypy-vrc/VRCX')")
.detail
- span.name Repository URL
+ span.name {{ $t("view.settings.general.general.repository_url") }}
span.extra https://github.com/pypy-vrc/VRCX
.x-friend-item(@click="openExternalLink('https://vrcx.pypy.moe/discord')")
.detail
- span.name Support
+ span.name {{ $t("view.settings.general.general.support") }}
span.extra https://vrcx.pypy.moe/discord
div.options-container
- span.header VRCX Updater
+ span.header {{ $t("view.settings.general.vrcx_updater.header") }}
div.options-container-item
- el-button(size="small" icon="el-icon-upload" @click="showVRCXUpdateDialog()") Change build
+ el-button(size="small" icon="el-icon-upload" @click="showVRCXUpdateDialog()") {{ $t("view.settings.general.vrcx_updater.change_build") }}
div.options-container-item
- span.name Auto update:
+ span.name {{ $t("view.settings.general.vrcx_updater.auto_update") }}
br
el-radio-group(v-model="autoUpdateVRCX" @change="saveAutoUpdateVRCX" size="mini")
- el-radio-button(label="Off")
- el-radio-button(label="Notify")
- el-radio-button(label="Auto Download")
- el-radio-button(label="Auto Install")
+ el-radio-button(label="Off") {{ $t("view.settings.general.vrcx_updater.auto_update_off") }}
+ el-radio-button(label="Notify") {{ $t("view.settings.general.vrcx_updater.auto_update_notify") }}
+ el-radio-button(label="Auto Download") {{ $t("view.settings.general.vrcx_updater.auto_update_download") }}
+ el-radio-button(label="Auto Install") {{ $t("view.settings.general.vrcx_updater.auto_update_install") }}
div.options-container
- span.header Application
+ span.header {{ $t("view.settings.general.application.header") }}
div.options-container-item
- span.name Start at Windows startup
+ span.name {{ $t("view.settings.general.application.startup") }}
el-switch(v-model="isStartAtWindowsStartup")
div.options-container-item
- span.name Start as minimized state
+ span.name {{ $t("view.settings.general.application.minimized") }}
el-switch(v-model="isStartAsMinimizedState")
div.options-container-item
- span.name Close to tray
+ span.name {{ $t("view.settings.general.application.tray") }}
el-switch(v-model="isCloseToTray")
div.options-container
div.options-container(style="margin-top:45px;border-top:1px solid #eee;padding-top:30px")
- span.header Legal Notice
+ span.header {{ $t("view.settings.general.legal_notice.header" )}}
div.options-container-item
p © 2019-2022 #[a(@click="openExternalLink('https://github.com/pypy-vrc')") pypy] (mina#5656) & #[a(@click="openExternalLink('https://github.com/Natsumi-sama')") Natsumi]
- p VRCX is an assistant application for provide information about manage friendship. this application uses unofficial VRChat API (VRCSDK).
- p VRCX isn't endorsed by VRChat and doesn't reflect the views or opinions of VRChat or anyone officially involved in producing or managing VRChat. VRChat is trademark of VRChat Inc. VRChat © VRChat Inc.
- p pypy or Natsumi aren't responsible for any problems caused by VRCX. Use at your own risk!
+ p {{ $t("view.settings.general.legal_notice.info" )}}
+ p {{ $t("view.settings.general.legal_notice.disclaimer1" )}}
+ p {{ $t("view.settings.general.legal_notice.disclaimer2" )}}
div.options-container-item
- el-button(@click="ossDialog = true" size="small") Open Source Software Notice
- el-tab-pane(label="Appearance")
+ el-button(@click="ossDialog = true" size="small") {{ $t("view.settings.general.legal_notice.open_source_software_notice" )}}
+ el-tab-pane(:label="$t('view.settings.category.appearance')")
div.options-container(style="margin-top:0")
- span.header Appearance
+ span.header {{ $t("view.settings.appearance.appearance.header") }}
div.options-container-item
- span.name Theme mode
+ span.name {{ $t('view.settings.appearance.appearance.theme_mode') }}
el-radio-group(v-model="themeMode" size="mini")
- el-radio-button(label="system") System
- el-radio-button(label="light") Light
- el-radio-button(label="dark") Dark
+ el-radio-button(label="system") {{ $t('view.settings.appearance.appearance.theme_mode_system') }}
+ el-radio-button(label="light") {{ $t('view.settings.appearance.appearance.theme_mode_light') }}
+ el-radio-button(label="dark") {{ $t('view.settings.appearance.appearance.theme_mode_dark') }}
div.options-container-item
- span.name VRCPlus Profile Icons
+ span.name {{ $t('view.settings.appearance.appearance.vrcplus_profile_icons') }}
el-switch(v-model="displayVRCPlusIconsAsAvatar" @change="saveOpenVROption")
div.options-container-item
- span.name Disable Tooltips
+ span.name {{ $t('view.settings.appearance.appearance.disable_tooltips') }}
el-switch(v-model="hideTooltips" @change="saveOpenVROption")
div.options-container-item
- span.name Sort Favorites By
- el-switch(v-model="sortFavorites" inactive-text="name" active-text="date" @change="saveSortFavoritesOption")
+ span.name {{ $t('view.settings.appearance.appearance.sort_favorite_by') }}
+ el-switch(v-model="sortFavorites" :inactive-text="$t('view.settings.appearance.appearance.sort_favorite_by_name')" :active-text="$t('view.settings.appearance.appearance.sort_favorite_by_date')" @change="saveSortFavoritesOption")
div.options-container-item
- span.name Sort Instance Users By
- el-switch(v-model="instanceUsersSortAlphabetical" inactive-text="time" active-text="alphabetical" @change="saveOpenVROption")
+ span.name {{ $t('view.settings.appearance.appearance.sort_instance_users_by') }}
+ el-switch(v-model="instanceUsersSortAlphabetical" :inactive-text="$t('view.settings.appearance.appearance.sort_instance_users_by_time')" :active-text="$t('view.settings.appearance.appearance.sort_instance_users_by_alphabet')" @change="saveOpenVROption")
div.options-container-item
- el-button(size="small" icon="el-icon-notebook-1" @click="promptMaxTableSizeDialog") Table Max Size
+ el-button(size="small" icon="el-icon-notebook-1" @click="promptMaxTableSizeDialog") {{ $t('view.settings.appearance.appearance.table_max_size') }}
div.options-container-item
el-dropdown(@click.native.stop trigger="click" size="small")
el-button(size="mini")
- span Page Size: {{ tablePageSize }} #[i.el-icon-arrow-down.el-icon--right]
+ span {{ $t('view.settings.appearance.appearance.page_size') }} {{ tablePageSize }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(v-for="(number) in [10, 15, 25, 50, 100]" v-text="number" @click.native="setTablePageSize(number)")
div.options-container
- span.header Timedate
+ span.header {{ $t('view.settings.appearance.timedate.header') }}
div.options-container-item
- span.name Time Format
- el-switch(v-model="dtHour12" @change="setDatetimeFormat" inactive-text="24 Hour" active-text="12 Hour")
+ span.name {{ $t('view.settings.appearance.timedate.time_format') }}
+ el-switch(v-model="dtHour12" @change="setDatetimeFormat" :inactive-text="$t('view.settings.appearance.timedate.time_format_24')" :active-text="$t('view.settings.appearance.timedate.time_format_12')")
div.options-container-item
- span.name Force ISO date format
+ span.name {{ $t('view.settings.appearance.timedate.force_iso_date_format') }}
el-switch(v-model="dtIsoFormat" @change="setDatetimeFormat")
div.options-container
- span.header Side Panel
+ span.header {{ $t('view.settings.appearance.side_panel.header') }}
br
- span.sub-header Sorting
+ span.sub-header {{ $t('view.settings.appearance.side_panel.sorting.header') }}
div.options-container-item
- span.name Sort Private to bottom
+ span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_private_to_bottom') }}
el-switch(v-model="orderFriendsGroupPrivate" @change="saveOrderFriendGroup")
div.options-container-item
- span.name Sort by status
+ span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_by_status') }}
el-switch(v-model="orderFriendsGroupStatus" @change="saveOrderFriendGroup")
div.options-container-item
- span.name Sort GPS to top
+ span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_gps_to_top') }}
el-switch(v-model="orderFriendsGroupGPS" @change="saveOrderFriendGroup")
- span.name(style="margin-left:5px") (online for only)
+ span.name(style="margin-left:5px") {{ $t('view.settings.appearance.side_panel.sorting.sort_gps_to_top_notice') }}
div.options-container-item
- span.name VIP
- el-switch(v-model="orderFriendsGroup0" inactive-text="alphabetical" active-text="online for" @change="saveOrderFriendGroup")
+ span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_favorite_by') }}
+ el-switch(v-model="orderFriendsGroup0" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_favorite_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_favorite_by_online_time')" @change="saveOrderFriendGroup")
div.options-container-item
- span.name Online
- el-switch(v-model="orderFriendsGroup1" inactive-text="alphabetical" active-text="online for" @change="saveOrderFriendGroup")
+ span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_online_by') }}
+ el-switch(v-model="orderFriendsGroup1" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_online_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_online_by_online_time')" @change="saveOrderFriendGroup")
div.options-container-item
- span.name Active
- el-switch(v-model="orderFriendsGroup2" inactive-text="alphabetical" active-text="online for" @change="saveOrderFriendGroup")
+ span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_active_by') }}
+ el-switch(v-model="orderFriendsGroup2" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_active_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_active_by_online_time')" @change="saveOrderFriendGroup")
div.options-container-item
- span.name Offline
- el-switch(v-model="orderFriendsGroup3" inactive-text="alphabetical" active-text="online for" @change="saveOrderFriendGroup")
- span.sub-header Width
+ span.name {{ $t('view.settings.appearance.side_panel.sorting.sort_offline_by') }}
+ el-switch(v-model="orderFriendsGroup3" :inactive-text="$t('view.settings.appearance.side_panel.sorting.sort_offline_by_alphabet')" :active-text="$t('view.settings.appearance.side_panel.sorting.sort_offline_by_offline_time')" @change="saveOrderFriendGroup")
+ span.sub-header {{ $t('view.settings.appearance.side_panel.width') }}
div.options-container-item
el-slider(v-model="asideWidth" @input="setAsideWidth" :show-tooltip="false" :marks="{236: ''}" :min="141" :max="500" style="width:300px")
div.options-container
- span.header User Dialog
+ span.header {{ $t('view.settings.appearance.user_dialog.header') }}
div.options-container-item
- span.name Hide VRChat Notes
+ span.name {{ $t('view.settings.appearance.user_dialog.hide_vrchat_notes') }}
el-switch(v-model="hideUserNotes" @change="saveUserDialogOption")
div.options-container-item
- span.name Hide VRCX Memos
+ span.name {{ $t('view.settings.appearance.user_dialog.hide_vrcx_memos') }}
el-switch(v-model="hideUserMemos" @change="saveUserDialogOption")
div.options-container-item
- span.name Export VRCX memos into VRChat notes
+ span.name {{ $t('view.settings.appearance.user_dialog.export_vrcx_memos_into_vrchat_notes') }}
br
- el-button(size="small" icon="el-icon-document-copy" @click="showNoteExportDialog") Export Notes
+ el-button(size="small" icon="el-icon-document-copy" @click="showNoteExportDialog") {{ $t('view.settings.appearance.user_dialog.export_notes') }}
div.options-container
- span.header User Colours
+ span.header {{ $t('view.settings.appearance.user_colors.header') }}
div.options-container-item
- span.name Random colours from user ID
+ span.name {{ $t('view.settings.appearance.user_colors.random_colors_from_user_id') }}
el-switch(v-model="randomUserColours" @change="updatetrustColor")
div.options-container-item
div
@@ -1223,288 +1223,288 @@ html
div
el-color-picker(v-model="trustColor.troll" @change="updatetrustColor" size="mini" :predefine="['#782f2f']")
span.color-picker(slot="trigger" class="x-tag-troll") Nuisance
- el-tab-pane(label="Notifications")
+ el-tab-pane(:label="$t('view.settings.category.notifications')")
div.options-container(style="margin-top:0")
- span.header Notifications
+ span.header {{ $t('view.settings.notifications.notifications.header') }}
div.options-container-item
- el-button(size="small" icon="el-icon-chat-square" @click="showNotyFeedFiltersDialog") Notification Filters
- span.sub-header SteamVR Notifications
+ el-button(size="small" icon="el-icon-chat-square" @click="showNotyFeedFiltersDialog") {{ $t('view.settings.notifications.notifications.notification_filter') }}
+ span.sub-header {{ $t('view.settings.notifications.notifications.steamvr_notifications.header') }}
div.options-container-item
- span.name SteamVR Overlay
+ span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.steamvr_overlay') }}
el-switch(v-model="openVR" @change="saveOpenVROption")
div.options-container-item
- span.name Overlay Notifications
+ span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.overlay_notifications') }}
el-switch(v-model="overlayNotifications" @change="saveOpenVROption" :disabled="!openVR")
div.options-container-item
- el-button(size="small" icon="el-icon-rank" @click="showNotificationPositionDialog" :disabled="!overlayNotifications || !openVR") Notification Position
+ el-button(size="small" icon="el-icon-rank" @click="showNotificationPositionDialog" :disabled="!overlayNotifications || !openVR") {{ $t('view.settings.notifications.notifications.steamvr_notifications.notification_position') }}
div.options-container-item
- span.name XSOverlay Notifications
+ span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.xsoverlay_notifications') }}
el-switch(v-model="xsNotifications" @change="saveOpenVROption")
div.options-container-item
- span.name User images (slower)
+ span.name {{ $t('view.settings.notifications.notifications.steamvr_notifications.user_images') }}
el-switch(v-model="imageNotifications" @change="saveOpenVROption")
div.options-container-item
- el-button(size="small" icon="el-icon-time" @click="promptNotificationTimeout" :disabled="(!overlayNotifications || !openVR) && !xsNotifications") Notification Timeout
- span.sub-header Desktop Notifications
+ el-button(size="small" icon="el-icon-time" @click="promptNotificationTimeout" :disabled="(!overlayNotifications || !openVR) && !xsNotifications") {{ $t('view.settings.notifications.notifications.steamvr_notifications.notification_timeout') }}
+ span.sub-header {{ $t('view.settings.notifications.notifications.desktop_notifications.header') }}
div.options-container-item
- span.name When to display:
+ span.name {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display') }}
br
el-radio-group(v-model="desktopToast" @change="saveOpenVROption" size="mini")
- el-radio-button(label="Never")
- el-radio-button(label="Desktop Mode")
- el-radio-button(label="Inside VR")
- el-radio-button(label="Outside VR")
- el-radio-button(label="Game Closed")
- el-radio-button(label="Game Running")
- el-radio-button(label="Always")
+ el-radio-button(label="Never") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_never') }}
+ el-radio-button(label="Desktop Mode") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_desktop') }}
+ el-radio-button(label="Inside VR") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_inside_vr') }}
+ el-radio-button(label="Outside VR") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_outside_vr') }}
+ el-radio-button(label="Game Closed") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_game_closed') }}
+ el-radio-button(label="Game Running") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_game_running') }}
+ el-radio-button(label="Always") {{ $t('view.settings.notifications.notifications.desktop_notifications.when_to_display_always') }}
br
- span.sub-header Text-To-Speech Options
+ span.sub-header {{ $t('view.settings.notifications.notifications.text_to_speech.header') }}
div.options-container-item
- span.name Notification TTS, When to play:
+ span.name {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play') }}
br
el-radio-group(v-model="notificationTTS" @change="saveNotificationTTS" size="mini")
- el-radio-button(label="Never")
- el-radio-button(label="Inside VR")
- el-radio-button(label="Game Closed")
- el-radio-button(label="Game Running")
- el-radio-button(label="Always")
+ el-radio-button(label="Never") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_never') }}
+ el-radio-button(label="Inside VR") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_inside_vr') }}
+ el-radio-button(label="Game Closed") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_game_closed') }}
+ el-radio-button(label="Game Running") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_game_running') }}
+ el-radio-button(label="Always") {{ $t('view.settings.notifications.notifications.text_to_speech.when_to_play_always') }}
div.options-container-item
- span.name TTS Voice
+ span.name {{ $t('view.settings.notifications.notifications.text_to_speech.tts_voice') }}
el-dropdown(@command="(voice) => changeTTSVoice(voice)" trigger="click" size="small")
el-button(size="mini" :disabled="notificationTTS === 'Never'")
span {{ getTTSVoiceName() }} #[i.el-icon-arrow-down.el-icon--right]
el-dropdown-menu(#default="dropdown")
el-dropdown-item(v-if="voice" v-for="(voice, index) in TTSvoices" :key="index" v-text="voice.name" :command="index")
- el-tab-pane(label="Wrist Overlay")
+ el-tab-pane(:label="$t('view.settings.category.wrist_overlay')")
div.options-container(style="margin-top:0")
- span.header SteamVR Wrist Overlay
+ span.header {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.header') }}
div.options-container-item
- span * It runs automatically when VRChat is running.
+ span {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.description') }}
br
br
- span Grip: Vive or Other Controllers Grab, Oculus X/A Buttons
+ span {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.grip') }}
br
- span Menu: Vive Menu, Index B, Oculus Y/B Buttons
+ span {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.menu') }}
br
div.options-container-item
- span.name SteamVR Overlay
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.steamvr_overlay') }}
el-switch(v-model="openVR" @change="saveOpenVROption")
div.options-container-item
- span.name Wrist Feed Overlay
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_overlay') }}
el-switch(v-model="overlayWrist" @change="saveOpenVROption" :disabled="!openVR")
div.options-container-item
- span.name Hide Private Worlds
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_private_worlds') }}
el-switch(v-model="hidePrivateFromFeed" @change="saveOpenVROption")
div.options-container-item(style="min-width:118px")
- span.name Start Overlay With
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.start_overlay_with') }}
el-switch(v-model="openVRAlways" @change="saveOpenVROption" inactive-text="VRChat" active-text="SteamVR" :disabled="!openVR")
div.options-container-item
- span.name Overlay Button
- el-switch(v-model="overlaybutton" @change="saveOpenVROption" inactive-text="Grip" active-text="Menu" :disabled="!openVR || !overlayWrist")
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button') }}
+ el-switch(v-model="overlaybutton" @change="saveOpenVROption" :inactive-text="$t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button_grip')" :active-text="$t('view.settings.wrist_overlay.steamvr_wrist_overlay.overlay_button_menu')" :disabled="!openVR || !overlayWrist")
div.options-container-item
- span.name Display Overlay On
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on') }}
el-radio-group(v-model="overlayHand" @change="saveOpenVROption" size="mini")
- el-radio-button(label="1") Left Hand
- el-radio-button(label="2") Right Hand
- el-radio-button(label="0") Both Hands
+ el-radio-button(label="1") {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_left') }}
+ el-radio-button(label="2") {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_right') }}
+ el-radio-button(label="0") {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.display_overlay_on_both') }}
div.options-container-item
- span.name Background Colour
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.background_color') }}
el-switch(v-model="vrBackgroundEnabled" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
div.options-container-item
- span.name Minimal Feed Icons
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.minimal_feed_icons') }}
el-switch(v-model="minimalFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
div.options-container-item
- span.name Hide VR Devices
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_vr_devices') }}
el-switch(v-model="hideDevicesFromFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
div.options-container-item
- span.name Hide CPU Usage
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_cpu_usage') }}
el-switch(v-model="hideCpuUsageFromFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
div.options-container-item
- span.name Hide Game Uptime
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.hide_game_uptime') }}
el-switch(v-model="hideUptimeFromFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
div.options-container-item
- span.name Show PC Uptime
+ span.name {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.show_pc_uptime') }}
el-switch(v-model="pcUptimeOnFeed" @change="saveOpenVROption" :disabled="!openVR || !overlayWrist")
div.options-container-item
- el-button(size="small" icon="el-icon-notebook-2" @click="showWristFeedFiltersDialog" :disabled="!openVR || !overlayWrist") Wrist Feed Filters
- el-tab-pane(label="Discord Presence")
+ el-button(size="small" icon="el-icon-notebook-2" @click="showWristFeedFiltersDialog" :disabled="!openVR || !overlayWrist") {{ $t('view.settings.wrist_overlay.steamvr_wrist_overlay.wrist_feed_filters') }}
+ el-tab-pane(:label="$t('view.settings.category.discord_presence')")
div.options-container(style="margin-top:0")
- span.header Discord Presence
+ span.header {{ $t('view.settings.discord_presence.discord_presence.header') }}
div.options-container-item
- span * Only works when VRChat is running.
+ span {{ $t('view.settings.discord_presence.discord_presence.description') }}
div.options-container-item
- span.name Enable
- el-tooltip(placement="top" style="margin-left:5px" content="Recommended to disable Rich Presence in VRChat config.json to stop it from conflicting")
+ span.name {{ $t('view.settings.discord_presence.discord_presence.enable') }}
+ el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.discord_presence.discord_presence.enable_tooltip')")
i.el-icon-warning(style="cursor:pointer" @click="showVRChatConfig")
el-switch(v-model="discordActive" @change="saveDiscordOption")
div.options-container-item
- span.name Instance type/player count
+ span.name {{ $t('view.settings.discord_presence.discord_presence.instance_type_player_count') }}
el-switch(v-model="discordInstance" @change="saveDiscordOption" :disabled="!discordActive")
div.options-container-item
- span.name Join button (public only)
+ span.name {{ $t('view.settings.discord_presence.discord_presence.join_button') }}
el-switch(v-model="discordJoinButton" @change="saveDiscordOption" :disabled="!discordActive")
div.options-container-item
- span.name Hide world details in private
+ span.name {{ $t('view.settings.discord_presence.discord_presence.hide_details_in_private') }}
el-switch(v-model="discordHideInvite" @change="saveDiscordOption" :disabled="!discordActive")
div.options-container-item
- span.name Hide world images
+ span.name {{ $t('view.settings.discord_presence.discord_presence.hide_images') }}
el-switch(v-model="discordHideImage" @change="saveDiscordOption" :disabled="!discordActive")
- el-tab-pane(label="Advanced")
+ el-tab-pane(:label="$t('view.settings.category.advanced')")
div.options-container(style="margin-top:0")
- span.header Advanced
+ span.header {{ $t('view.settings.advanced.advanced.header') }}
div.options-container-item
el-button-group
el-button(size="small" icon="el-icon-s-operation" @click="showVRChatConfig()") VRChat config.json
- el-button(size="small" icon="el-icon-s-operation" @click="showLaunchOptions()") Launch Options
+ el-button(size="small" icon="el-icon-s-operation" @click="showLaunchOptions()") {{ $t('view.settings.advanced.advanced.launch_options') }}
div.options-container
- span.sub-header Pending Offline
+ span.sub-header {{ $t('view.settings.advanced.advanced.pending_offline.header') }}
div.options-container-item
- span.name Delay before marking user as offline (fixes false positives)
+ span.name {{ $t('view.settings.advanced.advanced.pending_offline.description') }}
el-button-group(style="display:block")
- el-button(size="small" icon="el-icon-s-operation" @click="promptSetPendingOffline") Set Delay
- span.sub-header Primary password
+ el-button(size="small" icon="el-icon-s-operation" @click="promptSetPendingOffline") {{ $t('view.settings.advanced.advanced.pending_offline.set_delay') }}
+ span.sub-header {{ $t('view.settings.advanced.advanced.primary_password.header') }}
div.options-container-item
- span.name(style="min-width:300px") Encrypt password (disables auto login)
+ span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.primary_password.description') }}
el-switch(v-model="enablePrimaryPassword" @change="enablePrimaryPasswordChange" :disabled="!loginForm.savedCredentials[API.currentUser.username]")
- span.sub-header VRChat Quit Fix
+ span.sub-header {{ $t('view.settings.advanced.advanced.vrchat_quit_fix.header') }}
div.options-container-item
- span.name(style="min-width:300px") Kill VRChat after exiting game
+ span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.vrchat_quit_fix.description') }}
el-switch(v-model="vrcQuitFix" @change="saveOpenVROption")
- span.sub-header Automatically Manage Cache When Closing VRChat
+ span.sub-header {{ $t('view.settings.advanced.advanced.auto_cache_management.header') }}
div.options-container-item
- span.name(style="min-width:300px") Auto delete old versions from cache
+ span.name(style="min-width:300px") {{ $t('view.settings.advanced.advanced.auto_cache_management.description') }}
el-switch(v-model="autoSweepVRChatCache" @change="saveOpenVROption")
div.options-container
- span.header Remote Avatar Database
+ span.header {{ $t('view.settings.advanced.advanced.remote_database.header') }}
div.options-container-item
- span.name Enable
+ span.name {{ $t('view.settings.advanced.advanced.remote_database.enable') }}
el-switch(v-model="avatarRemoteDatabase" @change="saveOpenVROption")
div.options-container-item
- el-button(size="small" icon="el-icon-user-solid" @click="showAvatarProviderDialog") Avatar Database Provider
+ el-button(size="small" icon="el-icon-user-solid" @click="showAvatarProviderDialog") {{ $t('view.settings.advanced.advanced.remote_database.avatar_database_provider') }}
div.options-container
- span.header YouTube API
+ span.header {{ $t('view.settings.advanced.advanced.youtube_api.header') }}
div.options-container-item
- span.name Enabled
+ span.name {{ $t('view.settings.advanced.advanced.youtube_api.enable') }}
el-switch(v-model="youTubeApi" @change="changeYouTubeApi")
div.options-container-item
- el-button(size="small" icon="el-icon-caret-right" @click="showYouTubeApiDialog") YouTube API Key
- span.header Progress pie overlay for videos
+ el-button(size="small" icon="el-icon-caret-right" @click="showYouTubeApiDialog") {{ $t('view.settings.advanced.advanced.youtube_api.youtube_api_key') }}
+ span.header {{ $t('view.settings.advanced.advanced.video_progress_pie.header') }}
div.options-container-item
- span.name Enable
- el-tooltip(placement="top" style="margin-left:5px" content="Requires SteamVR overlay to be enabled")
+ span.name {{ $t('view.settings.advanced.advanced.video_progress_pie.enable') }}
+ el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.advanced.video_progress_pie.enable_tooltip')")
i.el-icon-warning
el-switch(v-model="progressPie" @change="changeYouTubeApi" :disabled="!openVR")
div.options-container-item
- span.name Dance worlds only
+ span.name {{ $t('view.settings.advanced.advanced.video_progress_pie.dance_world_only') }}
el-switch(v-model="progressPieFilter" @change="changeYouTubeApi" :disabled="!openVR")
div.options-container(v-if="photonLoggingEnabled")
- span.header Photon Logging Overlay
+ span.header {{ $t('view.settings.advanced.photon.header') }}
div.options-container-item
- span.sub-header Photon Event HUD
+ span.sub-header {{ $t('view.settings.advanced.photon.event_hud.header') }}
div.options-container-item
- span.name Enable
- el-tooltip(placement="top" style="margin-left:5px" content="Requires SteamVR overlay to be enabled")
+ span.name {{ $t('view.settings.advanced.photon.event_hud.enable') }}
+ el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.photon.event_hud.enable_tooltip')")
i.el-icon-warning
el-switch(v-model="photonEventOverlay" @change="saveEventOverlay" :disabled="!openVR")
div.options-container-item
- span.name Filter
+ span.name {{ $t('view.settings.advanced.photon.event_hud.filter') }}
el-radio-group(v-model="photonEventOverlayFilter" @change="saveEventOverlay" size="mini" :disabled="!openVR || !photonEventOverlay")
- el-radio-button(label="VIP")
- el-radio-button(label="Friends")
- el-radio-button(label="Everyone")
+ el-radio-button(label="VIP") {{ $t('view.settings.advanced.photon.event_hud.filter_favorites') }}
+ el-radio-button(label="Friends") {{ $t('view.settings.advanced.photon.event_hud.filter_friends') }}
+ el-radio-button(label="Everyone") {{ $t('view.settings.advanced.photon.event_hud.filter_everyone') }}
div.options-container-item
- el-button(size="small" icon="el-icon-time" @click="promptPhotonOverlayMessageTimeout" :disabled="!openVR") Message Timeout
+ el-button(size="small" icon="el-icon-time" @click="promptPhotonOverlayMessageTimeout" :disabled="!openVR") {{ $t('view.settings.advanced.photon.event_hud.message_timeout') }}
div.options-container-item
el-select(v-model="photonEventTableTypeOverlayFilter" @change="photonEventTableFilterChange" multiple clearable collapse-tags style="flex:1" placeholder="Filter")
el-option(v-once v-for="type in photonEventTableTypeFilterList" :key="type" :label="type" :value="type")
br
- span.sub-header User timeout HUD
+ span.sub-header {{ $t('view.settings.advanced.photon.timeout_hud.header') }}
div.options-container-item
- span.name Enable
- el-tooltip(placement="top" style="margin-left:5px" content="Requires SteamVR overlay to be enabled")
+ span.name {{ $t('view.settings.advanced.photon.timeout_hud.enable') }}
+ el-tooltip(placement="top" style="margin-left:5px" :content="$t('view.settings.advanced.photon.timeout_hud.enable_tooltip')")
i.el-icon-warning
el-switch(v-model="timeoutHudOverlay" @change="saveEventOverlay" :disabled="!openVR")
div.options-container-item
- span.name Filter
+ span.name {{ $t('view.settings.advanced.photon.timeout_hud.filter') }}
el-radio-group(v-model="timeoutHudOverlayFilter" @change="saveEventOverlay" size="mini" :disabled="!openVR || !timeoutHudOverlay")
- el-radio-button(label="VIP")
- el-radio-button(label="Friends")
- el-radio-button(label="Everyone")
+ el-radio-button(label="VIP") {{ $t('view.settings.advanced.photon.timeout_hud.filter_favorites') }}
+ el-radio-button(label="Friends") {{ $t('view.settings.advanced.photon.timeout_hud.filter_friends') }}
+ el-radio-button(label="Everyone") {{ $t('view.settings.advanced.photon.timeout_hud.filter_everyone') }}
div.options-container-item
- el-button(size="small" icon="el-icon-time" @click="promptPhotonLobbyTimeoutThreshold" :disabled="!openVR") Timeout Threshold
+ el-button(size="small" icon="el-icon-time" @click="promptPhotonLobbyTimeoutThreshold" :disabled="!openVR") {{ $t('view.settings.advanced.photon.timeout_hud.timeout_threshold') }}
div.options-container
- span.header VRCX Instance Cache/Debug
+ span.header {{ $t('view.settings.advanced.advanced.cache_debug.header') }}
div.options-container-item
- span.name Disable GameLog
+ span.name {{ $t('view.settings.advanced.advanced.cache_debug.disable_gamelog') }}
el-switch(v-model="gameLogDisabled" @change="disableGameLogDialog")
- span.name(style="margin-left:15px") (will likely break things)
+ span.name(style="margin-left:15px") {{ $t('view.settings.advanced.advanced.cache_debug.disable_gamelog_notice') }}
div.options-container-item
- span.name User cache: #[span(v-text="API.cachedUsers.size")]
+ span.name {{ $t('view.settings.advanced.advanced.cache_debug.user_cache') }} #[span(v-text="API.cachedUsers.size")]
div.options-container-item
- span.name World cache: #[span(v-text="API.cachedWorlds.size")]
+ span.name {{ $t('view.settings.advanced.advanced.cache_debug.world_cache') }} #[span(v-text="API.cachedWorlds.size")]
div.options-container-item
- span.name Avatar cache: #[span(v-text="API.cachedAvatars.size")]
+ span.name {{ $t('view.settings.advanced.advanced.cache_debug.avatar_cache') }} #[span(v-text="API.cachedAvatars.size")]
div.options-container-item
- span.name Avatar Name cache: #[span(v-text="API.cachedAvatarNames.size")]
+ span.name {{ $t('view.settings.advanced.advanced.cache_debug.avatar_name_cache') }} #[span(v-text="API.cachedAvatarNames.size")]
div.options-container-item
- el-button(size="small" icon="el-icon-delete-solid" @click="clearVRCXCache") Clear Cache
- el-button(size="small" icon="el-icon-time" @click="promptAutoClearVRCXCacheFrequency") Auto Clear Cache
+ el-button(size="small" icon="el-icon-delete-solid" @click="clearVRCXCache") {{ $t('view.settings.advanced.advanced.cache_debug.clear_cache') }}
+ el-button(size="small" icon="el-icon-time" @click="promptAutoClearVRCXCacheFrequency") {{ $t('view.settings.advanced.advanced.cache_debug.auto_clear_cache') }}
div.options-container-item
- el-button(size="small" icon="el-icon-download" @click="showDownloadDialog") Download History
- el-button(size="small" icon="el-icon-tickets" @click="showConsole") Show Console
+ el-button(size="small" icon="el-icon-download" @click="showDownloadDialog") {{ $t('view.settings.advanced.advanced.cache_debug.download_history') }}
+ el-button(size="small" icon="el-icon-tickets" @click="showConsole") {{ $t('view.settings.advanced.advanced.cache_debug.show_console') }}
div.options-container
- span.sub-header SQLite Table Size
+ span.sub-header {{ $t('view.settings.advanced.advanced.sqlite_table_size.header') }}
div.options-container-item
- el-button(size="small" icon="el-icon-refresh" @click="getSqliteTableSizes") Refresh
+ el-button(size="small" icon="el-icon-refresh" @click="getSqliteTableSizes") {{ $t('view.settings.advanced.advanced.sqlite_table_size.refresh') }}
div.options-container-item
- span.name GPS: #[span(v-text="sqliteTableSizes.gps")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.gps') }} #[span(v-text="sqliteTableSizes.gps")]
div.options-container-item
- span.name Status: #[span(v-text="sqliteTableSizes.status")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.status') }} #[span(v-text="sqliteTableSizes.status")]
div.options-container-item
- span.name Bio: #[span(v-text="sqliteTableSizes.bio")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.bio') }} #[span(v-text="sqliteTableSizes.bio")]
div.options-container-item
- span.name Avatar: #[span(v-text="sqliteTableSizes.avatar")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.avatar') }} #[span(v-text="sqliteTableSizes.avatar")]
div.options-container-item
- span.name Online/Offline: #[span(v-text="sqliteTableSizes.onlineOffline")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.online_offline') }} #[span(v-text="sqliteTableSizes.onlineOffline")]
div.options-container-item
- span.name Friend Log History: #[span(v-text="sqliteTableSizes.friendLogHistory")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.friend_log_history') }} #[span(v-text="sqliteTableSizes.friendLogHistory")]
div.options-container-item
- span.name Notifications: #[span(v-text="sqliteTableSizes.notification")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.notification') }} #[span(v-text="sqliteTableSizes.notification")]
div.options-container-item
- span.name Location: #[span(v-text="sqliteTableSizes.location")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.location') }} #[span(v-text="sqliteTableSizes.location")]
div.options-container-item
- span.name Join/Leave: #[span(v-text="sqliteTableSizes.joinLeave")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.join_leave') }} #[span(v-text="sqliteTableSizes.joinLeave")]
div.options-container-item
- span.name Portal Spawn: #[span(v-text="sqliteTableSizes.portalSpawn")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.portal_spawn') }} #[span(v-text="sqliteTableSizes.portalSpawn")]
div.options-container-item
- span.name Video Play: #[span(v-text="sqliteTableSizes.videoPlay")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.video_play') }} #[span(v-text="sqliteTableSizes.videoPlay")]
div.options-container-item
- span.name Event: #[span(v-text="sqliteTableSizes.event")]
+ span.name {{ $t('view.settings.advanced.advanced.sqlite_table_size.event') }} #[span(v-text="sqliteTableSizes.event")]
//- friends
- .x-aside-container(v-show="$refs.menu && $refs.menu.activeIndex !== 'friendsList'" id="aside")
+ .x-aside-container(v-show="$refs.menu && $refs.menu.activeIndex !== 'friendsList'" id="aside")
div(style="display:flex;align-items:baseline")
- el-select(v-model="quickSearch" clearable placeholder="Search" filterable remote :remote-method="quickSearchRemoteMethod" popper-class="x-quick-search" @change="quickSearchChange" @visible-change="quickSearchVisibleChange" style="flex:1;padding:10px")
+ el-select(v-model="quickSearch" clearable :placeholder="$t('side_panel.search_placeholder')" filterable remote :remote-method="quickSearchRemoteMethod" popper-class="x-quick-search" @change="quickSearchChange" @visible-change="quickSearchVisibleChange" style="flex:1;padding:10px")
el-option(v-for="item in quickSearchItems" :key="item.value" :value="item.value" :label="item.label")
.x-friend-item
template(v-if="item.ref")
.detail
span.name(v-text="item.ref.displayName" :style="{'color':item.ref.$userColour}")
- span.extra(v-if="item.ref.state === 'offline'") Offline
- span.extra(v-else-if="item.ref.state === 'active'") Active
+ span.extra(v-if="item.ref.state === 'offline'") {{ $t('side_panel.search_result_offline') }}
+ span.extra(v-else-if="item.ref.state === 'active'") {{ $t('side_panel.search_result_active') }}
location.extra(v-else :location="item.ref.location" :traveling="item.ref.travelingToLocation" :link="false")
img.avatar(v-lazy="userImage(item.ref)")
- span(v-else) Search More: #[span(v-text="item.label" style="font-weight:bold")]
- el-tooltip(placement="bottom" content="Direct access ID/URL from clipboard" :disabled="hideTooltips")
+ span(v-else) {{ $t('side_panel.search_result_more') }} #[span(v-text="item.label" style="font-weight:bold")]
+ el-tooltip(placement="bottom" :content="$t('side_panel.direct_access_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="directAccessPaste" size="mini" icon="el-icon-discover" circle)
- el-tooltip(placement="bottom" content="Refresh friends" :disabled="hideTooltips")
+ el-tooltip(placement="bottom" :content="$t('side_panel.refresh_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="API.closeWebSocket(); API.getCurrentUser(); API.refreshFriends()" :loading="API.isRefreshFriendsLoading" size="mini" icon="el-icon-refresh" circle style="margin-right:10px")
.x-friend-list(style="padding-bottom:10px")
.x-friend-group(style="padding:5px 0 0")
- span FRIENDS―{{ onlineFriendCount }}/{{ friends.size }}
+ span {{ $t('side_panel.friends') }} ― {{ onlineFriendCount }}/{{ friends.size }}
.x-friend-group(style="padding:10px 0 5px")
i.el-icon-arrow-right(:class="{ rotate: isFriendsGroupMe }")
- span.x-link(@click="isFriendsGroupMe = !isFriendsGroupMe" style="margin-left:5px") ME
+ span.x-link(@click="isFriendsGroupMe = !isFriendsGroupMe" style="margin-left:5px") {{ $t('side_panel.me') }}
div(v-show="isFriendsGroupMe")
.x-friend-item(:key="API.currentUser.id" @click="showUserDialog(API.currentUser.id)")
.avatar(:class="userStatusClass(API.currentUser)")
@@ -1515,7 +1515,7 @@ html
span.extra(v-else v-text="API.currentUser.statusDescription" :link="false")
.x-friend-group(v-show="friendsGroup0.length")
i.el-icon-arrow-right(:class="{ rotate: isFriendsGroup0 }")
- span.x-link(@click="isFriendsGroup0 = !isFriendsGroup0" style="margin-left:5px") VIP―{{ friendsGroup0.length }}
+ span.x-link(@click="isFriendsGroup0 = !isFriendsGroup0" style="margin-left:5px") {{ $t('side_panel.favorite') }} ― {{ friendsGroup0.length }}
div(v-show="isFriendsGroup0")
.x-friend-item(v-for="friend in friendsGroup0" :key="friend.id" @click="showUserDialog(friend.id)")
template(v-if="friend.ref")
@@ -1524,14 +1524,14 @@ html
.detail
span.name(v-if="!hideUserMemos && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
- span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] Pending Offline
+ span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.penfing_offline') }}
location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false")
template(v-else)
span(v-text="friend.name || friend.id")
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
.x-friend-group(v-show="friendsGroup1.length")
i.el-icon-arrow-right(:class="{ rotate: isFriendsGroup1 }")
- span.x-link(@click="isFriendsGroup1 = !isFriendsGroup1" style="margin-left:5px") ONLINE―{{ friendsGroup1.length }}
+ span.x-link(@click="isFriendsGroup1 = !isFriendsGroup1" style="margin-left:5px") {{ $t('side_panel.online') }} ― {{ friendsGroup1.length }}
div(v-show="isFriendsGroup1")
.x-friend-item(v-for="friend in friendsGroup1" :key="friend.id" @click="showUserDialog(friend.id)")
template(v-if="friend.ref")
@@ -1540,14 +1540,14 @@ html
.detail
span.name(v-if="!hideUserMemos && friend.$nickName" :style="{'color':friend.ref.$userColour}") {{ friend.ref.displayName }} ({{ friend.$nickName }})
span.name(v-else v-text="friend.ref.displayName" :style="{'color':friend.ref.$userColour}")
- span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] Pending Offline
+ span.extra(v-if="friend.pendingOffline") #[i.el-icon-warning-outline] {{ $t('side_panel.penfing_offline') }}
location.extra(v-else :location="friend.ref.location" :traveling="friend.ref.travelingToLocation" :link="false")
template(v-else)
span(v-text="friend.name || friend.id")
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
.x-friend-group(v-show="friendsGroup2.length")
i.el-icon-arrow-right(:class="{ rotate: isFriendsGroup2 }")
- span.x-link(@click="isFriendsGroup2 = !isFriendsGroup2" style="margin-left:5px") ACTIVE―{{ friendsGroup2.length }}
+ span.x-link(@click="isFriendsGroup2 = !isFriendsGroup2" style="margin-left:5px") {{ $t('side_panel.active') }} ― {{ friendsGroup2.length }}
div(v-show="isFriendsGroup2")
.x-friend-item(v-for="friend in friendsGroup2" :key="friend.id" @click="showUserDialog(friend.id)")
template(v-if="friend.ref")
@@ -1562,7 +1562,7 @@ html
el-button(type="text" icon="el-icon-close" size="mini" @click.stop="confirmDeleteFriend(friend.id)" style="margin-left:5px")
.x-friend-group(v-show="friendsGroup3.length")
i.el-icon-arrow-right(:class="{ rotate: isFriendsGroup3 }")
- span.x-link(@click="isFriendsGroup3 = !isFriendsGroup3" style="margin-left:5px") OFFLINE―{{ friendsGroup3.length }}
+ span.x-link(@click="isFriendsGroup3 = !isFriendsGroup3" style="margin-left:5px") {{ $t('side_panel.offline') }} ― {{ friendsGroup3.length }}
div(v-show="isFriendsGroup3")
.x-friend-item(v-for="friend in friendsGroup3" :key="friend.id" @click="showUserDialog(friend.id)")
template(v-if="friend.ref")
@@ -1591,18 +1591,18 @@ html
div
el-tooltip(v-if="userDialog.ref.status" placement="top")
template(#content)
- span(v-if="userDialog.ref.state === 'active'") Active
- span(v-else-if="userDialog.ref.location === 'offline'") Offline
- span(v-else-if="userDialog.ref.status === 'active'") Online
- span(v-else-if="userDialog.ref.status === 'join me'") Join Me
- span(v-else-if="userDialog.ref.status === 'ask me'") Ask Me
- span(v-else-if="userDialog.ref.status === 'busy'") Do Not Disturb
- span(v-else) Offline
+ span(v-if="userDialog.ref.state === 'active'") {{ $t('dialog.user.status.active') }}
+ span(v-else-if="userDialog.ref.location === 'offline'") {{ $t('dialog.user.status.offline') }}
+ span(v-else-if="userDialog.ref.status === 'active'") {{ $t('dialog.user.status.online') }}
+ span(v-else-if="userDialog.ref.status === 'join me'") {{ $t('dialog.user.status.join_me') }}
+ span(v-else-if="userDialog.ref.status === 'ask me'") {{ $t('dialog.user.status.ask_me') }}
+ span(v-else-if="userDialog.ref.status === 'busy'") {{ $t('dialog.user.status.busy') }}
+ span(v-else) {{ $t('dialog.user.status.offline') }}
i.x-user-status(:class="userStatusClass(userDialog.ref)")
template(v-if="userDialog.previousDisplayNames.length > 0")
el-tooltip(placement="bottom")
template(#content)
- span Previous Display Names:
+ span {{ $t('dialog.user.previous_display_names') }}
div(v-for="displayName in userDialog.previousDisplayNames" placement="top")
span(v-text="displayName")
i.el-icon-caret-bottom
@@ -1617,9 +1617,9 @@ html
span.flags(:class="languageClass(item.key)" style="display:inline-block;margin-right:5px")
div
el-tag.name(type="info" effect="plain" size="mini" :class="userDialog.ref.$trustClass" v-text="userDialog.ref.$trustLevel" style="margin-right:5px;margin-top:5px")
- el-tag.x-tag-friend(v-if="userDialog.isFriend && userDialog.friend" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Friend No.{{userDialog.friend.no}}
+ el-tag.x-tag-friend(v-if="userDialog.isFriend && userDialog.friend" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.user.tags.friend_no', { number: userDialog.friend.no }) }}
el-tag.x-tag-troll(v-if="userDialog.ref.$isTroll" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Nuisance
- el-tag.x-tag-vip(v-if="userDialog.ref.$isModerator" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") VRChat Team
+ el-tag.x-tag-vip(v-if="userDialog.ref.$isModerator" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.user.tags.vrchat_team') }}
el-tag.x-tag-vrcplus(v-if="userDialog.ref.$isVRCPlus" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") VRC+
el-tag.x-tag-platform-pc(v-if="userDialog.ref.last_platform === 'standalonewindows'" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") PC
el-tag.x-tag-platform-quest(v-else-if="userDialog.ref.last_platform === 'android'" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Quest
@@ -1631,62 +1631,62 @@ html
img.x-link(v-lazy="userDialog.ref.userIcon" style="height:500px" @click="downloadAndSaveImage(userDialog.ref.userIcon)")
div(style="flex:none")
template(v-if="API.currentUser.id !== userDialog.ref.id")
- el-tooltip(v-if="userDialog.isFavorite" placement="top" content="Remove from favorites" :disabled="hideTooltips")
+ el-tooltip(v-if="userDialog.isFavorite" placement="top" :content="$t('dialog.user.actions.unfavorite_tooltip')" :disabled="hideTooltips")
el-button(@click="userDialogCommand('Delete Favorite')" type="warning" icon="el-icon-star-on" circle)
- el-tooltip(v-else placement="top" content="Add to favorites" :disabled="hideTooltips")
+ el-tooltip(v-else placement="top" :content="$t('dialog.user.actions.favorite_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="userDialogCommand('Add Favorite')" icon="el-icon-star-off" circle)
el-dropdown(trigger="click" @command="userDialogCommand" size="small")
el-button(:type="(userDialog.incomingRequest || userDialog.outgoingRequest || userDialog.isShowAvatar) ? 'success' : (userDialog.isBlock || userDialog.isMute || userDialog.isHideAvatar) ? 'danger' : 'default'" icon="el-icon-more" circle style="margin-left:5px")
el-dropdown-menu(#default="dropdown")
- el-dropdown-item(icon="el-icon-refresh" command="Refresh") Refresh
- el-dropdown-item(icon="el-icon-s-order" command="Copy User") Copy User URL
+ el-dropdown-item(icon="el-icon-refresh" command="Refresh") {{ $t('dialog.user.actions.refresh') }}
+ el-dropdown-item(icon="el-icon-s-order" command="Copy User") {{ $t('dialog.user.actions.copy_url') }}
template(v-if="userDialog.ref.id === API.currentUser.id")
- el-dropdown-item(icon="el-icon-picture-outline" command="Manage Gallery" divided) Manage Gallery/Icons
- el-dropdown-item(icon="el-icon-s-custom" command="Show Avatar Author") Show Avatar Author
- el-dropdown-item(icon="el-icon-s-custom" command="Show Fallback Avatar Details") Show Fallback Avatar Details
- el-dropdown-item(icon="el-icon-edit" command="Edit Social Status" divided) Social Status
- el-dropdown-item(icon="el-icon-edit" command="Edit Language") Language
- el-dropdown-item(icon="el-icon-edit" command="Edit Bio") Bio
- el-dropdown-item(icon="el-icon-switch-button" command="Logout" divided) Logout
+ el-dropdown-item(icon="el-icon-picture-outline" command="Manage Gallery" divided) {{ $t('dialog.user.actions.manage_gallery_icon') }}
+ el-dropdown-item(icon="el-icon-s-custom" command="Show Avatar Author") {{ $t('dialog.user.actions.show_avatar_author') }}
+ el-dropdown-item(icon="el-icon-s-custom" command="Show Fallback Avatar Details") {{ $t('dialog.user.actions.show_fallback_avatar') }}
+ el-dropdown-item(icon="el-icon-edit" command="Edit Social Status" divided) {{ $t('dialog.user.actions.edit_status') }}
+ el-dropdown-item(icon="el-icon-edit" command="Edit Language") {{ $t('dialog.user.actions.edit_language') }}
+ el-dropdown-item(icon="el-icon-edit" command="Edit Bio") {{ $t('dialog.user.actions.edit_bio') }}
+ el-dropdown-item(icon="el-icon-switch-button" command="Logout" divided) {{ $t('dialog.user.actions.logout') }}
template(v-else)
template(v-if="userDialog.isFriend")
- el-dropdown-item(icon="el-icon-postcard" command="Request Invite" divided) Request Invite
- el-dropdown-item(icon="el-icon-postcard" command="Request Invite Message") Request Invite With Message
+ el-dropdown-item(icon="el-icon-postcard" command="Request Invite" divided) {{ $t('dialog.user.actions.request_invite') }}
+ el-dropdown-item(icon="el-icon-postcard" command="Request Invite Message") {{ $t('dialog.user.actions.request_invite_with_message') }}
template(v-if="lastLocation.location && isGameRunning && checkCanInvite(lastLocation.location)")
- el-dropdown-item(icon="el-icon-message" command="Invite") Invite
- el-dropdown-item(icon="el-icon-message" command="Invite Message") Invite With Message
+ el-dropdown-item(icon="el-icon-message" command="Invite") {{ $t('dialog.user.actions.invite') }}
+ el-dropdown-item(icon="el-icon-message" command="Invite Message") {{ $t('dialog.user.actions.invite_with_message') }}
template(v-else-if="userDialog.incomingRequest")
- el-dropdown-item(icon="el-icon-check" command="Accept Friend Request") Accept Friend Request
- el-dropdown-item(icon="el-icon-close" command="Decline Friend Request") Decline Friend Request
- el-dropdown-item(v-else-if="userDialog.outgoingRequest" icon="el-icon-close" command="Cancel Friend Request") Cancel Friend Request
- el-dropdown-item(v-else icon="el-icon-plus" command="Send Friend Request") Send Friend Request
- el-dropdown-item(icon="el-icon-message" command="Invite To Group") Invite To Group
- el-dropdown-item(icon="el-icon-s-custom" command="Show Avatar Author" divided) Show Avatar Author
- el-dropdown-item(icon="el-icon-s-custom" command="Show Fallback Avatar Details") Show Fallback Avatar Details
- el-dropdown-item(icon="el-icon-tickets" command="Previous Instances") Show Previous Instances
- el-dropdown-item(v-if="userDialog.ref.currentAvatarImageUrl" icon="el-icon-picture-outline" command="Previous Images") Show Avatar Previous Images
- el-dropdown-item(v-if="userDialog.isBlock" icon="el-icon-circle-check" command="Unblock" divided style="color:#F56C6C") Unblock
- el-dropdown-item(v-else icon="el-icon-circle-close" command="Block" divided :disabled="userDialog.ref.$isModerator") Block
- el-dropdown-item(v-if="userDialog.isMute" icon="el-icon-microphone" command="Unmute" style="color:#F56C6C") Unmute
- el-dropdown-item(v-else icon="el-icon-turn-off-microphone" command="Mute" :disabled="userDialog.ref.$isModerator") Mute
- el-dropdown-item(icon="el-icon-user-solid" command="Show Avatar") #[i.el-icon-check.el-icon--left(v-if="userDialog.isShowAvatar")]Show Avatar
- el-dropdown-item(icon="el-icon-user" command="Hide Avatar") #[i.el-icon-check.el-icon--left(v-if="userDialog.isHideAvatar")]Hide Avatar
- el-dropdown-item(v-if="userDialog.isInteractOff" icon="el-icon-thumb" command="Enable Avatar Interaction" style="color:#F56C6C") Enable Avatar Interaction
- el-dropdown-item(v-else icon="el-icon-circle-close" command="Disable Avatar Interaction") Disable Avatar Interaction
+ el-dropdown-item(icon="el-icon-check" command="Accept Friend Request") {{ $t('dialog.user.actions.accept_friend_request') }}
+ el-dropdown-item(icon="el-icon-close" command="Decline Friend Request") {{ $t('dialog.user.actions.decline_friend_request') }}
+ el-dropdown-item(v-else-if="userDialog.outgoingRequest" icon="el-icon-close" command="Cancel Friend Request") {{ $t('dialog.user.actions.cancel_friend_request') }}
+ el-dropdown-item(v-else icon="el-icon-plus" command="Send Friend Request") {{ $t('dialog.user.actions.send_friend_request') }}
+ el-dropdown-item(icon="el-icon-message" command="Invite To Group") {{ $t('dialog.user.actions.invite_to_group') }}
+ el-dropdown-item(icon="el-icon-s-custom" command="Show Avatar Author" divided) {{ $t('dialog.user.actions.show_avatar_author') }}
+ el-dropdown-item(icon="el-icon-s-custom" command="Show Fallback Avatar Details") {{ $t('dialog.user.actions.show_fallback_avatar') }}
+ el-dropdown-item(icon="el-icon-tickets" command="Previous Instances") {{ $t('dialog.user.actions.show_previous_instances') }}
+ el-dropdown-item(v-if="userDialog.ref.currentAvatarImageUrl" icon="el-icon-picture-outline" command="Previous Images") {{ $t('dialog.user.actions.show_previous_images') }}
+ el-dropdown-item(v-if="userDialog.isBlock" icon="el-icon-circle-check" command="Unblock" divided style="color:#F56C6C") {{ $t('dialog.user.actions.moderation_unblock') }}
+ el-dropdown-item(v-else icon="el-icon-circle-close" command="Block" divided :disabled="userDialog.ref.$isModerator") {{ $t('dialog.user.actions.moderation_block') }}
+ el-dropdown-item(v-if="userDialog.isMute" icon="el-icon-microphone" command="Unmute" style="color:#F56C6C") {{ $t('dialog.user.actions.moderation_unmute') }}
+ el-dropdown-item(v-else icon="el-icon-turn-off-microphone" command="Mute" :disabled="userDialog.ref.$isModerator") {{ $t('dialog.user.actions.moderation_mute') }}
+ el-dropdown-item(icon="el-icon-user-solid" command="Show Avatar") #[i.el-icon-check.el-icon--left(v-if="userDialog.isShowAvatar")] {{ $t('dialog.user.actions.moderation_show_avatar') }}
+ el-dropdown-item(icon="el-icon-user" command="Hide Avatar") #[i.el-icon-check.el-icon--left(v-if="userDialog.isHideAvatar")] {{ $t('dialog.user.actions.moderation_hide_avatar') }}
+ el-dropdown-item(v-if="userDialog.isInteractOff" icon="el-icon-thumb" command="Enable Avatar Interaction" style="color:#F56C6C") {{ $t('dialog.user.actions.moderation_enable_avatar_interaction') }}
+ el-dropdown-item(v-else icon="el-icon-circle-close" command="Disable Avatar Interaction") {{ $t('dialog.user.actions.moderation_disable_avatar_interaction') }}
template(v-if="userDialog.isFriend")
- el-dropdown-item(icon="el-icon-delete" command="Unfriend" divided style="color:#F56C6C") Unfriend
+ el-dropdown-item(icon="el-icon-delete" command="Unfriend" divided style="color:#F56C6C") {{ $t('dialog.user.actions.unfriend') }}
el-tabs(ref="userDialogTabs" @tab-click="userDialogTabClick")
- el-tab-pane(label="Info")
+ el-tab-pane(:label="$t('dialog.user.info.header')")
template(v-if="isFriendOnline(userDialog.friend) || API.currentUser.id === userDialog.id")
div(v-if="userDialog.ref.location" style="display:flex;flex-direction:column;margin-bottom:10px;padding-bottom:10px;border-bottom:1px solid #e4e7ed14")
div(style="flex:none")
location(:location="userDialog.ref.location" :traveling="userDialog.ref.travelingToLocation")
template(v-if="isRealInstance(userDialog.$location.tag)")
- el-tooltip(placement="top" content="Launch/Invite" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.user.info.launch_invite_tooltip')" :disabled="hideTooltips")
launch(:location="userDialog.$location.tag" style="margin-left:5px")
- el-tooltip(placement="top" content="Invite yourself" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.user.info.self_invite_tooltip')" :disabled="hideTooltips")
invite-yourself(:location="userDialog.$location.tag" :shortname="userDialog.$location.shortName" style="margin-left:5px")
- el-tooltip(placement="top" content="Refresh player count" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.user.info.refresh_user_count_tooltip')" :disabled="hideTooltips")
el-button(v-if="userDialog.$location.tag !== lastLocation.location" @click="refreshInstancePlayerCount(userDialog.$location.tag)" size="mini" icon="el-icon-refresh" style="margin-left:5px" circle)
span(v-if="userDialog.instance.occupants" style="margin-left:5px") {{ userDialog.instance.occupants }} #[template(v-if="userDialog.instance.friendCount > 0") ({{ userDialog.instance.friendCount }})]
.x-friend-list(style="flex:1;margin-top:10px;max-height:150px")
@@ -1696,7 +1696,7 @@ html
img(v-lazy="userImage(userDialog.$location.user)")
.detail
span.name(v-text="userDialog.$location.user.displayName" :style="{'color':userDialog.$location.user.$userColour}")
- span.extra Instance Creator
+ span.extra {{ $t('dialog.user.info.instance_creator') }}
span(v-else v-text="userDialog.$location.userId")
.x-friend-item(v-for="user in userDialog.users" :key="user.id" @click="showUserDialog(user.id)" class="x-friend-item-border")
.avatar(:class="userStatusClass(user)")
@@ -1711,25 +1711,25 @@ html
.x-friend-list(style="max-height:none")
.x-friend-item(v-if="!hideUserNotes" style="width:100%;cursor:default")
.detail
- span.name Note
- el-input(v-model="userDialog.note" type="textarea" maxlength="256" show-word-limit :rows="2" :autosize="{ minRows: 1, maxRows: 20 }" @change="checkNote(userDialog.ref, userDialog.note)" @input="cleanNote(userDialog.note)" placeholder="Click to add a note" size="mini" resize="none")
+ span.name {{ $t('dialog.user.info.note') }}
+ el-input(v-model="userDialog.note" type="textarea" maxlength="256" show-word-limit :rows="2" :autosize="{ minRows: 1, maxRows: 20 }" @change="checkNote(userDialog.ref, userDialog.note)" @input="cleanNote(userDialog.note)" :placeholder="$t('dialog.user.info.note_placeholder')" size="mini" resize="none")
div(style="float:right")
i.el-icon-loading(v-if="userDialog.noteSaving" style="margin-left:5px")
i.el-icon-more-outline(v-else-if="userDialog.note !== userDialog.ref.note" style="margin-left:5px")
el-button(v-if="userDialog.note" type="text" icon="el-icon-delete" size="mini" @click="deleteNote(userDialog.id)" style="margin-left:5px")
.x-friend-item(v-if="!hideUserMemos" style="width:100%;cursor:default")
.detail
- span.name Memo
- el-input.extra(v-model="userDialog.memo" type="textarea" :rows="2" :autosize="{ minRows: 1, maxRows: 20 }" placeholder="Click to add a memo" size="mini" resize="none")
+ span.name {{ $t('dialog.user.info.memo') }}
+ el-input.extra(v-model="userDialog.memo" type="textarea" :rows="2" :autosize="{ minRows: 1, maxRows: 20 }" :placeholder="$t('dialog.user.info.memo_placeholder')" size="mini" resize="none")
.x-friend-item(style="width:100%;cursor:default")
.detail
- span.name(v-if="userDialog.id !== API.currentUser.id && userDialog.ref.profilePicOverride && userDialog.ref.currentAvatarImageUrl") Avatar Info Last Seen
- span.name(v-else) Avatar Info
+ span.name(v-if="userDialog.id !== API.currentUser.id && userDialog.ref.profilePicOverride && userDialog.ref.currentAvatarImageUrl") {{ $t('dialog.user.info.avatar_info_last_seen') }}
+ span.name(v-else) {{ $t('dialog.user.info.avatar_info') }}
.extra
avatar-info(:imageurl="userDialog.ref.currentAvatarImageUrl" :userid="userDialog.id")
.x-friend-item(style="width:100%;cursor:default")
.detail
- span.name Represented Group
+ span.name {{ $t('dialog.user.info.represented_group') }}
.extra(v-if="userDialog.representedGroup.isRepresenting")
div(style="display:inline-block;flex:none;margin-right:5px")
el-popover(placement="right" width="500px" trigger="click")
@@ -1742,7 +1742,7 @@ html
.extra(v-else) -
.x-friend-item(style="width:100%;cursor:default")
.detail
- span.name Bio
+ span.name {{ $t('dialog.user.info.bio') }}
pre.extra(style="font-family:inherit;font-size:12px;white-space:pre-wrap;margin:0 0.5em 0 0") {{ userDialog.ref.bio || '-' }}
div(v-if="userDialog.id === API.currentUser.id" style="float:right")
el-button(type="text" icon="el-icon-edit" size="mini" @click="showBioDialog" style="margin-left:5px")
@@ -1754,21 +1754,21 @@ html
template(v-if="API.currentUser.id !== userDialog.id")
.x-friend-item(style="cursor:default")
.detail
- span.name Last Seen
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name {{ $t('dialog.user.info.last_seen') }}
+ el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.user.info.accuracy_notice')")
i.el-icon-warning
span.extra {{ userDialog.lastSeen | formatDate('long') }}
.x-friend-item(@click="showPreviousInstancesUserDialog(userDialog.ref)")
.detail
- span.name Join Count
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name {{ $t('dialog.user.info.join_count') }}
+ el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.user.info.accuracy_notice')")
i.el-icon-warning
span.extra(v-if="userDialog.joinCount === 0") -
span.extra(v-else v-text="userDialog.joinCount")
.x-friend-item(style="cursor:default")
.detail
- span.name Time Together
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name {{ $t('dialog.user.info.time_together') }}
+ el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.user.info.accuracy_notice')")
i.el-icon-warning
span.extra(v-if="userDialog.timeSpent === 0") -
span.extra(v-else) {{ userDialog.timeSpent | timeToText }}
@@ -1777,57 +1777,57 @@ html
template(#content)
span {{ userOnlineForTimestamp(userDialog) | formatDate('short') }}
.detail
- span.name(v-if="userDialog.ref.state === 'online' && userDialog.ref.$online_for") Online For
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name(v-if="userDialog.ref.state === 'online' && userDialog.ref.$online_for") {{ $t('dialog.user.info.online_for') }}
+ el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.user.info.accuracy_notice')")
i.el-icon-warning
- span.name(v-else) Offline For
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name(v-else) {{ $t('dialog.user.info.offline_for') }}
+ el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.user.info.accuracy_notice')")
i.el-icon-warning
span.extra {{ userOnlineFor(userDialog) | timeToText }}
.x-friend-item(style="cursor:default")
el-tooltip(placement="top")
template(#content)
- span Last Login {{ userDialog.ref.last_login | formatDate('short') }}
+ span {{ $t('dialog.user.info.last_login') }} {{ userDialog.ref.last_login | formatDate('short') }}
.detail
- span.name Last Activity
+ span.name {{ $t('dialog.user.info.last_activity') }}
span.extra {{ userDialog.ref.last_activity | formatDate('long') }}
.x-friend-item(style="cursor:default")
.detail
- span.name Date Joined
+ span.name {{ $t('dialog.user.info.date_joined') }}
span.extra(v-text="userDialog.ref.date_joined")
.x-friend-item(v-if="API.currentUser.id !== userDialog.id" style="cursor:default")
.detail
- span.name(v-if="userDialog.unFriended") Unfriended
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name(v-if="userDialog.unFriended") {{ $t('dialog.user.info.unfriended') }}
+ el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.user.info.accuracy_notice')")
i.el-icon-warning
- span.name(v-else) Friended
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name(v-else) {{ $t('dialog.user.info.friended') }}
+ el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.user.info.accuracy_notice')")
i.el-icon-warning
span.extra {{ userDialog.dateFriended | formatDate('long') }}
template(v-if="API.currentUser.id === userDialog.id")
.x-friend-item(@click="toggleAvatarCopying")
.detail
- span.name Avatar Cloning
- span.extra(v-if="userDialog.ref.allowAvatarCopying" style="color:#67C23A") Allow
- span.extra(v-else style="color:#F56C6C") Deny
+ span.name {{ $t('dialog.user.info.avatar_cloning') }}
+ span.extra(v-if="userDialog.ref.allowAvatarCopying" style="color:#67C23A") {{ $t('dialog.user.info.avatar_cloning_allow') }}
+ span.extra(v-else style="color:#F56C6C") {{ $t('dialog.user.info.avatar_cloning_deny') }}
template(v-else)
.x-friend-item(style="cursor:default")
.detail
- span.name Avatar Cloning
- span.extra(v-if="userDialog.ref.allowAvatarCopying" style="color:#67C23A") Allow
- span.extra(v-else style="color:#F56C6C") Deny
+ span.name {{ $t('dialog.user.info.avatar_cloning') }}
+ span.extra(v-if="userDialog.ref.allowAvatarCopying" style="color:#67C23A") {{ $t('dialog.user.info.avatar_cloning_allow') }}
+ span.extra(v-else style="color:#F56C6C") {{ $t('dialog.user.info.avatar_cloning_deny') }}
.x-friend-item(v-if="userDialog.ref.id === API.currentUser.id && API.currentUser.homeLocation" @click="showWorldDialog(API.currentUser.homeLocation)" style="width:100%")
.detail
- span.name Home Location
+ span.name {{ $t('dialog.user.info.home_location') }}
span.extra
span(v-text="userDialog.$homeLocationName")
el-button(@click.stop="resetHome()" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
- el-tab-pane(label="Groups")
+ el-tab-pane(:label="$t('dialog.user.groups.header')")
el-button(type="default" :loading="userDialog.isGroupsLoading" @click="getUserGroups(userDialog.id)" size="mini" icon="el-icon-refresh" circle)
- span(style="margin-left:5px") Total {{ userGroups.groups.length }}
+ span(style="margin-left:5px") {{ $t('dialog.user.groups.total_count', { count: userGroups.groups.length }) }}
div(v-loading="userDialog.isGroupsLoading" style="margin-top:10px")
template(v-if="userGroups.ownGroups.length > 0")
- span(style="font-weight:bold;font-size:16px") Own Groups
+ span(style="font-weight:bold;font-size:16px") {{ $t('dialog.user.groups.own_groups') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ userGroups.ownGroups.length }}
.x-friend-list(style="margin-top:10px;margin-bottom:15px;min-height:60px")
.x-friend-item(v-for="group in userGroups.ownGroups" :key="group.id" @click="showGroupDialog(group.id)" class="x-friend-item-border")
@@ -1837,7 +1837,7 @@ html
span.name(v-text="group.name")
span.extra ({{ group.memberCount }})
template(v-if="userGroups.mutualGroups.length > 0")
- span(style="font-weight:bold;font-size:16px") Mutual Groups
+ span(style="font-weight:bold;font-size:16px") {{ $t('dialog.user.groups.mutual_groups') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ userGroups.mutualGroups.length }}
.x-friend-list(style="margin-top:10px;margin-bottom:15px;min-height:60px")
.x-friend-item(v-for="group in userGroups.mutualGroups" :key="group.id" @click="showGroupDialog(group.id)" class="x-friend-item-border")
@@ -1847,7 +1847,7 @@ html
span.name(v-text="group.name")
span.extra ({{ group.memberCount }})
template(v-if="userGroups.remainingGroups.length > 0")
- span(style="font-weight:bold;font-size:16px") Groups
+ span(style="font-weight:bold;font-size:16px") {{ $t('dialog.user.groups.groups') }}
span(style="color:#909399;font-size:12px;margin-left:5px") {{ userGroups.remainingGroups.length }}
.x-friend-list(style="margin-top:10px;margin-bottom:15px;min-height:60px")
.x-friend-item(v-for="group in userGroups.remainingGroups" :key="group.id" @click="showGroupDialog(group.id)" class="x-friend-item-border")
@@ -1856,12 +1856,12 @@ html
.detail
span.name(v-text="group.name")
span.extra ({{ group.memberCount }})
- el-tab-pane(label="Worlds")
+ el-tab-pane(:label="$t('dialog.user.worlds.header')")
el-button(type="default" :loading="userDialog.isWorldsLoading" @click="refreshUserDialogWorlds()" size="mini" icon="el-icon-refresh" circle)
- span(style="margin-left:5px") Total {{ userDialog.worlds.length }}
+ span(style="margin-left:5px") {{ $t('dialog.user.worlds.total_count', { count: userDialog.worlds.length }) }}
el-radio-group(v-model="userDialog.worldSorting" size="mini" style="margin-left:30px" @change="changeUserDialogWorldSorting")
- el-radio(label="name") by name
- el-radio(label="update") by update
+ el-radio(label="name") {{ $t('dialog.user.worlds.sort_by_name') }}
+ el-radio(label="update") {{ $t('dialog.user.worlds.sort_by_update') }}
.x-friend-list(v-loading="userDialog.isWorldsLoading" style="margin-top:10px;min-height:60px")
.x-friend-item(v-for="world in userDialog.worlds" :key="world.id" @click="showWorldDialog(world.id)" class="x-friend-item-border")
.avatar
@@ -1869,7 +1869,7 @@ html
.detail
span.name(v-text="world.name")
span.extra(v-if="world.occupants") ({{ world.occupants }})
- el-tab-pane(label="Favorite Worlds")
+ el-tab-pane(:label="$t('dialog.user.favorite_worlds.header')")
el-button(type="default" :loading="userDialog.isFavoriteWorldsLoading" @click="getUserFavoriteWorlds(userDialog.id)" size="mini" icon="el-icon-refresh" circle)
el-tabs(type="card" v-loading="userDialog.isFavoriteWorldsLoading" style="margin-top:10px")
template(v-for="(list, index) in userFavoriteWorlds" v-if="list")
@@ -1885,17 +1885,17 @@ html
.detail
span.name(v-text="world.name")
span.extra(v-if="world.occupants") ({{ world.occupants }})
- el-tab-pane(label="Avatars")
+ el-tab-pane(:label="$t('dialog.user.avatars.header')")
template(v-if="userDialog.ref.id === API.currentUser.id")
el-button(type="default" :loading="userDialog.isAvatarsLoading" @click="refreshUserDialogAvatars()" size="mini" icon="el-icon-refresh" circle)
- span(style="margin-left:5px") Total {{ userDialogAvatars.length }}
+ span(style="margin-left:5px") {{ $t('dialog.user.avatars.total_count', { count: userDialogAvatars.length }) }}
el-radio-group(v-if="userDialog.ref.id === API.currentUser.id" v-model="userDialog.avatarSorting" size="mini" style="margin-left:30px;margin-right:30px" @change="changeUserDialogAvatarSorting")
- el-radio(label="name") by name
- el-radio(label="update") by update
+ el-radio(label="name") {{ $t('dialog.user.avatars.sort_by_name') }}
+ el-radio(label="update") {{ $t('dialog.user.avatars.sort_by_update') }}
el-radio-group(v-if="userDialog.ref.id === API.currentUser.id" v-model="userDialog.avatarReleaseStatus" size="mini" style="margin-left:30px")
- el-radio(label="all") all
- el-radio(label="public") public
- el-radio(label="private") private
+ el-radio(label="all") {{ $t('dialog.user.avatars.all') }}
+ el-radio(label="public") {{ $t('dialog.user.avatars.public') }}
+ el-radio(label="private") {{ $t('dialog.user.avatars.private') }}
.x-friend-list(style="margin-top:10px;min-height:60px")
.x-friend-item(v-for="avatar in userDialogAvatars" @click="showAvatarDialog(avatar.id)" class="x-friend-item-border")
.avatar
@@ -1905,7 +1905,7 @@ html
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)
- el-tab-pane(label="JSON")
+ el-tab-pane(:label="$t('dialog.user.json.header')")
el-button(type="default" @click="refreshUserDialogTreeData()" size="mini" icon="el-icon-refresh" circle)
el-tree(:data="userDialog.treeData" style="margin-top:5px;font-size:12px")
template(#default="scope")
@@ -1928,57 +1928,57 @@ html
div(style="margin-top:5px")
span.x-link(v-text="worldDialog.ref.authorName" @click="showUserDialog(worldDialog.ref.authorId)" style="color:#909399;font-family:monospace")
div
- el-tag(v-if="worldDialog.ref.$isLabs" type="primary" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Labs
- el-tag(v-else-if="worldDialog.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Public
- el-tag(v-else type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Private
+ el-tag(v-if="worldDialog.ref.$isLabs" type="primary" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.world.tags.labs') }}
+ el-tag(v-else-if="worldDialog.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.world.tags.public') }}
+ el-tag(v-else type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.world.tags.private') }}
el-tag.x-tag-platform-pc(v-if="worldDialog.isPC" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") PC
el-tag.x-tag-platform-quest(v-if="worldDialog.isQuest" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Quest
el-tag(type="info" effect="plain" size="mini" v-text="worldDialog.fileSize" style="margin-right:5px;margin-top:5px")
el-tag(v-if="worldDialog.inCache" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px")
span(v-text="worldDialog.cacheSize")
- | Cache
+ | {{ $t('dialog.world.tags.cache')}}
div(style="margin-top:5px")
span(v-show="worldDialog.ref.name !== worldDialog.ref.description" v-text="worldDialog.ref.description" style="font-size:12px")
div(style="flex:none;margin-left:10px")
- el-tooltip(v-if="worldDialog.inCache" placement="top" content="Delete world from cache" :disabled="hideTooltips")
+ el-tooltip(v-if="worldDialog.inCache" placement="top" :content="$t('dialog.world.actions.delete_cache_tooltip')" :disabled="hideTooltips")
el-button(icon="el-icon-delete" circle @click="deleteVRChatCache(worldDialog.ref)" :disabled="isGameRunning && worldDialog.cacheLocked")
- el-tooltip(v-if="worldDialog.isFavorite" placement="top" content="Favorite/Unfavorite" :disabled="hideTooltips")
+ el-tooltip(v-if="worldDialog.isFavorite" placement="top" :content="$t('dialog.world.actions.unfavorite_tooltip')" :disabled="hideTooltips")
el-button(type="default" icon="el-icon-star-on" circle @click="worldDialogCommand('Add Favorite')" style="margin-left:5px")
- el-tooltip(v-else placement="top" content="Favorite/Unfavorite" :disabled="hideTooltips")
+ el-tooltip(v-else placement="top" :content="$t('dialog.world.actions.favorite_tooltip')" :disabled="hideTooltips")
el-button(type="default" icon="el-icon-star-off" circle @click="worldDialogCommand('Add Favorite')" style="margin-left:5px")
el-dropdown(trigger="click" @command="worldDialogCommand" size="small" style="margin-left:5px")
el-button(type="default" icon="el-icon-more" circle)
el-dropdown-menu(#default="dropdown")
- el-dropdown-item(icon="el-icon-refresh" command="Refresh") Refresh
- el-dropdown-item(icon="el-icon-s-flag" command="New Instance" divided) New Instance
- el-dropdown-item(v-if="API.currentUser.$homeLocation && API.currentUser.$homeLocation.worldId === worldDialog.id" icon="el-icon-magic-stick" command="Reset Home" divided) Reset Home
- el-dropdown-item(v-else icon="el-icon-s-home" command="Make Home" divided) Make Home
- el-dropdown-item(icon="el-icon-tickets" command="Previous Instances") Show Previous Instances
+ el-dropdown-item(icon="el-icon-refresh" command="Refresh") {{ $t('dialog.world.actions.refresh') }}
+ el-dropdown-item(icon="el-icon-s-flag" command="New Instance" divided) {{ $t('dialog.world.actions.new_instance') }}
+ el-dropdown-item(v-if="API.currentUser.$homeLocation && API.currentUser.$homeLocation.worldId === worldDialog.id" icon="el-icon-magic-stick" command="Reset Home" divided) {{ $t('dialog.world.actions.reset_home') }}
+ el-dropdown-item(v-else icon="el-icon-s-home" command="Make Home" divided) {{ $t('dialog.world.actions.make_home') }}
+ el-dropdown-item(icon="el-icon-tickets" command="Previous Instances") {{ $t('dialog.world.actions.show_previous_instances') }}
template(v-if="API.currentUser.id !== worldDialog.ref.authorId")
- el-dropdown-item(icon="el-icon-picture-outline" command="Previous Images") Show Previous Images
+ el-dropdown-item(icon="el-icon-picture-outline" command="Previous Images") {{ $t('dialog.world.actions.show_previous_images') }}
template(v-else)
- el-dropdown-item(icon="el-icon-edit" command="Rename") Rename
- el-dropdown-item(icon="el-icon-edit" command="Change Description") Change Description
- el-dropdown-item(icon="el-icon-edit" command="Change Capacity") Change Capacity
- el-dropdown-item(icon="el-icon-edit" command="Change YouTube Preview") Change YouTube Preview
- el-dropdown-item(icon="el-icon-edit" command="Change Tags") Change Tags
- el-dropdown-item(icon="el-icon-picture-outline" command="Change Image") Change Image
- el-dropdown-item(v-if="worldDialog.ref.unityPackageUrl" icon="el-icon-download" command="Download Unity Package") Download Unity Package
- el-dropdown-item(v-if="worldDialog.ref.tags.includes('system_approved') || worldDialog.ref.tags.includes('system_labs')" icon="el-icon-view" command="Unpublish" divided) Unpublish
- el-dropdown-item(v-else icon="el-icon-view" command="Publish" divided) Publish To Labs
- el-dropdown-item(icon="el-icon-delete" command="Delete" style="color:#F56C6C") Delete
+ el-dropdown-item(icon="el-icon-edit" command="Rename") {{ $t('dialog.world.actions.rename') }}
+ el-dropdown-item(icon="el-icon-edit" command="Change Description") {{ $t('dialog.world.actions.change_description') }}
+ el-dropdown-item(icon="el-icon-edit" command="Change Capacity") {{ $t('dialog.world.actions.change_capacity') }}
+ el-dropdown-item(icon="el-icon-edit" command="Change YouTube Preview") {{ $t('dialog.world.actions.change_preview') }}
+ el-dropdown-item(icon="el-icon-edit" command="Change Tags") {{ $t('dialog.world.actions.change_tags') }}
+ el-dropdown-item(icon="el-icon-picture-outline" command="Change Image") {{ $t('dialog.world.actions.change_image') }}
+ el-dropdown-item(v-if="worldDialog.ref.unityPackageUrl" icon="el-icon-download" command="Download Unity Package") {{ $t('dialog.world.actions.download_package') }}
+ el-dropdown-item(v-if="worldDialog.ref.tags.includes('system_approved') || worldDialog.ref.tags.includes('system_labs')" icon="el-icon-view" command="Unpublish" divided) {{ $t('dialog.world.actions.unpublish') }}
+ el-dropdown-item(v-else icon="el-icon-view" command="Publish" divided) {{ $t('dialog.world.actions.publish_to_labs') }}
+ el-dropdown-item(icon="el-icon-delete" command="Delete" style="color:#F56C6C") {{ $t('dialog.world.actions.delete') }}
el-tabs
- el-tab-pane(label="Instances")
+ el-tab-pane(:label="$t('dialog.world.instances.header')")
div.
- #[i.el-icon-user] Public {{ worldDialog.ref.publicOccupants | commaNumber }}
- #[i.el-icon-user-solid(style="margin-left:10px")] Private {{ worldDialog.ref.privateOccupants | commaNumber }}
- #[i.el-icon-check(style="margin-left:10px")] Capacity {{ worldDialog.ref.capacity | commaNumber }} ({{ worldDialog.ref.capacity * 2 | commaNumber }})
+ #[i.el-icon-user] {{ $t('dialog.world.instances.public_count', { count: worldDialog.ref.publicOccupants }) }}
+ #[i.el-icon-user-solid(style="margin-left:10px")] {{ $t('dialog.world.instances.private_count', { count: worldDialog.ref.privateOccupants }) }}
+ #[i.el-icon-check(style="margin-left:10px")] {{ $t('dialog.world.instances.capacity_count', { count: worldDialog.ref.capacity, max: worldDialog.ref.capacity * 2 }) }}
div(v-for="room in worldDialog.rooms" :key="room.id")
div(style="margin:5px 0")
location-world(:locationobject="room.$location" :currentuserid="API.currentUser.id" :worlddialogshortname="worldDialog.$location.shortName")
- el-tooltip(placement="top" content="Invite yourself" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.world.instances.self_invite_tooltip')" :disabled="hideTooltips")
invite-yourself(:location="room.$location.tag" :shortname="room.$location.shortName" style="margin-left:5px")
- el-tooltip(placement="top" content="Refresh player count" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.world.instances.refresh_user_count_tooltip')" :disabled="hideTooltips")
el-button(v-if="room.$location.tag !== lastLocation.location" @click="refreshInstancePlayerCount(room.$location.tag)" size="mini" icon="el-icon-refresh" style="margin-left:5px" circle)
span(v-if="room.occupants" style="margin-left:5px") {{ room.occupants }} #[template(v-if="room.friendCount > 0") ({{ room.friendCount }})]
.x-friend-list(style="margin:10px 0;max-height:unset" v-if="room.$location.userId || room.users.length")
@@ -1988,7 +1988,7 @@ html
img(v-lazy="userImage(room.$location.user)")
.detail
span.name(v-text="room.$location.user.displayName" :style="{'color':room.$location.user.$userColour}")
- span.extra Instance Creator
+ span.extra {{ $t('dialog.world.instances.instance_creator') }}
span(v-else v-text="room.$location.userId")
.x-friend-item(v-for="user in room.users" :key="user.id" @click="showUserDialog(user.id)" class="x-friend-item-border")
.avatar(:class="userStatusClass(user)")
@@ -2000,84 +2000,84 @@ html
timer(:epoch="user.$travelingToTime")
span.extra(v-else)
timer(:epoch="user.$location_at")
- el-tab-pane(label="Info")
+ el-tab-pane(:label="$t('dialog.world.info.header')")
.x-friend-list(style="max-height:none")
div(style="width:100%;display:flex")
.x-friend-item(style="width:350px;cursor:default")
.detail
- span.name World ID
+ span.name {{ $t('dialog.world.info.id') }}
span.extra {{ worldDialog.id }}
- el-tooltip(placement="top" content="Copy to clipboard" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.world.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="copyWorldId(worldDialog.id)") Copy ID
- el-dropdown-item(@click.native="copyWorldUrl(worldDialog.id)") Copy URL
+ el-dropdown-item(@click.native="copyWorldId(worldDialog.id)") {{ $t('dialog.world.info.copy_id') }}
+ el-dropdown-item(@click.native="copyWorldUrl(worldDialog.id)") {{ $t('dialog.world.info.copy_url') }}
.x-friend-item(v-if="worldDialog.ref.previewYoutubeId" style="width:350px" @click="openExternalLink(`https://www.youtube.com/watch?v=${worldDialog.ref.previewYoutubeId}`)")
.detail
- span.name YouTube Preview
+ span.name {{ $t('dialog.world.info.youtube_preview') }}
span.extra https://www.youtube.com/watch?v={{ worldDialog.ref.previewYoutubeId }}
.x-friend-item(style="cursor:default")
.detail
- span.name Players
+ span.name {{ $t('dialog.world.info.players') }}
span.extra {{ worldDialog.ref.occupants | commaNumber }}
.x-friend-item(style="cursor:default")
.detail
- span.name Favorites
+ span.name {{ $t('dialog.world.info.favorites') }}
span.extra {{ worldDialog.ref.favorites | commaNumber }}
| #[template(v-if="worldDialog.ref.favorites > 0 && worldDialog.ref.visits > 0") ({{ Math.round(((worldDialog.ref.favorites - worldDialog.ref.visits) / worldDialog.ref.visits * 100 + 100) * 100) / 100 }}%)]
.x-friend-item(style="cursor:default")
.detail
- span.name Visits
+ span.name {{ $t('dialog.world.info.visits') }}
span.extra {{ worldDialog.ref.visits | commaNumber }}
.x-friend-item(style="cursor:default")
.detail
- span.name Capacity
+ span.name {{ $t('dialog.world.info.capacity') }}
span.extra {{ worldDialog.ref.capacity | commaNumber }} ({{ worldDialog.ref.capacity * 2 | commaNumber }})
.x-friend-item(style="cursor:default")
.detail
- span.name Heat
+ span.name {{ $t('dialog.world.info.heat') }}
span.extra {{ worldDialog.ref.heat | commaNumber }} {{ '🔥'.repeat(worldDialog.ref.heat) }}
.x-friend-item(style="cursor:default")
.detail
- span.name Popularity
+ span.name {{ $t('dialog.world.info.popularity') }}
span.extra {{ worldDialog.ref.popularity | commaNumber }} {{ '💖'.repeat(worldDialog.ref.popularity) }}
.x-friend-item(style="cursor:default")
.detail
- span.name Created
+ span.name {{ $t('dialog.world.info.created_at') }}
span.extra {{ worldDialog.ref.created_at | formatDate('long') }}
.x-friend-item(style="cursor:default")
.detail
- span.name Last Updated
+ span.name {{ $t('dialog.world.info.last_updated') }}
span.extra {{ worldDialog.fileCreatedAt | formatDate('long') }}
.x-friend-item(style="cursor:default")
.detail
- span.name Version
+ span.name {{ $t('dialog.world.info.version') }}
span.extra(v-text="worldDialog.ref.version")
.x-friend-item(style="width:525px;cursor:default")
.detail
- span.name Platform
+ span.name {{ $t('dialog.world.info.platform') }}
span.extra(v-text="worldDialogPlatform")
.x-friend-item(style="cursor:default")
.detail
- span.name Last Visit
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name {{ $t('dialog.world.info.last_visited') }}
+ el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" :content="$t('dialog.world.info.accuracy_notice')")
i.el-icon-warning
span.extra {{ worldDialog.lastVisit | formatDate('long') }}
.x-friend-item(@click="showPreviousInstancesWorldDialog(worldDialog.ref)")
.detail
- span.name Visit Count
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name {{ $t('dialog.world.info.visit_count') }}
+ 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-text="worldDialog.visitCount")
.x-friend-item(style="cursor:default")
.detail
- span.name Time Spent
- el-tooltip(v-if="!hideTooltips" placement="top" style="margin-left:5px" content="Info from local database may not be accurate")
+ span.name {{ $t('dialog.world.info.time_spent') }}
+ 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="worldDialog.timeSpent === 0") -
span.extra(v-else) {{ worldDialog.timeSpent | timeToText }}
- el-tab-pane(label="JSON")
+ el-tab-pane(:label="$t('dialog.world.json.header')")
el-button(type="default" @click="refreshWorldDialogTreeData()" size="mini" icon="el-icon-refresh" circle)
el-tree(:data="worldDialog.treeData" style="margin-top:5px;font-size:12px")
template(#default="scope")
@@ -2099,71 +2099,71 @@ html
div(style="margin-top:5px")
span.x-link(v-text="avatarDialog.ref.authorName" @click="showUserDialog(avatarDialog.ref.authorId)" style="color:#909399;font-family:monospace")
div(style="margin-top:5px")
- el-tag(v-if="avatarDialog.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini" style="margin-right:5px") Public
- el-tag(v-else type="danger" effect="plain" size="mini" style="margin-right:5px") Private
- el-tag(v-if="avatarDialog.isQuestFallback" type="info" effect="plain" size="mini" style="margin-right:5px") Fallback
+ el-tag(v-if="avatarDialog.ref.releaseStatus === 'public'" type="success" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.avatar.tags.public') }}
+ el-tag(v-else type="danger" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.avatar.tags.private') }}
+ el-tag(v-if="avatarDialog.isQuestFallback" type="info" effect="plain" size="mini" style="margin-right:5px") {{ $t('dialog.avatar.tags.fallback') }}
el-tag(v-if="avatarDialog.fileSize" type="info" effect="plain" size="mini" v-text="avatarDialog.fileSize" style="margin-right:5px")
el-tag(v-if="avatarDialog.inCache" type="info" effect="plain" size="mini")
span(v-text="avatarDialog.cacheSize")
- | Cache
+ | {{ $t('dialog.avatar.tags.cache') }}
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="Delete avatar from cache" :disabled="hideTooltips")
+ 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="Remove from favorites" :disabled="hideTooltips")
+ el-tooltip(v-if="avatarDialog.isFavorite" placement="top" :content="$t('dialog.avatar.actions.unfavorite_tooltip')" :disabled="hideTooltips")
el-button(type="warning" icon="el-icon-star-on" circle @click="avatarDialogCommand('Delete Favorite')" style="margin-left:5px")
- el-tooltip(v-else placement="top" content="Add to favorites" :disabled="hideTooltips")
+ 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 style="margin-left:5px")
el-dropdown-menu(#default="dropdown")
- el-dropdown-item(icon="el-icon-refresh" command="Refresh") Refresh
- el-dropdown-item(icon="el-icon-check" command="Select Avatar") Select Avatar
- el-dropdown-item(v-if="/quest/.test(avatarDialog.ref.tags)" icon="el-icon-check" command="Select Fallback Avatar") Select Fallback Avatar
- el-dropdown-item(v-if="avatarDialog.isBlocked" icon="el-icon-circle-check" command="Unblock Avatar" style="color:#F56C6C") Unblock Avatar
- el-dropdown-item(v-else icon="el-icon-circle-close" command="Block Avatar") Block Avatar
- el-dropdown-item(v-if="avatarDialog.ref.authorId !== API.currentUser.id" icon="el-icon-picture-outline" command="Previous Images") Previous Images
+ el-dropdown-item(icon="el-icon-refresh" command="Refresh") {{ $t('dialog.avatar.actions.refresh') }}
+ el-dropdown-item(icon="el-icon-check" 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) Make Private
- el-dropdown-item(v-else icon="el-icon-user" command="Make Public" divided) Make Public
- el-dropdown-item(icon="el-icon-edit" command="Rename") Rename
- el-dropdown-item(icon="el-icon-edit" command="Change Description") Change Description
- el-dropdown-item(icon="el-icon-picture-outline" command="Change Image") Change Image
- el-dropdown-item(v-if="avatarDialog.ref.unityPackageUrl" icon="el-icon-download" command="Download Unity Package") Download Unity Package
- el-dropdown-item(icon="el-icon-user" command="Delete" style="color:#F56C6C" divided) Delete
+ 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-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(icon="el-icon-user" command="Delete" style="color:#F56C6C" divided) {{ $t('dialog.avatar.actions.delete') }}
el-tabs
- el-tab-pane(label="Info")
+ el-tab-pane(:label="$t('dialog.avatar.info.header')")
.x-friend-list
.x-friend-item(style="width:100%;cursor:default")
.detail
- span.name Avatar ID
+ span.name {{ $t('dialog.avatar.info.id') }}
span.extra {{ avatarDialog.id }}
- el-tooltip(placement="top" content="Copy to clipboard" :disabled="hideTooltips")
+ 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)") Copy ID
- el-dropdown-item(@click.native="copyAvatarUrl(avatarDialog.id)") Copy URL
+ 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 Created
+ span.name {{ $t('dialog.avatar.info.created_at') }}
span.extra {{ avatarDialog.ref.created_at | formatDate('long') }}
.x-friend-item(style="cursor:default")
.detail
- span.name Last Updated
+ span.name {{ $t('dialog.avatar.info.last_updated') }}
span.extra {{ avatarDialog.ref.updated_at | formatDate('long') }}
.x-friend-item(style="cursor:default")
.detail
- span.name Version
+ span.name {{ $t('dialog.avatar.info.version') }}
span.extra(v-if="avatarDialog.ref.version !== 0" v-text="avatarDialog.ref.version")
span.extra(v-else) -
.x-friend-item(style="width:100%;cursor:default")
.detail
- span.name Platform
+ span.name {{ $t('dialog.avatar.info.platform') }}
span.extra(v-if="avatarDialogPlatform" v-text="avatarDialogPlatform")
span.extra(v-else) -
- el-tab-pane(label="JSON")
+ el-tab-pane(:label="$t('dialog.avatar.json.header')")
el-button(type="default" @click="refreshAvatarDialogTreeData()" size="mini" icon="el-icon-refresh" circle)
el-tree(:data="avatarDialog.treeData" style="margin-top:5px;font-size:12px")
template(#default="scope")
@@ -2194,66 +2194,66 @@ html
div(style="margin-top:5px")
span.x-link(v-text="groupDialog.ownerDisplayName" @click="showUserDialog(groupDialog.ref.ownerId)" style="color:#909399;font-family:monospace")
.group-tags
- el-tag(v-if="groupDialog.ref.isVerified" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Verified
+ el-tag(v-if="groupDialog.ref.isVerified" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.verified') }}
- el-tag(v-if="groupDialog.ref.privacy === 'private'" type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Private
- el-tag(v-if="groupDialog.ref.privacy === 'default'" type="success" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Public
+ el-tag(v-if="groupDialog.ref.privacy === 'private'" type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.private') }}
+ el-tag(v-if="groupDialog.ref.privacy === 'default'" type="success" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.public') }}
- el-tag(v-if="groupDialog.ref.joinState === 'open'" type="success" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Open
- el-tag(v-else-if="groupDialog.ref.joinState === 'request'" type="warning" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Request
- el-tag(v-else-if="groupDialog.ref.joinState === 'invite'" type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Invite
- el-tag(v-else-if="groupDialog.ref.joinState === 'closed'" type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Closed
+ el-tag(v-if="groupDialog.ref.joinState === 'open'" type="success" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.open') }}
+ el-tag(v-else-if="groupDialog.ref.joinState === 'request'" type="warning" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.request') }}
+ el-tag(v-else-if="groupDialog.ref.joinState === 'invite'" type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.invite') }}
+ el-tag(v-else-if="groupDialog.ref.joinState === 'closed'" type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.closed') }}
- el-tag(v-if="groupDialog.inGroup" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Joined
- el-tag(v-if="groupDialog.ref.myMember && groupDialog.ref.myMember.bannedAt" type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Banned
+ el-tag(v-if="groupDialog.inGroup" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.joined') }}
+ el-tag(v-if="groupDialog.ref.myMember && groupDialog.ref.myMember.bannedAt" type="danger" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.banned') }}
template(v-if="groupDialog.inGroup && groupDialog.ref.myMember")
- el-tag(v-if="groupDialog.ref.myMember.visibility === 'visible'" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Visible
- el-tag(v-else-if="groupDialog.ref.myMember.visibility === 'friends'" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Friends
- el-tag(v-else-if="groupDialog.ref.myMember.visibility === 'hidden'" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Hidden
- el-tag(v-if="groupDialog.ref.myMember.isSubscribedToAnnouncements" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") Subscribed
+ el-tag(v-if="groupDialog.ref.myMember.visibility === 'visible'" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.visible') }}
+ el-tag(v-else-if="groupDialog.ref.myMember.visibility === 'friends'" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.friends') }}
+ el-tag(v-else-if="groupDialog.ref.myMember.visibility === 'hidden'" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.hidden') }}
+ el-tag(v-if="groupDialog.ref.myMember.isSubscribedToAnnouncements" type="info" effect="plain" size="mini" style="margin-right:5px;margin-top:5px") {{ $t('dialog.group.tags.subscribed') }}
.group-description(style="margin-top:5px")
span(v-show="groupDialog.ref.name !== groupDialog.ref.description" v-text="groupDialog.ref.description" style="font-size:12px")
div(style="flex:none;margin-left:10px")
template(v-if="groupDialog.inGroup")
- el-tooltip(v-if="groupDialog.ref.isRepresenting" placement="top" content="Stop Representing" :disabled="hideTooltips")
+ el-tooltip(v-if="groupDialog.ref.isRepresenting" placement="top" :content="$t('dialog.group.actions.unrepresent_tooltip')" :disabled="hideTooltips")
el-button(type="warning" icon="el-icon-star-on" circle @click="clearGroupRepresentation(groupDialog.id)" style="margin-left:5px")
- el-tooltip(v-else placement="top" content="Set Representing" :disabled="hideTooltips")
+ el-tooltip(v-else placement="top" :content="$t('dialog.group.actions.represent_tooltip')" :disabled="hideTooltips")
span
el-button(type="default" icon="el-icon-star-off" circle @click="setGroupRepresentation(groupDialog.id)" style="margin-left:5px" :disabled="groupDialog.ref.privacy === 'private'")
template(v-else-if="groupDialog.ref.membershipStatus === 'requested'")
- el-tooltip(placement="top" content="Cancel join request" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.group.actions.cancel_join_request_tooltip')" :disabled="hideTooltips")
span
el-button(type="default" icon="el-icon-close" circle @click="cancelGroupRequest(groupDialog.id)" style="margin-left:5px")
template(v-else-if="groupDialog.ref.membershipStatus === 'invited'")
- el-tooltip(placement="top" content="Pending invite" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.group.actions.pending_request_tooltip')" :disabled="hideTooltips")
span
el-button(type="default" icon="el-icon-check" circle @click="joinGroup(groupDialog.id)" style="margin-left:5px")
template(v-else)
- el-tooltip(v-if="groupDialog.ref.joinState === 'request'" placement="top" content="Request to join" :disabled="hideTooltips")
+ el-tooltip(v-if="groupDialog.ref.joinState === 'request'" placement="top" :content="$t('dialog.group.actions.request_join_tooltip')" :disabled="hideTooltips")
el-button(type="default" icon="el-icon-message" circle @click="joinGroup(groupDialog.id)" style="margin-left:5px")
- el-tooltip(v-if="groupDialog.ref.joinState === 'invite'" placement="top" content="Invite required" :disabled="hideTooltips")
+ el-tooltip(v-if="groupDialog.ref.joinState === 'invite'" placement="top" :content="$t('dialog.group.actions.invite_required_tooltip')" :disabled="hideTooltips")
span
el-button(type="default" icon="el-icon-message" disabled circle style="margin-left:5px")
- el-tooltip(v-if="groupDialog.ref.joinState === 'open'" placement="top" content="Join Group" :disabled="hideTooltips")
+ el-tooltip(v-if="groupDialog.ref.joinState === 'open'" placement="top" :content="$t('dialog.group.actions.join_group_tooltip')" :disabled="hideTooltips")
el-button(type="default" icon="el-icon-check" circle @click="joinGroup(groupDialog.id)" style="margin-left:5px")
el-dropdown(trigger="click" @command="groupDialogCommand" size="small" style="margin-left:5px")
el-button(type="default" icon="el-icon-more" circle)
el-dropdown-menu(#default="dropdown")
- el-dropdown-item(icon="el-icon-refresh" command="Refresh") Refresh
+ el-dropdown-item(icon="el-icon-refresh" command="Refresh") {{ $t('dialog.group.actions.refresh') }}
template(v-if="groupDialog.inGroup")
template(v-if="groupDialog.ref.myMember")
- el-dropdown-item(v-if="groupDialog.ref.myMember.isSubscribedToAnnouncements" icon="el-icon-close" command="Unsubscribe To Announcements" divided) Unsubscribe From Announcements
- el-dropdown-item(v-else icon="el-icon-check" command="Subscribe To Announcements" divided) Subscribe To Announcements
- el-dropdown-item(v-if="hasGroupPermission(groupDialog.ref, 'group-invites-manage')" icon="el-icon-message" command="Invite To Group") Invite To Group
+ el-dropdown-item(v-if="groupDialog.ref.myMember.isSubscribedToAnnouncements" icon="el-icon-close" command="Unsubscribe To Announcements" divided) {{ $t('dialog.group.actions.unsubscribe') }}
+ el-dropdown-item(v-else icon="el-icon-check" command="Subscribe To Announcements" divided) {{ $t('dialog.group.actions.subscribe') }}
+ el-dropdown-item(v-if="hasGroupPermission(groupDialog.ref, 'group-invites-manage')" icon="el-icon-message" command="Invite To Group") {{ $t('dialog.group.actions.invite_to_group') }}
template(v-if="groupDialog.ref.myMember && groupDialog.ref.privacy === 'default'")
- el-dropdown-item(icon="el-icon-view" command="Visibility Everyone" divided) #[i.el-icon-check(v-if="groupDialog.ref.myMember.visibility === 'visible'")] Visibility Everyone
- el-dropdown-item(icon="el-icon-view" command="Visibility Friends") #[i.el-icon-check(v-if="groupDialog.ref.myMember.visibility === 'friends'")] Visibility Friends
- el-dropdown-item(icon="el-icon-view" command="Visibility Hidden") #[i.el-icon-check(v-if="groupDialog.ref.myMember.visibility === 'hidden'")] Visibility Hidden
- el-dropdown-item(icon="el-icon-delete" command="Leave Group" style="color:#F56C6C" divided) Leave Group
+ el-dropdown-item(icon="el-icon-view" command="Visibility Everyone" divided) #[i.el-icon-check(v-if="groupDialog.ref.myMember.visibility === 'visible'")] {{ $t('dialog.group.actions.visibility_everyone') }}
+ el-dropdown-item(icon="el-icon-view" command="Visibility Friends") #[i.el-icon-check(v-if="groupDialog.ref.myMember.visibility === 'friends'")] {{ $t('dialog.group.actions.visibility_friends') }}
+ el-dropdown-item(icon="el-icon-view" command="Visibility Hidden") #[i.el-icon-check(v-if="groupDialog.ref.myMember.visibility === 'hidden'")] {{ $t('dialog.group.actions.visibility_hidden') }}
+ el-dropdown-item(icon="el-icon-delete" command="Leave Group" style="color:#F56C6C" divided) {{ $t('dialog.group.actions.leave') }}
el-tabs(ref="groupDialogTabs" @tab-click="groupDialogTabClick")
- el-tab-pane(label="Info")
+ el-tab-pane(:label="$t('dialog.group.info.header')")
.group-banner-image-info
el-popover(placement="right" width="500px" trigger="click")
img.x-link(slot="reference" v-lazy="groupDialog.ref.bannerUrl" style="flex:none;width:100%;aspect-ratio:6/1;object-fit:cover;border-radius:4px")
@@ -2261,7 +2261,7 @@ html
.x-friend-list(style="max-height:none")
.x-friend-item(v-if="groupDialog.ref.membershipStatus === 'member'" style="width:100%;cursor:default")
.detail
- span.name Announcement
+ span.name {{ $t('dialog.group.info.announcement') }}
span(style="display:block" v-text="groupDialog.announcement.title")
div(v-if="groupDialog.announcement.imageUrl" style="display:inline-block;margin-right:5px")
el-popover(placement="right" width="500px" trigger="click")
@@ -2297,19 +2297,19 @@ html
timer(:epoch="user.$location_at")
.x-friend-item(style="width:100%;cursor:default")
.detail
- span.name Rules
+ span.name {{ $t('dialog.group.info.rules') }}
pre.extra(style="font-family:inherit;font-size:12px;white-space:pre-wrap;margin:0 0.5em 0 0") {{ groupDialog.ref.rules || '-' }}
.x-friend-item(style="cursor:default")
.detail
- span.name Members
+ span.name {{ $t('dialog.group.info.members') }}
.extra {{ groupDialog.ref.memberCount }} ({{ groupDialog.ref.onlineMemberCount }})
.x-friend-item(style="cursor:default")
.detail
- span.name Created
+ span.name {{ $t('dialog.group.info.created_at') }}
span.extra {{ groupDialog.ref.createdAt | formatDate('long') }}
.x-friend-item(style="cursor:default")
.detail
- span.name Links
+ span.name {{ $t('dialog.group.info.links') }}
div(v-if="groupDialog.ref.links && groupDialog.ref.links.length > 0" style="margin-top:5px")
el-tooltip(v-if="link" v-for="(link, index) in groupDialog.ref.links" :key="index")
template(#content)
@@ -2318,45 +2318,45 @@ html
.extra(v-else) -
.x-friend-item(style="width:350px;cursor:default")
.detail
- span.name Group URL
+ span.name {{ $t('dialog.group.info.url') }}
span.extra {{ groupDialog.ref.$url }}
- el-tooltip(placement="top" content="Copy URL to clipboard" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.group.info.url_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="copyGroupUrl(groupDialog.ref.$url)" size="mini" icon="el-icon-s-order" circle style="margin-left:5px")
.x-friend-item(style="width:350px;cursor:default")
.detail
- span.name Group ID
+ span.name {{ $t('dialog.group.info.id') }}
span.extra {{ groupDialog.id }}
- el-tooltip(placement="top" content="Copy ID to clipboard" :disabled="hideTooltips")
+ el-tooltip(placement="top" :content="$t('dialog.group.info.id_tooltip')" :disabled="hideTooltips")
el-button(type="default" @click="copyGroupId(groupDialog.id)" size="mini" icon="el-icon-s-order" circle style="margin-left:5px")
div(v-if="groupDialog.ref.membershipStatus === 'member'" style="width:100%;margin-top:10px;border-top:1px solid #e4e7ed14")
div(style="width:100%;display:flex;margin-top:10px")
.x-friend-item(style="cursor:default")
.detail
- span.name Joined At
+ span.name {{ $t('dialog.group.info.joined_at') }}
span.extra {{ groupDialog.ref.myMember.joinedAt | formatDate('long') }}
.x-friend-item(style="cursor:default")
.detail
- span.name Roles
+ span.name {{ $t('dialog.group.info.roles') }}
span.extra(v-if="groupDialog.memberRoles.length === 0") -
span.extra(v-else)
template(v-for="(role, rIndex) in groupDialog.memberRoles" :key="rIndex")
el-tooltip(placement="top")
template(#content)
- span Description: {{ role.description }}
+ span {{ $t('dialog.group.info.role_description') }} {{ role.description }}
br
- span(v-if="role.updatedAt") Updated At: {{ role.updatedAt | formatDate('long') }}
- span(v-else) Created At: {{ role.createdAt | formatDate('long') }}
+ span(v-if="role.updatedAt") {{ $t('dialog.group.info.role_updated_at') }} {{ role.updatedAt | formatDate('long') }}
+ span(v-else) {{ $t('dialog.group.info.role_created_at') }} {{ role.createdAt | formatDate('long') }}
br
- span Permissions:
+ span {{ $t('dialog.group.info.role_permissions') }}
br
template(v-for="(permission, pIndex) in role.permissions" :key="pIndex")
span {{ permission }}
br
span {{ role.name }}{{ rIndex < groupDialog.memberRoles.length - 1 ? ', ' : '' }}
- el-tab-pane(label="Members")
+ el-tab-pane(:label="$t('dialog.group.members.header')")
template(v-if="groupDialog.visible && groupDialog.ref.membershipStatus === 'member'")
- span(v-if="hasGroupPermission(groupDialog.ref, 'group-members-viewall')" style="font-weight:bold;font-size:16px") All Members
- span(v-else style="font-weight:bold;font-size:16px") Friends Only
+ span(v-if="hasGroupPermission(groupDialog.ref, 'group-members-viewall')" style="font-weight:bold;font-size:16px") {{ $t('dialog.group.members.all_members') }}
+ span(v-else style="font-weight:bold;font-size:16px") {{ $t('dialog.group.members.friends_only') }}
br
el-button(type="default" @click="getGroupDialogGroupMembers()" size="mini" icon="el-icon-refresh" circle)
span(style="font-size:14px;margin-left:5px;margin-right:5px") {{ groupDialog.members.length }}/{{ groupDialog.ref.memberCount }}
@@ -2369,8 +2369,8 @@ html
span.extra
.x-friend-item(v-if="!isGroupMembersDone" v-loading="isGroupMembersLoading" style="width:100%;height:45px;text-align:center" @click="loadMoreGroupMembers")
.detail(v-if="!isGroupMembersLoading")
- span.name Load more...
- el-tab-pane(label="JSON")
+ span.name {{ $t('dialog.group.members.load_more') }}
+ el-tab-pane(:label="$t('dialog.group.json.header')")
el-button(type="default" @click="refreshGroupDialogTreeData()" size="mini" icon="el-icon-refresh" circle)
el-tree(:data="groupDialog.treeData" style="margin-top:5px;font-size:12px")
template(#default="scope")
@@ -2432,57 +2432,57 @@ html
el-button(type="primary" size="small" :disabled="inviteDialog.loading || !inviteDialog.userIds.length" @click="sendInvite()") Invite
//- dialog: social status
- el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="socialStatusDialog" :visible.sync="socialStatusDialog.visible" title="Social Status" width="400px")
+ 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") History
+ 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="No" prop="no" width="40")
- el-table-column(label="Status" prop="status")
+ el-table-column(:label="$t('table.social_status.no')" prop="no" width="40")
+ el-table-column(:label="$t('table.social_status.status')" prop="status")
el-select(v-model="socialStatusDialog.status" style="dispaly:block;margin-top:10px")
- el-option(label="Online" value="active").
- #[i.x-user-status.online] Online
- el-option(label="Join Me" value="join me").
- #[i.x-user-status.joinme] Join Me
- el-option(label="Ask Me" value="ask me").
- #[i.x-user-status.askme] Ask Me
- el-option(label="Do Not Disturb" value="busy").
- #[i.x-user-status.busy] Do Not Disturb
- el-option(v-if="API.currentUser.$isModerator" label="Offline" value="offline").
- #[i.x-user-status.offline] Offline
- el-input(v-model="socialStatusDialog.statusDescription" placeholder="Status" maxlength="32" show-word-limit style="dispaly:block;margin-top:10px")
+ 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.join_me')" value="join me").
+ #[i.x-user-status.joinme] {{ $t('dialog.user.status.join_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").
+ #[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").
+ #[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="dispaly:block;margin-top:10px")
template(#footer)
- el-button(type="primary" size="small" :disabled="socialStatusDialog.loading" @click="saveSocialStatus") 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="Language" width="400px")
+ 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" size="mini")
+ 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") Ok
- el-button(@click="languageDialog.languageChoice=false" size="mini" style="margin-left:0") 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") 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="Bio" width="600px")
+ 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="Please input a bio")
+ 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('')" size="mini" style="margin-top:5px") Add Link
+ el-button(@click="bioDialog.bioLinks.push('')" size="mini" style="margin-top:5px") {{ $t('dialog.bio.add_link') }}
template(#footer)
- el-button(type="primary" size="small" :disabled="bioDialog.loading" @click="saveBio") Update
+ el-button(type="primary" size="small" :disabled="bioDialog.loading" @click="saveBio") {{ $t('dialog.bio.update') }}
//- dialog: new instance
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="newInstanceDialog" :visible.sync="newInstanceDialog.visible" title="New Instance" width="600px")
@@ -2580,7 +2580,7 @@ html
| These options are for advanced users only. #[br]
| Leave field empty to set as default, game restart required to apply settings.
br
- span Cache Size:
+ span Cache Size:
span(v-text="VRChatUsedCacheSize")
span /
span(v-text="VRChatTotalCacheSize")
@@ -3347,7 +3347,7 @@ html
div(style="float:right;margin-top:5px")
el-button(type="default" @click="downloadAndSaveImage(image.versions[image.versions.length - 1].file.url)" size="mini" icon="el-icon-paperclip" circle)
el-button(type="default" @click="deleteVRCPlusIcon(image.id)" size="mini" icon="el-icon-delete" circle style="margin-left:5px")
-
+
//- dialog Table: Previous Instances User
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="previousInstancesUserDialog" :visible.sync="previousInstancesUserDialog.visible" title="Previous Instances" width="800px")
span(v-text="previousInstancesUserDialog.userRef.displayName" style="font-size:14px")
@@ -3373,7 +3373,7 @@ html
el-button(type="text" icon="el-icon-info" size="mini" @click="showLaunchDialog(scope.row.location)")
el-button(type="text" icon="el-icon-tickets" size="mini" @click="showPreviousInstanceInfoDialog(scope.row.location)")
el-button(type="text" icon="el-icon-close" size="mini" @click="confirmDeleteGameLogUserInstance(scope.row)")
-
+
//- dialog Table: Previous Instances World
el-dialog.x-dialog(:before-close="beforeDialogClose" @mousedown.native="dialogMouseDown" @mouseup.native="dialogMouseUp" ref="previousInstancesWorldDialog" :visible.sync="previousInstancesWorldDialog.visible" title="Previous Instances" width="800px")
span(v-text="previousInstancesWorldDialog.worldRef.name" style="font-size:14px")
diff --git a/html/src/localization/localizedStrings.js b/html/src/localization/localizedStrings.js
new file mode 100644
index 00000000..d33c20c8
--- /dev/null
+++ b/html/src/localization/localizedStrings.js
@@ -0,0 +1,5 @@
+import en from './strings/en.json' assert { type: 'JSON' };
+// import ja from './strings/ja.json' assert { type: 'JSON' };
+import zh_TW from './strings/zh_TW.json' assert { type: 'JSON' };
+
+export { en, zh_TW };
\ No newline at end of file
diff --git a/html/src/localization/strings/en.json b/html/src/localization/strings/en.json
new file mode 100644
index 00000000..695ffa59
--- /dev/null
+++ b/html/src/localization/strings/en.json
@@ -0,0 +1,800 @@
+{
+ "language": "English",
+ "translator": "-",
+ "nav_tooltip": {
+ "feed": "Feed",
+ "game_log": "Game Log",
+ "player_list": "Player List",
+ "search": "Search",
+ "favorites": "Favorites",
+ "friend_log": "Friend Log",
+ "moderation": "Moderation",
+ "notification": "Notification",
+ "friend_list": "Friend List",
+ "profile": "Profile",
+ "settings": "Settings"
+ },
+ "view": {
+ "login": {
+ "savedAccounts": "Saved Accounts",
+ "login": "Login",
+ "register": "Register",
+ "forgotPassword": "Forgot Password?",
+ "field": {
+ "username": "Username or Email",
+ "password": "Password",
+ "saveCredentials": "Save Credentials",
+ "devEndpoint": "Dev Endpoint",
+ "endpoint": "Endpoint",
+ "websocket": "WebSocket"
+ }
+ },
+ "feed": {
+ "favorites_only_tooltip": "Filter VIP only",
+ "filter_placeholder": "Filter",
+ "search_placeholder": "Search"
+ },
+ "game_log": {
+ "filter_placeholder": "Filter",
+ "search_placeholder": "Search"
+ },
+ "search": {
+ "search_placeholder": "Search",
+ "clear_results_tooltip": "Clear Search Results",
+ "user": {
+ "header": "User"
+ },
+ "world": {
+ "header": "World",
+ "category": "Search by category",
+ "community_lab": "Include community labs"
+ },
+ "avatar": {
+ "header": "Avatar",
+ "search_provider": "Search Provider",
+ "refresh_tooltip": "Refresh own avatars",
+ "result_count": "Results {count}",
+ "all": "All",
+ "public": "Public",
+ "private": "Private",
+ "local": "Local",
+ "remote": "Remote",
+ "sort_name": "Sort by name",
+ "sort_update": "Sort by update",
+ "sort_created": "Sort by created"
+ },
+ "prev_page": "Prev",
+ "next_page": "Nect"
+ },
+ "favorite": {
+ "friends": {
+ "header": "Friends"
+ },
+ "worlds": {
+ "header": "Worlds",
+ "vrchat_favorites": "VRChat Favorites",
+ "local_favorites": "Local Favorites",
+ "new_group": "New Group"
+ },
+ "avatars": {
+ "header": "Avatars"
+ },
+ "refresh_tooltip": "Refresh all favorites",
+ "export": "Export",
+ "import": "Import",
+ "move_tooltip": "Move",
+ "unfavorite_tooltip": "Unfavorite",
+ "visibility_tooltip": "Change Visibility",
+ "rename_tooltip": "Rename",
+ "clear_tooltip": "Clear",
+ "delete_tooltip": "Delete"
+ },
+ "friend_log": {
+ "filter_placeholder": "Filter",
+ "search_placeholder": "Search"
+ },
+ "moderation": {
+ "filter_placeholder": "Filter",
+ "search_placeholder": "Search",
+ "refresh_tooltip": "Refresh"
+ },
+ "notification": {
+ "filter_placeholder": "Filter",
+ "search_placeholder": "Search",
+ "refresh_tooltip": "Refresh"
+ },
+ "friend_list": {
+ "header": "Friend List",
+ "bulk_unfriend": "Bulk Unfriend Mode",
+ "bulk_unfriend_selection": "Bulk Unfriend Selection",
+ "load": "Load missing entries",
+ "load_notice": "This takes a lot of API requests so use it sparingly",
+ "load_tooltip": "Load",
+ "favorites_only_tooltip": "Filter VIP only",
+ "search_placeholder": "Search",
+ "filter_placeholder": "Filter",
+ "refresh_tooltip": "Refresh",
+ "clear_tooltip": "Clear Results"
+ },
+ "profile": {
+ "profile": {
+ "header": "Profile",
+ "last_activity": "Last Activity",
+ "two_factor": "Two-Factor Auth (2FA)",
+ "two_factor_enabled": "Enabled",
+ "two_factor_disabled": "Disabled",
+ "logout": "Logout",
+ "export_friend_list": "Export Friends List",
+ "export_own_avatars": "Export Own Avatars",
+ "discord_names": "Discord Names",
+ "export_notes": "Export Notes"
+ },
+ "game_info": {
+ "header": "Game Info",
+ "online_users": "Online Users",
+ "user_online": "{count} users online.",
+ "refresh": "Click to refresh"
+ },
+ "vrc_sdk_downloads": {
+ "header": "VRC SDK Downloads"
+ },
+ "direct_access": {
+ "header": "Direct Access",
+ "username": "Username",
+ "user_id": "User ID",
+ "world_instance": "World/Instance",
+ "avatar": "Avatar"
+ },
+ "invite_messages": "Invite Messages",
+ "invite_response_messages": "Invite Response Messages",
+ "invite_request_messages": "Invite Request Messages",
+ "invite__request_response_messages": "Invite Request Response Messages",
+ "past_display_names": "Past Display Names",
+ "config_json": "Config JSON",
+ "current_user_json": "Current User JSON",
+ "refresh_tooltip": "Refresh",
+ "clear_results_tooltip": "Clear results"
+ },
+ "settings": {
+ "header": "Settings",
+ "category": {
+ "general": "General",
+ "appearance": "Appearance",
+ "notifications": "Notifications",
+ "wrist_overlay": "Wrist Overlay",
+ "discord_presence": "Discord Presence",
+ "advanced": "Advanced"
+ },
+ "general": {
+ "general": {
+ "header": "General",
+ "version": "Version",
+ "latest_app_version": "Latest Version",
+ "latest_app_version_refresh": "Click to refresh",
+ "repository_url": "Repository URL",
+ "support": "Support"
+ },
+ "vrcx_updater": {
+ "header": "VRCX Updater",
+ "change_build": "Change build",
+ "auto_update": "Auto update",
+ "auto_update_off": "Off",
+ "auto_update_notify": "Notify",
+ "auto_update_download": "Auto Download",
+ "auto_update_install": "Auto Install"
+ },
+ "application": {
+ "header": "Application",
+ "startup": "Start as Windows startup",
+ "minimized": "Start as minimized state",
+ "tray": "Close to tray"
+ },
+ "legal_notice": {
+ "header": "Legal Notice",
+ "info": "VRCX is an assistant application for provide information about manage friendship. this application uses unofficial VRChat API (VRCSDK).",
+ "disclaimer1": "VRCX isn't endorsed by VRChat and doesn't reflect the views or opinions of VRChat or anyone officially involved in producing or managing VRChat. VRChat is trademark of VRChat Inc. VRChat © VRChat Inc.",
+ "disclaimer2": "pypy or Natsumi aren't responsible for any problems caused by VRCX. Use at your own risk!",
+ "open_source_software_notice": "Open Source Software Notice"
+ }
+ },
+ "appearance": {
+ "appearance": {
+ "header": "Appearance",
+ "theme_mode": "Theme mode",
+ "theme_mode_system": "System",
+ "theme_mode_light": "Light",
+ "theme_mode_dark": "Dark",
+ "vrcplus_profile_icons": "VRCPlus Profile Icons",
+ "disable_tooltips": "Disable Tooltips",
+ "sort_favorite_by": "Sort Favorites by",
+ "sort_favorite_by_name": "name",
+ "sort_favorite_by_date": "date",
+ "sort_instance_users_by": "Sort Instance Users by",
+ "sort_instance_users_by_time": "time",
+ "sort_instance_users_by_alphabet": "alphabetical",
+ "table_max_size": "Table Max Size",
+ "page_size": "Page Size:"
+ },
+ "timedate": {
+ "header": "Time/Date",
+ "time_format": "Time Format",
+ "time_format_24": "24 Hour",
+ "time_format_12": "12 Hour",
+ "force_iso_date_format": "Force ISO Date Format"
+ },
+ "side_panel": {
+ "header": "Side Panel",
+ "sorting": {
+ "header": "Sorting",
+ "sort_private_to_bottom": "Sort Private to bottom",
+ "sort_by_status": "Sort by status",
+ "sort_gps_to_top": "Sort GPS to top",
+ "sort_gps_to_top_notice": "(online for only)",
+ "sort_favorite_by": "Sort VIP by",
+ "sort_favorite_by_alphabet": "alphabetical",
+ "sort_favorite_by_online_time": "online for",
+ "sort_online_by": "Sort Online by",
+ "sort_online_by_alphabet": "alphabetical",
+ "sort_online_by_online_time": "online for",
+ "sort_active_by": "Sort Active by",
+ "sort_active_by_alphabet": "alphabetical",
+ "sort_active_by_online_time": "online for",
+ "sort_offline_by": "Sort Offline by",
+ "sort_offline_by_alphabet": "alphabetical",
+ "sort_offline_by_offline_time": "offline for"
+ },
+ "width": "Width"
+ },
+ "user_dialog": {
+ "header": "User Dialog",
+ "hide_vrchat_notes": "Hide VRChat Notes",
+ "hide_vrcx_memos": "Hide VRCX Memos",
+ "export_vrcx_memos_into_vrchat_notes": "Export VRCX Memos into VRChat notes",
+ "export_notes": "Export Notes"
+ },
+ "user_colors": {
+ "header": "User Colors",
+ "random_colors_from_user_id": "Random Colors from User ID"
+ }
+ },
+ "notifications": {
+ "notifications": {
+ "header": "Notifications",
+ "notification_filter": "Notification Filter",
+ "steamvr_notifications": {
+ "header": "SteamVR Notifications",
+ "steamvr_overlay": "SteamVR Overlay",
+ "overlay_notifications": "Overlay Notifications",
+ "notification_position": "Notification Position",
+ "xsoverlay_notifications": "XSOverlay Notifications",
+ "user_images": "User Images (slower)",
+ "notification_timeout": "Notification Timeout"
+ },
+ "desktop_notifications": {
+ "header": "Desktop Notifications",
+ "when_to_display": "When to display",
+ "when_to_display_never": "Never",
+ "when_to_display_desktop": "Desktop Mode",
+ "when_to_display_inside_vr": "Inside VR",
+ "when_to_display_outside_vr": "Outside VR",
+ "when_to_display_game_closed": "Game Closed",
+ "when_to_display_game_running": "Game Running",
+ "when_to_display_always": "Always"
+ },
+ "text_to_speech": {
+ "header": "Text-To-Speech Options",
+ "when_to_play": "Notification TTS. When to play",
+ "when_to_play_never": "Never",
+ "when_to_play_inside_vr": "Inside VR",
+ "when_to_play_game_closed": "Game Closed",
+ "when_to_play_game_running": "Game Running",
+ "when_to_play_always": "Always",
+ "tts_voice": "TTS Voice"
+ }
+ }
+ },
+ "wrist_overlay": {
+ "steamvr_wrist_overlay": {
+ "header": "SteamVR Wrist Overlay",
+ "description": "* It runs automatically when VRChat is running.",
+ "grip": "Grip: Vive or Other Controllers Grab, Oculus X/A Buttons",
+ "menu": "Menu: Vive Menu, Index B, Oculus Y/B Buttons",
+ "steamvr_overlay": "SteamVR Overlay",
+ "wrist_feed_overlay": "Wrist Feed Overlay",
+ "hide_private_worlds": "Hide Private Worlds",
+ "start_overlay_with": "Start Overlay With",
+ "overlay_button": "Overlay Button",
+ "overlay_button_grip": "Grip",
+ "overlay_button_menu": "Menu",
+ "display_overlay_on": "Display Overlay On",
+ "display_overlay_on_left": "Left Hand",
+ "display_overlay_on_right": "Right Hand",
+ "display_overlay_on_both": "Both Hand",
+ "background_color": "Background Color",
+ "minimal_feed_icons": "Minimal Feed Icons",
+ "hide_vr_devices": "Hide VR Devices",
+ "hide_cpu_usage": "Hide CPU Usage",
+ "hide_game_uptime": "Hide Game Uptime",
+ "show_pc_uptime": "Show PC Uptime",
+ "wrist_feed_filters": "Wrist Feed Filters"
+ }
+ },
+ "discord_presence": {
+ "discord_presence": {
+ "header": "Discord Presence",
+ "description": "* Only works when VRChat is running.",
+ "enable": "Enable",
+ "enable_tooltip": "Recommended to disable Rich Presence in VRChat config.json to stop it from conflicting",
+ "instance_type_player_count": "Instance type/player count",
+ "join_button": "Join button (public only)",
+ "hide_details_in_private": "Hide world details in private",
+ "hide_images": "Hide World Images"
+ }
+ },
+ "advanced": {
+ "advanced": {
+ "header": "Advanced",
+ "launch_options": "Launch Options",
+ "pending_offline": {
+ "header": "Pending Offline",
+ "description": "Delay before marking user as offline (fixes false positives)",
+ "set_delay": "Set Delay"
+ },
+ "primary_password": {
+ "header": "Primary Password",
+ "description": "Encrypt password (disables auto login)"
+ },
+ "vrchat_quit_fix": {
+ "header": "VRChat Quit Fix",
+ "description": "Kill VRChat after exiting game"
+ },
+ "auto_cache_management": {
+ "header": "Automatically Manage Cache When Closing VRChat",
+ "description": "Auto delete old versions from cache"
+ },
+ "remote_database": {
+ "header": "Remote Avatar Database",
+ "enable": "Enable",
+ "avatar_database_provider": "Avatar Database Provider"
+ },
+ "youtube_api": {
+ "header": "Youtube API",
+ "enable": "Enable",
+ "youtube_api_key": "Youtube API Key"
+ },
+ "video_progress_pie": {
+ "header": "Progress pie overlay for videos",
+ "enable": "Enable",
+ "enable_tooltip": "Requires SteamVR overlay to be enabled",
+ "dance_world_only": "Dance worlds only"
+ },
+ "cache_debug": {
+ "header": "VRCX Instance Cache/Debug",
+ "disable_gamelog": "Disable GameLog",
+ "disable_gamelog_notice": "(will likely break things)",
+ "user_cache": "User cache:",
+ "world_cache": "World cache:",
+ "avatar_cache": "Avatar cache:",
+ "avatar_name_cache": "Avatar Name cache:",
+ "clear_cache": "Clear Cache",
+ "auto_clear_cache": "Auto Clear Cache",
+ "download_history": "Download History",
+ "show_console": "Show Console"
+ },
+ "sqlite_table_size": {
+ "header": "SQLite Table Size",
+ "refresh": "Refresh",
+ "gps": "GPS:",
+ "status": "Status:",
+ "bio": "Bio:",
+ "avatar": "Avatar:",
+ "online_offline": "Online/Offline:",
+ "friend_log_history": "Friend Log History:",
+ "notification": "Notifications:",
+ "location": "Location:",
+ "join_leave": "Join/Leave:",
+ "portal_spawn": "Portal Spawn:",
+ "video_play": "Video Play:",
+ "event": "Event:"
+ }
+ },
+ "photon": {
+ "header": "Photon Logging Overlay",
+ "event_hud": {
+ "header": "Photon Event HUD",
+ "enable": "Enable",
+ "enable_tooltip": "Requires SteamVR overlay to be enabled",
+ "filter": "Filter",
+ "filter_favorites": "VIP",
+ "filter_friends": "Friends",
+ "filter_everyone": "Everyone",
+ "message_timeout": "Message Timeout"
+ },
+ "timeout_hud": {
+ "header": "User Timeout HUD",
+ "enable": "Enable",
+ "enable_tooltip": "Requires SteamVR overlay to be enabled",
+ "filter": "Filter",
+ "filter_favorites": "VIP",
+ "filter_friends": "Friends",
+ "filter_everyone": "Everyone",
+ "timeout_threshold": "Timeout Threshold"
+ }
+ }
+ }
+ }
+ },
+ "side_panel": {
+ "search_placeholder": "Search",
+ "search_result_active": "Offline",
+ "search_result_offline": "Active",
+ "search_result_more": "Search More:",
+ "direct_access_tooltip": "Direct access ID/URL from clipboard",
+ "refresh_tooltip": "Refresh friends",
+ "friends": "FRIENDS",
+ "me": "ME",
+ "favorite": "VIP",
+ "online": "ONLINE",
+ "active": "ACTIVE",
+ "offline": "OFFLINE",
+ "penfing_offline": "Pending Offline"
+ },
+ "dialog": {
+ "user": {
+ "status": {
+ "active": "Active",
+ "offline": "Offline",
+ "online": "Online",
+ "join_me": "Join Me",
+ "ask_me": "Ask Me",
+ "busy": "Do Not Disturb"
+ },
+ "previous_display_names": "Previous Display Names:",
+ "tags": {
+ "friend_no": "Friend No.{number}",
+ "vrchat_team": "VRChat Team"
+ },
+ "actions": {
+ "favorite_tooltip": "Add to favorites",
+ "unfavorite_tooltip": "Remove from favorites",
+ "refresh": "Refresh",
+ "copy_url": "Copy User URL",
+ "invite": "Invite",
+ "invite_with_message": "Invite With Message",
+ "request_invite": "Request Invite",
+ "request_invite_with_message": "Request Invite With Message",
+ "invite_to_group": "Invite To Group",
+ "manage_gallery_icon": "Manage Gallery/Icons",
+ "accept_friend_request": "Accept Friend Request",
+ "decline_friend_request": "Decline Friend Request",
+ "cancel_friend_request": "Cancel Friend Request",
+ "send_friend_request": "Send Friend Request",
+ "show_avatar_author": "Show Avatar Author",
+ "show_fallback_avatar": "Show Fallback Avatar Details",
+ "show_previous_instances": "Show Previous Instances",
+ "show_previous_images": "Show Previous Images",
+ "moderation_block": "Block",
+ "moderation_unblock": "Unblock",
+ "moderation_mute": "Mute",
+ "moderation_unmute": "Unmute",
+ "moderation_hide_avatar": "Show Avatar",
+ "moderation_show_avatar": "Hide Avatar",
+ "moderation_enable_avatar_interaction": "Enable Avatar Interaction",
+ "moderation_disable_avatar_interaction": "Disable Avatar Interaction",
+ "edit_status": "Social Status",
+ "edit_language": "Language",
+ "edit_bio": "Bio",
+ "unfriend": "Unfriend",
+ "logout": "Logout"
+ },
+ "info": {
+ "header": "Info",
+ "launch_invite_tooltip": "Launch/Invite",
+ "self_invite_tooltip": "Invite Yourself",
+ "refresh_user_count_tooltip": "Refresh User Count",
+ "instance_creator": "Instance Creator",
+ "note": "Note",
+ "note_placeholder": "Click to add a note",
+ "memo": "Memo",
+ "memo_placeholder": "Click to add a memo",
+ "avatar_info": "Avatar Info",
+ "avatar_info_last_seen": "Avatar Info Last Seen",
+ "represented_group": "Represented Group",
+ "bio": "Bio",
+ "last_seen": "Last Seen",
+ "join_count": "Join Count",
+ "time_together": "Time Together",
+ "online_for": "Online For",
+ "offline_for": "Offline For",
+ "last_activity": "Last Activity",
+ "last_login": "Last Login",
+ "date_joined": "Date Joined",
+ "friended": "Friended",
+ "unfriended": "Unfriended",
+ "avatar_cloning": "Avatar Cloning",
+ "avatar_cloning_allow": "Allowed",
+ "avatar_cloning_deny": "Deny",
+ "home_location": "Home Location",
+ "accuracy_notice": "Info from local database may not be accurate"
+ },
+ "groups": {
+ "header": "Groups",
+ "total_count": "Total {count}",
+ "own_groups": "Own Groups",
+ "mutual_groups": "Mutual Groups",
+ "groups": "Groups"
+ },
+ "worlds": {
+ "header": "Worlds",
+ "total_count": "Total {count}",
+ "sort_by_name": "Sort by name",
+ "sort_by_update": "Sort by update"
+ },
+ "favorite_worlds": {
+ "header": "Favorite Worlds"
+ },
+ "avatars": {
+ "header": "Avatars",
+ "total_count": "Total {count}",
+ "sort_by_name": "Sort by name",
+ "sort_by_update": "Sort by update",
+ "all": "All",
+ "public": "Public",
+ "private": "Private"
+ },
+ "json": {
+ "header": "JSON"
+ }
+ },
+ "world": {
+ "tags": {
+ "public": "Public",
+ "private": "Private",
+ "labs": "Labs",
+ "cache": "Cache"
+ },
+ "actions": {
+ "delete_cache_tooltip": "Delete world from cache",
+ "favorite_tooltip": "Add to favorites",
+ "unfavorite_tooltip": "Remove from favorites",
+ "refresh": "Refresh",
+ "new_instance": "New Instance",
+ "make_home": "Make Home",
+ "reset_home": "Reset Home",
+ "show_previous_instances": "Show Previous Instances",
+ "show_previous_images": "Show Previous Images",
+ "rename": "Rename",
+ "change_description": "Change Description",
+ "change_capacity": "Change Capacity",
+ "change_preview": "Change Youtube Preview",
+ "change_tags": "Change Tags",
+ "change_image": "Change Image",
+ "download_package": "Download Unity Package",
+ "publish_to_labs": "Publish To Labs",
+ "unpublish": "Unpublish",
+ "delete": "Delete"
+ },
+ "instances": {
+ "header": "Instances",
+ "public_count": "Public {count}",
+ "private_count": "Private {count}",
+ "capacity_count": "Capacity {count} ({max})",
+ "self_invite_tooltip": "Invite Yourself",
+ "refresh_user_count_tooltip": "Refresh User Count",
+ "instance_creator": "Instance Creator"
+ },
+ "info": {
+ "header": "Info",
+ "id": "World ID",
+ "id_tooltip": "Copy to clipboard",
+ "copy_id": "Copy ID",
+ "copy_url": "Copy URL",
+ "youtube_preview": "Youtube Preview",
+ "players": "Players",
+ "favorites": "Favorites",
+ "visits": "Visits",
+ "capacity": "Capacity",
+ "heat": "Heat",
+ "popularity": "Popularity",
+ "created_at": "Created At",
+ "last_updated": "Last Updated",
+ "version": "Version",
+ "platform": "Platform",
+ "last_visited": "Last Visited",
+ "visit_count": "Visit Count",
+ "time_spent": "Time Spent",
+ "accuracy_notice": "Info from local database may not be accurate"
+ },
+ "json": {
+ "header": "JSON"
+ }
+ },
+ "avatar": {
+ "tags": {
+ "public": "Public",
+ "private": "Private",
+ "fallback": "Fallback",
+ "cache": "Cache"
+ },
+ "actions": {
+ "delete_cache_tooltip": "Delete avatar from cache",
+ "favorite_tooltip": "Add to favorites",
+ "unfavorite_tooltip": "Remove from favorites",
+ "refresh": "Refresh",
+ "select": "Select Avatar",
+ "select_fallback": "Select Fallback Avatar",
+ "block": "Block Avatar",
+ "unblock": "Unblock Avatar",
+ "show_previous_images": "Show Previous Images",
+ "make_public": "Make Public",
+ "make_private": "Make Private",
+ "rename": "Rename",
+ "change_description": "Change Description",
+ "change_image": "Change Image",
+ "download_package": "Download Unity Package",
+ "delete": "Delete"
+ },
+ "info": {
+ "header": "Info",
+ "id": "Avatar ID",
+ "id_tooltip": "Copy to clipboard",
+ "copy_id": "Copy ID",
+ "copy_url": "Copy URL",
+ "created_at": "Created At",
+ "last_updated": "Last Updated",
+ "version": "Version",
+ "platform": "Platform"
+ },
+ "json": {
+ "header": "JSON"
+ }
+ },
+ "group": {
+ "tags": {
+ "verified": "Verified",
+ "public": "Public",
+ "private": "Private",
+ "open": "Open",
+ "request": "Request",
+ "invite": "Invite",
+ "closed": "Closed",
+ "joined": "Joined",
+ "banned": "Banned",
+ "visible": "Visible",
+ "friends": "Friends",
+ "hidden": "Hidden",
+ "subscribed": "Subscribed"
+ },
+ "actions": {
+ "represent_tooltip": "Set Representing",
+ "unrepresent_tooltip": "Stop Representing",
+ "cancel_join_request_tooltip": "Cancel join request",
+ "pending_request_tooltip": "Pending invite",
+ "request_join_tooltip": "Request to join",
+ "invite_required_tooltip": "Invite required",
+ "join_group_tooltip": "Join Group",
+ "refresh": "Refresh",
+ "unsubscribe": "Unsubscribe From Announcements",
+ "subscribe": "Subscribe To Announcements",
+ "invite_to_group": "Invite To Group",
+ "visibility_everyone": "Visibility Everyone",
+ "visibility_friends": "Visibility Friends",
+ "visibility_hidden": "Visibility Hidden",
+ "leave": "Leave Group"
+ },
+ "info": {
+ "header": "Info",
+ "announcement": "Announcement",
+ "rules": "Rules",
+ "members": "Members",
+ "created_at": "Created At",
+ "links": "Links",
+ "url": "Group URL",
+ "url_tooltip": "Copy URL to clipboard",
+ "id": "Group ID",
+ "id_tooltip": "Copy ID to clipboard",
+ "joined_at": "Joined At",
+ "roles": "Roles",
+ "role_description": "Description:",
+ "role_updated_at": "Updated At:",
+ "role_created_at": "Created At:",
+ "role_permissions": "Permissions:"
+ },
+ "members": {
+ "header": "Members",
+ "all_members": "All Members",
+ "friends_only": "Friends Only",
+ "load_more": "Load more..."
+ },
+ "json": {
+ "header": "JSON"
+ }
+ },
+ "social_status": {
+ "header": "Social Status",
+ "history": "History",
+ "status_placeholder": "Status",
+ "update": "Update"
+ },
+ "language": {
+ "header": "Language",
+ "add_language": "Add Language",
+ "select_language": "Select Language",
+ "ok": "OK",
+ "cancel": "Cancel"
+ },
+ "bio": {
+ "header": "Bio",
+ "bio_placeholder": "Please input a bio",
+ "add_link": "Add Link",
+ "update": "Update"
+ }
+ },
+ "table": {
+ "feed": {
+ "date": "Date",
+ "type": "Type",
+ "user": "User",
+ "detail": "Detail"
+ },
+ "gameLog": {
+ "date": "Date",
+ "type": "Type",
+ "user": "User",
+ "detail": "Detail"
+ },
+ "playerList": {
+ "avatar": "Avatar",
+ "timer": "Timer",
+ "photonId": "Photon ID",
+ "icon": "Icons",
+ "platform": "Platform",
+ "displayName": "Display Name",
+ "status": "Status",
+ "rank": "Rank",
+ "language": "Language",
+ "bioLink": "Bio Links"
+ },
+ "friendLog": {
+ "date": "Date",
+ "type": "Type",
+ "user": "User",
+ "action": "Action"
+ },
+ "moderation": {
+ "date": "Date",
+ "type": "Type",
+ "source": "Source",
+ "target": "Target",
+ "action": "Action"
+ },
+ "notification": {
+ "date": "Date",
+ "type": "Type",
+ "user": "User",
+ "photo": "Photo",
+ "message": "Message",
+ "action": "Action"
+ },
+ "friendList": {
+ "no": "No.",
+ "avatar": "Avatar",
+ "displayName": "Display Name",
+ "rank": "Rank",
+ "status": "Status",
+ "language": "Language",
+ "bioLink": "Bio Links",
+ "joinCount": "Join Counts",
+ "timeTogether": "Time Together",
+ "lastSeen": "Last Seen",
+ "lastActivity": "Last Activity",
+ "lastLogin": "Last Login",
+ "dateJoined": "Date Joined",
+ "unfriend": "Unfriend"
+ },
+ "social_status": {
+ "no": "No.",
+ "status": "Status"
+ }
+ }
+}
\ No newline at end of file
diff --git a/html/src/localization/strings/zh_TW.json b/html/src/localization/strings/zh_TW.json
new file mode 100644
index 00000000..3cc0bd9e
--- /dev/null
+++ b/html/src/localization/strings/zh_TW.json
@@ -0,0 +1,802 @@
+{
+ "language": "繁體中文",
+ "translator": "Kamiya",
+ "nav_tooltip": {
+ "feed": "動態",
+ "game_log": "遊戲紀錄",
+ "player_list": "玩家列表",
+ "search": "搜尋",
+ "favorites": "最愛",
+ "friend_log": "好友紀錄",
+ "moderation": "玩家處置",
+ "notification": "通知",
+ "friend_list": "好友列表",
+ "profile": "個人檔案",
+ "settings": "設定"
+ },
+ "view": {
+ "login": {
+ "savedAccounts": "已儲存的帳號",
+ "login": "登入",
+ "register": "註冊",
+ "forgotPassword": "忘記密碼?",
+ "field": {
+ "username": "玩家名稱或電子郵件",
+ "password": "密碼",
+ "saveCredentials": "儲存登入資料",
+ "devEndpoint": "開發接口",
+ "endpoint": "Endpoint",
+ "websocket": "WebSocket"
+ }
+ },
+ "feed": {
+ "favorites_only_tooltip": "僅篩選最愛",
+ "filter_placeholder": "篩選動態",
+ "search_placeholder": "搜尋動態"
+ },
+ "game_log": {
+ "filter_placeholder": "篩選遊戲紀錄",
+ "search_placeholder": "搜尋遊戲紀錄"
+ },
+ "search": {
+ "search_placeholder": "搜尋",
+ "clear_results_tooltip": "清除搜尋結果",
+ "user": {
+ "header": "玩家"
+ },
+ "world": {
+ "header": "世界",
+ "category": "依類別搜尋",
+ "community_lab": "包含社區實驗室"
+ },
+ "avatar": {
+ "header": "角色",
+ "search_provider": "搜尋提供芳",
+ "refresh_tooltip": "重新整理自己的角色",
+ "result_count": "{count} 個搜尋結果",
+ "all": "所有",
+ "public": "公開",
+ "private": "私人",
+ "local": "本地",
+ "remote": "遠端",
+ "sort_name": "依名稱排序",
+ "sort_update": "依更新排序",
+ "sort_created": "依建立時間排序"
+ },
+ "prev_page": "上一頁",
+ "next_page": "下一頁"
+ },
+ "favorite": {
+ "friends": {
+ "header": "好友"
+ },
+ "worlds": {
+ "header": "世界",
+ "vrchat_favorites": "VRChat 最愛",
+ "local_favorites": "本地最愛",
+ "new_group": "新群組"
+ },
+ "avatars": {
+ "header": "角色"
+ },
+ "refresh_tooltip": "重新整理所有最愛",
+ "export": "匯出",
+ "import": "匯入",
+ "move_tooltip": "移動",
+ "unfavorite_tooltip": "解除最愛",
+ "visibility_tooltip": "變更可見度",
+ "rename_tooltip": "重新命名",
+ "clear_tooltip": "清除",
+ "delete_tooltip": "刪除"
+ },
+ "friend_log": {
+ "filter_placeholder": "篩選好友紀錄",
+ "search_placeholder": "搜尋好友紀錄"
+ },
+ "moderation": {
+ "filter_placeholder": "篩選玩家處置",
+ "search_placeholder": "搜尋玩家處置",
+ "refresh_tooltip": "重新整理"
+ },
+ "notification": {
+ "filter_placeholder": "篩選通知",
+ "search_placeholder": "搜尋通知",
+ "refresh_tooltip": "重新整理"
+ },
+ "friend_list": {
+ "header": "好友列表",
+ "bulk_unfriend": "批量解除好友",
+ "bulk_unfriend_selection": "批量解除已選擇的好友",
+ "load": "讀取缺失的項目",
+ "load_notice": "這會向 API 傳送大量請求,所以請謹慎使用",
+ "load_tooltip": "讀取",
+ "cancel_tooltip": "取消",
+ "favorites_only_tooltip": "僅篩選最愛",
+ "search_placeholder": "搜尋好友",
+ "filter_placeholder": "篩選好友",
+ "refresh_tooltip": "重新整理",
+ "clear_tooltip": "清除結果"
+ },
+ "profile": {
+ "profile": {
+ "header": "個人檔案",
+ "last_activity": "最後動態",
+ "two_factor": "雙重認證 (2FA)",
+ "two_factor_enabled": "已啟用",
+ "two_factor_disabled": "已停用",
+ "logout": "登出",
+ "export_friend_list": "匯出好友列表",
+ "export_own_avatars": "匯出私有角色",
+ "discord_names": "Discord 名稱",
+ "export_notes": "匯出備註"
+ },
+ "game_info": {
+ "header": "遊戲資訊",
+ "online_users": "線上玩家",
+ "user_online": "{count} 位玩家在線上",
+ "refresh": "點擊以重新整理"
+ },
+ "vrc_sdk_downloads": {
+ "header": "下載 VRC SDK"
+ },
+ "direct_access": {
+ "header": "直接存取",
+ "username": "玩家名稱",
+ "user_id": "玩家 ID",
+ "world_instance": "世界 / 房間",
+ "avatar": "角色"
+ },
+ "invite_messages": "邀請訊息",
+ "invite_response_messages": "邀請回覆訊息",
+ "invite_request_messages": "邀請請求訊息",
+ "invite__request_response_messages": "邀請請求回覆訊息",
+ "past_display_names": "過去顯示名稱",
+ "config_json": "JSON 資料",
+ "current_user_json": "目前玩家的 JSON 資料",
+ "refresh_tooltip": "重新整理",
+ "clear_results_tooltip": "清除結果"
+ },
+ "settings": {
+ "header": "設定",
+ "category": {
+ "general": "一般",
+ "appearance": "外觀",
+ "notifications": "通知",
+ "wrist_overlay": "手腕疊層",
+ "discord_presence": "Discord 遊戲動態",
+ "advanced": "進階"
+ },
+ "general": {
+ "general": {
+ "header": "一般",
+ "version": "版本",
+ "latest_app_version": "最新版本",
+ "latest_app_version_refresh": "點擊以重新整理",
+ "repository_url": "原始碼連結",
+ "support": "支援"
+ },
+ "vrcx_updater": {
+ "header": "VRCX 更新器",
+ "change_build": "變更版本",
+ "auto_update": "自動更新",
+ "auto_update_off": "關閉",
+ "auto_update_notify": "通知",
+ "auto_update_download": "自動下載",
+ "auto_update_install": "自動安裝"
+ },
+ "application": {
+ "header": "應用程式",
+ "startup": "在 Windows 啟動時啟動",
+ "minimized": "以最小化啟動",
+ "tray": "最小化到系統列"
+ },
+ "legal_notice": {
+ "header": "法律聲明",
+ "info": "VRCX 是一個提供好友管理的輔助應用程式。這個程式使用非官方的 VRChat API (VRCSDK)。",
+ "disclaimer1": "VRCX 不受 VRChat 的認可,也不反應 VRChat 或任何正式參與製作或管理 VRChat 的觀點或意見。VRChat 是 VRChat Inc. 的商標。 VRChat © VRChat Inc.",
+ "disclaimer2": "pypy 和 Natsumi 將不對使用 VRCX 引起的任何問題負責。使用時請自負風險!",
+ "open_source_software_notice": "開放原始碼軟體授權條款"
+ }
+ },
+ "appearance": {
+ "appearance": {
+ "header": "外觀",
+ "theme_mode": "主題",
+ "theme_mode_system": "系統",
+ "theme_mode_light": "淺色",
+ "theme_mode_dark": "深色",
+ "vrcplus_profile_icons": "VRChat+ 個人檔案圖示",
+ "disable_tooltips": "關閉提示",
+ "sort_favorite_by": "最愛排序依據",
+ "sort_favorite_by_name": "名稱",
+ "sort_favorite_by_date": "時間",
+ "sort_instance_users_by": "坊間玩家排序依據",
+ "sort_instance_users_by_time": "時間",
+ "sort_instance_users_by_alphabet": "字母順序",
+ "table_max_size": "表格大小",
+ "page_size": "頁面大小:"
+ },
+ "timedate": {
+ "header": "時間 / 日期",
+ "time_format": "時間格式",
+ "time_format_24": "24 小時制",
+ "time_format_12": "12 小時制",
+ "force_iso_date_format": "強制使用 ISO 時間格式"
+ },
+ "side_panel": {
+ "header": "側板",
+ "sorting": {
+ "header": "排序",
+ "sort_private_to_bottom": "將 私人世界 排序到底部",
+ "sort_by_status": "依狀態排序",
+ "sort_gps_to_top": "將 GPS 排序到頂部",
+ "sort_gps_to_top_notice": "(僅限上線玩家)",
+ "sort_favorite_by": "最愛玩家 排序依據",
+ "sort_favorite_by_alphabet": "字母順序",
+ "sort_favorite_by_online_time": "上線時長",
+ "sort_online_by": "網頁玩家 排序依據",
+ "sort_online_by_alphabet": "字母順序",
+ "sort_online_by_online_time": "上線時長",
+ "sort_active_by": "上線玩家 排序依據",
+ "sort_active_by_alphabet": "字母順序",
+ "sort_active_by_online_time": "上線時長",
+ "sort_offline_by": "離線玩家 排序依據",
+ "sort_offline_by_alphabet": "字母順序",
+ "sort_offline_by_offline_time": "離線時長"
+ },
+ "width": "寬度"
+ },
+ "user_dialog": {
+ "header": "玩家資訊",
+ "hide_vrchat_notes": "隱藏 VRChat 備註",
+ "hide_vrcx_memos": "隱藏 VRCX 備忘錄",
+ "export_vrcx_memos_into_vrchat_notes": "將 VRCX 備忘錄匯出成 VRChat 備註",
+ "export_notes": "匯出備註"
+ },
+ "user_colors": {
+ "header": "玩家名稱顏色",
+ "random_colors_from_user_id": "從玩家 ID 隨機挑選顏色"
+ }
+ },
+ "notifications": {
+ "notifications": {
+ "header": "通知",
+ "notification_filter": "通知篩選器",
+ "steamvr_notifications": {
+ "header": "SteamVR 通知",
+ "steamvr_overlay": "SteamVR 疊層",
+ "overlay_notifications": "疊層通知",
+ "notification_position": "通知位置",
+ "xsoverlay_notifications": "XSOverlay 通知",
+ "user_images": "玩家照片(較慢)",
+ "notification_timeout": "通知時長"
+ },
+ "desktop_notifications": {
+ "header": "桌面通知",
+ "when_to_display": "顯示時機",
+ "when_to_display_never": "永不",
+ "when_to_display_desktop": "在桌面模式時",
+ "when_to_display_inside_vr": "在 VR 裡時",
+ "when_to_display_outside_vr": "在 VR 外時",
+ "when_to_display_game_closed": "遊戲關閉時",
+ "when_to_display_game_running": "遊戲執行中",
+ "when_to_display_always": "總是"
+ },
+ "text_to_speech": {
+ "header": "文字轉語音選項",
+ "when_to_play": "通知文字轉語音播放時機",
+ "when_to_play_never": "永不",
+ "when_to_play_inside_vr": "在 VR 裡時",
+ "when_to_play_game_closed": "遊戲關閉時",
+ "when_to_play_game_running": "遊戲執行中",
+ "when_to_play_always": "總是",
+ "tts_voice": "語音樣式"
+ }
+ }
+ },
+ "wrist_overlay": {
+ "steamvr_wrist_overlay": {
+ "header": "SteamVR 手腕疊層",
+ "description": "* 當 VRChat 開啟時它會自動開啟",
+ "grip": "握持:Vive 或其它控制器的握持鍵、Oculus X/A 按鍵",
+ "menu": "選單:Vive 選單鍵、Index B、Oculus Y/B 按鍵",
+ "steamvr_overlay": "SteamVR 疊層",
+ "wrist_feed_overlay": "手腕動態疊層",
+ "hide_private_worlds": "隱藏私人世界",
+ "start_overlay_with": "啟動時一併啟動",
+ "overlay_button": "疊層按鍵",
+ "overlay_button_grip": "握持",
+ "overlay_button_menu": "選單",
+ "display_overlay_on": "疊層顯示位置",
+ "display_overlay_on_left": "左手",
+ "display_overlay_on_right": "右手",
+ "display_overlay_on_both": "雙手",
+ "background_color": "背景顏色",
+ "minimal_feed_icons": "迷你動態圖示",
+ "hide_vr_devices": "隱藏 VR 裝置",
+ "hide_cpu_usage": "隱藏 CPU 使用率",
+ "hide_game_uptime": "隱藏啟動時長",
+ "show_pc_uptime": "顯示電腦啟動時長",
+ "wrist_feed_filters": "手腕動態篩選器"
+ }
+ },
+ "discord_presence": {
+ "discord_presence": {
+ "header": "Discord 遊戲動態",
+ "description": "* 僅在 VRChat 開啟時有效",
+ "enable": "啟用",
+ "enable_tooltip": "建議在 VRChat config.json 中停用原生 Discord 遊戲動態來防止衝突",
+ "instance_type_player_count": "房間種類 / 玩家人數",
+ "join_button": "加入按鈕(僅限公開房間)",
+ "hide_details_in_private": "在私人房間時隱藏世界資訊",
+ "hide_images": "隱藏世界縮圖"
+ }
+ },
+ "advanced": {
+ "advanced": {
+ "header": "進階設定",
+ "launch_options": "啟動選項",
+ "pending_offline": {
+ "header": "待確認離線",
+ "description": "將玩家標記為離線之前延遲(防止誤判)",
+ "set_delay": "設定延遲"
+ },
+ "primary_password": {
+ "header": "主密碼",
+ "description": "密碼加密(將停用自動登入)"
+ },
+ "vrchat_quit_fix": {
+ "header": "VRChat 關閉修正",
+ "description": "在離開遊戲時強制停止 VRChat"
+ },
+ "auto_cache_management": {
+ "header": "關閉 VRChat 時自動管理快取",
+ "description": "自動從快取中刪除舊版本"
+ },
+ "remote_database": {
+ "header": "遠端角色資料庫",
+ "enable": "啟用",
+ "avatar_database_provider": "角色資料庫提供方"
+ },
+ "youtube_api": {
+ "header": "Youtube API",
+ "enable": "啟用",
+ "youtube_api_key": "Youtube API 金鑰"
+ },
+ "video_progress_pie": {
+ "header": "影片進度圓餅疊層",
+ "enable": "啟用",
+ "enable_tooltip": "需要啟用 SteamVR 疊層選項",
+ "dance_world_only": "僅限跳舞世界"
+ },
+ "cache_debug": {
+ "header": "VRCX 世界快取/除錯",
+ "disable_gamelog": "關閉遊戲紀錄",
+ "disable_gamelog_notice": "(可能會弄壞很多東西)",
+ "user_cache": "玩家快取:",
+ "world_cache": "世界快取:",
+ "avatar_cache": "角色快取:",
+ "avatar_name_cache": "角色名稱快取:",
+ "clear_cache": "清除快取",
+ "auto_clear_cache": "自動清除快取",
+ "download_history": "下載紀錄",
+ "show_console": "顯示主控台"
+ },
+ "sqlite_table_size": {
+ "header": "SQLite 數據表大小",
+ "refresh": "重新整理",
+ "gps": "GPS:",
+ "status": "狀態:",
+ "bio": "自我介紹:",
+ "avatar": "角色:",
+ "online_offline": "上線 / 離線:",
+ "friend_log_history": "好友歷史紀錄:",
+ "notification": "通知:",
+ "location": "位置:",
+ "join_leave": "加入 / 離開:",
+ "portal_spawn": "開啟傳送門:",
+ "video_play": "影片播放:",
+ "event": "事件:"
+ }
+ },
+ "photon": {
+ "header": "Photon 紀錄疊層",
+ "event_hud": {
+ "header": "Photon 事件 HUD",
+ "enable": "啟用",
+ "enable_tooltip": "需要啟用 SteamVR 疊層選項",
+ "filter": "篩選器",
+ "filter_favorites": "最愛",
+ "filter_friends": "好友",
+ "filter_everyone": "所有人",
+ "message_timeout": "訊息時長"
+ },
+ "event_hud": {
+ "header": "玩家愈時 HUD",
+ "enable": "啟用",
+ "enable_tooltip": "需要啟用 SteamVR 疊層選項",
+ "filter": "篩選器",
+ "filter_favorites": "最愛",
+ "filter_friends": "好友",
+ "filter_everyone": "所有人",
+ "timeout_threshold": "愈時閾值"
+ }
+ }
+ }
+ }
+ },
+ "side_panel": {
+ "search_placeholder": "搜尋",
+ "search_result_active": "活躍",
+ "search_result_offline": "離線",
+ "search_result_more": "搜尋更多:",
+ "direct_access_tooltip": "直接存取解貼簿的 ID / 連結",
+ "refresh_tooltip": "重新整理好友",
+ "friends": "好友",
+ "me": "我",
+ "favorite": "最愛",
+ "online": "上線",
+ "active": "活躍",
+ "offline": "離線",
+ "penfing_offline": "待確認離線"
+ },
+ "dialog": {
+ "user": {
+ "status": {
+ "active": "活躍",
+ "offline": "離線",
+ "online": "上線",
+ "join_me": "加入我",
+ "ask_me": "詢問我",
+ "busy": "請勿打擾"
+ },
+ "previous_display_names": "過去的顯示名稱:",
+ "tags": {
+ "friend_no": "第 {number} 位好友",
+ "vrchat_team": "VRChat 團隊"
+ },
+ "actions": {
+ "favorite_tooltip": "添加到我的最愛",
+ "unfavorite_tooltip": "從我的最愛中移除",
+ "refresh": "重新整理",
+ "copy_url": "複製玩家連結",
+ "invite": "邀請",
+ "invite_with_message": "邀請(訊息)",
+ "request_invite": "請求邀請",
+ "request_invite_with_message": "請求邀請(訊息)",
+ "invite_to_group": "邀情到群組",
+ "manage_gallery_icon": "管理相簿 / 圖示",
+ "accept_friend_request": "接受好友邀請",
+ "deny_friend_request": "回絕好友邀請",
+ "cancel_friend_request": "取消好友邀請",
+ "send_friend_request": "傳送好友邀請",
+ "show_avatar_author": "顯示角色作者",
+ "show_fallback_avatar": "顯示備用角色資訊",
+ "show_previous_instances": "顯示過去的房間",
+ "show_previous_images": "顯示角色以前的圖片",
+ "moderation_block": "封鎖",
+ "moderation_unblock": "解除封鎖",
+ "moderation_mute": "靜音",
+ "moderation_unmute": "解除靜音",
+ "moderation_hide_avatar": "顯示角色",
+ "moderation_show_avatar": "隱藏角色",
+ "moderation_enable_avatar_interaction": "開啟角色互動",
+ "moderation_disable_avatar_interaction": "關閉角色互動",
+ "edit_status": "社交狀態",
+ "edit_language": "語言",
+ "edit_bio": "自我介紹",
+ "unfriend": "解除好友",
+ "logout": "登出"
+ },
+ "info": {
+ "header": "資訊",
+ "launch_invite_tooltip": "啟動 / 邀請",
+ "self_invite_tooltip": "自我邀請",
+ "refresh_user_count_tooltip": "重新整理房間人數",
+ "instance_creator": "房間建立者",
+ "note": "備註",
+ "note_placeholder": "點擊添加備註",
+ "memo": "備忘錄",
+ "memo_placeholder": "點擊添加備忘錄",
+ "avatar_info": "角色資訊",
+ "avatar_info_last_seen": "最後已知角色資訊",
+ "represented_group": "代表群組",
+ "bio": "自我介紹",
+ "last_seen": "最後上線",
+ "join_count": "加入次數",
+ "time_together": "一起遊玩時長",
+ "online_for": "上線時長",
+ "offline_for": "離線時長",
+ "last_activity": "最後動態",
+ "last_login": "最後登入",
+ "date_joined": "加入時間",
+ "friended": "好友",
+ "unfriended": "解除好友",
+ "avatar_cloning": "角色複製",
+ "avatar_cloning_allow": "允許",
+ "avatar_cloning_deny": "不允許",
+ "home_location": "家點",
+ "accuracy_notice": "本地資料庫的資料可能不精確"
+ },
+ "groups": {
+ "header": "群組",
+ "total_count": "總共 {count}",
+ "own_groups": "擁有群組",
+ "mutual_groups": "共同群組",
+ "groups": "群組"
+ },
+ "worlds": {
+ "header": "世界",
+ "total_count": "總共 {count}",
+ "sort_by_name": "依名稱排序",
+ "sort_by_update": "依更新排序"
+ },
+ "favorite_worlds": {
+ "header": "最愛世界"
+ },
+ "avatars": {
+ "header": "角色",
+ "total_count": "總共 {count}",
+ "sort_by_name": "依名稱排序",
+ "sort_by_update": "依更新排序",
+ "all": "所有",
+ "public": "公開",
+ "private": "私人"
+ },
+ "json": {
+ "header": "原始資料"
+ }
+ },
+ "world": {
+ "tags": {
+ "public": "公開",
+ "private": "私人",
+ "labs": "社區實驗室",
+ "cache": "快取"
+ },
+ "actions": {
+ "delete_cache_tooltip": "從快取中刪除世界",
+ "favorite_tooltip": "添加到我的最愛",
+ "unfavorite_tooltip": "從我的最愛中移除",
+ "refresh": "重新整理",
+ "new_instance": "新房間",
+ "make_home": "設為家點",
+ "reset_home": "重設家點",
+ "show_previous_instances": "顯示過去的房間",
+ "show_previous_images": "顯示過去的圖片",
+ "rename": "重新命名",
+ "change_description": "變更敘述",
+ "change_capacity": "變更最大玩家上限",
+ "change_preview": "變更 YouTube 預覽",
+ "change_tags": "變更標籤",
+ "change_image": "變更圖片",
+ "download_package": "下載 Unity Package",
+ "publish_to_labs": "發佈到社區實驗室",
+ "unpublish": "取消發佈",
+ "delete": "刪除"
+ },
+ "instances": {
+ "header": "房間",
+ "public_count": "公開 {count}",
+ "private_count": "私人 {count}",
+ "capacity_count": "玩家上限 {count} ({max})",
+ "self_invite_tooltip": "自我邀請",
+ "refresh_user_count_tooltip": "重新整理房間人數",
+ "instance_creator": "房間建立者"
+ },
+ "info": {
+ "header": "資訊",
+ "id": "世界 ID",
+ "id_tooltip": "複製到剪貼簿",
+ "copy_id": "複製 ID",
+ "copy_url": "複製連結",
+ "youtube_preview": "YouTube 預覽",
+ "players": "玩家人數",
+ "favorites": "最愛次數",
+ "visits": "總綁訪次數",
+ "capacity": "最大玩家上限",
+ "heat": "熱度",
+ "popularity": "熱門度",
+ "created_at": "創建時間",
+ "last_updated": "最後更新",
+ "version": "版本",
+ "platform": "平台",
+ "last_visited": "上次拜訪",
+ "visit_count": "我綁訪次數",
+ "time_spent": "停留時長",
+ "accuracy_notice": "本地資料庫的資料可能不精確"
+ },
+ "json": {
+ "header": "原始資料"
+ }
+ },
+ "avatar": {
+ "header": "角色",
+ "tags": {
+ "public": "公開",
+ "private": "私人",
+ "fallback": "備用",
+ "cache": "快取"
+ },
+ "actions": {
+ "delete_cache_tooltip": "從快取中刪除角色",
+ "favorite_tooltip": "添加到我的最愛",
+ "unfavorite_tooltip": "從我的最愛中移除",
+ "refresh": "重新整理",
+ "select": "選擇角色",
+ "select_fallback": "選擇為備用角色",
+ "block": "封鎖角色",
+ "unblock": "解除封鎖角色",
+ "show_previous_images": "顯示過去的圖片",
+ "make_public": "設為公開",
+ "make_private": "設為私人",
+ "rename": "重新命名",
+ "change_description": "變更敘述",
+ "change_image": "變更圖片",
+ "download_package": "下載 Unity Package",
+ "delete": "刪除"
+ },
+ "info": {
+ "header": "資訊",
+ "id": "角色 ID",
+ "id_tooltip": "複製到剪貼簿",
+ "copy_id": "複製 ID",
+ "copy_url": "複製連結",
+ "created_at": "創建時間",
+ "last_updated": "最後更新",
+ "version": "版本",
+ "platform": "平台"
+ },
+ "json": {
+ "header": "原始資料"
+ }
+ },
+ "group": {
+ "tags": {
+ "verified": "已認證",
+ "public": "公開",
+ "private": "私人",
+ "open": "開放",
+ "request": "請求",
+ "invite": "邀請",
+ "closed": "關閉",
+ "joined": "已加入",
+ "banned": "已封鎖",
+ "visible": "能見度:所有人",
+ "friends": "能見度:好友",
+ "hidden": "能見度:隱藏",
+ "subscribed": "已訂閱公告"
+ },
+ "actions": {
+ "represent_tooltip": "顯示在個人檔案上",
+ "unrepresent_tooltip": "停止顯示在個人檔案上",
+ "cancel_join_request_tooltip": "取消加入請求",
+ "pending_request_tooltip": "待接受邀請",
+ "request_join_tooltip": "清求加入",
+ "invite_required_tooltip": "需要被邀請才能加入",
+ "join_group_tooltip": "加入群組",
+ "refresh": "重新整理",
+ "unsubscribe": "取消訂閱公告",
+ "subscribe": "訂閱公告",
+ "invite_to_group": "邀請到群組",
+ "visibility_everyone": "能見度:所有人",
+ "visibility_friends": "能見度:好友",
+ "visibility_hidden": "能見度:隱藏",
+ "leave": "離開群組"
+ },
+ "info": {
+ "header": "資訊",
+ "announcement": "公告",
+ "rules": "規則",
+ "members": "成員",
+ "created_at": "創建時間",
+ "links": "連結",
+ "url": "群組連結",
+ "url_tooltip": "複製連結到剪貼簿",
+ "id": "群組 ID",
+ "id_tooltip": "複製 ID 到剪貼簿",
+ "joined_at": "加入時間",
+ "roles": "身分",
+ "role_description": "敘述:",
+ "role_updated_at": "更新時間:",
+ "role_created_at": "創建時間:",
+ "role_permissions": "權限:"
+ },
+ "members": {
+ "header": "成員",
+ "all_members": "所有成員",
+ "friends_only": "好友",
+ "load_more": "載入更多……"
+ },
+ "json": {
+ "header": "原始資料"
+ }
+ },
+ "social_status": {
+ "header": "社交狀態",
+ "history": "過去的社交狀態",
+ "status_placeholder": "今天心情如何?",
+ "update": "更新"
+ },
+ "language": {
+ "header": "語言",
+ "add_language": "新增語言",
+ "select_language": "選擇語言",
+ "ok": "確定",
+ "cancel": "取消"
+ },
+ "bio": {
+ "header": "自我介紹",
+ "bio_placeholder": "在這裡介紹一下自己吧!",
+ "add_link": "新增社交連結",
+ "update": "更新"
+ }
+ },
+ "table": {
+ "feed": {
+ "date": "時間",
+ "type": "類型",
+ "user": "玩家",
+ "detail": "詳細"
+ },
+ "gameLog": {
+ "date": "時間",
+ "type": "類型",
+ "user": "玩家",
+ "detail": "詳細"
+ },
+ "playerList": {
+ "avatar": "角色",
+ "timer": "時長",
+ "photonId": "Photon ID",
+ "icon": "圖示",
+ "platform": "平台",
+ "displayName": "顯示名稱",
+ "status": "狀態",
+ "rank": "階級",
+ "language": "語言",
+ "bioLink": "社交連結"
+ },
+ "friendLog": {
+ "date": "時間",
+ "type": "類型",
+ "user": "玩家",
+ "action": "動作"
+ },
+ "moderation": {
+ "date": "時間",
+ "type": "類型",
+ "source": "來源",
+ "target": "目標",
+ "action": "動作"
+ },
+ "notification": {
+ "date": "時間",
+ "type": "類型",
+ "user": "玩家",
+ "photo": "照片",
+ "message": "訊息",
+ "action": "動作"
+ },
+ "friendList": {
+ "no": "No.",
+ "avatar": "角色",
+ "displayName": "顯示名稱",
+ "rank": "階級",
+ "status": "狀態",
+ "language": "語言",
+ "bioLink": "社交連結",
+ "joinCount": "加入次數",
+ "timeTogether": "一起遊玩時長",
+ "lastSeen": "最後上線",
+ "lastActivity": "最後活動",
+ "lastLogin": "最後登入",
+ "dateJoined": "加入時間",
+ "unfriend": "解除好友"
+ },
+ "social_status": {
+ "no": "No.",
+ "status": "狀蓋"
+ }
+ }
+}
\ No newline at end of file