From b02378d396b577878d75ddf0b54b3a864a2e9892 Mon Sep 17 00:00:00 2001 From: Luke Policinski Date: Tue, 6 Oct 2026 03:34:08 +0000 Subject: [PATCH 1/3] Add message requests for direct messages from non-friends Players can message anyone who takes message requests, not only friends. A first message from a non-friend waits under a Requests button on the chat rail instead of opening a tab, badging or flashing. Opening one shows the conversation with a banner; replying accepts it and Deny hides it. The sender's composer stays locked with a hint until they get a reply. Message buttons now show for non-friends, except on the profile of a player who has turned requests off. The setting lives on the blocked players page. --- components/hub/ChatPanel.vue | 133 +++++++++++++- components/hub/MessageRequests.vue | 122 +++++++++++++ components/hub/MessageRequestsRailButton.vue | 40 +++++ components/hub/NewConversation.vue | 5 +- composables/useDirectMessages.ts | 14 +- composables/useIncomingDirectMessages.ts | 47 ++++- composables/useMessageRequests.ts | 165 ++++++++++++++++++ graphql/messageRequests.ts | 25 +++ i18n/locales/ar_SA.json | 26 ++- i18n/locales/da_DK.json | 26 ++- i18n/locales/de_DE.json | 26 ++- i18n/locales/en.json | 26 ++- i18n/locales/es_ES.json | 26 ++- i18n/locales/fr_FR.json | 26 ++- i18n/locales/it_IT.json | 26 ++- i18n/locales/ja_JP.json | 26 ++- i18n/locales/ko_KR.json | 26 ++- i18n/locales/pl_PL.json | 26 ++- i18n/locales/pt_BR.json | 26 ++- i18n/locales/ru_RU.json | 26 ++- i18n/locales/sv_SE.json | 26 ++- i18n/locales/tr_TR.json | 26 ++- i18n/locales/uk_UA.json | 26 ++- i18n/locales/zh_Hans.json | 26 ++- i18n/locales/zh_Hant.json | 26 ++- pages/players/[id].vue | 32 +++- pages/settings/blocked-players.vue | 84 +++++++++ tests/components/ChatPanel.spec.ts | 1 + .../useIncomingDirectMessages.spec.ts | 80 +++++++++ utilities/chatErrors.ts | 2 + 30 files changed, 1123 insertions(+), 69 deletions(-) create mode 100644 components/hub/MessageRequests.vue create mode 100644 components/hub/MessageRequestsRailButton.vue create mode 100644 composables/useMessageRequests.ts create mode 100644 graphql/messageRequests.ts diff --git a/components/hub/ChatPanel.vue b/components/hub/ChatPanel.vue index 42904ebaa..df334b42e 100644 --- a/components/hub/ChatPanel.vue +++ b/components/hub/ChatPanel.vue @@ -1,5 +1,5 @@ + + diff --git a/components/hub/MessageRequestsRailButton.vue b/components/hub/MessageRequestsRailButton.vue new file mode 100644 index 000000000..f2e872a70 --- /dev/null +++ b/components/hub/MessageRequestsRailButton.vue @@ -0,0 +1,40 @@ + + + diff --git a/components/hub/NewConversation.vue b/components/hub/NewConversation.vue index ec9affd78..888baa4bb 100644 --- a/components/hub/NewConversation.vue +++ b/components/hub/NewConversation.vue @@ -9,9 +9,8 @@ import { setActiveHub } from "~/composables/useHubState"; import { resolveAvatarUrl } from "~/utilities/avatarUrl"; // Starting a conversation, inside Chat itself: the thread area becomes a -// "To:" field over your friends, online first. Direct messages are between -// accepted friends only (the server enforces the same), so this lists friends -// rather than searching every player and refusing most of them. +// "To:" field over your friends, online first. Anyone else is messaged from +// their profile or name, where a first message goes out as a request. const emit = defineEmits<{ (e: "close"): void }>(); const matchmakingStore = useMatchmakingStore(); diff --git a/composables/useDirectMessages.ts b/composables/useDirectMessages.ts index 82e75f9c6..5e30df9f5 100644 --- a/composables/useDirectMessages.ts +++ b/composables/useDirectMessages.ts @@ -55,9 +55,13 @@ export function useDirectMessages() { const authStore = useAuthStore(); const { setRightSidebarOpen } = useRightSidebar(); - // Accepted friends only -- a pending request in either direction is not a - // friendship, and the server enforces the same rule. - function canMessage(steamId: string | number | undefined | null): boolean { + // Friends always. Anyone else gets a message request, unless they are known to + // take messages from friends only -- the server enforces the same rule, and a + // caller that cannot tell leaves the server to say so. + function canMessage( + steamId: string | number | undefined | null, + allowsMessageRequests?: boolean | null, + ): boolean { if (!steamId || !authStore.me?.steam_id) { return false; } @@ -66,7 +70,9 @@ export function useDirectMessages() { return false; } - return relationship(steamId) === "friend"; + return ( + relationship(steamId) === "friend" || allowsMessageRequests !== false + ); } function openConversation( diff --git a/composables/useIncomingDirectMessages.ts b/composables/useIncomingDirectMessages.ts index 239098648..dbf34a9cb 100644 --- a/composables/useIncomingDirectMessages.ts +++ b/composables/useIncomingDirectMessages.ts @@ -21,6 +21,8 @@ export function useIncomingDirectMessages() { const { openTab, closeTab, incrementUnread, setUnread, noteActivity, tabs } = useChatTabs(); const { topPosition } = useDirectConversationBar(); + const { addRequest, setRequests, setAwaitingReply, reset } = + useMessageRequests(); function ensureTab( roomId: string, @@ -84,13 +86,34 @@ export function useIncomingDirectMessages() { isOpen: boolean; position: number; peer: DirectMessagePeer; + // Waiting on this player: a stranger's first message. + request?: boolean; + // This player's own request, not yet replied to. + awaitingReply?: boolean; }>; }>( `https://${useRuntimeConfig().public.apiDomain}/chat/direct/conversations`, { credentials: "include" }, ); + setRequests( + conversations + .filter( + (conversation) => + conversation.request && + !socket.hidesAuthor(conversation.peer?.steam_id), + ) + .map(({ roomId, peer, unread }) => ({ roomId, peer, unread })), + ); + for (const conversation of conversations) { + // Requests wait in their own list, off the rail and out of the badges. + if (conversation.request) { + continue; + } + + setAwaitingReply(conversation.roomId, !!conversation.awaitingReply); + if (!conversation.isOpen && conversation.unread <= 0) { continue; } @@ -115,6 +138,8 @@ export function useIncomingDirectMessages() { roomId: string; from: DirectMessagePeer; message?: LobbyMessage; + // A stranger's first message: it goes to requests, quietly. + request?: boolean; }) => { const steamId = authStore.me?.steam_id; @@ -131,17 +156,27 @@ export function useIncomingDirectMessages() { return; } + const from = { + steam_id: peerId, + name: data.from?.name, + avatar_url: data.from?.avatar_url, + }; + + if (data.request) { + addRequest({ roomId: data.roomId, peer: from, unread: 1 }); + return; + } + + // They wrote back, so whatever this player sent them is answered. + setAwaitingReply(data.roomId, false); + // The room's own `lobby:chat` carries the same id when its tab is open. useTabFlash().signalChat("direct", data.message); // Deliberately does not inject the message: opening the tab makes // useChatTabSetup join the room, and the join's history snapshot delivers // it (deduped by chatMessageKey either way). - ensureTab(data.roomId, { - steam_id: peerId, - name: data.from?.name, - avatar_url: data.from?.avatar_url, - }); + ensureTab(data.roomId, from); // Counted here for an existing tab too: a burst that lands before a new // tab's join reaches no lobby:chat, and the join's snapshot is never @@ -164,6 +199,8 @@ export function useIncomingDirectMessages() { return; } + reset(); + for (const tab of [...tabs.value]) { if (tab.type === "direct") { closeTab(tab.id); diff --git a/composables/useMessageRequests.ts b/composables/useMessageRequests.ts new file mode 100644 index 000000000..126ac793c --- /dev/null +++ b/composables/useMessageRequests.ts @@ -0,0 +1,165 @@ +import { computed, ref } from "vue"; +import socket from "~/web-sockets/Socket"; +import { + directTabId, + type DirectMessagePeer, +} from "~/composables/useDirectMessages"; + +// A first message from someone who is not a friend. It waits here rather than +// on the rail: no tab, no badge, no flash, so a flood of them cannot take over +// the chat. Replying accepts it; declining hides it, and the sender is never +// told. The server owns the state -- this mirrors it. +export interface MessageRequest { + roomId: string; + peer: DirectMessagePeer; + unread: number; +} + +const requestsRef = ref([]); +// Conversations the server says are waiting on the other side to reply to this +// player's request, and ones it says are not. A conversation started in this +// session is in neither, and is worked out from its messages instead. +const awaitingRef = ref>(new Set()); +const settledRef = ref>(new Set()); + +function apiBase() { + return `https://${useRuntimeConfig().public.apiDomain}/chat/direct/conversations`; +} + +export function useMessageRequests() { + const authStore = useAuthStore(); + const { relationship } = useFriendActions(); + + const requests = computed(() => requestsRef.value); + const requestCount = computed(() => requestsRef.value.length); + + function isRequest(roomId: string | undefined) { + return ( + !!roomId && requestsRef.value.some((request) => request.roomId === roomId) + ); + } + + function addRequest(request: MessageRequest) { + const existing = requestsRef.value.find( + ({ roomId }) => roomId === request.roomId, + ); + + if (existing) { + existing.unread = Math.max(existing.unread, request.unread); + return; + } + + requestsRef.value = [request, ...requestsRef.value]; + } + + function removeRequest(roomId: string) { + requestsRef.value = requestsRef.value.filter( + (request) => request.roomId !== roomId, + ); + } + + function setRequests(list: MessageRequest[]) { + requestsRef.value = list; + } + + // What the server last said about this player's side of a conversation. + function setAwaitingReply(roomId: string, awaiting: boolean) { + const awaitingRooms = new Set(awaitingRef.value); + const settledRooms = new Set(settledRef.value); + + if (awaiting) { + awaitingRooms.add(roomId); + settledRooms.delete(roomId); + } else { + awaitingRooms.delete(roomId); + settledRooms.add(roomId); + } + + awaitingRef.value = awaitingRooms; + settledRef.value = settledRooms; + } + + // Whether this player has sent their one message and is waiting on a reply. + // Anything from the other side ends the wait, whatever the server said last. + function isAwaitingReply( + roomId: string | undefined, + peerSteamId: string | undefined, + ): boolean { + const me = authStore.me?.steam_id; + + if (!roomId || !peerSteamId || !me) { + return false; + } + + const messages = socket.lobbyMessages("direct", roomId); + const fromPeer = messages.some( + (message) => String(message.from?.steam_id) === String(peerSteamId), + ); + + if (fromPeer) { + return false; + } + + if (awaitingRef.value.has(roomId)) { + return true; + } + + if ( + settledRef.value.has(roomId) || + relationship(peerSteamId) === "friend" + ) { + return false; + } + + return messages.some( + (message) => String(message.from?.steam_id) === String(me), + ); + } + + // Replying is what accepts a request, so once this player has written in it, + // it is an ordinary conversation. + function acceptIfReplied(roomId: string) { + const me = authStore.me?.steam_id; + + if ( + me && + isRequest(roomId) && + socket + .lobbyMessages("direct", roomId) + .some((message) => String(message.from?.steam_id) === String(me)) + ) { + removeRequest(roomId); + setAwaitingReply(roomId, false); + } + } + + async function decline(roomId: string) { + await $fetch(`${apiBase()}/${encodeURIComponent(roomId)}/decline`, { + method: "POST", + credentials: "include", + }); + + removeRequest(roomId); + useChatTabs().closeTab(directTabId(roomId)); + } + + function reset() { + requestsRef.value = []; + awaitingRef.value = new Set(); + settledRef.value = new Set(); + } + + return { + requests, + requestCount, + isRequest, + addRequest, + removeRequest, + setRequests, + setAwaitingReply, + isAwaitingReply, + acceptIfReplied, + decline, + reset, + }; +} diff --git a/graphql/messageRequests.ts b/graphql/messageRequests.ts new file mode 100644 index 000000000..abdc77a04 --- /dev/null +++ b/graphql/messageRequests.ts @@ -0,0 +1,25 @@ +import gql from "graphql-tag"; + +// Raw documents until `yarn codegen` runs against an api with +// players.allow_message_requests; rewrite them as Zeus selectors then. Kept out +// of meFields, which every sign-in depends on. +export const MY_MESSAGE_REQUESTS_SETTING_QUERY = gql` + query MyMessageRequestsSetting($steamId: bigint!) { + players_by_pk(steam_id: $steamId) { + steam_id + allow_message_requests + } + } +`; + +export const SET_MESSAGE_REQUESTS_SETTING_MUTATION = gql` + mutation SetMessageRequestsSetting($steamId: bigint!, $allow: Boolean!) { + update_players_by_pk( + pk_columns: { steam_id: $steamId } + _set: { allow_message_requests: $allow } + ) { + steam_id + allow_message_requests + } + } +`; diff --git a/i18n/locales/ar_SA.json b/i18n/locales/ar_SA.json index 77e4eff60..bde34df47 100644 --- a/i18n/locales/ar_SA.json +++ b/i18n/locales/ar_SA.json @@ -3265,7 +3265,13 @@ "description": "لا يمكن للاعبين المحظورين مراسلتك أو دعوتك أو إرسال طلبات صداقة إليك. إلغاء حظر أي لاعب لا يعيد صداقتكما.", "empty_title": "لا يوجد لاعبون محظورون", "empty_description": "سيظهر هنا اللاعبون الذين تحظرهم من ملفهم الشخصي أو من قائمة اللاعب.", - "blocked_on": "حُظر" + "blocked_on": "حُظر", + "message_requests": { + "title": "طلبات الرسائل", + "description": "اسمح للاعبين الذين ليسوا من أصدقائك بإرسال رسالة واحدة إليك. تنتظر في طلباتك حتى ترد.", + "updated": "تم حفظ إعداد طلبات الرسائل", + "update_failed": "تعذّر حفظ إعداد طلبات الرسائل" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "انتهت · تُغلق خلال {time}", "tournament_ended_days": "{count} ي", "tournament_ended_hours": "{count} س", - "tournament_ended_tooltip": "انتهت هذه البطولة. تبقى دردشتها مفتوحة لمدة 7 أيام." + "tournament_ended_tooltip": "انتهت هذه البطولة. تبقى دردشتها مفتوحة لمدة 7 أيام.", + "requests": { + "open": "طلبات الرسائل ({count})", + "title": "طلبات الرسائل", + "hint": "من لاعبين ليسوا من أصدقائك", + "close": "إغلاق طلبات الرسائل", + "wants_to_message": "يريد مراسلتك", + "deny": "رفض", + "deny_failed": "تعذّر رفض هذا الطلب", + "empty_title": "لا توجد طلبات رسائل", + "empty_description": "تنتظر هنا الرسائل الأولى من لاعبين ليسوا من أصدقائك.", + "banner": "{name} ليس من أصدقائك. رُدّ لقبول طلب الرسالة، أو ارفضه.", + "awaiting_reply": "بانتظار رد {name} على طلب رسالتك." + } }, "recent_games": { "title": "المباريات الأخيرة", @@ -9862,7 +9881,8 @@ "direct": { "message": "رسالة", "empty": "لا رسائل بعد. ألقِ التحية." - } + }, + "awaiting_reply": "لم يتم الرد على طلب رسالتك بعد. يمكنك الكتابة مجددًا بعد أن يرد." }, "charts": { "usage": "الاستخدام", diff --git a/i18n/locales/da_DK.json b/i18n/locales/da_DK.json index e9b37267d..c58e50c3f 100644 --- a/i18n/locales/da_DK.json +++ b/i18n/locales/da_DK.json @@ -3265,7 +3265,13 @@ "description": "Blokerede spillere kan ikke sende dig beskeder, invitationer eller venneanmodninger. At fjerne en blokering gendanner ikke jeres venskab.", "empty_title": "Ingen blokerede spillere", "empty_description": "Spillere, du blokerer fra deres profil eller spillermenuen, vises her.", - "blocked_on": "Blokeret" + "blocked_on": "Blokeret", + "message_requests": { + "title": "Beskedanmodninger", + "description": "Lad spillere, der ikke er dine venner, sende dig én besked. Den venter i dine anmodninger, indtil du svarer.", + "updated": "Indstilling for beskedanmodninger gemt", + "update_failed": "Kunne ikke gemme indstillingen for beskedanmodninger" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Afsluttet · lukker om {time}", "tournament_ended_days": "{count} d", "tournament_ended_hours": "{count} t", - "tournament_ended_tooltip": "Denne turnering er afsluttet. Dens chat er åben i 7 dage." + "tournament_ended_tooltip": "Denne turnering er afsluttet. Dens chat er åben i 7 dage.", + "requests": { + "open": "Beskedanmodninger ({count})", + "title": "Beskedanmodninger", + "hint": "Fra spillere, der ikke er dine venner", + "close": "Luk beskedanmodninger", + "wants_to_message": "Vil gerne skrive til dig", + "deny": "Afvis", + "deny_failed": "Kunne ikke afvise anmodningen", + "empty_title": "Ingen beskedanmodninger", + "empty_description": "Første beskeder fra spillere, der ikke er dine venner, venter her.", + "banner": "{name} er ikke din ven. Svar for at acceptere beskedanmodningen, eller afvis den.", + "awaiting_reply": "Venter på, at {name} svarer på din beskedanmodning." + } }, "recent_games": { "title": "Seneste kampe", @@ -9862,7 +9881,8 @@ "direct": { "message": "Besked", "empty": "Ingen beskeder endnu. Sig hej." - } + }, + "awaiting_reply": "Din beskedanmodning er ikke besvaret endnu. Du kan skrive igen, når de svarer." }, "charts": { "usage": "Forbrug", diff --git a/i18n/locales/de_DE.json b/i18n/locales/de_DE.json index d93710b3a..dab887eaf 100644 --- a/i18n/locales/de_DE.json +++ b/i18n/locales/de_DE.json @@ -3265,7 +3265,13 @@ "description": "Blockierte Spieler können dir keine Nachrichten, Einladungen oder Freundschaftsanfragen senden. Das Aufheben einer Blockierung stellt eure Freundschaft nicht wieder her.", "empty_title": "Keine blockierten Spieler", "empty_description": "Spieler, die du über ihr Profil oder das Spielermenü blockierst, erscheinen hier.", - "blocked_on": "Blockiert" + "blocked_on": "Blockiert", + "message_requests": { + "title": "Nachrichtenanfragen", + "description": "Erlaube Spielern, die nicht mit dir befreundet sind, dir eine Nachricht zu senden. Sie wartet in deinen Anfragen, bis du antwortest.", + "updated": "Einstellung für Nachrichtenanfragen gespeichert", + "update_failed": "Einstellung für Nachrichtenanfragen konnte nicht gespeichert werden" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Beendet · schließt in {time}", "tournament_ended_days": "{count} T.", "tournament_ended_hours": "{count} Std.", - "tournament_ended_tooltip": "Dieses Turnier ist beendet. Der Chat bleibt 7 Tage lang geöffnet." + "tournament_ended_tooltip": "Dieses Turnier ist beendet. Der Chat bleibt 7 Tage lang geöffnet.", + "requests": { + "open": "Nachrichtenanfragen ({count})", + "title": "Nachrichtenanfragen", + "hint": "Von Spielern, die nicht mit dir befreundet sind", + "close": "Nachrichtenanfragen schließen", + "wants_to_message": "Möchte dir schreiben", + "deny": "Ablehnen", + "deny_failed": "Anfrage konnte nicht abgelehnt werden", + "empty_title": "Keine Nachrichtenanfragen", + "empty_description": "Erste Nachrichten von Spielern, die nicht mit dir befreundet sind, warten hier.", + "banner": "{name} ist nicht mit dir befreundet. Antworte, um die Nachrichtenanfrage anzunehmen, oder lehne sie ab.", + "awaiting_reply": "Warte darauf, dass {name} auf deine Nachrichtenanfrage antwortet." + } }, "recent_games": { "title": "Letzte Spiele", @@ -9862,7 +9881,8 @@ "direct": { "message": "Nachricht", "empty": "Noch keine Nachrichten. Sag Hallo." - } + }, + "awaiting_reply": "Deine Nachrichtenanfrage wurde noch nicht beantwortet. Du kannst wieder schreiben, sobald geantwortet wurde." }, "charts": { "usage": "Auslastung", diff --git a/i18n/locales/en.json b/i18n/locales/en.json index 96de271cc..07ef560cd 100644 --- a/i18n/locales/en.json +++ b/i18n/locales/en.json @@ -3265,7 +3265,13 @@ "description": "Blocked players can't message you, invite you, or send you friend requests. Unblocking someone doesn't restore your friendship.", "empty_title": "No blocked players", "empty_description": "Players you block from their profile or the player menu will show up here.", - "blocked_on": "Blocked" + "blocked_on": "Blocked", + "message_requests": { + "title": "Message requests", + "description": "Let players who aren't your friends send you one message. It waits in your requests until you reply.", + "updated": "Message request setting saved", + "update_failed": "Couldn't save your message request setting" + } } }, "watch": { @@ -6580,7 +6586,20 @@ "tournament_ended": "Ended · closes in {time}", "tournament_ended_days": "{count}d", "tournament_ended_hours": "{count}h", - "tournament_ended_tooltip": "This tournament has ended. Its chat stays open for 7 days." + "tournament_ended_tooltip": "This tournament has ended. Its chat stays open for 7 days.", + "requests": { + "open": "Message requests ({count})", + "title": "Message requests", + "hint": "From players who aren't your friends", + "close": "Close message requests", + "wants_to_message": "Wants to message you", + "deny": "Deny", + "deny_failed": "Couldn't deny that request", + "empty_title": "No message requests", + "empty_description": "First messages from players who aren't your friends wait here.", + "banner": "{name} isn't your friend. Reply to accept their message request, or deny it.", + "awaiting_reply": "Waiting for {name} to reply to your message request." + } }, "recent_games": { "title": "Recent Games", @@ -9864,7 +9883,8 @@ "direct": { "message": "Message", "empty": "No messages yet. Say hello." - } + }, + "awaiting_reply": "Your message request hasn't been answered yet. You can write again once they reply." }, "charts": { "usage": "Usage", diff --git a/i18n/locales/es_ES.json b/i18n/locales/es_ES.json index 8c1ebc05b..bedd42ee7 100644 --- a/i18n/locales/es_ES.json +++ b/i18n/locales/es_ES.json @@ -3265,7 +3265,13 @@ "description": "Los jugadores bloqueados no pueden enviarte mensajes, invitaciones ni solicitudes de amistad. Desbloquear a alguien no restaura vuestra amistad.", "empty_title": "No hay jugadores bloqueados", "empty_description": "Los jugadores que bloquees desde su perfil o el menú del jugador aparecerán aquí.", - "blocked_on": "Bloqueado" + "blocked_on": "Bloqueado", + "message_requests": { + "title": "Solicitudes de mensaje", + "description": "Permite que jugadores que no son tus amigos te envíen un mensaje. Espera en tus solicitudes hasta que respondas.", + "updated": "Ajuste de solicitudes de mensaje guardado", + "update_failed": "No se pudo guardar el ajuste de solicitudes de mensaje" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Finalizado · se cierra en {time}", "tournament_ended_days": "{count} d", "tournament_ended_hours": "{count} h", - "tournament_ended_tooltip": "Este torneo ha finalizado. Su chat sigue abierto durante 7 días." + "tournament_ended_tooltip": "Este torneo ha finalizado. Su chat sigue abierto durante 7 días.", + "requests": { + "open": "Solicitudes de mensaje ({count})", + "title": "Solicitudes de mensaje", + "hint": "De jugadores que no son tus amigos", + "close": "Cerrar solicitudes de mensaje", + "wants_to_message": "Quiere escribirte", + "deny": "Rechazar", + "deny_failed": "No se pudo rechazar la solicitud", + "empty_title": "No hay solicitudes de mensaje", + "empty_description": "Aquí esperan los primeros mensajes de jugadores que no son tus amigos.", + "banner": "{name} no es tu amigo. Responde para aceptar su solicitud de mensaje o recházala.", + "awaiting_reply": "Esperando a que {name} responda a tu solicitud de mensaje." + } }, "recent_games": { "title": "Partidas recientes", @@ -9862,7 +9881,8 @@ "direct": { "message": "Mensaje", "empty": "Aún no hay mensajes. Saluda." - } + }, + "awaiting_reply": "Aún no han respondido a tu solicitud de mensaje. Podrás volver a escribir cuando respondan." }, "charts": { "usage": "Uso", diff --git a/i18n/locales/fr_FR.json b/i18n/locales/fr_FR.json index d4db0b5f1..15a333869 100644 --- a/i18n/locales/fr_FR.json +++ b/i18n/locales/fr_FR.json @@ -3265,7 +3265,13 @@ "description": "Les joueurs bloqués ne peuvent pas vous envoyer de messages, d'invitations ni de demandes d'ami. Débloquer quelqu'un ne rétablit pas votre amitié.", "empty_title": "Aucun joueur bloqué", "empty_description": "Les joueurs que vous bloquez depuis leur profil ou le menu joueur apparaîtront ici.", - "blocked_on": "Bloqué" + "blocked_on": "Bloqué", + "message_requests": { + "title": "Demandes de message", + "description": "Autorisez les joueurs qui ne sont pas vos amis à vous envoyer un message. Il attend dans vos demandes jusqu'à ce que vous répondiez.", + "updated": "Paramètre des demandes de message enregistré", + "update_failed": "Impossible d'enregistrer le paramètre des demandes de message" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Terminé · ferme dans {time}", "tournament_ended_days": "{count} j", "tournament_ended_hours": "{count} h", - "tournament_ended_tooltip": "Ce tournoi est terminé. Son chat reste ouvert pendant 7 jours." + "tournament_ended_tooltip": "Ce tournoi est terminé. Son chat reste ouvert pendant 7 jours.", + "requests": { + "open": "Demandes de message ({count})", + "title": "Demandes de message", + "hint": "De joueurs qui ne sont pas vos amis", + "close": "Fermer les demandes de message", + "wants_to_message": "Souhaite vous écrire", + "deny": "Refuser", + "deny_failed": "Impossible de refuser cette demande", + "empty_title": "Aucune demande de message", + "empty_description": "Les premiers messages de joueurs qui ne sont pas vos amis attendent ici.", + "banner": "{name} n'est pas votre ami. Répondez pour accepter sa demande de message, ou refusez-la.", + "awaiting_reply": "En attente de la réponse de {name} à votre demande de message." + } }, "recent_games": { "title": "Parties récentes", @@ -9862,7 +9881,8 @@ "direct": { "message": "Message", "empty": "Aucun message pour l'instant. Dites bonjour." - } + }, + "awaiting_reply": "Votre demande de message n'a pas encore reçu de réponse. Vous pourrez réécrire après sa réponse." }, "charts": { "usage": "Utilisation", diff --git a/i18n/locales/it_IT.json b/i18n/locales/it_IT.json index 504527a95..6f3d4e5bd 100644 --- a/i18n/locales/it_IT.json +++ b/i18n/locales/it_IT.json @@ -3265,7 +3265,13 @@ "description": "I giocatori bloccati non possono inviarti messaggi, inviti o richieste di amicizia. Sbloccare qualcuno non ripristina la vostra amicizia.", "empty_title": "Nessun giocatore bloccato", "empty_description": "I giocatori che blocchi dal loro profilo o dal menu del giocatore appariranno qui.", - "blocked_on": "Bloccato" + "blocked_on": "Bloccato", + "message_requests": { + "title": "Richieste di messaggio", + "description": "Consenti ai giocatori che non sono tuoi amici di inviarti un messaggio. Resta nelle tue richieste finché non rispondi.", + "updated": "Impostazione delle richieste di messaggio salvata", + "update_failed": "Impossibile salvare l'impostazione delle richieste di messaggio" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Concluso · chiude tra {time}", "tournament_ended_days": "{count} g", "tournament_ended_hours": "{count} h", - "tournament_ended_tooltip": "Questo torneo è concluso. La sua chat resta aperta per 7 giorni." + "tournament_ended_tooltip": "Questo torneo è concluso. La sua chat resta aperta per 7 giorni.", + "requests": { + "open": "Richieste di messaggio ({count})", + "title": "Richieste di messaggio", + "hint": "Da giocatori che non sono tuoi amici", + "close": "Chiudi richieste di messaggio", + "wants_to_message": "Vuole scriverti", + "deny": "Rifiuta", + "deny_failed": "Impossibile rifiutare la richiesta", + "empty_title": "Nessuna richiesta di messaggio", + "empty_description": "I primi messaggi di giocatori che non sono tuoi amici aspettano qui.", + "banner": "{name} non è tuo amico. Rispondi per accettare la richiesta di messaggio, oppure rifiutala.", + "awaiting_reply": "In attesa che {name} risponda alla tua richiesta di messaggio." + } }, "recent_games": { "title": "Partite recenti", @@ -9862,7 +9881,8 @@ "direct": { "message": "Messaggio", "empty": "Ancora nessun messaggio. Fatti sentire." - } + }, + "awaiting_reply": "La tua richiesta di messaggio non ha ancora ricevuto risposta. Potrai scrivere di nuovo quando risponderanno." }, "charts": { "usage": "Utilizzo", diff --git a/i18n/locales/ja_JP.json b/i18n/locales/ja_JP.json index 6e747089c..138a84e12 100644 --- a/i18n/locales/ja_JP.json +++ b/i18n/locales/ja_JP.json @@ -3265,7 +3265,13 @@ "description": "ブロックしたプレイヤーは、あなたにメッセージ、招待、フレンド申請を送れません。ブロックを解除してもフレンド関係は元に戻りません。", "empty_title": "ブロックしたプレイヤーはいません", "empty_description": "プロフィールやプレイヤーメニューからブロックしたプレイヤーがここに表示されます。", - "blocked_on": "ブロック" + "blocked_on": "ブロック", + "message_requests": { + "title": "メッセージリクエスト", + "description": "フレンドではないプレイヤーが1通だけメッセージを送れるようにします。あなたが返信するまでリクエストに保留されます。", + "updated": "メッセージリクエストの設定を保存しました", + "update_failed": "メッセージリクエストの設定を保存できませんでした" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "終了 · あと{time}で閉鎖", "tournament_ended_days": "{count}日", "tournament_ended_hours": "{count}時間", - "tournament_ended_tooltip": "このトーナメントは終了しました。チャットは7日間開いたままです。" + "tournament_ended_tooltip": "このトーナメントは終了しました。チャットは7日間開いたままです。", + "requests": { + "open": "メッセージリクエスト ({count})", + "title": "メッセージリクエスト", + "hint": "フレンドではないプレイヤーから", + "close": "メッセージリクエストを閉じる", + "wants_to_message": "メッセージを送りたいようです", + "deny": "拒否", + "deny_failed": "リクエストを拒否できませんでした", + "empty_title": "メッセージリクエストはありません", + "empty_description": "フレンドではないプレイヤーからの最初のメッセージはここに届きます。", + "banner": "{name} はフレンドではありません。返信するとメッセージリクエストを承認します。拒否することもできます。", + "awaiting_reply": "{name} があなたのメッセージリクエストに返信するのを待っています。" + } }, "recent_games": { "title": "最近の試合", @@ -9862,7 +9881,8 @@ "direct": { "message": "メッセージ", "empty": "まだメッセージはありません。あいさつしてみましょう。" - } + }, + "awaiting_reply": "メッセージリクエストにまだ返信がありません。相手が返信すると再びメッセージを送れます。" }, "charts": { "usage": "使用量", diff --git a/i18n/locales/ko_KR.json b/i18n/locales/ko_KR.json index 6116cf496..38d3a3e95 100644 --- a/i18n/locales/ko_KR.json +++ b/i18n/locales/ko_KR.json @@ -3265,7 +3265,13 @@ "description": "차단한 플레이어는 메시지, 초대, 친구 요청을 보낼 수 없습니다. 차단을 해제해도 친구 관계는 복구되지 않습니다.", "empty_title": "차단한 플레이어가 없습니다", "empty_description": "프로필이나 플레이어 메뉴에서 차단한 플레이어가 여기에 표시됩니다.", - "blocked_on": "차단" + "blocked_on": "차단", + "message_requests": { + "title": "메시지 요청", + "description": "친구가 아닌 플레이어가 메시지를 한 통 보낼 수 있도록 허용합니다. 답장할 때까지 요청함에 보관됩니다.", + "updated": "메시지 요청 설정이 저장되었습니다", + "update_failed": "메시지 요청 설정을 저장하지 못했습니다" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "종료됨 · {time} 후 닫힘", "tournament_ended_days": "{count}일", "tournament_ended_hours": "{count}시간", - "tournament_ended_tooltip": "이 토너먼트는 종료되었습니다. 채팅은 7일 동안 열려 있습니다." + "tournament_ended_tooltip": "이 토너먼트는 종료되었습니다. 채팅은 7일 동안 열려 있습니다.", + "requests": { + "open": "메시지 요청 ({count})", + "title": "메시지 요청", + "hint": "친구가 아닌 플레이어로부터", + "close": "메시지 요청 닫기", + "wants_to_message": "메시지를 보내고 싶어 합니다", + "deny": "거절", + "deny_failed": "요청을 거절하지 못했습니다", + "empty_title": "메시지 요청이 없습니다", + "empty_description": "친구가 아닌 플레이어의 첫 메시지는 여기에서 기다립니다.", + "banner": "{name}님은 친구가 아닙니다. 답장하면 메시지 요청이 수락되며, 거절할 수도 있습니다.", + "awaiting_reply": "{name}님이 메시지 요청에 답장하기를 기다리는 중입니다." + } }, "recent_games": { "title": "최근 게임", @@ -9862,7 +9881,8 @@ "direct": { "message": "메시지", "empty": "아직 메시지가 없습니다. 인사를 건네보세요." - } + }, + "awaiting_reply": "메시지 요청에 아직 답장이 없습니다. 상대가 답장하면 다시 보낼 수 있습니다." }, "charts": { "usage": "사용량", diff --git a/i18n/locales/pl_PL.json b/i18n/locales/pl_PL.json index 1db91f921..09667083a 100644 --- a/i18n/locales/pl_PL.json +++ b/i18n/locales/pl_PL.json @@ -3265,7 +3265,13 @@ "description": "Zablokowani gracze nie mogą wysyłać ci wiadomości, zaproszeń ani próśb o dodanie do znajomych. Odblokowanie kogoś nie przywraca waszej znajomości.", "empty_title": "Brak zablokowanych graczy", "empty_description": "Gracze zablokowani z poziomu ich profilu lub menu gracza pojawią się tutaj.", - "blocked_on": "Zablokowano" + "blocked_on": "Zablokowano", + "message_requests": { + "title": "Prośby o wiadomość", + "description": "Pozwól graczom, którzy nie są twoimi znajomymi, wysłać ci jedną wiadomość. Czeka w twoich prośbach, dopóki nie odpowiesz.", + "updated": "Zapisano ustawienie próśb o wiadomość", + "update_failed": "Nie udało się zapisać ustawienia próśb o wiadomość" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Zakończony · zamknięcie za {time}", "tournament_ended_days": "{count} d.", "tournament_ended_hours": "{count} godz.", - "tournament_ended_tooltip": "Ten turniej się zakończył. Jego czat pozostaje otwarty przez 7 dni." + "tournament_ended_tooltip": "Ten turniej się zakończył. Jego czat pozostaje otwarty przez 7 dni.", + "requests": { + "open": "Prośby o wiadomość ({count})", + "title": "Prośby o wiadomość", + "hint": "Od graczy, którzy nie są twoimi znajomymi", + "close": "Zamknij prośby o wiadomość", + "wants_to_message": "Chce do ciebie napisać", + "deny": "Odrzuć", + "deny_failed": "Nie udało się odrzucić prośby", + "empty_title": "Brak próśb o wiadomość", + "empty_description": "Tutaj czekają pierwsze wiadomości od graczy, którzy nie są twoimi znajomymi.", + "banner": "{name} nie jest twoim znajomym. Odpowiedz, aby przyjąć prośbę o wiadomość, lub ją odrzuć.", + "awaiting_reply": "Czekasz, aż {name} odpowie na twoją prośbę o wiadomość." + } }, "recent_games": { "title": "Ostatnie gry", @@ -9862,7 +9881,8 @@ "direct": { "message": "Wiadomość", "empty": "Brak wiadomości. Przywitaj się." - } + }, + "awaiting_reply": "Twoja prośba o wiadomość nie doczekała się jeszcze odpowiedzi. Napiszesz ponownie, gdy ktoś odpowie." }, "charts": { "usage": "Wykorzystanie", diff --git a/i18n/locales/pt_BR.json b/i18n/locales/pt_BR.json index a6a7705d1..3b5f12bcd 100644 --- a/i18n/locales/pt_BR.json +++ b/i18n/locales/pt_BR.json @@ -3265,7 +3265,13 @@ "description": "Jogadores bloqueados não podem enviar mensagens, convites ou pedidos de amizade para você. Desbloquear alguém não restaura a amizade.", "empty_title": "Nenhum jogador bloqueado", "empty_description": "Os jogadores que você bloquear pelo perfil ou pelo menu do jogador aparecerão aqui.", - "blocked_on": "Bloqueado" + "blocked_on": "Bloqueado", + "message_requests": { + "title": "Solicitações de mensagem", + "description": "Permita que jogadores que não são seus amigos enviem uma mensagem para você. Ela aguarda nas suas solicitações até você responder.", + "updated": "Configuração de solicitações de mensagem salva", + "update_failed": "Não foi possível salvar a configuração de solicitações de mensagem" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Encerrado · fecha em {time}", "tournament_ended_days": "{count} d", "tournament_ended_hours": "{count} h", - "tournament_ended_tooltip": "Este torneio foi encerrado. O chat dele fica aberto por 7 dias." + "tournament_ended_tooltip": "Este torneio foi encerrado. O chat dele fica aberto por 7 dias.", + "requests": { + "open": "Solicitações de mensagem ({count})", + "title": "Solicitações de mensagem", + "hint": "De jogadores que não são seus amigos", + "close": "Fechar solicitações de mensagem", + "wants_to_message": "Quer enviar uma mensagem para você", + "deny": "Recusar", + "deny_failed": "Não foi possível recusar a solicitação", + "empty_title": "Nenhuma solicitação de mensagem", + "empty_description": "As primeiras mensagens de jogadores que não são seus amigos esperam aqui.", + "banner": "{name} não é seu amigo. Responda para aceitar a solicitação de mensagem ou recuse-a.", + "awaiting_reply": "Aguardando {name} responder à sua solicitação de mensagem." + } }, "recent_games": { "title": "Partidas Recentes", @@ -9862,7 +9881,8 @@ "direct": { "message": "Mensagem", "empty": "Nenhuma mensagem ainda. Diga Olá." - } + }, + "awaiting_reply": "Sua solicitação de mensagem ainda não foi respondida. Você poderá escrever de novo quando responderem." }, "charts": { "usage": "Uso", diff --git a/i18n/locales/ru_RU.json b/i18n/locales/ru_RU.json index a2af4f448..98ca7de82 100644 --- a/i18n/locales/ru_RU.json +++ b/i18n/locales/ru_RU.json @@ -3265,7 +3265,13 @@ "description": "Заблокированные игроки не могут отправлять вам сообщения, приглашения и заявки в друзья. Разблокировка не восстанавливает дружбу.", "empty_title": "Нет заблокированных игроков", "empty_description": "Здесь появятся игроки, которых вы заблокируете в их профиле или в меню игрока.", - "blocked_on": "Заблокирован" + "blocked_on": "Заблокирован", + "message_requests": { + "title": "Запросы на переписку", + "description": "Разрешить игрокам, которые не у вас в друзьях, отправить вам одно сообщение. Оно ждёт в запросах, пока вы не ответите.", + "updated": "Настройка запросов на переписку сохранена", + "update_failed": "Не удалось сохранить настройку запросов на переписку" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Завершён · закроется через {time}", "tournament_ended_days": "{count} дн.", "tournament_ended_hours": "{count} ч", - "tournament_ended_tooltip": "Этот турнир завершён. Его чат остаётся открытым 7 дней." + "tournament_ended_tooltip": "Этот турнир завершён. Его чат остаётся открытым 7 дней.", + "requests": { + "open": "Запросы на переписку ({count})", + "title": "Запросы на переписку", + "hint": "От игроков, которые не у вас в друзьях", + "close": "Закрыть запросы на переписку", + "wants_to_message": "Хочет написать вам", + "deny": "Отклонить", + "deny_failed": "Не удалось отклонить запрос", + "empty_title": "Запросов на переписку нет", + "empty_description": "Здесь ждут первые сообщения от игроков, которые не у вас в друзьях.", + "banner": "{name} не у вас в друзьях. Ответьте, чтобы принять запрос на переписку, или отклоните его.", + "awaiting_reply": "Ждём, пока {name} ответит на ваш запрос на переписку." + } }, "recent_games": { "title": "Недавние игры", @@ -9862,7 +9881,8 @@ "direct": { "message": "Сообщение", "empty": "Сообщений пока нет. Поздоровайтесь." - } + }, + "awaiting_reply": "На ваш запрос на переписку ещё не ответили. Написать снова можно будет после ответа." }, "charts": { "usage": "Использование", diff --git a/i18n/locales/sv_SE.json b/i18n/locales/sv_SE.json index f8b39f007..cd0952f14 100644 --- a/i18n/locales/sv_SE.json +++ b/i18n/locales/sv_SE.json @@ -3265,7 +3265,13 @@ "description": "Blockerade spelare kan inte skicka meddelanden, inbjudningar eller vänförfrågningar till dig. Att avblockera någon återställer inte er vänskap.", "empty_title": "Inga blockerade spelare", "empty_description": "Spelare som du blockerar från deras profil eller spelarmenyn visas här.", - "blocked_on": "Blockerad" + "blocked_on": "Blockerad", + "message_requests": { + "title": "Meddelandeförfrågningar", + "description": "Låt spelare som inte är dina vänner skicka ett meddelande till dig. Det väntar bland dina förfrågningar tills du svarar.", + "updated": "Inställningen för meddelandeförfrågningar sparades", + "update_failed": "Kunde inte spara inställningen för meddelandeförfrågningar" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Avslutad · stänger om {time}", "tournament_ended_days": "{count} d", "tournament_ended_hours": "{count} tim", - "tournament_ended_tooltip": "Den här turneringen är avslutad. Dess chatt är öppen i 7 dagar." + "tournament_ended_tooltip": "Den här turneringen är avslutad. Dess chatt är öppen i 7 dagar.", + "requests": { + "open": "Meddelandeförfrågningar ({count})", + "title": "Meddelandeförfrågningar", + "hint": "Från spelare som inte är dina vänner", + "close": "Stäng meddelandeförfrågningar", + "wants_to_message": "Vill skriva till dig", + "deny": "Avvisa", + "deny_failed": "Kunde inte avvisa förfrågan", + "empty_title": "Inga meddelandeförfrågningar", + "empty_description": "Första meddelanden från spelare som inte är dina vänner väntar här.", + "banner": "{name} är inte din vän. Svara för att godkänna meddelandeförfrågan, eller avvisa den.", + "awaiting_reply": "Väntar på att {name} ska svara på din meddelandeförfrågan." + } }, "recent_games": { "title": "Senaste matcher", @@ -9862,7 +9881,8 @@ "direct": { "message": "Meddelande", "empty": "Inga meddelanden än. Säg hej." - } + }, + "awaiting_reply": "Din meddelandeförfrågan har inte besvarats än. Du kan skriva igen när de svarar." }, "charts": { "usage": "Användning", diff --git a/i18n/locales/tr_TR.json b/i18n/locales/tr_TR.json index fb9dbfdb4..30800025a 100644 --- a/i18n/locales/tr_TR.json +++ b/i18n/locales/tr_TR.json @@ -3265,7 +3265,13 @@ "description": "Engellenen oyuncular sana mesaj, davet veya arkadaşlık isteği gönderemez. Birinin engelini kaldırmak arkadaşlığınızı geri getirmez.", "empty_title": "Engellenen oyuncu yok", "empty_description": "Profilinden veya oyuncu menüsünden engellediğin oyuncular burada görünür.", - "blocked_on": "Engellendi" + "blocked_on": "Engellendi", + "message_requests": { + "title": "Mesaj istekleri", + "description": "Arkadaşın olmayan oyuncuların sana bir mesaj göndermesine izin ver. Sen yanıtlayana kadar isteklerinde bekler.", + "updated": "Mesaj isteği ayarı kaydedildi", + "update_failed": "Mesaj isteği ayarı kaydedilemedi" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Bitti · {time} içinde kapanıyor", "tournament_ended_days": "{count} g", "tournament_ended_hours": "{count} sa", - "tournament_ended_tooltip": "Bu turnuva sona erdi. Sohbeti 7 gün boyunca açık kalır." + "tournament_ended_tooltip": "Bu turnuva sona erdi. Sohbeti 7 gün boyunca açık kalır.", + "requests": { + "open": "Mesaj istekleri ({count})", + "title": "Mesaj istekleri", + "hint": "Arkadaşın olmayan oyunculardan", + "close": "Mesaj isteklerini kapat", + "wants_to_message": "Sana mesaj göndermek istiyor", + "deny": "Reddet", + "deny_failed": "İstek reddedilemedi", + "empty_title": "Mesaj isteği yok", + "empty_description": "Arkadaşın olmayan oyuncuların ilk mesajları burada bekler.", + "banner": "{name} arkadaşın değil. Mesaj isteğini kabul etmek için yanıtla ya da reddet.", + "awaiting_reply": "{name} kullanıcısının mesaj isteğine yanıt vermesi bekleniyor." + } }, "recent_games": { "title": "Son maçlar", @@ -9862,7 +9881,8 @@ "direct": { "message": "Mesaj", "empty": "Henüz mesaj yok. Merhaba de." - } + }, + "awaiting_reply": "Mesaj isteğin henüz yanıtlanmadı. Yanıt verdiklerinde tekrar yazabilirsin." }, "charts": { "usage": "Kullanım", diff --git a/i18n/locales/uk_UA.json b/i18n/locales/uk_UA.json index ab7373836..822c53955 100644 --- a/i18n/locales/uk_UA.json +++ b/i18n/locales/uk_UA.json @@ -3265,7 +3265,13 @@ "description": "Заблоковані гравці не можуть надсилати вам повідомлення, запрошення та заявки в друзі. Розблокування не відновлює дружбу.", "empty_title": "Немає заблокованих гравців", "empty_description": "Тут з'являться гравці, яких ви заблокуєте в їхньому профілі або в меню гравця.", - "blocked_on": "Заблоковано" + "blocked_on": "Заблоковано", + "message_requests": { + "title": "Запити на листування", + "description": "Дозволити гравцям, які не у вас у друзях, надіслати вам одне повідомлення. Воно чекає в запитах, доки ви не відповісте.", + "updated": "Налаштування запитів на листування збережено", + "update_failed": "Не вдалося зберегти налаштування запитів на листування" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "Завершено · закриється через {time}", "tournament_ended_days": "{count} дн.", "tournament_ended_hours": "{count} год", - "tournament_ended_tooltip": "Цей турнір завершено. Його чат залишається відкритим 7 днів." + "tournament_ended_tooltip": "Цей турнір завершено. Його чат залишається відкритим 7 днів.", + "requests": { + "open": "Запити на листування ({count})", + "title": "Запити на листування", + "hint": "Від гравців, які не у вас у друзях", + "close": "Закрити запити на листування", + "wants_to_message": "Хоче вам написати", + "deny": "Відхилити", + "deny_failed": "Не вдалося відхилити запит", + "empty_title": "Запитів на листування немає", + "empty_description": "Тут чекають перші повідомлення від гравців, які не у вас у друзях.", + "banner": "{name} не у вас у друзях. Відповідайте, щоб прийняти запит на листування, або відхиліть його.", + "awaiting_reply": "Чекаємо, поки {name} відповість на ваш запит на листування." + } }, "recent_games": { "title": "Останні ігри", @@ -9862,7 +9881,8 @@ "direct": { "message": "Повідомлення", "empty": "Повідомлень поки немає. Привітайтеся." - } + }, + "awaiting_reply": "На ваш запит на листування ще не відповіли. Написати знову можна буде після відповіді." }, "charts": { "usage": "Використання", diff --git a/i18n/locales/zh_Hans.json b/i18n/locales/zh_Hans.json index 418d9b851..3bb02800c 100644 --- a/i18n/locales/zh_Hans.json +++ b/i18n/locales/zh_Hans.json @@ -3265,7 +3265,13 @@ "description": "被屏蔽的玩家无法向你发送消息、邀请或好友请求。取消屏蔽不会恢复你们的好友关系。", "empty_title": "没有已屏蔽的玩家", "empty_description": "你在玩家资料页或玩家菜单中屏蔽的玩家会显示在这里。", - "blocked_on": "已屏蔽" + "blocked_on": "已屏蔽", + "message_requests": { + "title": "消息请求", + "description": "允许非好友玩家给你发送一条消息。在你回复之前,它会留在你的请求中。", + "updated": "消息请求设置已保存", + "update_failed": "无法保存消息请求设置" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "已结束 · {time}后关闭", "tournament_ended_days": "{count}天", "tournament_ended_hours": "{count}小时", - "tournament_ended_tooltip": "本赛事已结束。其聊天将保持开放 7 天。" + "tournament_ended_tooltip": "本赛事已结束。其聊天将保持开放 7 天。", + "requests": { + "open": "消息请求({count})", + "title": "消息请求", + "hint": "来自非好友玩家", + "close": "关闭消息请求", + "wants_to_message": "想给你发消息", + "deny": "拒绝", + "deny_failed": "无法拒绝该请求", + "empty_title": "没有消息请求", + "empty_description": "非好友玩家发来的第一条消息会在这里等待。", + "banner": "{name} 不是你的好友。回复即可接受其消息请求,也可以拒绝。", + "awaiting_reply": "正在等待 {name} 回复你的消息请求。" + } }, "recent_games": { "title": "近期比赛", @@ -9862,7 +9881,8 @@ "direct": { "message": "消息", "empty": "还没有消息,先打个招呼吧。" - } + }, + "awaiting_reply": "你的消息请求尚未得到回复。对方回复后你才能再次发送。" }, "charts": { "usage": "使用量", diff --git a/i18n/locales/zh_Hant.json b/i18n/locales/zh_Hant.json index 009781b08..612f28ad5 100644 --- a/i18n/locales/zh_Hant.json +++ b/i18n/locales/zh_Hant.json @@ -3265,7 +3265,13 @@ "description": "被封鎖的玩家無法傳送訊息、邀請或好友邀請給你。解除封鎖不會恢復你們的好友關係。", "empty_title": "沒有已封鎖的玩家", "empty_description": "你從玩家個人檔案或玩家選單封鎖的玩家會顯示在這裡。", - "blocked_on": "已封鎖" + "blocked_on": "已封鎖", + "message_requests": { + "title": "訊息請求", + "description": "允許非好友玩家傳送一則訊息給你。在你回覆之前,它會留在你的請求中。", + "updated": "訊息請求設定已儲存", + "update_failed": "無法儲存訊息請求設定" + } } }, "watch": { @@ -6578,7 +6584,20 @@ "tournament_ended": "已結束 · {time}後關閉", "tournament_ended_days": "{count}天", "tournament_ended_hours": "{count}小時", - "tournament_ended_tooltip": "本賽事已結束。其聊天將保持開放 7 天。" + "tournament_ended_tooltip": "本賽事已結束。其聊天將保持開放 7 天。", + "requests": { + "open": "訊息請求({count})", + "title": "訊息請求", + "hint": "來自非好友玩家", + "close": "關閉訊息請求", + "wants_to_message": "想傳訊息給你", + "deny": "拒絕", + "deny_failed": "無法拒絕此請求", + "empty_title": "沒有訊息請求", + "empty_description": "非好友玩家傳來的第一則訊息會在這裡等待。", + "banner": "{name} 不是你的好友。回覆即可接受其訊息請求,也可以拒絕。", + "awaiting_reply": "正在等待 {name} 回覆你的訊息請求。" + } }, "recent_games": { "title": "近期比賽", @@ -9862,7 +9881,8 @@ "direct": { "message": "訊息", "empty": "還沒有訊息,先打個招呼吧。" - } + }, + "awaiting_reply": "你的訊息請求尚未獲得回覆。對方回覆後你才能再次傳送。" }, "charts": { "usage": "使用量", diff --git a/pages/players/[id].vue b/pages/players/[id].vue index 7d17a0642..bfa2e6128 100644 --- a/pages/players/[id].vue +++ b/pages/players/[id].vue @@ -3681,6 +3681,7 @@ const playerHeroTeamChipDotClasses =