mirror of
https://github.com/MrUnknownDE/VRCX.git
synced 2026-05-07 14:56:06 +02:00
improve i18n
This commit is contained in:
@@ -204,11 +204,11 @@
|
|||||||
const accessTypeLabel = translateAccessType(L.accessTypeName);
|
const accessTypeLabel = translateAccessType(L.accessTypeName);
|
||||||
|
|
||||||
if (L.isOffline) {
|
if (L.isOffline) {
|
||||||
text.value = 'Offline';
|
text.value = t('location.offline');
|
||||||
} else if (L.isPrivate) {
|
} else if (L.isPrivate) {
|
||||||
text.value = 'Private';
|
text.value = t('location.private');
|
||||||
} else if (L.isTraveling) {
|
} else if (L.isTraveling) {
|
||||||
text.value = 'Traveling';
|
text.value = t('location.traveling');
|
||||||
} else if (typeof props.hint === 'string' && props.hint !== '') {
|
} else if (typeof props.hint === 'string' && props.hint !== '') {
|
||||||
if (L.instanceId) {
|
if (L.instanceId) {
|
||||||
text.value = `${props.hint} · ${accessTypeLabel}`;
|
text.value = `${props.hint} · ${accessTypeLabel}`;
|
||||||
|
|||||||
@@ -455,7 +455,6 @@
|
|||||||
"header": "System Tools",
|
"header": "System Tools",
|
||||||
"vrchat_config": "VRChat Config",
|
"vrchat_config": "VRChat Config",
|
||||||
"vrchat_config_description": "Open VRChat config.json settings",
|
"vrchat_config_description": "Open VRChat config.json settings",
|
||||||
"launch_options": "Launch Options",
|
|
||||||
"launch_options_description": "Edit VRChat launch options",
|
"launch_options_description": "Edit VRChat launch options",
|
||||||
"registry_backup": "VRChat Registry Backup",
|
"registry_backup": "VRChat Registry Backup",
|
||||||
"registry_backup_description": "Create or restore a VRChat registry backup"
|
"registry_backup_description": "Create or restore a VRChat registry backup"
|
||||||
@@ -815,6 +814,14 @@
|
|||||||
"header": "Self Invite",
|
"header": "Self Invite",
|
||||||
"description": "Self invite instead of opening instance in VRChat"
|
"description": "Self invite instead of opening instance in VRChat"
|
||||||
},
|
},
|
||||||
|
"anonymous_error_reporting": {
|
||||||
|
"header": "Anonymous Error Reporting (Nightly Only)",
|
||||||
|
"description": "Help improve VRCX by sending anonymous crash and error reports. No personal or VRChat data is collected.",
|
||||||
|
"consent_title": "Anonymous Error Reporting",
|
||||||
|
"consent_description": "Allow anonymous error reporting to help improve VRCX?\n\n• Crash and error data only\n• No personal or VRChat data\n• Nightly builds only\n• Can be disabled in Advanced Settings",
|
||||||
|
"enabled_restart_description": "Error reporting enabled. Restart VRCX to apply changes?",
|
||||||
|
"disabled_restart_description": "Error reporting disabled. Restart VRCX to apply changes?"
|
||||||
|
},
|
||||||
"save_instance_prints_to_file": {
|
"save_instance_prints_to_file": {
|
||||||
"header": "Save Instance Prints To File",
|
"header": "Save Instance Prints To File",
|
||||||
"header_tooltip": "Requires \"--enable-sdk-log-levels\" VRC launch option",
|
"header_tooltip": "Requires \"--enable-sdk-log-levels\" VRC launch option",
|
||||||
@@ -1869,7 +1876,15 @@
|
|||||||
"copy_image": "Copy Image",
|
"copy_image": "Copy Image",
|
||||||
"open_folder": "Open Folder",
|
"open_folder": "Open Folder",
|
||||||
"delete_metadata": "Delete Metadata",
|
"delete_metadata": "Delete Metadata",
|
||||||
"upload": "Upload"
|
"upload": "Upload",
|
||||||
|
"search_placeholder": "Search",
|
||||||
|
"search_type_placeholder": "Search Type",
|
||||||
|
"search_types": {
|
||||||
|
"player_name": "Player Name",
|
||||||
|
"player_id": "Player ID",
|
||||||
|
"world_name": "World Name",
|
||||||
|
"world_id": "World ID"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"registry_backup": {
|
"registry_backup": {
|
||||||
"header": "VRC Registry Settings Backup",
|
"header": "VRC Registry Settings Backup",
|
||||||
@@ -2018,6 +2033,11 @@
|
|||||||
"status": {
|
"status": {
|
||||||
"title": "VRChat Status"
|
"title": "VRChat Status"
|
||||||
},
|
},
|
||||||
|
"location": {
|
||||||
|
"offline": "Offline",
|
||||||
|
"private": "Private",
|
||||||
|
"traveling": "Traveling"
|
||||||
|
},
|
||||||
"message": {
|
"message": {
|
||||||
"vrcx_updater": {
|
"vrcx_updater": {
|
||||||
"failed": "Failed to check for update, {message}",
|
"failed": "Failed to check for update, {message}",
|
||||||
@@ -2475,7 +2495,14 @@
|
|||||||
},
|
},
|
||||||
"common": {
|
"common": {
|
||||||
"no_data": "No data",
|
"no_data": "No data",
|
||||||
"no_matching_records": "No matching records"
|
"no_matching_records": "No matching records",
|
||||||
|
"time_units": {
|
||||||
|
"y": "y",
|
||||||
|
"d": "d",
|
||||||
|
"h": "h",
|
||||||
|
"m": "m",
|
||||||
|
"s": "s"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"vr": {
|
"vr": {
|
||||||
"status": {
|
"status": {
|
||||||
|
|||||||
@@ -1778,7 +1778,7 @@
|
|||||||
"ok": "确定"
|
"ok": "确定"
|
||||||
},
|
},
|
||||||
"screenshot_metadata": {
|
"screenshot_metadata": {
|
||||||
"header": "元数据查看器",
|
"header": "截图管理",
|
||||||
"drag": "拖放图片到这里",
|
"drag": "拖放图片到这里",
|
||||||
"browse": "选择文件",
|
"browse": "选择文件",
|
||||||
"last_screenshot": "上一张图片",
|
"last_screenshot": "上一张图片",
|
||||||
|
|||||||
@@ -1,5 +1,23 @@
|
|||||||
|
import { i18n } from '../../../plugin/i18n';
|
||||||
import { escapeTag } from './string';
|
import { escapeTag } from './string';
|
||||||
|
|
||||||
|
const TIME_UNIT_KEYS = {
|
||||||
|
y: 'common.time_units.y',
|
||||||
|
d: 'common.time_units.d',
|
||||||
|
h: 'common.time_units.h',
|
||||||
|
m: 'common.time_units.m',
|
||||||
|
s: 'common.time_units.s'
|
||||||
|
};
|
||||||
|
|
||||||
|
function getTimeUnitLabel(unit) {
|
||||||
|
const key = TIME_UNIT_KEYS[unit];
|
||||||
|
if (!key) {
|
||||||
|
return unit;
|
||||||
|
}
|
||||||
|
const t = i18n?.global?.t;
|
||||||
|
return typeof t === 'function' ? t(key) : unit;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param {number} sec
|
* @param {number} sec
|
||||||
@@ -17,25 +35,25 @@ function timeToText(sec, isNeedSeconds = false) {
|
|||||||
n = -n;
|
n = -n;
|
||||||
}
|
}
|
||||||
if (n >= 31536000) {
|
if (n >= 31536000) {
|
||||||
arr.push(`${Math.floor(n / 31536000)}y`);
|
arr.push(`${Math.floor(n / 31536000)}${getTimeUnitLabel('y')}`);
|
||||||
n %= 31536000;
|
n %= 31536000;
|
||||||
}
|
}
|
||||||
if (n >= 86400) {
|
if (n >= 86400) {
|
||||||
arr.push(`${Math.floor(n / 86400)}d`);
|
arr.push(`${Math.floor(n / 86400)}${getTimeUnitLabel('d')}`);
|
||||||
n %= 86400;
|
n %= 86400;
|
||||||
}
|
}
|
||||||
if (n >= 3600) {
|
if (n >= 3600) {
|
||||||
arr.push(`${Math.floor(n / 3600)}h`);
|
arr.push(`${Math.floor(n / 3600)}${getTimeUnitLabel('h')}`);
|
||||||
n %= 3600;
|
n %= 3600;
|
||||||
}
|
}
|
||||||
if (n >= 60) {
|
if (n >= 60) {
|
||||||
arr.push(`${Math.floor(n / 60)}m`);
|
arr.push(`${Math.floor(n / 60)}${getTimeUnitLabel('m')}`);
|
||||||
n %= 60;
|
n %= 60;
|
||||||
}
|
}
|
||||||
if (isNeedSeconds || (arr.length === 0 && n < 60)) {
|
if (isNeedSeconds || (arr.length === 0 && n < 60)) {
|
||||||
// round to 5 seconds
|
// round to 5 seconds
|
||||||
n = Math.floor((n + 2.5) / 5) * 5;
|
n = Math.floor((n + 2.5) / 5) * 5;
|
||||||
arr.push(`${n}s`);
|
arr.push(`${n}${getTimeUnitLabel('s')}`);
|
||||||
}
|
}
|
||||||
return arr.join(' ');
|
return arr.join(' ');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -471,20 +471,20 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
|
|||||||
async function checkSentryConsent() {
|
async function checkSentryConsent() {
|
||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description:
|
description: t(
|
||||||
'Help improve VRCX by allowing anonymous error reporting?</br></br>' +
|
'view.settings.advanced.advanced.anonymous_error_reporting.consent_description'
|
||||||
'• Only collects crash and error information.</br>' +
|
),
|
||||||
'• No personal data or VRChat information is collected.</br>' +
|
title: t(
|
||||||
'• Only enabled in nightly builds.</br>' +
|
'view.settings.advanced.advanced.anonymous_error_reporting.consent_title'
|
||||||
'• Can be disabled at anytime in Advanced Settings.',
|
)
|
||||||
title: 'Anonymous Error Reporting'
|
|
||||||
})
|
})
|
||||||
.then(async ({ ok }) => {
|
.then(async ({ ok }) => {
|
||||||
if (!ok) return;
|
if (!ok) return;
|
||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description:
|
description: t(
|
||||||
'Error reporting setting has been enabled. Would you like to restart VRCX now for the change to take effect?',
|
'view.settings.advanced.advanced.anonymous_error_reporting.enabled_restart_description'
|
||||||
|
),
|
||||||
title: t('confirm.restart_required_title'),
|
title: t('confirm.restart_required_title'),
|
||||||
confirmText: t('confirm.restart_now'),
|
confirmText: t('confirm.restart_now'),
|
||||||
cancelText: t('confirm.restart_later')
|
cancelText: t('confirm.restart_later')
|
||||||
@@ -505,8 +505,9 @@ export const useAdvancedSettingsStore = defineStore('AdvancedSettings', () => {
|
|||||||
|
|
||||||
modalStore
|
modalStore
|
||||||
.confirm({
|
.confirm({
|
||||||
description:
|
description: t(
|
||||||
'Error reporting setting has been disabled. Would you like to restart VRCX now for the change to take effect?',
|
'view.settings.advanced.advanced.anonymous_error_reporting.disabled_restart_description'
|
||||||
|
),
|
||||||
title: t('confirm.restart_required_title'),
|
title: t('confirm.restart_required_title'),
|
||||||
confirmText: t('confirm.restart_now'),
|
confirmText: t('confirm.restart_now'),
|
||||||
cancelText: t('confirm.restart_later')
|
cancelText: t('confirm.restart_later')
|
||||||
|
|||||||
@@ -165,9 +165,9 @@
|
|||||||
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
|
import { HoverCard, HoverCardContent, HoverCardTrigger } from '@/components/ui/hover-card';
|
||||||
import { fromDate, getLocalTimeZone, today } from '@internationalized/date';
|
import { fromDate, getLocalTimeZone, today } from '@internationalized/date';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { DataTableEmpty } from '@/components/ui/data-table';
|
|
||||||
import { ButtonGroup } from '@/components/ui/button-group';
|
import { ButtonGroup } from '@/components/ui/button-group';
|
||||||
import { Calendar } from '@/components/ui/calendar';
|
import { Calendar } from '@/components/ui/calendar';
|
||||||
|
import { DataTableEmpty } from '@/components/ui/data-table';
|
||||||
import { Separator } from '@/components/ui/separator';
|
import { Separator } from '@/components/ui/separator';
|
||||||
import { storeToRefs } from 'pinia';
|
import { storeToRefs } from 'pinia';
|
||||||
import { toDate } from 'reka-ui/date';
|
import { toDate } from 'reka-ui/date';
|
||||||
|
|||||||
@@ -57,9 +57,11 @@
|
|||||||
@change="setSelfInviteOverride" />
|
@change="setSelfInviteOverride" />
|
||||||
|
|
||||||
<div v-if="branch === 'Nightly'">
|
<div v-if="branch === 'Nightly'">
|
||||||
<span class="sub-header">Anonymous Error Reporting (Nightly Only)</span>
|
<span class="sub-header">{{
|
||||||
|
t('view.settings.advanced.advanced.anonymous_error_reporting.header')
|
||||||
|
}}</span>
|
||||||
<simple-switch
|
<simple-switch
|
||||||
label="Help improve VRCX by sending anonymous error reports. Only collects crash and error information, no personal data or VRChat information is collected."
|
:label="t('view.settings.advanced.advanced.anonymous_error_reporting.description')"
|
||||||
:value="sentryErrorReporting"
|
:value="sentryErrorReporting"
|
||||||
:long-label="true"
|
:long-label="true"
|
||||||
@change="setSentryErrorReporting()" />
|
@change="setSentryErrorReporting()" />
|
||||||
|
|||||||
@@ -52,17 +52,17 @@
|
|||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<InputGroupSearch
|
<InputGroupSearch
|
||||||
v-model="screenshotMetadataDialog.search"
|
v-model="screenshotMetadataDialog.search"
|
||||||
placeholder="Search"
|
:placeholder="t('dialog.screenshot_metadata.search_placeholder')"
|
||||||
style="width: 200px"
|
style="width: 200px"
|
||||||
@input="screenshotMetadataSearch" />
|
@input="screenshotMetadataSearch" />
|
||||||
<Select :model-value="screenshotMetadataDialog.searchType" @update:modelValue="handleSearchTypeChange">
|
<Select :model-value="screenshotMetadataDialog.searchType" @update:modelValue="handleSearchTypeChange">
|
||||||
<SelectTrigger size="sm" style="width: 150px; margin-left: 10px">
|
<SelectTrigger size="sm" style="width: 150px; margin-left: 10px">
|
||||||
<SelectValue placeholder="Search Type" />
|
<SelectValue :placeholder="t('dialog.screenshot_metadata.search_type_placeholder')" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectItem v-for="type in screenshotMetadataDialog.searchTypes" :key="type" :value="type">
|
<SelectItem v-for="type in screenshotMetadataDialog.searchTypes" :key="type" :value="type">
|
||||||
{{ type }}
|
{{ t(screenshotMetadataSearchTypeLabels[type] ?? type) }}
|
||||||
</SelectItem>
|
</SelectItem>
|
||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
@@ -178,13 +178,20 @@
|
|||||||
loading: false,
|
loading: false,
|
||||||
search: '',
|
search: '',
|
||||||
searchType: 'Player Name',
|
searchType: 'Player Name',
|
||||||
searchTypes: ['Player Name', 'Player ID', 'World Name', 'World ID'],
|
searchTypes: ['Player Name', 'Player ID', 'World Name', 'World ID'],
|
||||||
searchIndex: null,
|
searchIndex: null,
|
||||||
searchResults: null,
|
searchResults: null,
|
||||||
metadata: {},
|
metadata: {},
|
||||||
isUploading: false
|
isUploading: false
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const screenshotMetadataSearchTypeLabels = {
|
||||||
|
'Player Name': 'dialog.screenshot_metadata.search_types.player_name',
|
||||||
|
'Player ID': 'dialog.screenshot_metadata.search_types.player_id',
|
||||||
|
'World Name': 'dialog.screenshot_metadata.search_types.world_name',
|
||||||
|
'World ID': 'dialog.screenshot_metadata.search_types.world_id'
|
||||||
|
};
|
||||||
|
|
||||||
const screenshotMetadataSearchInputs = ref(0);
|
const screenshotMetadataSearchInputs = ref(0);
|
||||||
const screenshotMetadataCarouselApi = ref(null);
|
const screenshotMetadataCarouselApi = ref(null);
|
||||||
const ignoreCarouselSelect = ref(false);
|
const ignoreCarouselSelect = ref(false);
|
||||||
|
|||||||
@@ -146,7 +146,9 @@
|
|||||||
<Settings />
|
<Settings />
|
||||||
</div>
|
</div>
|
||||||
<div class="tool-info">
|
<div class="tool-info">
|
||||||
<div class="tool-name">{{ t('view.tools.system_tools.launch_options') }}</div>
|
<div class="tool-name">
|
||||||
|
{{ t('view.settings.advanced.advanced.launch_options') }}
|
||||||
|
</div>
|
||||||
<div class="tool-description">
|
<div class="tool-description">
|
||||||
{{ t('view.tools.system_tools.launch_options_description') }}
|
{{ t('view.tools.system_tools.launch_options_description') }}
|
||||||
</div>
|
</div>
|
||||||
@@ -159,7 +161,9 @@
|
|||||||
<Package />
|
<Package />
|
||||||
</div>
|
</div>
|
||||||
<div class="tool-info">
|
<div class="tool-info">
|
||||||
<div class="tool-name">{{ t('view.tools.system_tools.registry_backup') }}</div>
|
<div class="tool-name">
|
||||||
|
{{ t('view.settings.advanced.advanced.vrc_registry_backup') }}
|
||||||
|
</div>
|
||||||
<div class="tool-description">
|
<div class="tool-description">
|
||||||
{{ t('view.tools.system_tools.registry_backup_description') }}
|
{{ t('view.tools.system_tools.registry_backup_description') }}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user