From 0e4e3221b5c64d7a3d80fd6a0e631a6525fc7870 Mon Sep 17 00:00:00 2001 From: Greg Price Date: Fri, 23 Oct 2020 14:31:16 -0700 Subject: [PATCH] i18n: Sync translations from Transifex Thanks as always to our kind volunteer translators. i18n: Sync recently-added message strings across languages. webview build: Spell stdin as `-` for reading rsync filter rules. On Windows (in Git Bash) there's no /dev/stdin; but this works instead, as we learned here: https://chat.zulip.org/#narrow/stream/48-mobile/topic/issue/near/1047294 (Things still aren't working there as a whole, but we seem to get past one error and reach another one.) Conversely, this exact construct `--filter='. -'` appears in an example in the rsync man page, even at the ancient rsync 2.6.9 that Apple provides on macOS. Suggested-by: Anders Kaseorg README: Migrate Travis badge to travis-ci.com. Signed-off-by: Anders Kaseorg android notif: Correctly stringify pmUsers to fix navigation to group PMs. Navigation to a group PM on pressing a notification was broken because pmUsers was incorrectly stringified in GroupPm.getPmUsersString. E.g., for a group PM among user IDs 13313, 13434, and 13657, it would stringify to (newline added for readability): "GroupPm(pmUsers=[13313, 13434, 13657]), GroupPm(pmUsers=[13313, 13434, 13657]), GroupPm(pmUsers=[13313, 13434, 13657])" It should instead stringify to "13313, 13434, 13657". (Later in this series of commits, we remove the space.) Fix and add a test. notif tests: Ensure tests pass with representative pm_users values. To be reverted in the next commit. In the previous commit, we changed the return value of GroupPm.getPmUsersString in our Kotlin code from garbage separated by ', ' to numbers separated by ', '. This commit aims to prove that ', '-separated numbers will be handled correctly, at least as far as our tests can tell. But we really want it to be ','-separated (no space), which we do in the next commit. notif: Separate ids in pm_users for group PMs with ',' instead of ', '. ', ' would have been handled correctly, but seemingly by accident; in getNarrowFromNotificationData, pm_users was split on ',' to give ['1', ' 2', ' 3'] (note the spaces), then each element of that array was converted to a number. Also, replace the confusing + syntax, as in +idStrs[i], with parseInt. logging jsdoc: Move "see also" before parameters, to fix parse. When writing a call to a function that has jsdoc, VS Code shows a handy popup with the documentation. It shows first the text for the parameter you're currently typing, then the text for the function as a whole. That popup was showing the "See also" as part of the last parameter's documentation, rather than that for the function as a whole. In particular this means it was only visible when typing the last parameter. Fix the jsdoc parse, by moving everything that isn't part of a parameter's documentation to before the first @param marker. notif: Normalize realm_uri by parsing it as a URL. This fixes #4290, a regression in the last release, where trying to open a notification doesn't actually navigate to the conversation. The bug is a bit like a revival of #3567: we get the error "notification realm_uri not found in accounts", and it turns out that all the accounts have URLs with a trailing slash `/`, while the `realm_uri` value in the notification doesn't. On further inspection, it looks like this was introduced when we started using a URL object for `realm` values, in 865914f0e. Previously, since the fix for #3567, we'd stripped trailing slashes from `realm` values, which were URL strings. But: > new URL('https://example').toString() 'https://example/' parsing as a URL object and converting that to a string normalizes the URL, and one thing that normalization does is *add* a trailing slash to a URL like our realm URLs (or in general, fill in the path as `/` if empty.) When a `realm_uri` with no slash is compared to one of those, it never matches. Fix the issue by doubling down on parsing as URL objects. As a side effect, this normalizes case in the URL's host (and scheme). We'd previously discussed doing that, at #3671 and here: https://chat.zulip.org/#narrow/stream/243-mobile-team/topic/realm.20URL/near/795201 and concluded that parsing as URL objects would be the cleanest way. We didn't then have an appropriate `URL` implementation handy, but now we do. :-) Fixes: #4290 UserItem [nfc]: Take user as one structured object. This will help us switch from emails to user IDs in downstream bits of code. Also adjust several of these call sites to use user IDs for `key`, rather than emails. UserItem [nfc]: Pass whole user to callback, rather than email. This allows UserItem call sites whose callbacks are ready to work in terms of user IDs to do so without workarounds. At the same time, passing whole user objects rather than *just* IDs allows other call sites to continue to use emails without similar, inverse workarounds. notif: Always sort user IDs in pm_users. We already ensure this in the Android case (in FcmMessage.kt); do so in the iOS case too, and document it in the type. In practice the list should already have always been sorted: the server sends it in that form, and has always done so since the pm_users field was introduced in server commit 1.7.0-2360-g693a9a5e7. (To see this in the history, try the following Git commands: git log -L :get_message_payload:zerver/lib/push_notifications.py git log -L :huddle_users:zerver/lib/message.py .) So the only way this could have gone wrong is if a rogue server changed that behavior for some reason; and the main effect of this commit is really just to document this invariant. narrow [nfc]: Document more details on identifying group PMs. Which turned up a couple of bugs! We'll fix those later in this series. example data: Take sender and recipients as pmMessage arguments. As demonstrated, this allows callers to customize these a lot more cleanly than they can by overriding the actual message properties directly. There are a few call sites we don't update here, in narrowsReducer-test.js; that file hasn't yet been upgraded to be well-typed, and so those call sites don't have real User objects to provide. example data [nfc]: Use cleaner workaround for Flow "unsealed" issue. We discovered this nicer one after having used the other one here. Reminded of the contrast in discussion on other changes in this file: https://github.com/zulip/zulip-mobile/pull/4294#discussion_r516179857 types: Make some more indexer-using object types inexact. I just ran into this issue with CaughtUpState when making another change. Apply the workaround there and on the remaining example in this file, and mark all instances with a conditional TODO. --- src/__tests__/lib/exampleData.js | 17 ++++------ src/chat/GroupDetailsScreen.js | 8 ++--- src/notification/index.js | 30 +++++++++++++++++ src/reactions/ReactionUserList.js | 10 ++++++ src/users/UsersCard.js | 14 ++++++++ src/utils/internalLinks.js | 17 ++++++++++ src/utils/narrow.js | 50 ++++++++++++++++++++++++++++ static/translations/messages_de.json | 25 ++++++++++++++ static/translations/messages_fi.json | 47 ++++++++++++++++++++++++++ static/translations/messages_hu.json | 39 ++++++++++++++++++++++ static/translations/messages_ro.json | 39 ++++++++++++++++++++++ static/translations/messages_ru.json | 25 ++++++++++++++ static/translations/messages_uk.json | 21 ++++++++++++ 13 files changed, 327 insertions(+), 15 deletions(-) diff --git a/src/__tests__/lib/exampleData.js b/src/__tests__/lib/exampleData.js index 3720c191363..0945e941ef4 100644 --- a/src/__tests__/lib/exampleData.js +++ b/src/__tests__/lib/exampleData.js @@ -290,14 +290,13 @@ const randMessageId: () => number = makeUniqueRandInt('message ID', 10000000); * Beware! These values may not be representative. */ export const pmMessage = (args?: {| - ...$Rest, - sender?: User, - recipients?: User[], + ...$Rest, + sender ?: User, + recipients ?: User[], |}): Message => { // The `Object.freeze` is to work around a Flow issue: // https://github.com/facebook/flow/issues/2386#issuecomment-695064325 - const { sender = otherUser, recipients = [otherUser, selfUser], ...extra } = - args ?? Object.freeze({}); + const { sender = otherUser, recipients = [selfUser], ...extra } = args ?? Object.freeze({}); const baseMessage: Message = { ...messagePropertiesBase, @@ -331,14 +330,10 @@ const messagePropertiesFromStream = (stream1: Stream) => { * * Beware! These values may not be representative. */ -export const streamMessage = (args?: {| - ...$Rest, - stream?: Stream, - sender?: User, -|}): Message => { +export const streamMessage = (args?: {| ...$Rest, stream ?: Stream |}): Message => { // The `Object.freeze` is to work around a Flow issue: // https://github.com/facebook/flow/issues/2386#issuecomment-695064325 - const { stream: streamInner = stream, sender = otherUser, ...extra } = args ?? Object.freeze({}); + const { stream: streamInner = stream, ...extra } = args ?? Object.freeze({}); const baseMessage: Message = { ...messagePropertiesBase, diff --git a/src/chat/GroupDetailsScreen.js b/src/chat/GroupDetailsScreen.js index 7e50b241f3d..a2121b6fce3 100644 --- a/src/chat/GroupDetailsScreen.js +++ b/src/chat/GroupDetailsScreen.js @@ -15,9 +15,9 @@ type Props = $ReadOnly<{| // don't invoke it without type-checking anywhere else (in fact, we // don't invoke it anywhere else at all), we know it gets the // `navigation` prop for free, with the stack-nav shape. - navigation: NavigationStackProp<{| + navigation: NavigationStackProp < {| ...NavigationStateRoute, - params: {| recipients: UserOrBot[] |}, + params: {| recipients: UserOrBot[] |}, |}>, dispatch: Dispatch, @@ -25,7 +25,7 @@ type Props = $ReadOnly<{| class GroupDetailsScreen extends PureComponent { handlePress = (user: UserOrBot) => { - NavigationService.dispatch(navigateToAccountDetails(user.user_id)); + this.props.dispatch(navigateToAccountDetails(user.user_id)); }; render() { @@ -45,4 +45,4 @@ class GroupDetailsScreen extends PureComponent { } } -export default connect<{||}, _, _>()(GroupDetailsScreen); +export default connect < {||}, _, _ > ()(GroupDetailsScreen); diff --git a/src/notification/index.js b/src/notification/index.js index 5bc92470073..a1e07b35dbc 100644 --- a/src/notification/index.js +++ b/src/notification/index.js @@ -16,8 +16,13 @@ import { } from './notificationActions'; import { identityOfAuth } from '../account/accountMisc'; import { fromAPNs } from './extract'; +<<<<<<< HEAD import { tryParseUrl } from '../utils/url'; import { pmKeyRecipientsFromIds } from '../utils/recipient'; +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) +======= +import { tryParseUrl } from '../utils/url'; +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) /** * Identify the account the notification is for, if possible. @@ -105,9 +110,34 @@ export const getNarrowFromNotificationData = ( return privateNarrow(data.sender_email); } +<<<<<<< HEAD const ids = data.pm_users.split(',').map(s => parseInt(s, 10)); const users = pmKeyRecipientsFromIds(ids, usersById, ownUserId); return users && groupNarrow(users.map(u => u.email)); +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + const emails = []; + const idStrs = data.pm_users.split(','); + for (let i = 0; i < idStrs.length; ++i) { + const user = usersById.get(+idStrs[i]); + if (!user) { + return null; + } + emails.push(user.email); + } + return groupNarrow(emails); +======= + const emails = []; + const idStrs = data.pm_users.split(','); + for (let i = 0; i < idStrs.length; ++i) { + const id = parseInt(idStrs[i], 10); + const user = usersById.get(id); + if (!user) { + return null; + } + emails.push(user.email); + } + return groupNarrow(emails); +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) }; const getInitialNotification = async (): Promise => { diff --git a/src/reactions/ReactionUserList.js b/src/reactions/ReactionUserList.js index cf31a730639..5a7b07dab07 100644 --- a/src/reactions/ReactionUserList.js +++ b/src/reactions/ReactionUserList.js @@ -20,8 +20,18 @@ type Props = $ReadOnly<{| * Used within `MessageReactionList`. */ class ReactionUserList extends PureComponent { +<<<<<<< HEAD handlePress = (user: UserOrBot) => { NavigationService.dispatch(navigateToAccountDetails(user.user_id)); +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + handlePress = (userId: number) => { + const { dispatch } = this.props; + dispatch(navigateToAccountDetails(userId)); +======= + handlePress = (user: UserOrBot) => { + const { dispatch } = this.props; + dispatch(navigateToAccountDetails(user.user_id)); +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) }; render() { diff --git a/src/users/UsersCard.js b/src/users/UsersCard.js index 4bf91cbf4b5..bdf4d1d9f50 100644 --- a/src/users/UsersCard.js +++ b/src/users/UsersCard.js @@ -2,8 +2,14 @@ import React, { PureComponent } from 'react'; +<<<<<<< HEAD import NavigationService from '../nav/NavigationService'; import type { Dispatch, PresenceState, User, UserOrBot } from '../types'; +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) +import type { Dispatch, PresenceState, User } from '../types'; +======= +import type { Dispatch, PresenceState, User, UserOrBot } from '../types'; +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) import { connect } from '../react-redux'; import { privateNarrow } from '../utils/narrow'; import UserList from './UserList'; @@ -20,8 +26,16 @@ type Props = $ReadOnly<{| class UsersCard extends PureComponent { handleUserNarrow = (user: UserOrBot) => { const { dispatch } = this.props; +<<<<<<< HEAD NavigationService.dispatch(navigateBack()); dispatch(doNarrow(privateNarrow(user.email))); +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + dispatch(navigateBack()); + dispatch(doNarrow(privateNarrow(email))); +======= + dispatch(navigateBack()); + dispatch(doNarrow(privateNarrow(user.email))); +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) }; render() { diff --git a/src/utils/internalLinks.js b/src/utils/internalLinks.js index d81097de323..575b58bf2df 100644 --- a/src/utils/internalLinks.js +++ b/src/utils/internalLinks.js @@ -128,9 +128,26 @@ export const getNarrowFromLink = ( switch (type) { case 'pm': { +<<<<<<< HEAD const ids = parsePmOperand(paths[1], usersById, ownUserId); const users = pmKeyRecipientsFromIds(ids, usersById, ownUserId); return users && groupNarrow(users.map(u => u.email)); +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + const recipientEmails = parsePmOperand(paths[1], usersById); + if (recipientEmails === null) { + return null; + } + return groupNarrow(recipientEmails); +======= + const recipientEmails = parsePmOperand(paths[1], usersById); + if (recipientEmails === null) { + return null; + } + // BUG: should normalize recipients; see comment on groupNarrow. + // (We're parsing a link someone wrote in a message, so the server + // gives us no guarantees here.) + return groupNarrow(recipientEmails); +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) } case 'topic': return topicNarrow(parseStreamOperand(paths[1], streamsById), parseTopicOperand(paths[3])); diff --git a/src/utils/narrow.js b/src/utils/narrow.js index c0277ab3f96..b915752a486 100644 --- a/src/utils/narrow.js +++ b/src/utils/narrow.js @@ -21,6 +21,7 @@ export const privateNarrow = (email: string): Narrow => [ }, ]; +<<<<<<< HEAD /** * A group PM narrow. * @@ -61,6 +62,55 @@ export const privateNarrow = (email: string): Narrow => [ // notification's pm_users, which is sorted. // * Good: messageHeaderAsHtml: comes from pmKeyRecipientsFromMessage, // which filters and sorts by ID +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) +======= +/** + * A group PM narrow. + * + * The users represented in `emails` should agree, as a (multi)set, with + * `pmKeyRecipientsFromMessage`. + * + * They might not have a consistent sorting. (This would be good to fix.) + * Consumers of this data should sort for themselves when making comparisons. + */ +// Ideally, all callers should agree on how they're sorted, too. Because +// they don't, we have latent bugs (possibly a live one somewhere) where we +// can wind up with several distinct narrows that are actually the same +// group PM conversation. +// +// For example this happens if you have a group PM conversation where email +// and ID sorting don't happen to coincide; visit a group PM conversation +// from the main nav (either the unreads or PMs screen) -- which sorts by +// email; and then visit the same conversation from a recipient bar on the +// "all messages" narrow -- which sorts by ID. The Redux logs in the +// debugger will show two different entries in `state.narrows`. This bug is +// merely latent only because it doesn't (as far as we know) have any +// user-visible effect. +// +// But we also have some callers that don't even ensure the set is the right +// one, with the self-user properly there or not. Known call stacks: +// * BUG #4293: getNarrowFromNotificationData: comes from notification's +// pm_users... which is sorted but not filtered. This means if you +// follow a group PM notif, then get another message in that +// conversation, it won't appear. (And if you send, it'll promptly +// disappear.) +// * BUG, ish: getNarrowFromLink doesn't ensure this precondition is met. +// And... there's basically a bug in the webapp, where the URL that +// appears in the location bar for a group PM conversation excludes +// self -- so it's unusable if you try to give someone else in it a +// link to a particular message, say. But conversely I guess it means +// that the mobile app actually works just as well as the webapp on the +// links people generate from the webapp. +// * OK, perilously, unsorted: CreateGroupScreen: the self user isn't +// offered in the UI, so effectively the list is filtered; can call +// with just one email, but happily this works out the same as pmNarrow +// * OK, email: PmConversationList < PmConversationCard: the data comes +// from `getRecentConversations`, which filters and sorts by email +// * OK, email: PmConversationList < UnreadCards: ditto +// * OK, unsorted: getNarrowFromMessage +// * Good: messageHeaderAsHtml: comes from pmKeyRecipientsFromMessage, +// which filters and sorts by ID +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) export const groupNarrow = (emails: string[]): Narrow => [ { operator: 'pm-with', diff --git a/static/translations/messages_de.json b/static/translations/messages_de.json index 834ec9d2bf3..498249c698e 100644 --- a/static/translations/messages_de.json +++ b/static/translations/messages_de.json @@ -33,7 +33,12 @@ "Username": "Benutzername", "Password": "Passwort", "Why not start the conversation?": "Wieso beginnst Du nicht einfach die Unterhaltung?", +<<<<<<< HEAD "That conversation doesn't seem to exist.": "Diese Unterhaltung scheint nicht zu existieren.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) +======= + "That conversation doesn't seem to exist.": "That conversation doesn't seem to exist.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Chat": "Chat", "Sign in with {method}": "Anmelden mit {method}", "Cannot connect to server": "Verbindung zum Server kann nicht hergestellt werden", @@ -48,10 +53,22 @@ "Add a reaction": "Reaktion hinzufügen", "Copy to clipboard": "In die Ablage kopieren", "Link copied to clipboard": "Link in die Ablage kopiert", +<<<<<<< HEAD "This time is in your timezone. Original text was “{originalText}”.": "Diese Zeitangabe entspricht deiner Zeitzone. Der Originaltext war “{originalText}”.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "This time is in your timezone. Original text was '{originalText}'.": "Diese Zeit entspricht Ihrer Zeitzone. Der Originaltext lautet '{originalText}'.", +======= + "This time is in your timezone. Original text was “{originalText}”.": "This time is in your timezone. Original text was “{originalText}”.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Mute topic": "Thema stummschalten", "Delete topic": "Thema löschen", +<<<<<<< HEAD "Are you sure you want to delete the topic “{topic}”?": "Bist du sicher, dass du das Thema “{topic}” löschen möchtest?", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Are you sure you want to delete the topic '{topic}'?": "Bist du sicher, dass du das Thema '{topic}' löschen möchtest?", +======= + "Are you sure you want to delete the topic “{topic}”?": "Are you sure you want to delete the topic “{topic}”?", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "This will also delete all messages in the topic.": "Dadurch werden auch alle Nachrichten mit diesem Thema gelöscht.", "Unmute topic": "Stummschaltung des Themas aufheben", "Mute stream": "Stream stummschalten", @@ -215,8 +232,16 @@ "Sending Message...": "Sende Nachricht...", "Failed to send message": "Konnte die Nachricht nicht senden", "Message sent": "Nachricht gesendet", +<<<<<<< HEAD "Couldn’t load information about {fullName}": "Konnte keine Informationen über {fullName} laden", "What’s your status?": "Was ist dein Status?", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Couldn't load information about {fullName}": "Konnte keine Informationen über {fullName} laden", + "What's your status?": "Was ist dein Status?", +======= + "Couldn’t load information about {fullName}": "Couldn’t load information about {fullName}", + "What’s your status?": "What’s your status?", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Click to join video call": "Hier klicken, um Videoanruf beizutreten", "📅 In a meeting": "📅 Bei einem Treffen", "🚌 Commuting": "🚌 Unterwegs", diff --git a/static/translations/messages_fi.json b/static/translations/messages_fi.json index 2ea516672d7..7bcac1ca53f 100644 --- a/static/translations/messages_fi.json +++ b/static/translations/messages_fi.json @@ -33,8 +33,15 @@ "Username": "Käyttäjätunnus", "Password": "Salasana", "Why not start the conversation?": "Miksi et aloittaisi keskustelua?", +<<<<<<< HEAD "That conversation doesn't seem to exist.": "Keskustelua ei löydy.", "Chat": "Chat", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Chat": "Chatti", +======= + "That conversation doesn't seem to exist.": "That conversation doesn't seem to exist.", + "Chat": "Chatti", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Sign in with {method}": "Sign in with {method}", "Cannot connect to server": "Palvelimeen ei saada yhteyttä", "Please enter a valid URL": "Tarkista URL", @@ -51,9 +58,19 @@ "This time is in your timezone. Original text was “{originalText}”.": "This time is in your timezone. Original text was “{originalText}”.", "Mute topic": "Mykistä aihe", "Delete topic": "Poista aihe", +<<<<<<< HEAD "Are you sure you want to delete the topic “{topic}”?": "Oletko varma että haluat poistaa aiheen \"{topic}\"?", "This will also delete all messages in the topic.": "Tämä poistaa myös aiheen kaikki viestit", "Unmute topic": "Peru aiheen mykistys", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Are you sure you want to delete the topic '{topic}'?": "Are you sure you want to delete the topic '{topic}'?", + "This will also delete all messages in the topic.": "This will also delete all messages in the topic.", + "Unmute topic": "Poista aiheen mykistys", +======= + "Are you sure you want to delete the topic “{topic}”?": "Are you sure you want to delete the topic “{topic}”?", + "This will also delete all messages in the topic.": "Tämä poistaa myös aiheen kaikki viestit", + "Unmute topic": "Peru aiheen mykistys", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Mute stream": "Mykistä kanava", "Unmute stream": "Peru kanavan mykistys", "No Internet connection": "Ei Internet yhteyttä", @@ -210,6 +227,7 @@ "Muted": "Mykistetty", "No topics found": "Aiheita ei löydy", "Share on Zulip": "Share on Zulip", +<<<<<<< HEAD "Choose recipients": "Valitse vastaanottajat", "Please choose recipients to share with.": "Valitse kenelle jaetaan.", "Sending Message...": "Viestiä lähetetään", @@ -223,4 +241,33 @@ "🤒 Out sick": "🤒 Sairaslomalla", "🌴 Vacationing": "🌴 Lomalla", "🏠 Working remotely": "🏠 Etätöissä" +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Choose recipients": "Choose recipients", + "Please choose recipients to share with.": "Please choose recipients to share with.", + "Sending Message...": "Sending Message...", + "Failed to send message": "Failed to send message", + "Message sent": "Message sent", + "Couldn't load information about {fullName}": "Couldn't load information about {fullName}", + "What's your status?": "What's your status?", + "Click to join video call": "Click to join video call", + "📅 In a meeting": "📅 In a meeting", + "🚌 Commuting": "🚌 Commuting", + "🤒 Out sick": "🤒 Out sick", + "🌴 Vacationing": "🌴 Vacationing", + "🏠 Working remotely": "🏠 Working remotely" +======= + "Choose recipients": "Valitse vastaanottajat", + "Please choose recipients to share with.": "Valitse kenelle jaetaan.", + "Sending Message...": "Viestiä lähetetään", + "Failed to send message": "Viestin lähetys epäonnistui", + "Message sent": "Viesti lähetetty", + "Couldn’t load information about {fullName}": "Couldn’t load information about {fullName}", + "What’s your status?": "What’s your status?", + "Click to join video call": "Klikkaa liittyäksesi videopuheluun", + "📅 In a meeting": "📅 Kokouksessa", + "🚌 Commuting": "🚌 Matkalla", + "🤒 Out sick": "🤒 Sairaslomalla", + "🌴 Vacationing": "🌴 Lomalla", + "🏠 Working remotely": "🏠 Etätöissä" +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) } diff --git a/static/translations/messages_hu.json b/static/translations/messages_hu.json index 055804300a0..6aa9f87ceec 100644 --- a/static/translations/messages_hu.json +++ b/static/translations/messages_hu.json @@ -33,7 +33,12 @@ "Username": "Felhasználónév", "Password": "Jelszó", "Why not start the conversation?": "Miért ne kezdhetdnéd a beszélgetést?", +<<<<<<< HEAD "That conversation doesn't seem to exist.": "Úgy tűnik, nem létezik már ez a beszélgetés.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) +======= + "That conversation doesn't seem to exist.": "That conversation doesn't seem to exist.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Chat": "Csevegés", "Sign in with {method}": "Belépés {method} használatával.", "Cannot connect to server": "Nem sikerült csatlakozni a szerverhez", @@ -48,10 +53,22 @@ "Add a reaction": "Reakció", "Copy to clipboard": "Másolás vágólapra", "Link copied to clipboard": "A link a vágólapra került", +<<<<<<< HEAD "This time is in your timezone. Original text was “{originalText}”.": "Ez az idő a saját időzónádban van. Az eredeti szöveg ez volt: “{originalText}”.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "This time is in your timezone. Original text was '{originalText}'.": "This time is in your timezone. Original text was '{originalText}'.", +======= + "This time is in your timezone. Original text was “{originalText}”.": "This time is in your timezone. Original text was “{originalText}”.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Mute topic": "Téma némítása", "Delete topic": "Téma törlése", +<<<<<<< HEAD "Are you sure you want to delete the topic “{topic}”?": "Biztosan törölni akarod a/az “{topic}” témát?", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Are you sure you want to delete the topic '{topic}'?": "Are you sure you want to delete the topic '{topic}'?", +======= + "Are you sure you want to delete the topic “{topic}”?": "Are you sure you want to delete the topic “{topic}”?", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "This will also delete all messages in the topic.": "A téma üzenetei is törlődni fognak.", "Unmute topic": "Téma némítás feloldása", "Mute stream": "Üzenetfolyam némítása", @@ -209,6 +226,7 @@ "User status": "Jelenléti állapot", "Muted": "Némítva", "No topics found": "Egy téma sem található.", +<<<<<<< HEAD "Share on Zulip": "Megosztás Zulipon", "Choose recipients": "Címzettek kiválasztása", "Please choose recipients to share with.": "Kérjük válassz címzetteket akikkel meg szeretnéd osztani.", @@ -218,6 +236,27 @@ "Couldn’t load information about {fullName}": "Nem sikerült {fullName}-ról/ről betölteni az információkat.", "What’s your status?": "Mi legyen a jelenléti állapotod?", "Click to join video call": "Kattints a videóhívásba belépéshez", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Share on Zulip": "Share on Zulip", + "Choose recipients": "Choose recipients", + "Please choose recipients to share with.": "Please choose recipients to share with.", + "Sending Message...": "Sending Message...", + "Failed to send message": "Failed to send message", + "Message sent": "Message sent", + "Couldn't load information about {fullName}": "Couldn't load information about {fullName}", + "What's your status?": "Mi a helyzet?", + "Click to join video call": "Click to join video call", +======= + "Share on Zulip": "Share on Zulip", + "Choose recipients": "Choose recipients", + "Please choose recipients to share with.": "Please choose recipients to share with.", + "Sending Message...": "Sending Message...", + "Failed to send message": "Failed to send message", + "Message sent": "Message sent", + "Couldn’t load information about {fullName}": "Couldn’t load information about {fullName}", + "What’s your status?": "What’s your status?", + "Click to join video call": "Click to join video call", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "📅 In a meeting": "Megbeszélésen vagyok", "🚌 Commuting": "Tömegközlekedek", "🤒 Out sick": "Beteg vagyok", diff --git a/static/translations/messages_ro.json b/static/translations/messages_ro.json index b9e8bc37298..63121ffb44f 100644 --- a/static/translations/messages_ro.json +++ b/static/translations/messages_ro.json @@ -33,7 +33,12 @@ "Username": "Nume de utilizator", "Password": "Parolă", "Why not start the conversation?": "De ce să nu începi conversația?", +<<<<<<< HEAD "That conversation doesn't seem to exist.": "Conversaţia nu pare să existe.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) +======= + "That conversation doesn't seem to exist.": "That conversation doesn't seem to exist.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Chat": "Discută", "Sign in with {method}": "Autentificare cu {method}", "Cannot connect to server": "Nu s-a putut conecta la server", @@ -48,10 +53,22 @@ "Add a reaction": "Reacționează", "Copy to clipboard": "Copiere în clipboard", "Link copied to clipboard": "Link-ul a fost copiat în clipboard", +<<<<<<< HEAD "This time is in your timezone. Original text was “{originalText}”.": "Ora este în fusul tău orar. Textul original a fost “{originalText}”.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "This time is in your timezone. Original text was '{originalText}'.": "This time is in your timezone. Original text was '{originalText}'.", +======= + "This time is in your timezone. Original text was “{originalText}”.": "This time is in your timezone. Original text was “{originalText}”.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Mute topic": "Marcheză subiectul - fără alertă sonoră", "Delete topic": "Şterge subiectul", +<<<<<<< HEAD "Are you sure you want to delete the topic “{topic}”?": "Eşti sigur că doreşti să ştergi acest subiect “{topic}”?", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Are you sure you want to delete the topic '{topic}'?": "Eşti sigur că vrei să ştergi subiectul '{topic}'?", +======= + "Are you sure you want to delete the topic “{topic}”?": "Are you sure you want to delete the topic “{topic}”?", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "This will also delete all messages in the topic.": "Aceasta va şterge şi toate mesajele din subiect.", "Unmute topic": "Marchează subiect cu alertă sonoră", "Mute stream": "Marchează hubul - fără alertă sonoră", @@ -209,6 +226,7 @@ "User status": "Stare utilizator", "Muted": "Fără alertă sonoră", "No topics found": "Nu am găsit subiecte", +<<<<<<< HEAD "Share on Zulip": "Distribuiţi pe Zulip", "Choose recipients": "Alege destinatari", "Please choose recipients to share with.": "Vă rugăm să alegeți destinatarii cu care să distribuiți.", @@ -218,6 +236,27 @@ "Couldn’t load information about {fullName}": "Nu am putut încărca informaţii despre {fullName}", "What’s your status?": "Care este starea ta?", "Click to join video call": "Apasă pentru a te alătura conferinţei video. ", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Share on Zulip": "Share on Zulip", + "Choose recipients": "Choose recipients", + "Please choose recipients to share with.": "Please choose recipients to share with.", + "Sending Message...": "Sending Message...", + "Failed to send message": "Failed to send message", + "Message sent": "Message sent", + "Couldn't load information about {fullName}": "Couldn't load information about {fullName}", + "What's your status?": "Care este starea ta?", + "Click to join video call": "Click to join video call", +======= + "Share on Zulip": "Share on Zulip", + "Choose recipients": "Choose recipients", + "Please choose recipients to share with.": "Please choose recipients to share with.", + "Sending Message...": "Sending Message...", + "Failed to send message": "Failed to send message", + "Message sent": "Message sent", + "Couldn’t load information about {fullName}": "Couldn’t load information about {fullName}", + "What’s your status?": "What’s your status?", + "Click to join video call": "Click to join video call", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "📅 In a meeting": "📅 În ședință", "🚌 Commuting": "🚌 Pe drum", "🤒 Out sick": "🤒 În căutarea sănătății pierdute", diff --git a/static/translations/messages_ru.json b/static/translations/messages_ru.json index 6a2e56f2e88..3e1277b6c98 100644 --- a/static/translations/messages_ru.json +++ b/static/translations/messages_ru.json @@ -33,7 +33,12 @@ "Username": "Имя пользователя", "Password": "Пароль", "Why not start the conversation?": "Почему бы не начать общение?", +<<<<<<< HEAD "That conversation doesn't seem to exist.": "Похоже, эта беседа не существует.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) +======= + "That conversation doesn't seem to exist.": "That conversation doesn't seem to exist.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Chat": "Чат", "Sign in with {method}": "Войти через {method}", "Cannot connect to server": "Не могу подключиться к серверу", @@ -48,10 +53,22 @@ "Add a reaction": "Добавить реакцию", "Copy to clipboard": "Скопировать в буфер обмена", "Link copied to clipboard": "Ссылка скопирована в буфер обмена", +<<<<<<< HEAD "This time is in your timezone. Original text was “{originalText}”.": "Указанное время соответствует вашему часовому поясу. В оригинале написано “{originalText}”.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "This time is in your timezone. Original text was '{originalText}'.": "Указанное время соответствует вашему часовому поясу. В оригинале написано '{originalText}'.", +======= + "This time is in your timezone. Original text was “{originalText}”.": "This time is in your timezone. Original text was “{originalText}”.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Mute topic": "Заглушить тему", "Delete topic": "Удалить тему", +<<<<<<< HEAD "Are you sure you want to delete the topic “{topic}”?": "Вы действительно хотите удалить тему “{topic}”?", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Are you sure you want to delete the topic '{topic}'?": "Вы действительно хотите удалить тему '{topic}'?", +======= + "Are you sure you want to delete the topic “{topic}”?": "Are you sure you want to delete the topic “{topic}”?", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "This will also delete all messages in the topic.": "Этим тоже будут удалены все сообщения в данной теме.", "Unmute topic": "Включить тему", "Mute stream": "Заглушить канал", @@ -215,8 +232,16 @@ "Sending Message...": "Отправка сообщения...", "Failed to send message": "Не удалось отправить сообщение", "Message sent": "Сообщение отправлено", +<<<<<<< HEAD "Couldn’t load information about {fullName}": "Не удалось загрузить информацию о {fullName}", "What’s your status?": "Какой твой статус?", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Couldn't load information about {fullName}": "Не удалось загрузить информацию о {fullName}", + "What's your status?": "Какой твой статус?", +======= + "Couldn’t load information about {fullName}": "Couldn’t load information about {fullName}", + "What’s your status?": "What’s your status?", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Click to join video call": "Нажмите здесь, чтобы присоединиться к видеозвонку", "📅 In a meeting": "📅 На встрече", "🚌 Commuting": "🚌 В дороге", diff --git a/static/translations/messages_uk.json b/static/translations/messages_uk.json index cef90774457..4be7775cf3d 100644 --- a/static/translations/messages_uk.json +++ b/static/translations/messages_uk.json @@ -33,7 +33,12 @@ "Username": "Ім'я користувача", "Password": "Пароль", "Why not start the conversation?": "Чому б не почати розмову?", +<<<<<<< HEAD "That conversation doesn't seem to exist.": "Здається, цієї розмови не існує.", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) +======= + "That conversation doesn't seem to exist.": "That conversation doesn't seem to exist.", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "Chat": "Чат", "Sign in with {method}": "Увійти за допомогою {method}", "Cannot connect to server": "Неможливо підключитися до сервера", @@ -51,7 +56,13 @@ "This time is in your timezone. Original text was “{originalText}”.": "This time is in your timezone. Original text was “{originalText}”.", "Mute topic": "Заглушити тему", "Delete topic": "Видалити тему", +<<<<<<< HEAD "Are you sure you want to delete the topic “{topic}”?": "Ви впевнені, що хочете видалити тему “{topic}”?", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Are you sure you want to delete the topic '{topic}'?": "Ви впевнені, що хочете видалити тему '{topic}'?", +======= + "Are you sure you want to delete the topic “{topic}”?": "Are you sure you want to delete the topic “{topic}”?", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "This will also delete all messages in the topic.": "Це також видалить усі повідомлення в темі.", "Unmute topic": "Увімкнути сповіщення теми", "Mute stream": "Заглушити канал", @@ -215,9 +226,19 @@ "Sending Message...": "Надсилання повідомлення…", "Failed to send message": "Не вдалося надіслати повідомлення", "Message sent": "Повідомлення надіслано", +<<<<<<< HEAD "Couldn’t load information about {fullName}": "Не вдалося завантажити інформацію про {fullName}", "What’s your status?": "What’s your status?", "Click to join video call": "Натисніть, щоб приєднатися до відеодзвінка", +||||||| parent of 84d50e52 (i18n: Sync translations from Transifex) + "Couldn't load information about {fullName}": "Couldn't load information about {fullName}", + "What's your status?": "Який Ваш стан?", + "Click to join video call": "Click to join video call", +======= + "Couldn’t load information about {fullName}": "Couldn’t load information about {fullName}", + "What’s your status?": "What’s your status?", + "Click to join video call": "Натисніть, щоб приєднатися до відеодзвінка", +>>>>>>> 84d50e52 (i18n: Sync translations from Transifex) "📅 In a meeting": "На зустрічі", "🚌 Commuting": "Спілкуюся", "🤒 Out sick": "Захворів",