From 543e6eaa5015468a536f21e22213587cd606d115 Mon Sep 17 00:00:00 2001 From: h Date: Mon, 19 Oct 2026 05:32:34 +0000 Subject: [PATCH] feat(frontend): service messages speak russian and english --- .../src/lib/components/ActionMessage.svelte | 39 +++++++++------ frontend/src/lib/i18n/messages.ts | 2 + frontend/src/lib/i18n/messages/service.ts | 50 +++++++++++++++++++ 3 files changed, 75 insertions(+), 16 deletions(-) create mode 100644 frontend/src/lib/i18n/messages/service.ts diff --git a/frontend/src/lib/components/ActionMessage.svelte b/frontend/src/lib/components/ActionMessage.svelte index 3c88cf0..f62fe20 100644 --- a/frontend/src/lib/components/ActionMessage.svelte +++ b/frontend/src/lib/components/ActionMessage.svelte @@ -2,6 +2,7 @@ import type { MessageView } from "#lib/api/types.js"; import Icon from "#lib/components/ui/Icon.svelte"; import { accountName, peerName } from "#lib/format/peer.js"; + import { t } from "#lib/i18n/locale.svelte.js"; import { accounts } from "#lib/stores/accounts.svelte.js"; import { peers } from "#lib/stores/peers.svelte.js"; @@ -16,10 +17,12 @@ function nameOf(id: number | null): string { if (id === null) { - return "Someone"; + return t("service.someone"); } if (id === ownId) { - return accounts.selected ? accountName(accounts.selected) : "You"; + return accounts.selected + ? accountName(accounts.selected) + : t("service.you"); } const peer = peers.get(id); return peer ? peerName(peer) : String(id); @@ -44,35 +47,39 @@ const selfJoin = members.length === 1 && members[0] === message.sender_id; if (selfJoin) { - return `${actor} joined the group`; + return t("service.joined", { actor }); } const names = members.map(nameOf).join(", "); - return names ? `${actor} added ${names}` : `${actor} joined the group`; + return names + ? t("service.added", { actor, names }) + : t("service.joined", { actor }); } case "left_chat_members": - return `${actor} left the group`; + return t("service.left", { actor }); case "pinned_message": - return `${actor} pinned a message`; + return t("service.pinned", { actor }); case "group_chat_created": - return `${actor} created the group`; + return t("service.groupCreated", { actor }); case "channel_chat_created": - return "Channel created"; + return t("service.channelCreated"); case "phone_call_ended": return service.duration === null - ? "Call ended" - : `Call ended · ${durationOf(service.duration)}`; + ? t("service.callEnded") + : t("service.callEndedAfter", { + duration: durationOf(service.duration), + }); case "phone_call_started": - return "Call started"; + return t("service.callStarted"); case "poll_option_added": - return `${actor} added a poll option`; + return t("service.pollOption", { actor }); case "new_chat_title": - return `${actor} changed the group name`; + return t("service.titleChanged", { actor }); case "new_chat_photo": - return `${actor} changed the group photo`; + return t("service.photoChanged", { actor }); case "delete_chat_photo": - return `${actor} removed the group photo`; + return t("service.photoRemoved", { actor }); default: - return service.kind.replace(/_/g, " ") || "Service message"; + return t("service.unknown"); } }); diff --git a/frontend/src/lib/i18n/messages.ts b/frontend/src/lib/i18n/messages.ts index b230dc9..dae4238 100644 --- a/frontend/src/lib/i18n/messages.ts +++ b/frontend/src/lib/i18n/messages.ts @@ -14,6 +14,7 @@ import { policy } from "#lib/i18n/messages/policy.js"; import { profile } from "#lib/i18n/messages/profile.js"; import { read } from "#lib/i18n/messages/read.js"; import { search } from "#lib/i18n/messages/search.js"; +import { service } from "#lib/i18n/messages/service.js"; import { settings } from "#lib/i18n/messages/settings.js"; import { shares } from "#lib/i18n/messages/shares.js"; import { social } from "#lib/i18n/messages/social.js"; @@ -40,6 +41,7 @@ export const messages = { ...profile, ...read, ...search, + ...service, ...settings, ...shares, ...social, diff --git a/frontend/src/lib/i18n/messages/service.ts b/frontend/src/lib/i18n/messages/service.ts new file mode 100644 index 0000000..df7a2d2 --- /dev/null +++ b/frontend/src/lib/i18n/messages/service.ts @@ -0,0 +1,50 @@ +import type { Messages } from "#lib/i18n/types.js"; + +export const service = { + "service.added": { + en: "{actor} added {names}", + ru: "{actor} добавил(а) {names}", + }, + "service.callEnded": { en: "Call ended", ru: "Звонок завершён" }, + "service.callEndedAfter": { + en: "Call ended · {duration}", + ru: "Звонок завершён · {duration}", + }, + "service.callStarted": { en: "Call started", ru: "Звонок начат" }, + "service.channelCreated": { en: "Channel created", ru: "Канал создан" }, + "service.groupCreated": { + en: "{actor} created the group", + ru: "{actor} создал(а) группу", + }, + "service.joined": { + en: "{actor} joined the group", + ru: "{actor} вступил(а) в группу", + }, + "service.left": { + en: "{actor} left the group", + ru: "{actor} покинул(а) группу", + }, + "service.photoChanged": { + en: "{actor} changed the group photo", + ru: "{actor} изменил(а) фото группы", + }, + "service.photoRemoved": { + en: "{actor} removed the group photo", + ru: "{actor} удалил(а) фото группы", + }, + "service.pinned": { + en: "{actor} pinned a message", + ru: "{actor} закрепил(а) сообщение", + }, + "service.pollOption": { + en: "{actor} added a poll option", + ru: "{actor} добавил(а) вариант в опрос", + }, + "service.someone": { en: "Someone", ru: "Кто-то" }, + "service.titleChanged": { + en: "{actor} changed the group name", + ru: "{actor} изменил(а) название группы", + }, + "service.unknown": { en: "Service message", ru: "Служебное сообщение" }, + "service.you": { en: "You", ru: "Вы" }, +} satisfies Messages;