mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-04-29 11:43:48 +02:00
3
.gitignore
vendored
3
.gitignore
vendored
@@ -259,6 +259,3 @@ paket-files/
|
|||||||
# Python Tools for Visual Studio (PTVS)
|
# Python Tools for Visual Studio (PTVS)
|
||||||
__pycache__/
|
__pycache__/
|
||||||
*.pyc
|
*.pyc
|
||||||
|
|
||||||
# Visual Studio Code config directory
|
|
||||||
.vscode/
|
|
||||||
8
.vscode/i18n-ally-custom-framework.yml
vendored
Normal file
8
.vscode/i18n-ally-custom-framework.yml
vendored
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
languageIds:
|
||||||
|
- jade
|
||||||
|
- javascript
|
||||||
|
- vue
|
||||||
|
|
||||||
|
usageMatchRegex: "\\$t\\(['\"`]({key})['\"`]"
|
||||||
|
|
||||||
|
monoonly: true
|
||||||
5
.vscode/settings.json
vendored
Normal file
5
.vscode/settings.json
vendored
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"i18n-ally.localesPaths": ["html/src/localization/strings"],
|
||||||
|
"i18n-ally.keystyle": "nested",
|
||||||
|
"i18n-ally.sourceLanguage": "en"
|
||||||
|
}
|
||||||
41
AppApi.cs
41
AppApi.cs
@@ -5,26 +5,26 @@
|
|||||||
// For a copy, see <https://opensource.org/licenses/MIT>.
|
// For a copy, see <https://opensource.org/licenses/MIT>.
|
||||||
|
|
||||||
using CefSharp;
|
using CefSharp;
|
||||||
using Microsoft.Win32;
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Management;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Windows.Forms;
|
|
||||||
using System.IO;
|
|
||||||
using System.Security.Cryptography;
|
|
||||||
using System.Net;
|
|
||||||
using Windows.UI.Notifications;
|
|
||||||
using Windows.Data.Xml.Dom;
|
|
||||||
using librsync.net;
|
using librsync.net;
|
||||||
using System.Net.Sockets;
|
using Microsoft.Win32;
|
||||||
using System.Text;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Threading;
|
|
||||||
using System.IO.Pipes;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.IO.Pipes;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Sockets;
|
||||||
|
using System.Security.Cryptography;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Windows.Forms;
|
||||||
|
using Windows.Data.Xml.Dom;
|
||||||
|
using Windows.UI.Notifications;
|
||||||
|
|
||||||
namespace VRCX
|
namespace VRCX
|
||||||
{
|
{
|
||||||
@@ -410,7 +410,12 @@ namespace VRCX
|
|||||||
|
|
||||||
public string CurrentCulture()
|
public string CurrentCulture()
|
||||||
{
|
{
|
||||||
return System.Globalization.CultureInfo.CurrentCulture.ToString();
|
return CultureInfo.CurrentCulture.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string CurrentLanguage()
|
||||||
|
{
|
||||||
|
return CultureInfo.InstalledUICulture.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string GetVersion()
|
public string GetVersion()
|
||||||
|
|||||||
@@ -6,12 +6,20 @@
|
|||||||
"commonjs": true,
|
"commonjs": true,
|
||||||
"es2021": true
|
"es2021": true
|
||||||
},
|
},
|
||||||
|
"parser": "@babel/eslint-parser",
|
||||||
"parserOptions": {
|
"parserOptions": {
|
||||||
"ecmaVersion": "latest",
|
"ecmaVersion": "latest",
|
||||||
"sourceType": "module",
|
"sourceType": "module",
|
||||||
"ecmaFeatures": {
|
"ecmaFeatures": {
|
||||||
"impliedStrict": true,
|
"impliedStrict": true,
|
||||||
"jsx": true
|
"jsx": true
|
||||||
|
},
|
||||||
|
"requireConfigFile": false,
|
||||||
|
"babelOptions": {
|
||||||
|
"presets": ["@babel/preset-env"],
|
||||||
|
"parserOpts": {
|
||||||
|
"plugins": ["importAssertions"]
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"globals": {
|
"globals": {
|
||||||
|
|||||||
3447
html/package-lock.json
generated
3447
html/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -22,6 +22,9 @@
|
|||||||
},
|
},
|
||||||
"homepage": "https://github.com/pypy-vrc/VRCX#readme",
|
"homepage": "https://github.com/pypy-vrc/VRCX#readme",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"@babel/eslint-parser": "^7.19.1",
|
||||||
|
"@babel/plugin-syntax-import-assertions": "^7.20.0",
|
||||||
|
"@babel/preset-env": "^7.20.2",
|
||||||
"@fontsource/noto-sans-jp": "^4.5.12",
|
"@fontsource/noto-sans-jp": "^4.5.12",
|
||||||
"@fontsource/noto-sans-kr": "^4.5.12",
|
"@fontsource/noto-sans-kr": "^4.5.12",
|
||||||
"animate.css": "^4.1.1",
|
"animate.css": "^4.1.1",
|
||||||
@@ -44,6 +47,7 @@
|
|||||||
"uuid": "^9.0.0",
|
"uuid": "^9.0.0",
|
||||||
"vue": "^2.6.14",
|
"vue": "^2.6.14",
|
||||||
"vue-data-tables": "^3.4.5",
|
"vue-data-tables": "^3.4.5",
|
||||||
|
"vue-i18n": "^8.28.2",
|
||||||
"vue-lazyload": "^1.3.4",
|
"vue-lazyload": "^1.3.4",
|
||||||
"vue-marquee-text-component": "^1.2.0",
|
"vue-marquee-text-component": "^1.2.0",
|
||||||
"webpack": "^5.75.0",
|
"webpack": "^5.75.0",
|
||||||
|
|||||||
551
html/src/app.js
551
html/src/app.js
@@ -9,9 +9,9 @@ import '@fontsource/noto-sans-jp';
|
|||||||
import Noty from 'noty';
|
import Noty from 'noty';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import VueLazyload from 'vue-lazyload';
|
import VueLazyload from 'vue-lazyload';
|
||||||
|
import VueI18n from 'vue-i18n';
|
||||||
import {DataTables} from 'vue-data-tables';
|
import {DataTables} from 'vue-data-tables';
|
||||||
import ElementUI from 'element-ui';
|
import ElementUI from 'element-ui';
|
||||||
import locale from 'element-ui/lib/locale/lang/en';
|
|
||||||
import {v4 as uuidv4} from 'uuid';
|
import {v4 as uuidv4} from 'uuid';
|
||||||
import * as workerTimers from 'worker-timers';
|
import * as workerTimers from 'worker-timers';
|
||||||
import 'default-passive-events';
|
import 'default-passive-events';
|
||||||
@@ -21,6 +21,7 @@ import webApiService from './service/webapi.js';
|
|||||||
import gameLogService from './service/gamelog.js';
|
import gameLogService from './service/gamelog.js';
|
||||||
import security from './security.js';
|
import security from './security.js';
|
||||||
import database from './repository/database.js';
|
import database from './repository/database.js';
|
||||||
|
import * as localizedStrings from './localization/localizedStrings.js';
|
||||||
|
|
||||||
speechSynthesis.getVoices();
|
speechSynthesis.getVoices();
|
||||||
|
|
||||||
@@ -125,8 +126,18 @@ speechSynthesis.getVoices();
|
|||||||
timeout: 6000
|
timeout: 6000
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Vue.use(VueI18n);
|
||||||
|
|
||||||
|
var i18n = new VueI18n({
|
||||||
|
locale: 'en',
|
||||||
|
fallbackLocale: 'en',
|
||||||
|
messages: localizedStrings
|
||||||
|
});
|
||||||
|
|
||||||
|
var $t = i18n.t.bind(i18n);
|
||||||
|
|
||||||
Vue.use(ElementUI, {
|
Vue.use(ElementUI, {
|
||||||
locale
|
i18n: (key, value) => i18n.t(key, value)
|
||||||
});
|
});
|
||||||
|
|
||||||
var removeFromArray = function (array, item) {
|
var removeFromArray = function (array, item) {
|
||||||
@@ -4657,6 +4668,7 @@ speechSynthesis.getVoices();
|
|||||||
exportFriendsListDialog: false,
|
exportFriendsListDialog: false,
|
||||||
exportFriendsListContent: ''
|
exportFriendsListContent: ''
|
||||||
},
|
},
|
||||||
|
i18n,
|
||||||
computed: {},
|
computed: {},
|
||||||
methods: {},
|
methods: {},
|
||||||
watch: {},
|
watch: {},
|
||||||
@@ -6405,16 +6417,13 @@ speechSynthesis.getVoices();
|
|||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptTOTP = function () {
|
$app.methods.promptTOTP = function () {
|
||||||
this.$prompt(
|
this.$prompt($t('prompt.totp.description'), $t('prompt.totp.header'), {
|
||||||
'Enter a numeric code from your authenticator app',
|
|
||||||
'Two-factor Authentication',
|
|
||||||
{
|
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
cancelButtonText: 'Use OTP',
|
cancelButtonText: $t('prompt.totp.use_otp'),
|
||||||
confirmButtonText: 'Verify',
|
confirmButtonText: $t('prompt.totp.verify'),
|
||||||
inputPlaceholder: 'Code',
|
inputPlaceholder: $t('prompt.totp.input_placeholder'),
|
||||||
inputPattern: /^[0-9]{6}$/,
|
inputPattern: /^[0-9]{6}$/,
|
||||||
inputErrorMessage: 'Invalid Code',
|
inputErrorMessage: $t('prompt.totp.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
API.verifyTOTP({
|
API.verifyTOTP({
|
||||||
@@ -6432,21 +6441,17 @@ speechSynthesis.getVoices();
|
|||||||
this.promptOTP();
|
this.promptOTP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptOTP = function () {
|
$app.methods.promptOTP = function () {
|
||||||
this.$prompt(
|
this.$prompt($t('prompt.otp.description'), $t('prompt.otp.header'), {
|
||||||
'Enter one of your saved recovery codes',
|
|
||||||
'Two-factor Authentication',
|
|
||||||
{
|
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
cancelButtonText: 'Use TOTP',
|
cancelButtonText: $t('prompt.otp.use_otp'),
|
||||||
confirmButtonText: 'Verify',
|
confirmButtonText: $t('prompt.otp.verify'),
|
||||||
inputPlaceholder: 'Code',
|
inputPlaceholder: $t('prompt.otp.input_placeholder'),
|
||||||
inputPattern: /^[a-z0-9]{4}-[a-z0-9]{4}$/,
|
inputPattern: /^[a-z0-9]{4}-[a-z0-9]{4}$/,
|
||||||
inputErrorMessage: 'Invalid Code',
|
inputErrorMessage: $t('prompt.otp.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
API.verifyOTP({
|
API.verifyOTP({
|
||||||
@@ -6464,21 +6469,20 @@ speechSynthesis.getVoices();
|
|||||||
this.promptTOTP();
|
this.promptTOTP();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptEmailOTP = function () {
|
$app.methods.promptEmailOTP = function () {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
'Enter a numeric code that was sent to your email',
|
$t('prompt.email_otp.description'),
|
||||||
'Email Two-factor Authentication',
|
$t('prompt.email_otp.header'),
|
||||||
{
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.email_otp.cancel'),
|
||||||
confirmButtonText: 'Verify',
|
confirmButtonText: $t('prompt.email_otp.verify'),
|
||||||
inputPlaceholder: 'Code',
|
inputPlaceholder: $t('prompt.email_otp.input_placeholder'),
|
||||||
inputPattern: /^[0-9]{6}$/,
|
inputPattern: /^[0-9]{6}$/,
|
||||||
inputErrorMessage: 'Invalid Code',
|
inputErrorMessage: $t('prompt.email_otp.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
API.verifyEmailOTP({
|
API.verifyEmailOTP({
|
||||||
@@ -6614,8 +6618,8 @@ speechSynthesis.getVoices();
|
|||||||
resolve(args.password);
|
resolve(args.password);
|
||||||
}
|
}
|
||||||
$app.$prompt(
|
$app.$prompt(
|
||||||
'Please enter your Primary Password.',
|
$t('prompt.primary_password.description'),
|
||||||
'Primary Password Required',
|
$t('prompt.primary_password.header'),
|
||||||
{
|
{
|
||||||
inputType: 'password',
|
inputType: 'password',
|
||||||
inputPattern: /[\s\S]{1,32}/
|
inputPattern: /[\s\S]{1,32}/
|
||||||
@@ -6650,8 +6654,8 @@ speechSynthesis.getVoices();
|
|||||||
this.enablePrimaryPasswordDialog.visible = true;
|
this.enablePrimaryPasswordDialog.visible = true;
|
||||||
} else {
|
} else {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
'Please enter your Primary Password.',
|
$t('prompt.primary_password.description'),
|
||||||
'Primary Password Required',
|
$t('prompt.primary_password.header'),
|
||||||
{
|
{
|
||||||
inputType: 'password',
|
inputType: 'password',
|
||||||
inputPattern: /[\s\S]{1,32}/
|
inputPattern: /[\s\S]{1,32}/
|
||||||
@@ -6905,8 +6909,8 @@ speechSynthesis.getVoices();
|
|||||||
this.enablePrimaryPassword
|
this.enablePrimaryPassword
|
||||||
) {
|
) {
|
||||||
$app.$prompt(
|
$app.$prompt(
|
||||||
'Please enter your Primary Password.',
|
$t('prompt.primary_password.description'),
|
||||||
'Primary Password Required',
|
$t('prompt.primary_password.header'),
|
||||||
{
|
{
|
||||||
inputType: 'password',
|
inputType: 'password',
|
||||||
inputPattern: /[\s\S]{1,32}/
|
inputPattern: /[\s\S]{1,32}/
|
||||||
@@ -11780,14 +11784,25 @@ speechSynthesis.getVoices();
|
|||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.changeFavoriteGroupName = function (ctx) {
|
$app.methods.changeFavoriteGroupName = function (ctx) {
|
||||||
this.$prompt('Enter a new name', 'Change Group Name', {
|
this.$prompt(
|
||||||
|
$t('prompt.change_favorite_group_name.description'),
|
||||||
|
$t('prompt.change_favorite_group_name.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t(
|
||||||
confirmButtonText: 'Change',
|
'prompt.change_favorite_group_name.cancel'
|
||||||
inputPlaceholder: 'Name',
|
),
|
||||||
|
confirmButtonText: $t(
|
||||||
|
'prompt.change_favorite_group_name.change'
|
||||||
|
),
|
||||||
|
inputPlaceholder: $t(
|
||||||
|
'prompt.change_favorite_group_name.input_placeholder'
|
||||||
|
),
|
||||||
inputValue: ctx.displayName,
|
inputValue: ctx.displayName,
|
||||||
inputPattern: /\S+/,
|
inputPattern: /\S+/,
|
||||||
inputErrorMessage: 'Name is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.change_favorite_group_name.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm') {
|
if (action === 'confirm') {
|
||||||
API.saveFavoriteGroup({
|
API.saveFavoriteGroup({
|
||||||
@@ -11796,14 +11811,17 @@ speechSynthesis.getVoices();
|
|||||||
displayName: instance.inputValue
|
displayName: instance.inputValue
|
||||||
}).then((args) => {
|
}).then((args) => {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'Group renamed',
|
message: $t(
|
||||||
|
'prompt.change_favorite_group_name.message.success'
|
||||||
|
),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
});
|
});
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.clearFavoriteGroup = function (ctx) {
|
$app.methods.clearFavoriteGroup = function (ctx) {
|
||||||
@@ -13259,7 +13277,8 @@ speechSynthesis.getVoices();
|
|||||||
notificationTheme,
|
notificationTheme,
|
||||||
backgroundEnabled: this.vrBackgroundEnabled,
|
backgroundEnabled: this.vrBackgroundEnabled,
|
||||||
dtHour12: this.dtHour12,
|
dtHour12: this.dtHour12,
|
||||||
pcUptimeOnFeed: this.pcUptimeOnFeed
|
pcUptimeOnFeed: this.pcUptimeOnFeed,
|
||||||
|
appLanguage: this.appLanguage
|
||||||
};
|
};
|
||||||
var json = JSON.stringify(VRConfigVars);
|
var json = JSON.stringify(VRConfigVars);
|
||||||
AppApi.ExecuteVrFeedFunction('configUpdate', json);
|
AppApi.ExecuteVrFeedFunction('configUpdate', json);
|
||||||
@@ -13452,12 +13471,17 @@ speechSynthesis.getVoices();
|
|||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptUserIdDialog = function () {
|
$app.methods.promptUserIdDialog = function () {
|
||||||
this.$prompt('Enter a User URL or ID (UUID)', 'Direct Access', {
|
this.$prompt(
|
||||||
|
$t('prompt.direct_access_user_id.description'),
|
||||||
|
$t('prompt.direct_access_user_id.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.direct_access_user_id.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.direct_access_user_id.cancel'),
|
||||||
inputPattern: /\S+/,
|
inputPattern: /\S+/,
|
||||||
inputErrorMessage: 'User URL/ID is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.direct_access_user_id.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
var testUrl = instance.inputValue.substring(0, 15);
|
var testUrl = instance.inputValue.substring(0, 15);
|
||||||
@@ -13467,7 +13491,9 @@ speechSynthesis.getVoices();
|
|||||||
this.showUserDialog(userId);
|
this.showUserDialog(userId);
|
||||||
} else {
|
} else {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'Invalid URL',
|
message: $t(
|
||||||
|
'prompt.direct_access_user_id.message.error'
|
||||||
|
),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -13476,61 +13502,85 @@ speechSynthesis.getVoices();
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptUsernameDialog = function () {
|
$app.methods.promptUsernameDialog = function () {
|
||||||
this.$prompt('Enter a Username', 'Direct Access', {
|
this.$prompt(
|
||||||
|
$t('prompt.direct_access_username.description'),
|
||||||
|
$t('prompt.direct_access_username.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.direct_access_username.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.direct_access_username.cancel'),
|
||||||
inputPattern: /\S+/,
|
inputPattern: /\S+/,
|
||||||
inputErrorMessage: 'Username is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.direct_access_username.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
this.lookupUser({displayName: instance.inputValue});
|
this.lookupUser({displayName: instance.inputValue});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptWorldDialog = function () {
|
$app.methods.promptWorldDialog = function () {
|
||||||
this.$prompt('Enter a World URL or ID (UUID)', 'Direct Access', {
|
this.$prompt(
|
||||||
|
$t('prompt.direct_access_world_id.description'),
|
||||||
|
$t('prompt.direct_access_world_id.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.direct_access_world_id.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.direct_access_world_id.cancel'),
|
||||||
inputPattern: /\S+/,
|
inputPattern: /\S+/,
|
||||||
inputErrorMessage: 'World URL/ID is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.direct_access_world_id.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
if (!this.directAccessWorld(instance.inputValue)) {
|
if (!this.directAccessWorld(instance.inputValue)) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'Invalid URL/id',
|
message: $t(
|
||||||
|
'prompt.direct_access_world_id.message.error'
|
||||||
|
),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptAvatarDialog = function () {
|
$app.methods.promptAvatarDialog = function () {
|
||||||
this.$prompt('Enter a Avatar URL or ID (UUID)', 'Direct Access', {
|
this.$prompt(
|
||||||
|
$t('prompt.direct_access_avatar_id.description'),
|
||||||
|
$t('prompt.direct_access_avatar_id.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.direct_access_avatar_id.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.direct_access_avatar_id.cancel'),
|
||||||
inputPattern: /\S+/,
|
inputPattern: /\S+/,
|
||||||
inputErrorMessage: 'Avatar URL/ID is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.direct_access_avatar_id.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
var testUrl = instance.inputValue.substring(0, 15);
|
var testUrl = instance.inputValue.substring(0, 15);
|
||||||
if (testUrl === 'https://vrchat.') {
|
if (testUrl === 'https://vrchat.') {
|
||||||
var avatarId = this.parseAvatarUrl(instance.inputValue);
|
var avatarId = this.parseAvatarUrl(
|
||||||
|
instance.inputValue
|
||||||
|
);
|
||||||
if (avatarId) {
|
if (avatarId) {
|
||||||
this.showAvatarDialog(avatarId);
|
this.showAvatarDialog(avatarId);
|
||||||
} else {
|
} else {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'Invalid URL',
|
message: $t(
|
||||||
|
'prompt.direct_access_avatar_id.message.error'
|
||||||
|
),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -13539,25 +13589,28 @@ speechSynthesis.getVoices();
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptOmniDirectDialog = function () {
|
$app.methods.promptOmniDirectDialog = function () {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
'Enter a User/World/Instance/Avatar/Group URL or ID (UUID)',
|
$t('prompt.direct_access_omni.description'),
|
||||||
'Direct Access',
|
$t('prompt.direct_access_omni.header'),
|
||||||
{
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.direct_access_omni.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.direct_access_omni.cancel'),
|
||||||
inputPattern: /\S+/,
|
inputPattern: /\S+/,
|
||||||
inputErrorMessage: 'URL/ID is required',
|
inputErrorMessage: $t('prompt.direct_access_omni.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
var input = instance.inputValue;
|
var input = instance.inputValue;
|
||||||
if (!this.directAccessParse(input)) {
|
if (!this.directAccessParse(input)) {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'Invalid URL/ID',
|
message: $t(
|
||||||
|
'prompt.direct_access_omni.message.error'
|
||||||
|
),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -13689,13 +13742,18 @@ speechSynthesis.getVoices();
|
|||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptNotificationTimeout = function () {
|
$app.methods.promptNotificationTimeout = function () {
|
||||||
this.$prompt('Enter amount of seconds', 'Notification Timeout', {
|
this.$prompt(
|
||||||
|
$t('prompt.notification_timeout.description'),
|
||||||
|
$t('prompt.notification_timeout.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.notification_timeout.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.notification_timeout.cancel'),
|
||||||
inputValue: this.notificationTimeout / 1000,
|
inputValue: this.notificationTimeout / 1000,
|
||||||
inputPattern: /\d+$/,
|
inputPattern: /\d+$/,
|
||||||
inputErrorMessage: 'Valid number is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.notification_timeout.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13712,17 +13770,23 @@ speechSynthesis.getVoices();
|
|||||||
this.updateVRConfigVars();
|
this.updateVRConfigVars();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptPhotonOverlayMessageTimeout = function () {
|
$app.methods.promptPhotonOverlayMessageTimeout = function () {
|
||||||
this.$prompt('Enter amount of seconds', 'Overlay Message Timeout', {
|
this.$prompt(
|
||||||
|
$t('prompt.overlay_message_timeout.description'),
|
||||||
|
$t('prompt.overlay_message_timeout.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.overlay_message_timeout.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.overlay_message_timeout.cancel'),
|
||||||
inputValue: this.photonOverlayMessageTimeout / 1000,
|
inputValue: this.photonOverlayMessageTimeout / 1000,
|
||||||
inputPattern: /\d+$/,
|
inputPattern: /\d+$/,
|
||||||
inputErrorMessage: 'Valid number is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.overlay_message_timeout.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13739,16 +13803,20 @@ speechSynthesis.getVoices();
|
|||||||
this.updateVRConfigVars();
|
this.updateVRConfigVars();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptRenameAvatar = function (avatar) {
|
$app.methods.promptRenameAvatar = function (avatar) {
|
||||||
this.$prompt('Enter avatar name', 'Rename Avatar', {
|
this.$prompt(
|
||||||
|
$t('prompt.rename_avatar.description'),
|
||||||
|
$t('prompt.rename_avatar.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.rename_avatar.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.rename_avatar.cancel'),
|
||||||
inputValue: avatar.ref.name,
|
inputValue: avatar.ref.name,
|
||||||
inputErrorMessage: 'Valid name is required',
|
inputErrorMessage: $t('prompt.rename_avatar.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13759,23 +13827,31 @@ speechSynthesis.getVoices();
|
|||||||
name: instance.inputValue
|
name: instance.inputValue
|
||||||
}).then((args) => {
|
}).then((args) => {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'Avatar renamed',
|
message: $t(
|
||||||
|
'prompt.rename_avatar.message.success'
|
||||||
|
),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
});
|
});
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptChangeAvatarDescription = function (avatar) {
|
$app.methods.promptChangeAvatarDescription = function (avatar) {
|
||||||
this.$prompt('Enter avatar description', 'Change Description', {
|
this.$prompt(
|
||||||
|
$t('prompt.change_avatar_description.description'),
|
||||||
|
$t('prompt.change_avatar_description.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.change_avatar_description.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.change_avatar_description.cancel'),
|
||||||
inputValue: avatar.ref.description,
|
inputValue: avatar.ref.description,
|
||||||
inputErrorMessage: 'Valid description is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.change_avatar_description.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13786,23 +13862,29 @@ speechSynthesis.getVoices();
|
|||||||
description: instance.inputValue
|
description: instance.inputValue
|
||||||
}).then((args) => {
|
}).then((args) => {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'Avatar description changed',
|
message: $t(
|
||||||
|
'prompt.change_avatar_description.message.success'
|
||||||
|
),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
});
|
});
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptRenameWorld = function (world) {
|
$app.methods.promptRenameWorld = function (world) {
|
||||||
this.$prompt('Enter world name', 'Rename World', {
|
this.$prompt(
|
||||||
|
$t('prompt.rename_world.description'),
|
||||||
|
$t('prompt.rename_world.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.rename_world.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.rename_world.cancel'),
|
||||||
inputValue: world.ref.name,
|
inputValue: world.ref.name,
|
||||||
inputErrorMessage: 'Valid name is required',
|
inputErrorMessage: $t('prompt.rename_world.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13813,23 +13895,31 @@ speechSynthesis.getVoices();
|
|||||||
name: instance.inputValue
|
name: instance.inputValue
|
||||||
}).then((args) => {
|
}).then((args) => {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'World renamed',
|
message: $t(
|
||||||
|
'prompt.rename_world.message.success'
|
||||||
|
),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
});
|
});
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptChangeWorldDescription = function (world) {
|
$app.methods.promptChangeWorldDescription = function (world) {
|
||||||
this.$prompt('Enter world description', 'Change Description', {
|
this.$prompt(
|
||||||
|
$t('prompt.change_world_description.description'),
|
||||||
|
$t('prompt.change_world_description.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.change_world_description.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.change_world_description.cancel'),
|
||||||
inputValue: world.ref.description,
|
inputValue: world.ref.description,
|
||||||
inputErrorMessage: 'Valid description is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.change_world_description.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13840,24 +13930,32 @@ speechSynthesis.getVoices();
|
|||||||
description: instance.inputValue
|
description: instance.inputValue
|
||||||
}).then((args) => {
|
}).then((args) => {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'World description changed',
|
message: $t(
|
||||||
|
'prompt.change_world_description.message.success'
|
||||||
|
),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
});
|
});
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptChangeWorldCapacity = function (world) {
|
$app.methods.promptChangeWorldCapacity = function (world) {
|
||||||
this.$prompt('Enter world capacity, Max: 40', 'Change Capacity', {
|
this.$prompt(
|
||||||
|
$t('prompt.change_world_capacity.description'),
|
||||||
|
$t('prompt.change_world_capacity.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.change_world_capacity.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.change_world_capacity.cancel'),
|
||||||
inputValue: world.ref.capacity,
|
inputValue: world.ref.capacity,
|
||||||
inputPattern: /\d+$/,
|
inputPattern: /\d+$/,
|
||||||
inputErrorMessage: 'Valid number is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.change_world_capacity.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13868,23 +13966,31 @@ speechSynthesis.getVoices();
|
|||||||
capacity: instance.inputValue
|
capacity: instance.inputValue
|
||||||
}).then((args) => {
|
}).then((args) => {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'World capacity changed',
|
message: $t(
|
||||||
|
'prompt.change_world_capacity.message.success'
|
||||||
|
),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
});
|
});
|
||||||
return args;
|
return args;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptChangeWorldYouTubePreview = function (world) {
|
$app.methods.promptChangeWorldYouTubePreview = function (world) {
|
||||||
this.$prompt('Enter world YouTube preview', 'Change YouTube Preview', {
|
this.$prompt(
|
||||||
|
$t('prompt.change_world_preview.description'),
|
||||||
|
$t('prompt.change_world_preview.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.change_world_preview.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.change_world_preview.cancel'),
|
||||||
inputValue: world.ref.previewYoutubeId,
|
inputValue: world.ref.previewYoutubeId,
|
||||||
inputErrorMessage: 'Valid YouTube URL is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.change_world_preview.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13903,19 +14009,25 @@ speechSynthesis.getVoices();
|
|||||||
}
|
}
|
||||||
} catch {
|
} catch {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'Invalid YouTube URL',
|
message: $t(
|
||||||
|
'prompt.change_world_preview.message.error'
|
||||||
|
),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (instance.inputValue !== world.ref.previewYoutubeId) {
|
if (
|
||||||
|
instance.inputValue !== world.ref.previewYoutubeId
|
||||||
|
) {
|
||||||
API.saveWorld({
|
API.saveWorld({
|
||||||
id: world.id,
|
id: world.id,
|
||||||
previewYoutubeId: instance.inputValue
|
previewYoutubeId: instance.inputValue
|
||||||
}).then((args) => {
|
}).then((args) => {
|
||||||
this.$message({
|
this.$message({
|
||||||
message: 'World YouTube preview changed',
|
message: $t(
|
||||||
|
'prompt.change_world_preview.message.success'
|
||||||
|
),
|
||||||
type: 'success'
|
type: 'success'
|
||||||
});
|
});
|
||||||
return args;
|
return args;
|
||||||
@@ -13923,20 +14035,21 @@ speechSynthesis.getVoices();
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptMaxTableSizeDialog = function () {
|
$app.methods.promptMaxTableSizeDialog = function () {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
'Larger table sizes may impact RAM usage and performance (default: 1000)',
|
$t('prompt.change_table_size.description'),
|
||||||
'Max Table Size',
|
$t('prompt.change_table_size.header'),
|
||||||
{
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'Save',
|
confirmButtonText: $t('prompt.change_table_size.save'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.change_table_size.cancel'),
|
||||||
inputValue: this.maxTableSize,
|
inputValue: this.maxTableSize,
|
||||||
inputPattern: /\d+$/,
|
inputPattern: /\d+$/,
|
||||||
inputErrorMessage: 'Valid number is required',
|
inputErrorMessage: $t('prompt.change_table_size.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
this.maxTableSize = instance.inputValue;
|
this.maxTableSize = instance.inputValue;
|
||||||
@@ -13965,15 +14078,17 @@ speechSynthesis.getVoices();
|
|||||||
|
|
||||||
$app.methods.promptPhotonLobbyTimeoutThreshold = function () {
|
$app.methods.promptPhotonLobbyTimeoutThreshold = function () {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
'Enter amount of seconds (default: 3)',
|
$t('prompt.photon_lobby_timeout.description'),
|
||||||
'User Timeout Threshold',
|
$t('prompt.photon_lobby_timeout.header'),
|
||||||
{
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.photon_lobby_timeout.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.photon_lobby_timeout.cancel'),
|
||||||
inputValue: this.photonLobbyTimeoutThreshold / 1000,
|
inputValue: this.photonLobbyTimeoutThreshold / 1000,
|
||||||
inputPattern: /\d+$/,
|
inputPattern: /\d+$/,
|
||||||
inputErrorMessage: 'Valid number is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.photon_lobby_timeout.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -13995,15 +14110,15 @@ speechSynthesis.getVoices();
|
|||||||
|
|
||||||
$app.methods.promptAutoClearVRCXCacheFrequency = function () {
|
$app.methods.promptAutoClearVRCXCacheFrequency = function () {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
'Enter amount of hours, larger values may impact RAM usage and performance (default: 24, disabled: 0)',
|
$t('prompt.auto_clear_cache.description'),
|
||||||
'Clear VRCX Cache Timer',
|
$t('prompt.auto_clear_cache.header'),
|
||||||
{
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.auto_clear_cache.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.auto_clear_cache.cancel'),
|
||||||
inputValue: this.clearVRCXCacheFrequency / 3600 / 2,
|
inputValue: this.clearVRCXCacheFrequency / 3600 / 2,
|
||||||
inputPattern: /\d+$/,
|
inputPattern: /\d+$/,
|
||||||
inputErrorMessage: 'Valid number is required',
|
inputErrorMessage: $t('prompt.auto_clear_cache.input_error'),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -19560,45 +19675,7 @@ speechSynthesis.getVoices();
|
|||||||
// VRChat Config JSON
|
// VRChat Config JSON
|
||||||
|
|
||||||
$app.data.VRChatConfigFile = {};
|
$app.data.VRChatConfigFile = {};
|
||||||
|
$app.data.VRChatConfigList = {};
|
||||||
$app.data.VRChatConfigList = {
|
|
||||||
cache_size: {
|
|
||||||
name: 'Max Cache Size [GB] (min 20)',
|
|
||||||
default: '20',
|
|
||||||
type: 'number',
|
|
||||||
min: 20
|
|
||||||
},
|
|
||||||
cache_expiry_delay: {
|
|
||||||
name: 'Cache Expiry [Days] (30 - 150)',
|
|
||||||
default: '30',
|
|
||||||
type: 'number',
|
|
||||||
min: 30,
|
|
||||||
max: 150
|
|
||||||
},
|
|
||||||
cache_directory: {
|
|
||||||
name: 'Custom Cache Folder Location',
|
|
||||||
default: '%AppData%\\..\\LocalLow\\VRChat\\vrchat'
|
|
||||||
},
|
|
||||||
dynamic_bone_max_affected_transform_count: {
|
|
||||||
name: 'Dynamic Bones Limit Max Transforms (0 disable all transforms)',
|
|
||||||
default: '32',
|
|
||||||
type: 'number',
|
|
||||||
min: 0
|
|
||||||
},
|
|
||||||
dynamic_bone_max_collider_check_count: {
|
|
||||||
name: 'Dynamic Bones Limit Max Collider Collisions (0 disable all colliders)',
|
|
||||||
default: '8',
|
|
||||||
type: 'number',
|
|
||||||
min: 0
|
|
||||||
},
|
|
||||||
fpv_steadycam_fov: {
|
|
||||||
name: 'First-Person Steadycam FOV',
|
|
||||||
default: '50',
|
|
||||||
type: 'number',
|
|
||||||
min: 30,
|
|
||||||
max: 110
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
$app.methods.readVRChatConfigFile = async function () {
|
$app.methods.readVRChatConfigFile = async function () {
|
||||||
this.VRChatConfigFile = {};
|
this.VRChatConfigFile = {};
|
||||||
@@ -19630,6 +19707,44 @@ speechSynthesis.getVoices();
|
|||||||
});
|
});
|
||||||
|
|
||||||
$app.methods.showVRChatConfig = async function () {
|
$app.methods.showVRChatConfig = async function () {
|
||||||
|
this.VRChatConfigList = {
|
||||||
|
cache_size: {
|
||||||
|
name: $t('dialog.config_json.max_cache_size'),
|
||||||
|
default: '20',
|
||||||
|
type: 'number',
|
||||||
|
min: 20
|
||||||
|
},
|
||||||
|
cache_expiry_delay: {
|
||||||
|
name: $t('dialog.config_json.cache_expiry_delay'),
|
||||||
|
default: '30',
|
||||||
|
type: 'number',
|
||||||
|
min: 30,
|
||||||
|
max: 150
|
||||||
|
},
|
||||||
|
cache_directory: {
|
||||||
|
name: $t('dialog.config_json.cache_directory'),
|
||||||
|
default: '%AppData%\\..\\LocalLow\\VRChat\\vrchat'
|
||||||
|
},
|
||||||
|
// dynamic_bone_max_affected_transform_count: {
|
||||||
|
// name: 'Dynamic Bones Limit Max Transforms (0 disable all transforms)',
|
||||||
|
// default: '32',
|
||||||
|
// type: 'number',
|
||||||
|
// min: 0
|
||||||
|
// },
|
||||||
|
// dynamic_bone_max_collider_check_count: {
|
||||||
|
// name: 'Dynamic Bones Limit Max Collider Collisions (0 disable all colliders)',
|
||||||
|
// default: '8',
|
||||||
|
// type: 'number',
|
||||||
|
// min: 0
|
||||||
|
// },
|
||||||
|
fpv_steadycam_fov: {
|
||||||
|
name: $t('dialog.config_json.fpv_steadycam_fov'),
|
||||||
|
default: '50',
|
||||||
|
type: 'number',
|
||||||
|
min: 30,
|
||||||
|
max: 110
|
||||||
|
}
|
||||||
|
};
|
||||||
await this.readVRChatConfigFile();
|
await this.readVRChatConfigFile();
|
||||||
this.$nextTick(() => adjustDialogZ(this.$refs.VRChatConfigDialog.$el));
|
this.$nextTick(() => adjustDialogZ(this.$refs.VRChatConfigDialog.$el));
|
||||||
this.VRChatConfigDialog.visible = true;
|
this.VRChatConfigDialog.visible = true;
|
||||||
@@ -22662,24 +22777,32 @@ speechSynthesis.getVoices();
|
|||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptNewLocalWorldFavoriteGroup = function () {
|
$app.methods.promptNewLocalWorldFavoriteGroup = function () {
|
||||||
this.$prompt('Enter a world favorite group name', 'New Group', {
|
this.$prompt(
|
||||||
|
$t('prompt.new_local_favorite_group.description'),
|
||||||
|
$t('prompt.new_local_favorite_group.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'OK',
|
confirmButtonText: $t('prompt.new_local_favorite_group.ok'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.new_local_favorite_group.cancel'),
|
||||||
inputPattern: /\S+/,
|
inputPattern: /\S+/,
|
||||||
inputErrorMessage: 'Name is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.new_local_favorite_group.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
this.newLocalWorldFavoriteGroup(instance.inputValue);
|
this.newLocalWorldFavoriteGroup(instance.inputValue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.newLocalWorldFavoriteGroup = function (group) {
|
$app.methods.newLocalWorldFavoriteGroup = function (group) {
|
||||||
if (this.localWorldFavoriteGroups.includes(group)) {
|
if (this.localWorldFavoriteGroups.includes(group)) {
|
||||||
$app.$message({
|
$app.$message({
|
||||||
message: `Group already exists with the name ${group}`,
|
message: $t('prompt.new_local_favorite_group.message.error', {
|
||||||
|
name: group
|
||||||
|
}),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -22694,12 +22817,21 @@ speechSynthesis.getVoices();
|
|||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.promptLocalWorldFavoriteGroupRename = function (group) {
|
$app.methods.promptLocalWorldFavoriteGroupRename = function (group) {
|
||||||
this.$prompt('Enter a world favorite group name', 'Rename Group', {
|
this.$prompt(
|
||||||
|
$t('prompt.local_favorite_group_rename.description'),
|
||||||
|
$t('prompt.local_favorite_group_rename.header'),
|
||||||
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'Save',
|
confirmButtonText: $t(
|
||||||
cancelButtonText: 'Cancel',
|
'prompt.local_favorite_group_rename.save'
|
||||||
|
),
|
||||||
|
cancelButtonText: $t(
|
||||||
|
'prompt.local_favorite_group_rename.cancel'
|
||||||
|
),
|
||||||
inputPattern: /\S+/,
|
inputPattern: /\S+/,
|
||||||
inputErrorMessage: 'Name is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.local_favorite_group_rename.input_error'
|
||||||
|
),
|
||||||
inputValue: group,
|
inputValue: group,
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (action === 'confirm' && instance.inputValue) {
|
if (action === 'confirm' && instance.inputValue) {
|
||||||
@@ -22709,13 +22841,17 @@ speechSynthesis.getVoices();
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.renameLocalWorldFavoriteGroup = function (newName, group) {
|
$app.methods.renameLocalWorldFavoriteGroup = function (newName, group) {
|
||||||
if (this.localWorldFavoriteGroups.includes(newName)) {
|
if (this.localWorldFavoriteGroups.includes(newName)) {
|
||||||
$app.$message({
|
$app.$message({
|
||||||
message: `Group already exists with the name ${newName}`,
|
message: $t(
|
||||||
|
'prompt.local_favorite_group_rename.message.error',
|
||||||
|
{name: newName}
|
||||||
|
),
|
||||||
type: 'error'
|
type: 'error'
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
@@ -22805,15 +22941,17 @@ speechSynthesis.getVoices();
|
|||||||
|
|
||||||
$app.methods.promptSetPendingOffline = function () {
|
$app.methods.promptSetPendingOffline = function () {
|
||||||
this.$prompt(
|
this.$prompt(
|
||||||
'Set pending offline delay in seconds (default: 110)',
|
$t('prompt.pending_offline_delay.description'),
|
||||||
'Pending Offline',
|
$t('prompt.pending_offline_delay.header'),
|
||||||
{
|
{
|
||||||
distinguishCancelAndClose: true,
|
distinguishCancelAndClose: true,
|
||||||
confirmButtonText: 'Save',
|
confirmButtonText: $t('prompt.pending_offline_delay.save'),
|
||||||
cancelButtonText: 'Cancel',
|
cancelButtonText: $t('prompt.pending_offline_delay.cancel'),
|
||||||
inputValue: this.pendingOfflineDelay / 1000,
|
inputValue: this.pendingOfflineDelay / 1000,
|
||||||
inputPattern: /\d+$/,
|
inputPattern: /\d+$/,
|
||||||
inputErrorMessage: 'Valid number is required',
|
inputErrorMessage: $t(
|
||||||
|
'prompt.pending_offline_delay.input_error'
|
||||||
|
),
|
||||||
callback: (action, instance) => {
|
callback: (action, instance) => {
|
||||||
if (
|
if (
|
||||||
action === 'confirm' &&
|
action === 'confirm' &&
|
||||||
@@ -24102,6 +24240,37 @@ speechSynthesis.getVoices();
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// App: Language
|
||||||
|
|
||||||
|
$app.data.appLanguage = 'en';
|
||||||
|
if (configRepository.getString('VRCX_appLanguage')) {
|
||||||
|
$app.data.appLanguage = configRepository.getString('VRCX_appLanguage');
|
||||||
|
i18n.locale = $app.data.appLanguage;
|
||||||
|
} else {
|
||||||
|
AppApi.CurrentLanguage().then((result) => {
|
||||||
|
if (!result) {
|
||||||
|
console.error('Failed to get current language');
|
||||||
|
$app.changeAppLanguage('en');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var lang = result.split('-')[0];
|
||||||
|
i18n.availableLocales.forEach((ref) => {
|
||||||
|
var refLang = ref.split('_')[0];
|
||||||
|
if (refLang === lang) {
|
||||||
|
$app.changeAppLanguage(ref);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.methods.changeAppLanguage = function (language) {
|
||||||
|
console.log('Language changed:', language);
|
||||||
|
this.appLanguage = language;
|
||||||
|
i18n.locale = language;
|
||||||
|
configRepository.setString('VRCX_appLanguage', language);
|
||||||
|
this.updateVRConfigVars();
|
||||||
|
};
|
||||||
|
|
||||||
$app = new Vue($app);
|
$app = new Vue($app);
|
||||||
window.$app = $app;
|
window.$app = $app;
|
||||||
})();
|
})();
|
||||||
|
|||||||
2401
html/src/index.pug
2401
html/src/index.pug
File diff suppressed because it is too large
Load Diff
10
html/src/localization/localizedStrings.js
Normal file
10
html/src/localization/localizedStrings.js
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import en from './strings/en.json' assert {type: 'JSON'};
|
||||||
|
import elements_en from 'element-ui/lib/locale/lang/en';
|
||||||
|
// import ja from './strings/ja.json' assert { type: 'JSON' };
|
||||||
|
import zh_TW from './strings/zh_TW.json' assert {type: 'JSON'};
|
||||||
|
import elements_zh_TW from 'element-ui/lib/locale/lang/zh-TW';
|
||||||
|
|
||||||
|
const localized_en = {...en, ...elements_en};
|
||||||
|
const localized_zh_TW = {...zh_TW, ...elements_zh_TW};
|
||||||
|
|
||||||
|
export {localized_en as en, localized_zh_TW as zh_TW};
|
||||||
1376
html/src/localization/strings/en.json
Normal file
1376
html/src/localization/strings/en.json
Normal file
File diff suppressed because it is too large
Load Diff
1376
html/src/localization/strings/zh_TW.json
Normal file
1376
html/src/localization/strings/zh_TW.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -8,10 +8,11 @@ import '@fontsource/noto-sans-kr';
|
|||||||
import '@fontsource/noto-sans-jp';
|
import '@fontsource/noto-sans-jp';
|
||||||
import Noty from 'noty';
|
import Noty from 'noty';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import VueI18n from 'vue-i18n';
|
||||||
import ElementUI from 'element-ui';
|
import ElementUI from 'element-ui';
|
||||||
import locale from 'element-ui/lib/locale/lang/en';
|
|
||||||
import * as workerTimers from 'worker-timers';
|
import * as workerTimers from 'worker-timers';
|
||||||
import MarqueeText from 'vue-marquee-text-component';
|
import MarqueeText from 'vue-marquee-text-component';
|
||||||
|
import * as localizedStrings from './localization/localizedStrings.js';
|
||||||
Vue.component('marquee-text', MarqueeText);
|
Vue.component('marquee-text', MarqueeText);
|
||||||
|
|
||||||
(async function () {
|
(async function () {
|
||||||
@@ -29,8 +30,18 @@ Vue.component('marquee-text', MarqueeText);
|
|||||||
timeout: 3000
|
timeout: 3000
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Vue.use(VueI18n);
|
||||||
|
|
||||||
|
var i18n = new VueI18n({
|
||||||
|
locale: 'en',
|
||||||
|
fallbackLocale: 'en',
|
||||||
|
messages: localizedStrings
|
||||||
|
});
|
||||||
|
|
||||||
|
var $t = i18n.t.bind(i18n);
|
||||||
|
|
||||||
Vue.use(ElementUI, {
|
Vue.use(ElementUI, {
|
||||||
locale
|
i18n: (key, value) => i18n.t(key, value)
|
||||||
});
|
});
|
||||||
|
|
||||||
var escapeTag = (s) =>
|
var escapeTag = (s) =>
|
||||||
@@ -163,10 +174,12 @@ Vue.component('marquee-text', MarqueeText);
|
|||||||
};
|
};
|
||||||
|
|
||||||
var $app = {
|
var $app = {
|
||||||
|
i18n,
|
||||||
data: {
|
data: {
|
||||||
// 1 = 대시보드랑 손목에 보이는거
|
// 1 = 대시보드랑 손목에 보이는거
|
||||||
// 2 = 항상 화면에 보이는 거
|
// 2 = 항상 화면에 보이는 거
|
||||||
appType: location.href.substr(-1),
|
appType: location.href.substr(-1),
|
||||||
|
appLanguage: 'en',
|
||||||
currentTime: new Date().toJSON(),
|
currentTime: new Date().toJSON(),
|
||||||
cpuUsage: 0,
|
cpuUsage: 0,
|
||||||
pcUptime: '',
|
pcUptime: '',
|
||||||
@@ -310,6 +323,7 @@ Vue.component('marquee-text', MarqueeText);
|
|||||||
this.hudFeed = [];
|
this.hudFeed = [];
|
||||||
this.hudTimeout = [];
|
this.hudTimeout = [];
|
||||||
this.setDatetimeFormat();
|
this.setDatetimeFormat();
|
||||||
|
this.setAppLanguage(this.config.appLanguage);
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.methods.updateOnlineFriendCount = function (count) {
|
$app.methods.updateOnlineFriendCount = function (count) {
|
||||||
@@ -699,6 +713,16 @@ Vue.component('marquee-text', MarqueeText);
|
|||||||
Vue.filter('formatDate', formatDate);
|
Vue.filter('formatDate', formatDate);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.methods.setAppLanguage = function (appLanguage) {
|
||||||
|
if (!appLanguage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (appLanguage !== this.appLanguage) {
|
||||||
|
this.appLanguage = appLanguage;
|
||||||
|
i18n.locale = this.appLanguage;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
$app = new Vue($app);
|
$app = new Vue($app);
|
||||||
window.$app = $app;
|
window.$app = $app;
|
||||||
})();
|
})();
|
||||||
|
|||||||
@@ -32,12 +32,12 @@ html
|
|||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
| #[span.name(v-text="feed.displayName")] ✔
|
| #[span.name(v-text="feed.displayName")] ✔
|
||||||
template(v-if="feed.worldName")
|
template(v-if="feed.worldName")
|
||||||
| #[location(:location="feed.location" :hint="feed.worldName")]
|
| #[location(:location="feed.location" :hint="feed.worldName" style="margin-left:5px")]
|
||||||
div(v-else-if="feed.type === 'Status'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
div(v-else-if="feed.type === 'Status'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
||||||
.detail
|
.detail
|
||||||
span.extra
|
span.extra
|
||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
| #[span.name(v-text="feed.displayName")]
|
| #[span.name(v-text="feed.displayName" style="margin-right:5px")]
|
||||||
template(v-if="feed.statusDescription === feed.previousStatusDescription")
|
template(v-if="feed.statusDescription === feed.previousStatusDescription")
|
||||||
i.x-user-status(:class="statusClass(feed.previousStatus)")
|
i.x-user-status(:class="statusClass(feed.previousStatus)")
|
||||||
i.el-icon-right
|
i.el-icon-right
|
||||||
@@ -69,7 +69,7 @@ html
|
|||||||
.detail
|
.detail
|
||||||
span.extra
|
span.extra
|
||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
| 🎵 #[span.name(v-text="feed.displayName")]
|
| 🎵 #[span.name(v-text="feed.displayName" style="margin-right:5px")]
|
||||||
template(v-if="feed.videoName")
|
template(v-if="feed.videoName")
|
||||||
| #[span(v-text="feed.videoName")]
|
| #[span(v-text="feed.videoName")]
|
||||||
template(v-else)
|
template(v-else)
|
||||||
@@ -144,7 +144,7 @@ html
|
|||||||
span.extra
|
span.extra
|
||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
template(v-if="feed.displayName")
|
template(v-if="feed.displayName")
|
||||||
| ✨ #[span.name(v-text="feed.displayName")]
|
| ✨ #[span.name(v-text="feed.displayName" style="margin-right:5px")]
|
||||||
| #[location(:location="feed.instanceId" :hint="feed.worldName")]
|
| #[location(:location="feed.instanceId" :hint="feed.worldName")]
|
||||||
template(v-else)
|
template(v-else)
|
||||||
| ✨ User has spawned a portal
|
| ✨ User has spawned a portal
|
||||||
@@ -152,7 +152,7 @@ html
|
|||||||
.detail
|
.detail
|
||||||
span.extra
|
span.extra
|
||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
| 🧍 #[span.name(v-text="feed.displayName")]
|
| 🧍 #[span.name(v-text="feed.displayName" style="margin-right:5px")]
|
||||||
template(v-if="feed.releaseStatus === 'public'")
|
template(v-if="feed.releaseStatus === 'public'")
|
||||||
| #[i.x-user-status.online]
|
| #[i.x-user-status.online]
|
||||||
template(v-else)
|
template(v-else)
|
||||||
@@ -229,14 +229,15 @@ html
|
|||||||
.detail
|
.detail
|
||||||
span.extra
|
span.extra
|
||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
| #[span.name(v-text="feed.displayName")] has logged in
|
| #[span.name(v-text="feed.displayName")]
|
||||||
|
span(style="margin-left:5px;margin-right:5px") has logged in
|
||||||
template(v-if="feed.worldName")
|
template(v-if="feed.worldName")
|
||||||
| to #[location(:location="feed.location" :hint="feed.worldName")]
|
| to #[location(:location="feed.location" :hint="feed.worldName")]
|
||||||
div(v-else-if="feed.type === 'Status'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
div(v-else-if="feed.type === 'Status'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
||||||
.detail
|
.detail
|
||||||
span.extra
|
span.extra
|
||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
| #[span.name(v-text="feed.displayName")]
|
| #[span.name(v-text="feed.displayName" style="margin-right:5px")]
|
||||||
template(v-if="feed.statusDescription === feed.previousStatusDescription")
|
template(v-if="feed.statusDescription === feed.previousStatusDescription")
|
||||||
i.x-user-status(:class="statusClass(feed.previousStatus)")
|
i.x-user-status(:class="statusClass(feed.previousStatus)")
|
||||||
i.el-icon-right
|
i.el-icon-right
|
||||||
@@ -267,7 +268,8 @@ html
|
|||||||
.detail
|
.detail
|
||||||
span.extra
|
span.extra
|
||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
| #[span.name(v-text="feed.displayName")] changed video to
|
| #[span.name(v-text="feed.displayName")]
|
||||||
|
span(style="margin-left:5px;margin-right:5px") changed video to
|
||||||
template(v-if="feed.videoName")
|
template(v-if="feed.videoName")
|
||||||
| #[span(v-text="feed.videoName")]
|
| #[span(v-text="feed.videoName")]
|
||||||
template(v-else)
|
template(v-else)
|
||||||
@@ -343,14 +345,15 @@ html
|
|||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
template(v-if="feed.displayName")
|
template(v-if="feed.displayName")
|
||||||
| #[span.name(v-text="feed.displayName")] has spawned a portal to
|
| #[span.name(v-text="feed.displayName")] has spawned a portal to
|
||||||
| #[location(:location="feed.instanceId" :hint="feed.worldName")]
|
| #[location(:location="feed.instanceId" :hint="feed.worldName" style="margin-left:5px")]
|
||||||
template(v-else)
|
template(v-else)
|
||||||
| User has spawned a portal
|
| User has spawned a portal
|
||||||
div(v-else-if="feed.type === 'AvatarChange'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
div(v-else-if="feed.type === 'AvatarChange'" class="x-friend-item" :class="{ friend: feed.isFriend, favorite: feed.isFavorite }")
|
||||||
.detail
|
.detail
|
||||||
span.extra
|
span.extra
|
||||||
span.time {{ feed.created_at | formatDate }}
|
span.time {{ feed.created_at | formatDate }}
|
||||||
| #[span.name(v-text="feed.displayName")] changed into avatar
|
| #[span.name(v-text="feed.displayName")]
|
||||||
|
span(style="margin-left:5px;margin-right:5px") changed into avatar
|
||||||
template(v-if="feed.releaseStatus === 'public'")
|
template(v-if="feed.releaseStatus === 'public'")
|
||||||
| #[i.x-user-status.online]
|
| #[i.x-user-status.online]
|
||||||
template(v-else)
|
template(v-else)
|
||||||
@@ -415,12 +418,12 @@ html
|
|||||||
img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" class="tracker-device")
|
img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" class="tracker-device")
|
||||||
img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" class="tracker-device")
|
img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" class="tracker-device")
|
||||||
img(v-else src="images/controller_status_ready.png" class="tracker-device")
|
img(v-else src="images/controller_status_ready.png" class="tracker-device")
|
||||||
span L:{{ device[2] }}%
|
span {{ $t('vr.status.devices.left') }}{{ device[2] }}%
|
||||||
template(v-else-if="device[0] === 'rightController'")
|
template(v-else-if="device[0] === 'rightController'")
|
||||||
img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" class="tracker-device")
|
img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" class="tracker-device")
|
||||||
img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" class="tracker-device")
|
img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" class="tracker-device")
|
||||||
img(v-else src="images/controller_status_ready.png" class="tracker-device")
|
img(v-else src="images/controller_status_ready.png" class="tracker-device")
|
||||||
span R:{{ device[2] }}%
|
span {{ $t('vr.status.devices.right') }}{{ device[2] }}%
|
||||||
template(v-else-if="device[0] === 'controller'")
|
template(v-else-if="device[0] === 'controller'")
|
||||||
img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" class="tracker-device")
|
img(v-if="device[1] !== 'connected'" src="images/controller_status_off.png" class="tracker-device")
|
||||||
img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" class="tracker-device")
|
img(v-else-if="device[2] < 20" src="images/controller_status_ready_low.png" class="tracker-device")
|
||||||
@@ -454,17 +457,17 @@ html
|
|||||||
span(style="display:inline-block") {{ lastLocation.playerList.length }}
|
span(style="display:inline-block") {{ lastLocation.playerList.length }}
|
||||||
span(style="display:inline-block;font-weight:bold") {{ lastLocation.friendList.length !== 0 ? ` (${lastLocation.friendList.length})` : ''}}
|
span(style="display:inline-block;font-weight:bold") {{ lastLocation.friendList.length !== 0 ? ` (${lastLocation.friendList.length})` : ''}}
|
||||||
template(v-else)
|
template(v-else)
|
||||||
span(style="float:right") Timer: {{ lastLocationTimer }}
|
span(style="float:right") {{ $t('vr.status.timer') }} {{ lastLocationTimer }}
|
||||||
template(v-if="onlineForTimer")
|
template(v-if="onlineForTimer")
|
||||||
| / {{ onlineForTimer }}
|
| / {{ onlineForTimer }}
|
||||||
template(v-if="pcUptime")
|
template(v-if="pcUptime")
|
||||||
| / {{ pcUptime }}
|
| / {{ pcUptime }}
|
||||||
span(style="display:inline-block") Players: {{ lastLocation.playerList.length }}
|
span(style="display:inline-block") {{ $t('vr.status.players') }} {{ lastLocation.playerList.length }}
|
||||||
span(style="display:inline-block;font-weight:bold") {{ lastLocation.friendList.length !== 0 ? ` (${lastLocation.friendList.length})` : ''}}
|
span(style="display:inline-block;font-weight:bold") {{ lastLocation.friendList.length !== 0 ? ` (${lastLocation.friendList.length})` : ''}}
|
||||||
br
|
br
|
||||||
span(style="float:right") {{ currentTime }}
|
span(style="float:right") {{ currentTime }}
|
||||||
span(v-if="config && !config.hideCpuUsageFromFeed" style="display:inline-block;margin-right:5px") CPU: {{ cpuUsage }}%
|
span(v-if="config && !config.hideCpuUsageFromFeed" style="display:inline-block;margin-right:5px") {{ $t('vr.status.cpu') }} {{ cpuUsage }}%
|
||||||
span(style="display:inline-block") Online: {{ onlineFriendCount }}
|
span(style="display:inline-block") {{ $t('vr.status.online') }} {{ onlineFriendCount }}
|
||||||
template(v-else)
|
template(v-else)
|
||||||
svg(class="np-progress-circle")
|
svg(class="np-progress-circle")
|
||||||
circle(class="np-progress-circle-stroke" cx="60" cy="60" stroke="white" r="30" fill="transparent" stroke-width="60")
|
circle(class="np-progress-circle-stroke" cx="60" cy="60" stroke="white" r="30" fill="transparent" stroke-width="60")
|
||||||
|
|||||||
Reference in New Issue
Block a user