diff --git a/html/src/app.js b/html/src/app.js
index 3b654fa4..0aa676d1 100644
--- a/html/src/app.js
+++ b/html/src/app.js
@@ -1279,7 +1279,7 @@ speechSynthesis.getVoices();
throw err;
}
$app.$message({
- message: "you're not allowed to access this instance.",
+ message: $t('message.instance.not_allowed'),
type: 'error'
});
throw err;
@@ -5423,7 +5423,7 @@ speechSynthesis.getVoices();
} catch (err) {
if (!$app.dontLogMeOut) {
$app.$message({
- message: 'Failed to load friends list, logging out',
+ message: $t('message.friend.load_failed'),
type: 'error'
});
this.logout();
@@ -9474,7 +9474,7 @@ speechSynthesis.getVoices();
D.isMuteChat = true;
}
$app.$message({
- message: 'User moderated',
+ message: $t('message.user.moderated'),
type: 'success'
});
});
@@ -10796,16 +10796,30 @@ speechSynthesis.getVoices();
this.setPlayerModeration(D.id, 5);
}
} else {
- this.$confirm(`Continue? ${command}`, 'Confirm', {
- confirmButtonText: 'Confirm',
- cancelButtonText: 'Cancel',
- type: 'info',
- callback: (action) => {
- if (action === 'confirm') {
- performUserDialogCommand(command, D.id);
+ const i18nPreFix = 'dialog.user.actions.';
+ const formattedCommand = command.toLowerCase().replace(/ /g, '_');
+ const displayCommandText = $t(
+ `${i18nPreFix}${formattedCommand}`
+ ).includes('i18nPreFix')
+ ? command
+ : $t(`${i18nPreFix}${formattedCommand}`);
+
+ this.$confirm(
+ $t('confirm.message', {
+ command: displayCommandText
+ }),
+ $t('confirm.title'),
+ {
+ confirmButtonText: $t('confirm.confirm_button'),
+ cancelButtonText: $t('confirm.cancel_button'),
+ type: 'info',
+ callback: (action) => {
+ if (action === 'confirm') {
+ performUserDialogCommand(command, D.id);
+ }
}
}
- });
+ );
}
};
@@ -13790,7 +13804,7 @@ speechSynthesis.getVoices();
if (files[0].size >= 100000000) {
// 100MB
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
clearFile();
@@ -13798,7 +13812,7 @@ speechSynthesis.getVoices();
}
if (!files[0].type.match(/image.*/)) {
$app.$message({
- message: "File isn't an image",
+ message: $t('message.file.not_image'),
type: 'error'
});
clearFile();
@@ -13809,7 +13823,7 @@ speechSynthesis.getVoices();
var base64Body = btoa(r.result);
API.uploadVRCPlusIcon(base64Body).then((args) => {
$app.$message({
- message: 'Icon uploaded',
+ message: $t('message.icon.uploaded'),
type: 'success'
});
return args;
@@ -13858,7 +13872,7 @@ speechSynthesis.getVoices();
if (files[0].size >= 100000000) {
// 100MB
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
this.clearInviteImageUpload();
@@ -13866,7 +13880,7 @@ speechSynthesis.getVoices();
}
if (!files[0].type.match(/image.*/)) {
$app.$message({
- message: "File isn't a png",
+ message: $t('message.file.not_image'),
type: 'error'
});
this.clearInviteImageUpload();
@@ -14948,7 +14962,7 @@ speechSynthesis.getVoices();
if (files[0].size >= 100000000) {
// 100MB
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
clearFile();
@@ -14956,7 +14970,7 @@ speechSynthesis.getVoices();
}
if (!files[0].type.match(/image.*/)) {
$app.$message({
- message: "File isn't a png",
+ message: $t('message.file.not_image'),
type: 'error'
});
clearFile();
@@ -14981,7 +14995,7 @@ speechSynthesis.getVoices();
var fileId = $utils.extractFileId(imageUrl);
if (!fileId) {
$app.$message({
- message: 'Current avatar image invalid',
+ message: $t('message.avatar.image_invalid'),
type: 'error'
});
clearFile();
@@ -15284,7 +15298,7 @@ speechSynthesis.getVoices();
if (files[0].size >= 100000000) {
// 100MB
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
clearFile();
@@ -15292,7 +15306,7 @@ speechSynthesis.getVoices();
}
if (!files[0].type.match(/image.*/)) {
$app.$message({
- message: "File isn't a png",
+ message: $t('message.file.not_image'),
type: 'error'
});
clearFile();
@@ -15317,7 +15331,7 @@ speechSynthesis.getVoices();
var fileId = $utils.extractFileId(imageUrl);
if (!fileId) {
$app.$message({
- message: 'Current world image invalid',
+ message: $t('message.world.image_invalid'),
type: 'error'
});
clearFile();
@@ -15605,7 +15619,7 @@ speechSynthesis.getVoices();
$app.changeAvatarImageDialogLoading = false;
if (args.json.imageUrl === args.params.imageUrl) {
$app.$message({
- message: 'Avatar image changed',
+ message: $t('message.avatar.image_changed'),
type: 'success'
});
$app.displayPreviousImages('Avatar', 'Change');
@@ -15619,7 +15633,7 @@ speechSynthesis.getVoices();
$app.changeWorldImageDialogLoading = false;
if (args.json.imageUrl === args.params.imageUrl) {
$app.$message({
- message: 'World image changed',
+ message: $t('message.world.image_changed'),
type: 'success'
});
$app.displayPreviousImages('World', 'Change');
@@ -16495,7 +16509,7 @@ speechSynthesis.getVoices();
var D = this.screenshotMetadataDialog;
if (D.metadata.fileSizeBytes > 10000000) {
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
return;
@@ -16506,7 +16520,7 @@ speechSynthesis.getVoices();
API.uploadGalleryImage(base64Body)
.then((args) => {
$app.$message({
- message: 'Gallery image uploaded',
+ message: $t('message.gallery.uploaded'),
type: 'success'
});
return args;
@@ -16517,7 +16531,7 @@ speechSynthesis.getVoices();
})
.catch((err) => {
$app.$message({
- message: 'Failed to upload gallery image',
+ message: $t('message.gallery.failed'),
type: 'error'
});
console.error(err);
@@ -17490,7 +17504,7 @@ speechSynthesis.getVoices();
if (files[0].size >= 100000000) {
// 100MB
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
clearFile();
@@ -17498,7 +17512,7 @@ speechSynthesis.getVoices();
}
if (!files[0].type.match(/image.*/)) {
$app.$message({
- message: "File isn't an image",
+ message: $t('message.file.not_image'),
type: 'error'
});
clearFile();
@@ -17509,7 +17523,7 @@ speechSynthesis.getVoices();
var base64Body = btoa(r.result);
API.uploadGalleryImage(base64Body).then((args) => {
$app.$message({
- message: 'Gallery image uploaded',
+ message: $t('message.gallery.uploaded'),
type: 'success'
});
return args;
@@ -17601,7 +17615,7 @@ speechSynthesis.getVoices();
if (files[0].size >= 100000000) {
// 100MB
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
clearFile();
@@ -17609,7 +17623,7 @@ speechSynthesis.getVoices();
}
if (!files[0].type.match(/image.*/)) {
$app.$message({
- message: "File isn't an image",
+ message: $t('message.file.not_image'),
type: 'error'
});
clearFile();
@@ -17624,7 +17638,7 @@ speechSynthesis.getVoices();
var base64Body = btoa(r.result);
API.uploadSticker(base64Body, params).then((args) => {
$app.$message({
- message: 'Sticker uploaded',
+ message: $t('message.sticker.uploaded'),
type: 'success'
});
return args;
@@ -17759,7 +17773,7 @@ speechSynthesis.getVoices();
if (files[0].size >= 100000000) {
// 100MB
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
clearFile();
@@ -17767,7 +17781,7 @@ speechSynthesis.getVoices();
}
if (!files[0].type.match(/image.*/)) {
$app.$message({
- message: "File isn't an image",
+ message: $t('message.file.not_image'),
type: 'error'
});
clearFile();
@@ -17787,7 +17801,7 @@ speechSynthesis.getVoices();
var base64Body = btoa(r.result);
API.uploadPrint(base64Body, params).then((args) => {
$app.$message({
- message: 'Print uploaded',
+ message: $t('message.print.uploaded'),
type: 'success'
});
return args;
@@ -17971,7 +17985,7 @@ speechSynthesis.getVoices();
if (files[0].size >= 100000000) {
// 100MB
$app.$message({
- message: 'File size too large',
+ message: $t('message.file.too_large'),
type: 'error'
});
clearFile();
@@ -17979,7 +17993,7 @@ speechSynthesis.getVoices();
}
if (!files[0].type.match(/image.*/)) {
$app.$message({
- message: "File isn't an image",
+ message: $t('message.file.not_image'),
type: 'error'
});
clearFile();
@@ -18004,7 +18018,7 @@ speechSynthesis.getVoices();
var base64Body = btoa(r.result);
API.uploadEmoji(base64Body, params).then((args) => {
$app.$message({
- message: 'Emoji uploaded',
+ message: $t('message.emoji.uploaded'),
type: 'success'
});
return args;
@@ -21420,7 +21434,9 @@ speechSynthesis.getVoices();
API.queuedInstances.forEach((ref) => {
if (ref.location !== instanceId) {
$app.$message({
- message: `Removed instance ${ref.$worldName} from queue`,
+ message: $t('message.instance.removed_form_queue', {
+ worldName: ref.$worldName
+ }),
type: 'info'
});
ref.$msgBox?.close();
@@ -21707,7 +21723,7 @@ speechSynthesis.getVoices();
}
} else {
$app.$message({
- message: 'Failed to change avatar moderation',
+ message: $t('message.avatar.change_moderation_failed'),
type: 'error'
});
}
@@ -22197,7 +22213,7 @@ speechSynthesis.getVoices();
API.$on('INSTANCE:CLOSE', function (args) {
if (args.json) {
$app.$message({
- message: 'Instance closed',
+ message: $t('message.instance.closed'),
type: 'success'
});
@@ -22376,7 +22392,7 @@ speechSynthesis.getVoices();
API.$on('BADGE:UPDATE', function (args) {
if (args.json) {
$app.$message({
- message: 'Badge updated',
+ message: $t('message.badge.updated'),
type: 'success'
});
}
diff --git a/html/src/classes/apiRequestHandler.js b/html/src/classes/apiRequestHandler.js
index ab180a3f..c96be0bc 100644
--- a/html/src/classes/apiRequestHandler.js
+++ b/html/src/classes/apiRequestHandler.js
@@ -158,7 +158,9 @@ export default class extends baseClass {
endpoint.startsWith('avatars/')
) {
$app.$message({
- message: 'Avatar private or deleted',
+ message: $t(
+ 'message.api_headler.avatar_private_or_deleted'
+ ),
type: 'error'
});
$app.avatarDialog.visible = false;
diff --git a/html/src/classes/vrcxUpdater.js b/html/src/classes/vrcxUpdater.js
index 8d8fb709..f4e86492 100644
--- a/html/src/classes/vrcxUpdater.js
+++ b/html/src/classes/vrcxUpdater.js
@@ -128,7 +128,9 @@ export default class extends baseClass {
var releases = [];
if (typeof json !== 'object' || json.message) {
$app.$message({
- message: `Failed to check for update, "${json.message}"`,
+ message: $t('message.vrcx_updater.failed', {
+ message: json.message
+ }),
type: 'error'
});
return;
diff --git a/html/src/localization/en/en.json b/html/src/localization/en/en.json
index fb0b0533..65a79dce 100644
--- a/html/src/localization/en/en.json
+++ b/html/src/localization/en/en.json
@@ -1444,6 +1444,63 @@
"save": "Save"
}
},
+ "confirm": {
+ "title": "Confirm",
+ "confirm_button": "Confirm",
+ "cancel_button": "Cancel",
+ "message": "Continue {command}?"
+ },
+ "message": {
+ "vrcx_updater": {
+ "failed": "Failed to check for update, {message}"
+ },
+ "api_headler": {
+ "avatar_private_or_deleted": "Avatar is private or deleted"
+ },
+ "badge": {
+ "updated": "Badge updated"
+ },
+ "instance": {
+ "closed": "Instance closed",
+ "removed_form_queue": "Removed instance {worldName} from queue",
+ "not_allowed": "You're not allowed to access this instance"
+ },
+ "avatar": {
+ "change_moderation_failed": "Failed to change avatar moderation",
+ "image_changed": "Avatar image changed",
+ "image_invalid": "Current avatar image invalid"
+ },
+ "emoji": {
+ "uploaded": "Emoji uploaded"
+ },
+ "file": {
+ "not_image": "File isn't an image",
+ "too_large": "File size too large"
+ },
+ "print": {
+ "uploaded": "Print uploaded"
+ },
+ "sticker": {
+ "uploaded": "Sticker uploaded"
+ },
+ "gallery": {
+ "uploaded": "Gallery image uploaded",
+ "failed": "Failed to upload gallery image"
+ },
+ "world": {
+ "image_changed": "World image changed",
+ "image_invalid": "Current world image invalid"
+ },
+ "icon": {
+ "uploaded": "Icon uploaded"
+ },
+ "user": {
+ "moderated": "User moderated"
+ },
+ "friend": {
+ "load_failed": "Failed to load friends list, logging out"
+ }
+ },
"prompt": {
"totp": {
"header": "Two-factor Authentication",
@@ -1791,4 +1848,4 @@
"online": "Online:"
}
}
-}
+}
\ No newline at end of file
diff --git a/html/src/localization/ja/en.json b/html/src/localization/ja/en.json
index 70094459..f7b87a2d 100644
--- a/html/src/localization/ja/en.json
+++ b/html/src/localization/ja/en.json
@@ -1427,6 +1427,63 @@
"save": "保存"
}
},
+ "confirm": {
+ "title": "確認",
+ "confirm_button": "確認",
+ "cancel_button": "キャンセル",
+ "message": "{command}を続行しますか?"
+ },
+ "message": {
+ "vrcx_updater": {
+ "failed": "アップデートの確認に失敗しました、{message}"
+ },
+ "api_headler": {
+ "avatar_private_or_deleted": "アバターは非公開または削除されています"
+ },
+ "badge": {
+ "updated": "バッジが更新されました"
+ },
+ "instance": {
+ "closed": "インスタンスが閉じられました",
+ "removed_form_queue": "キューからインスタンス {worldName} が削除されました",
+ "not_allowed": "このインスタンスにアクセスする権限がありません"
+ },
+ "avatar": {
+ "change_moderation_failed": "アバターのモデレーションの変更に失敗しました",
+ "image_changed": "アバター画像が変更されました",
+ "image_invalid": "アバター画像が無効です"
+ },
+ "emoji": {
+ "uploaded": "Emoji がアップロードされました"
+ },
+ "file": {
+ "not_image": "ファイルが画像ではありません",
+ "too_large": "ファイルサイズが大きすぎます"
+ },
+ "print": {
+ "uploaded": "Print がアップロードされました"
+ },
+ "sticker": {
+ "uploaded": "ステッカーがアップロードされました"
+ },
+ "gallery": {
+ "uploaded": "ギャラリー画像がアップロードされました",
+ "failed": "ギャラリー画像のアップロードに失敗しました"
+ },
+ "world": {
+ "image_changed": "ワールド画像が変更されました",
+ "image_invalid": "現在のワールド画像が無効です"
+ },
+ "icon": {
+ "uploaded": "アイコンがアップロードされました"
+ },
+ "user": {
+ "moderated": "ユーザーがモデレートされました"
+ },
+ "friend": {
+ "load_failed": "フレンドリストの読み込みに失敗しました、ログアウトしています"
+ }
+ },
"prompt": {
"totp": {
"header": "2段階認証",
diff --git a/html/src/localization/zh-CN/en.json b/html/src/localization/zh-CN/en.json
index f53357bd..d58272c9 100644
--- a/html/src/localization/zh-CN/en.json
+++ b/html/src/localization/zh-CN/en.json
@@ -1430,6 +1430,63 @@
"save": "保存"
}
},
+ "confirm": {
+ "title": "确认",
+ "confirm_button": "确认",
+ "cancel_button": "取消",
+ "message": "确认{command}?"
+ },
+ "message": {
+ "vrcx_updater": {
+ "failed": "无法检查更新,{message}"
+ },
+ "api_headler": {
+ "avatar_private_or_deleted": "模型是私密的或已删除"
+ },
+ "badge": {
+ "updated": "徽章已更新"
+ },
+ "instance": {
+ "closed": "房间已关闭",
+ "removed_form_queue": "已从队列中移除房间 {worldName}",
+ "not_allowed": "您无权访问此房间"
+ },
+ "avatar": {
+ "change_moderation_failed": "无法更改模型显示状态",
+ "image_changed": "模型图片已更改",
+ "image_invalid": "当前模型图片无效"
+ },
+ "emoji": {
+ "uploaded": "Emoji 已上传"
+ },
+ "file": {
+ "not_image": "文件不是有效图片格式",
+ "too_large": "文件大小过大"
+ },
+ "print": {
+ "uploaded": "Print 已上传"
+ },
+ "sticker": {
+ "uploaded": "Sticker 已上传"
+ },
+ "gallery": {
+ "uploaded": "Gallery 图片已上传",
+ "failed": "无法上传 Gallery 图片"
+ },
+ "world": {
+ "image_changed": "世界图片已更改",
+ "image_invalid": "当前世界图片无效"
+ },
+ "icon": {
+ "uploaded": "Icon 已上传"
+ },
+ "user": {
+ "moderated": "用户状态已更改"
+ },
+ "friend": {
+ "load_failed": "加载好友列表失败,即将登出"
+ }
+ },
"prompt": {
"totp": {
"header": "双重认证",
diff --git a/html/src/mixins/dialogs/userDialog.pug b/html/src/mixins/dialogs/userDialog.pug
index 9e14122e..84471217 100644
--- a/html/src/mixins/dialogs/userDialog.pug
+++ b/html/src/mixins/dialogs/userDialog.pug
@@ -121,20 +121,20 @@ mixin userDialog()
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(v-if="userDialog.isMuteChat" icon="el-icon-chat-line-round" command="Unmute Chatbox" style="color:#F56C6C") {{ $t('dialog.user.actions.moderation_enable_chatbox') }}
- el-dropdown-item(v-else icon="el-icon-chat-dot-round" command="Mute Chatbox") {{ $t('dialog.user.actions.moderation_disable_chatbox') }}
+ el-dropdown-item(v-if="userDialog.isBlock" icon="el-icon-circle-check" command="Moderation Unblock" divided style="color:#F56C6C") {{ $t('dialog.user.actions.moderation_unblock') }}
+ el-dropdown-item(v-else icon="el-icon-circle-close" command="Moderation Block" divided :disabled="userDialog.ref.$isModerator") {{ $t('dialog.user.actions.moderation_block') }}
+ el-dropdown-item(v-if="userDialog.isMute" icon="el-icon-microphone" command="Moderation Unmute" style="color:#F56C6C") {{ $t('dialog.user.actions.moderation_unmute') }}
+ el-dropdown-item(v-else icon="el-icon-turn-off-microphone" command="Moderation Mute" :disabled="userDialog.ref.$isModerator") {{ $t('dialog.user.actions.moderation_mute') }}
+ el-dropdown-item(v-if="userDialog.isMuteChat" icon="el-icon-chat-line-round" command="Moderation Enable Chatbox" style="color:#F56C6C") {{ $t('dialog.user.actions.moderation_enable_chatbox') }}
+ el-dropdown-item(v-else icon="el-icon-chat-dot-round" command="Moderation Disable Chatbox") {{ $t('dialog.user.actions.moderation_disable_chatbox') }}
el-dropdown-item(icon="el-icon-user-solid" command="Show Avatar")
i.el-icon-check.el-icon--left(v-if="userDialog.isShowAvatar")
span {{ $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")
span {{ $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') }}
+ el-dropdown-item(v-if="userDialog.isInteractOff" icon="el-icon-thumb" command="Moderation 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="Moderation Disable Avatar Interaction") {{ $t('dialog.user.actions.moderation_disable_avatar_interaction') }}
el-dropdown-item(icon="el-icon-s-flag" command="Report Hacking" :disabled="userDialog.ref.$isModerator") {{ $t('dialog.user.actions.report_hacking') }}
template(v-if="userDialog.isFriend")
el-dropdown-item(icon="el-icon-delete" command="Unfriend" divided style="color:#F56C6C") {{ $t('dialog.user.actions.unfriend') }}