From 0bb52e72f74605c6d9ee566f531cd48a9766b94d Mon Sep 17 00:00:00 2001 From: MartinBraquet Date: Fri, 2 Jan 2026 14:59:53 +0200 Subject: [PATCH] Translate messages --- web/components/chat/message-actions.tsx | 16 +++++---- .../messaging/new-message-button.tsx | 7 ++-- web/messages/fr.json | 26 +++++++++++++- web/pages/messages/[channelId].tsx | 35 ++++++++++--------- 4 files changed, 58 insertions(+), 26 deletions(-) diff --git a/web/components/chat/message-actions.tsx b/web/components/chat/message-actions.tsx index d2c42ff2..9c9360a0 100644 --- a/web/components/chat/message-actions.tsx +++ b/web/components/chat/message-actions.tsx @@ -12,6 +12,7 @@ import {useClickOutside} from "web/hooks/use-click-outside" import {PrivateChatMessage} from "common/chat-message"; import {updateReactionUI} from "web/lib/supabase/chat-messages"; import {useIsMobile} from "web/hooks/use-is-mobile"; +import {useT} from 'web/lib/locale' const REACTIONS = ['👍', '❤️', '😂', '😮', '😢', '👎'] @@ -37,6 +38,7 @@ export function MessageActions(props: { const user = useUser() const isOwner = user?.id === message.userId const isMobile = useIsMobile() + const t = useT() useClickOutside(emojiPickerRef, () => { setShowEmojiPicker(false) @@ -50,17 +52,17 @@ export function MessageActions(props: { }, [openEmojiPickerKey]) const handleDelete = async () => { - if (!confirm('Are you sure you want to delete this message?')) return + if (!confirm(t('messages.delete_confirm', 'Are you sure you want to delete this message?'))) return const messageId = message.id try { await api('delete-message', {messageId}) - toast.success('Message deleted') + toast.success(t('messages.deleted', 'Message deleted')) setMessages?.((prevMessages) => { if (!prevMessages) return prevMessages return prevMessages.filter((m) => m.id !== messageId) }) } catch (error) { - toast.error('Failed to delete message') + toast.error(t('messages.delete_failed', 'Failed to delete message')) console.error(error) } } @@ -97,17 +99,17 @@ export function MessageActions(props: { , onClick: onRequestEdit, }, isOwner && { - name: 'Delete', + name: t('messages.action.delete', 'Delete'), icon: , onClick: handleDelete, }, { - name: 'Add Reaction', + name: t('messages.action.add_reaction', 'Add Reaction'), icon: , onClick: () => { setShowEmojiPicker(!showEmojiPicker) @@ -121,7 +123,7 @@ export function MessageActions(props: { /> )} {/*{message.isEdited && (*/} - {/* edited*/} + {/* {t('messages.edited', 'edited')}*/} {/*)}*/} ) diff --git a/web/components/messaging/new-message-button.tsx b/web/components/messaging/new-message-button.tsx index 004ff6b2..3301a94b 100644 --- a/web/components/messaging/new-message-button.tsx +++ b/web/components/messaging/new-message-button.tsx @@ -11,14 +11,16 @@ import { SelectUsers } from 'web/components/select-users' import { DisplayUser } from 'common/api/user-types' import { usePrivateUser } from 'web/hooks/use-user' import { buildArray } from 'common/util/array' +import { useT } from 'web/lib/locale' export default function NewMessageButton() { const [open, setOpen] = useState(false) + const t = useT() return ( <> @@ -32,6 +34,7 @@ function MessageModal(props: { const { open, setOpen } = props const privateUser = usePrivateUser() const router = useRouter() + const t = useT() const [users, setUsers] = useState([]) const createChannel = async () => { @@ -62,7 +65,7 @@ function MessageModal(props: { diff --git a/web/messages/fr.json b/web/messages/fr.json index 64044133..354601a1 100644 --- a/web/messages/fr.json +++ b/web/messages/fr.json @@ -408,7 +408,31 @@ "help.actions.faq_button": "Consulter la FAQ", "messages.title": "Messages", "messages.seo.description": "Vos messages", + "messages.input_placeholder": "Envoyer un message", + "messages.menu.see_members": "Voir les membres", + "messages.menu.mute_1_day": "Couper le son pendant 1 jour", + "messages.menu.mute_forever": "Couper le son définitivement", + "messages.menu.leave_chat": "Quitter la conversation", + "messages.action.edit": "Modifier", + "messages.action.delete": "Supprimer", + "messages.action.add_reaction": "Ajouter une réaction", + "messages.toast.muting_1_day.loading": "Couper le son pour 1 jour...", + "messages.toast.muting_1_day.success": "Son coupé pour 1 jour", + "messages.toast.muting_1_day.error": "Échec de la coupure du son", + "messages.toast.muting_forever.loading": "Couper le son définitivement...", + "messages.toast.muting_forever.success": "Son coupé définitivement", + "messages.toast.muting_forever.error": "Échec de la coupure du son", "messages.empty": "Vous n'avez pas encore de messages.", + "messages.delete_confirm": "Êtes-vous sûr de vouloir supprimer ce message ?", + "messages.deleted": "Message supprimé", + "messages.delete_failed": "Échec de la suppression du message", "messages.more": " de plus", - "messages.you_prefix": "Vous : " + "messages.new_message": "Nouveau message", + "messages.create": "Créer", + "messages.you_prefix": "Vous : ", + "messages.edited": "modifié", + "messages.toast.edit_failed": "Échec de la modification du message.", + "messages.toast.send_failed": "Échec de l'envoi du message. Veuillez réessayer plus tard ou contacter le support si le problème persiste.", + "aboutsettings.copied": "Copié !", + "aboutsettings.copy_info": "Copier les infos" } \ No newline at end of file diff --git a/web/pages/messages/[channelId].tsx b/web/pages/messages/[channelId].tsx index 1374681d..5a4be116 100644 --- a/web/pages/messages/[channelId].tsx +++ b/web/pages/messages/[channelId].tsx @@ -34,9 +34,11 @@ import {ChatMessage} from 'common/chat-message' import {BackButton} from 'web/components/back-button' import {SEO} from "web/components/SEO" import {cleanDoc} from "common/util/parse"; +import {useT} from 'web/lib/locale' export default function PrivateMessagesPage() { const router = useRouter() + const t = useT() const {channelId: channelIdString} = router.query as { channelId: string } const channelId = router.isReady ? parseInt(channelIdString) : undefined const user = useUser() @@ -47,8 +49,8 @@ export default function PrivateMessagesPage() { return ( {router.isReady && channelId && user ? ( @@ -96,6 +98,7 @@ export const PrivateChat = (props: { memberIds: string[] }) => { const {user, channel, memberIds} = props + const t = useT() const channelId = channel.channel_id const isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent) const isMobile = useIsMobile() @@ -147,7 +150,7 @@ export const PrivateChat = (props: { const editor = useTextEditor({ key: `private-message-${channelId}-${user.id}`, size: 'sm', - placeholder: 'Send a message', + placeholder: t('messages.input_placeholder', 'Send a message'), }) useEffect(() => { @@ -211,8 +214,8 @@ export const PrivateChat = (props: { } catch (e) { toast.error( editingMessage - ? "Couldn't edit message." - : "Couldn't send message. Please try again later or contact support if the problem persists." + ? t('messages.toast.edit_failed', "Couldn't edit message.") + : t('messages.toast.send_failed', "Couldn't send message. Please try again later or contact support if the problem persists.") ) console.error(e) } finally { @@ -277,14 +280,14 @@ export const PrivateChat = (props: { items={buildArray( { icon: , - name: 'See members', + name: t('messages.menu.see_members', 'See members'), onClick: () => { setShowUsers(true) }, }, { icon: , - name: 'Mute 1 day', + name: t('messages.menu.mute_1_day', 'Mute 1 day'), onClick: async () => { await toast.promise( api('update-private-user-message-channel', { @@ -292,16 +295,16 @@ export const PrivateChat = (props: { notifyAfterTime: Date.now() + DAY_MS, }), { - loading: 'Muting for 1 day...', - success: 'Muted for 1 day', - error: 'Failed to mute', + loading: t('messages.toast.muting_1_day.loading', 'Muting for 1 day...'), + success: t('messages.toast.muting_1_day.success', 'Muted for 1 day'), + error: t('messages.toast.muting_1_day.error', 'Failed to mute'), } ) }, }, { icon: , - name: 'Mute forever', + name: t('messages.menu.mute_forever', 'Mute forever'), onClick: async () => { await toast.promise( api('update-private-user-message-channel', { @@ -309,16 +312,16 @@ export const PrivateChat = (props: { notifyAfterTime: Date.now() + 100 * YEAR_MS, }), { - loading: 'Muting forever...', - success: 'Muted forever', - error: 'Failed to mute', + loading: t('messages.toast.muting_forever.loading', 'Muting forever...'), + success: t('messages.toast.muting_forever.success', 'Muted forever'), + error: t('messages.toast.muting_forever.error', 'Failed to mute'), } ) }, }, { icon: , - name: 'Leave chat', + name: t('messages.menu.leave_chat', 'Leave chat'), onClick: async () => { await api('leave-private-user-message-channel', { channelId: channelId, @@ -410,7 +413,7 @@ export const PrivateChat = (props: { )} {realtimeMessages && messages.length === 0 && (
- No messages yet. + {t('messages.empty', 'No messages yet.')}
)}