Update Japanese translation and add localization support in notification (#1706)

This commit is contained in:
Yuki
2026-03-27 13:31:12 +09:00
committed by GitHub
parent 1e5cc91fc2
commit 3dc7b07dd4
9 changed files with 990 additions and 276 deletions

View File

@@ -1,7 +1,7 @@
<template>
<Dialog v-model:open="isOpen">
<DialogContent
class="border border-border bg-background/85 shadow-lg backdrop-blur-xl backdrop-saturate-[1.4] sm:max-w-xl"
class="border border-border bg-background/85 shadow-lg backdrop-blur-xl backdrop-saturate-[1.4] sm:max-w-3xl"
:show-close-button="false"
@escape-key-down="handleDismiss"
@pointer-down-outside="handleDismiss"

View File

@@ -1,7 +1,7 @@
<template>
<Dialog v-model:open="whatsNewDialog.visible">
<DialogContent
class="border border-border bg-background/88 p-5 shadow-lg backdrop-blur-xl backdrop-saturate-[1.4] sm:max-w-xl"
class="border border-border bg-background/88 p-5 shadow-lg backdrop-blur-xl backdrop-saturate-[1.4] sm:max-w-3xl"
:show-close-button="false"
@escape-key-down="handleDismiss"
@pointer-down-outside="handleDismiss"

View File

@@ -490,9 +490,10 @@ export function selectAvatarWithConfirmation(id) {
*/
export async function selectAvatarWithoutConfirmation(id) {
const userStore = useUserStore();
const t = i18n.global.t;
if (userStore.currentUser.currentAvatar === id) {
toast.info('Avatar already selected');
toast.info(t('message.avatar.already_selected'));
return;
}
return avatarRequest
@@ -500,7 +501,7 @@ export async function selectAvatarWithoutConfirmation(id) {
avatarId: id
})
.then(() => {
toast.success('Avatar changed');
toast.success(t('message.avatar.selected'));
});
}

View File

@@ -972,6 +972,7 @@
"layout_table": "Notifications Tab",
"notification_filter": "Notification Filters",
"test_notification": "Send Test Notification",
"test_message": "Test notification.",
"steamvr_notifications": {
"header": "SteamVR Notifications",
"steamvr_overlay": "SteamVR Overlay",
@@ -2657,6 +2658,8 @@
"create_failed": "Failed to create instance"
},
"avatar": {
"selected": "Avatar changed",
"already_selected": "Avatar already selected",
"change_moderation_failed": "Failed to change avatar moderation",
"fallback_changed": "Fallback avatar changed",
"blocked": "Avatar blocked",
@@ -2710,7 +2713,9 @@
},
"gallery": {
"uploaded": "Gallery image uploaded",
"failed": "Failed to upload gallery image"
"failed": "Failed to upload gallery image",
"profile_pic_changed": "Profile picture changed",
"profile_icon_changed": "Profile icon changed"
},
"upload": {
"loading": "Uploading",
@@ -2773,6 +2778,44 @@
"copy_failed": "Copy failed",
"error": "Error"
},
"notifications": {
"has_joined": "has joined",
"has_left": "has left",
"is_joining": "is joining",
"gps": "is in {location}",
"online_location": "has logged in to {location}",
"online": "has logged in",
"offline": "has logged out",
"status_update": "status is now {status} {description}",
"invite": "has invited you to {location} {message}",
"request_invite": "has requested an invite {message}",
"invite_response": "has responded to your invite {message}",
"request_invite_response": "has responded to your invite request {message}",
"friend_request": "has sent you a friend request",
"friend": "is now your friend",
"unfriend": "is no longer your friend",
"trust_level": "Trust level is now {trustLevel}",
"display_name": "changed their name to {displayName}",
"group_announcement_title": "Group Announcement",
"group_informative_title": "Group Informative",
"group_invite_title": "Group Invite",
"group_join_request_title": "Group Join Request",
"group_transfer_request_title": "Group Transfer Request",
"group_queue_ready_title": "Instance Queue Ready",
"instance_closed_title": "Instance Closed",
"portal_spawn_name": "has spawned a portal to {location}",
"portal_spawn": "User has spawned a portal",
"avatar_change": "changed into avatar {avatar}",
"chat_message": "said: {message}",
"blocked_player_joined": "Blocked user has joined",
"blocked_player_left": "Blocked user has left",
"muted_player_joined": "Muted user has joined",
"muted_player_left": "Muted user has left",
"blocked": "has blocked you",
"unblocked": "has unblocked you",
"muted": "has muted you",
"unmuted": "has unmuted you"
},
"status": {
"title": "VRChat Status"
},

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
const toolCategories = [
{ key: 'image', labelKey: 'view.tools.pictures.header' },
{ key: 'shortcuts', labelKey: 'view.tools.shortcuts.header' },
{ key: 'system', labelKey: 'view.tools.system_tools.header' },
{ key: 'group', labelKey: 'view.tools.group.header' },
{ key: 'system', labelKey: 'view.tools.system_tools.header' },
{ key: 'user', labelKey: 'view.tools.export.header' },
{ key: 'other', labelKey: 'view.tools.other.header' }
];

View File

@@ -1,4 +1,5 @@
import { displayLocation } from './locationParser';
import { i18n } from '../../plugins/i18n';
/**
* Extracts the notification title and body from a notification object.
@@ -13,128 +14,131 @@ import { displayLocation } from './locationParser';
export function getNotificationMessage(noty, message, displayNameOverride) {
const name = displayNameOverride || noty.displayName;
const sender = displayNameOverride || noty.senderUsername;
const t = i18n.global.t;
switch (noty.type) {
case 'OnPlayerJoined':
return { title: name, body: 'has joined' };
return { title: name, body: t('notifications.has_joined') };
case 'OnPlayerLeft':
return { title: name, body: 'has left' };
return { title: name, body: t('notifications.has_left') };
case 'OnPlayerJoining':
return { title: name, body: 'is joining' };
return { title: name, body: t('notifications.is_joining') };
case 'GPS':
return {
title: name,
body: `is in ${displayLocation(
body: t('notifications.gps', { location: displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`
)})
};
case 'Online': {
let locationName = '';
if (noty.worldName) {
locationName = ` to ${displayLocation(
noty.location,
noty.worldName,
noty.groupName
)}`;
return {
title: name,
body: t('notifications.online_location', { location: displayLocation(
noty.location,
noty.worldName,
noty.groupName
) })
};
}
return {
title: name,
body: `has logged in${locationName}`
title: name, body: t('notifications.online')
};
}
case 'Offline':
return { title: name, body: 'has logged out' };
return { title: name, body: t('notifications.offline') };
case 'Status':
return {
title: name,
body: `status is now ${noty.status} ${noty.statusDescription}`
body: t('notifications.status_update', { status: noty.status, description: noty.statusDescription })
};
case 'invite':
return {
title: sender,
body: `has invited you to ${displayLocation(
body: t('notifications.invite', { location: displayLocation(
noty.details.worldId,
noty.details.worldName
)}${message}`
), message })
};
case 'requestInvite':
return {
title: sender,
body: `has requested an invite${message}`
body: t('notifications.request_invite', { message })
};
case 'inviteResponse':
return {
title: sender,
body: `has responded to your invite${message}`
body: t('notifications.invite_response', { message })
};
case 'requestInviteResponse':
return {
title: sender,
body: `has responded to your invite request${message}`
body: t('notifications.request_invite_response', { message })
};
case 'friendRequest':
return {
title: sender,
body: 'has sent you a friend request'
body: t('notifications.friend_request')
};
case 'Friend':
return { title: name, body: 'is now your friend' };
return { title: name, body: t('notifications.friend') };
case 'Unfriend':
return {
title: name,
body: 'is no longer your friend'
body: t('notifications.unfriend')
};
case 'TrustLevel':
return {
title: name,
body: `trust level is now ${noty.trustLevel}`
body: t('notifications.trust_level', { trustLevel: noty.trustLevel })
};
case 'DisplayName':
return {
title: displayNameOverride || noty.previousDisplayName,
body: `changed their name to ${noty.displayName}`
body: t('notifications.display_name', { displayName: noty.displayName })
};
case 'boop':
return { title: sender, body: noty.message };
case 'groupChange':
return { title: sender, body: noty.message };
case 'group.announcement':
return { title: 'Group Announcement', body: noty.message };
return { title: t('notifications.group_announcement_title'), body: noty.message };
case 'group.informative':
return { title: 'Group Informative', body: noty.message };
return { title: t('notifications.group_informative_title'), body: noty.message };
case 'group.invite':
return { title: 'Group Invite', body: noty.message };
return { title: t('notifications.group_invite_title'), body: noty.message };
case 'group.joinRequest':
return { title: 'Group Join Request', body: noty.message };
return { title: t('notifications.group_join_request_title'), body: noty.message };
case 'group.transfer':
return { title: 'Group Transfer Request', body: noty.message };
return { title: t('notifications.group_transfer_request_title'), body: noty.message };
case 'group.queueReady':
return { title: 'Instance Queue Ready', body: noty.message };
return { title: t('notifications.group_queue_ready_title'), body: noty.message };
case 'instance.closed':
return { title: 'Instance Closed', body: noty.message };
return { title: t('notifications.instance_closed_title'), body: noty.message };
case 'PortalSpawn':
if (name) {
return {
title: name,
body: `has spawned a portal to ${displayLocation(
body: t('notifications.portal_spawn_name', { location: displayLocation(
noty.instanceId,
noty.worldName,
noty.groupName
)}`
) })
};
}
return { title: '', body: 'User has spawned a portal' };
return { title: '', body: t('notifications.portal_spawn') };
case 'AvatarChange':
return {
title: name,
body: `changed into avatar ${noty.name}`
body: t('notifications.avatar_change', { avatar: noty.name })
};
case 'ChatBoxMessage':
return {
title: name,
body: `said ${noty.text}`
body: t('notifications.chat_message', { message: noty.text })
};
case 'Event':
return { title: 'Event', body: noty.data };
@@ -145,31 +149,31 @@ export function getNotificationMessage(noty, message, displayNameOverride) {
case 'BlockedOnPlayerJoined':
return {
title: name,
body: 'Blocked user has joined'
body: t('notifications.blocked_player_joined')
};
case 'BlockedOnPlayerLeft':
return {
title: name,
body: 'Blocked user has left'
body: t('notifications.blocked_player_left')
};
case 'MutedOnPlayerJoined':
return {
title: name,
body: 'Muted user has joined'
body: t('notifications.muted_player_joined')
};
case 'MutedOnPlayerLeft':
return {
title: name,
body: 'Muted user has left'
body: t('notifications.muted_player_left')
};
case 'Blocked':
return { title: name, body: 'has blocked you' };
return { title: name, body: t('notifications.blocked') };
case 'Unblocked':
return { title: name, body: 'has unblocked you' };
return { title: name, body: t('notifications.unblocked') };
case 'Muted':
return { title: name, body: 'has muted you' };
return { title: name, body: t('notifications.muted') };
case 'Unmuted':
return { title: name, body: 'has unmuted you' };
return { title: name, body: t('notifications.unmuted') };
default:
return null;
}

View File

@@ -1198,7 +1198,7 @@ export const useNotificationStore = defineStore('Notification', () => {
playNoty({
type: 'Event',
created_at: new Date().toJSON(),
data: 'Notification Test'
data: t('view.settings.notifications.notifications.test_message')
});
}

View File

@@ -896,7 +896,7 @@
profilePicOverride
})
.then((args) => {
toast.success('Profile picture changed');
toast.success(t('message.gallery.profile_pic_changed'));
return args;
});
}
@@ -963,7 +963,7 @@
userIcon
})
.then((args) => {
toast.success('Icon changed');
toast.success(t('message.gallery.profile_icon_changed'));
return args;
});
}