From 63ecbbd3fb744434c65a8dc4ecbe9e167637faed Mon Sep 17 00:00:00 2001 From: Isham Mahajan Date: Sun, 24 Mar 2019 19:56:02 +0530 Subject: [PATCH 1/3] webview js: Fix unexpected `click` on long-press on iOS. The long press logic is very subtle, as described in `js.js`, and the logic around `lastTouchEventTimestamp` is even more obscure. There was a bug in iOS, where the a shortPress, or a `click`, was triggered after releasing the finger after a `longPress` event. This commit fixes this bug by introducing a flag which detects whether a long press was triggered before the detection of this click. While this could be potentially implemented without an extra flag and with the already existing `lastTouchEventTimestamp`, on trying to implement it, there arise a slew of other bugs. Besides, if a new flag was not used, the logic around `lastTouchEventTimestamp` would become unreadable. Fixes #3429. --- src/webview/js/generatedEs3.js | 11 ++++++++++- src/webview/js/js.js | 10 ++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/webview/js/generatedEs3.js b/src/webview/js/generatedEs3.js index d61840afb8f..28295a2d1e4 100644 --- a/src/webview/js/generatedEs3.js +++ b/src/webview/js/generatedEs3.js @@ -152,7 +152,7 @@ function someVisibleMessage(top, bottom) { function idFromMessage(element) { var idStr = element.getAttribute('data-msg-id'); - if (!idStr) { + if (idStr === null || idStr === undefined) { throw new Error('Bad message element'); } @@ -231,6 +231,7 @@ var sendScrollMessageIfListShort = function sendScrollMessageIfListShort() { var scrollEventsDisabled = true; var lastTouchEventTimestamp = 0; +var hasLongPressed = false; var lastTouchPositionX = -1; var lastTouchPositionY = -1; @@ -421,6 +422,12 @@ var requireAttribute = function requireAttribute(e, name) { documentBody.addEventListener('click', function (e) { e.preventDefault(); lastTouchEventTimestamp = 0; + + if (hasLongPressed) { + hasLongPressed = false; + return; + } + var target = e.target; if (!(target instanceof Element)) { @@ -495,6 +502,7 @@ var handleLongPress = function handleLongPress(target) { } lastTouchEventTimestamp = 0; + hasLongPressed = true; sendMessage({ type: 'longPress', target: target.matches('.header') ? 'header' : 'message', @@ -512,6 +520,7 @@ documentBody.addEventListener('touchstart', function (e) { lastTouchPositionX = e.changedTouches[0].pageX; lastTouchPositionY = e.changedTouches[0].pageY; lastTouchEventTimestamp = Date.now(); + hasLongPressed = false; setTimeout(function () { return handleLongPress(target); }, 500); diff --git a/src/webview/js/js.js b/src/webview/js/js.js index 18d69a4f69f..2da3f1dce01 100644 --- a/src/webview/js/js.js +++ b/src/webview/js/js.js @@ -351,6 +351,7 @@ const sendScrollMessageIfListShort = () => { let scrollEventsDisabled = true; let lastTouchEventTimestamp = 0; +let hasLongPressed = false; let lastTouchPositionX = -1; let lastTouchPositionY = -1; @@ -558,6 +559,13 @@ documentBody.addEventListener('click', (e: MouseEvent) => { e.preventDefault(); lastTouchEventTimestamp = 0; + /* Without a flag `hasLongPressed`, both the short press and the long + * press actions get triggered. See PR #3404 for more context. */ + if (hasLongPressed) { + hasLongPressed = false; + return; + } + const { target } = e; if (!(target instanceof Element)) { @@ -650,6 +658,7 @@ const handleLongPress = (target: Element) => { } lastTouchEventTimestamp = 0; + hasLongPressed = true; sendMessage({ type: 'longPress', @@ -667,6 +676,7 @@ documentBody.addEventListener('touchstart', (e: TouchEvent) => { lastTouchPositionX = e.changedTouches[0].pageX; lastTouchPositionY = e.changedTouches[0].pageY; lastTouchEventTimestamp = Date.now(); + hasLongPressed = false; setTimeout(() => handleLongPress(target), 500); }); From f34fe6130ecce7353e7030b2cac47ec3299afea3 Mon Sep 17 00:00:00 2001 From: Isham Mahajan Date: Thu, 21 Mar 2019 01:49:12 +0530 Subject: [PATCH 2/3] webview: Add ability to copy links found in messages. There is no way to copy only links from a message at the moment, which makes it hard for some users to copy only the links to share with other people. There could be two solutions to this. One is that another menu option could be provided to copy only the link in your message, which is not a correct approach as immediately some problems come to mind. For example, if there were two links in the message, which one would the app copy? Another solution to this could be what commercial applications already apply, which is if you hold the link text, it gets copied. Which is what has been implemented here. I have modified the already existing `MessageListEventLongPress` to include functionality for long-pressing on links. Tests have been conducted on iOS simulator and Android emulator. Functionality has also been checked for Android on a real device. This commit also made conspicuous a related bug which already affected long-presses on iOS (#3429), fixed separately in the previous commit for the sake of clarity. Fixes #3385. --- src/webview/js/generatedEs3.js | 5 +++-- src/webview/js/js.js | 3 ++- src/webview/webViewEventHandlers.js | 22 ++++++++++++++++++---- static/translations/messages_en.json | 1 + 4 files changed, 24 insertions(+), 7 deletions(-) diff --git a/src/webview/js/generatedEs3.js b/src/webview/js/generatedEs3.js index 28295a2d1e4..a60f97b0be1 100644 --- a/src/webview/js/generatedEs3.js +++ b/src/webview/js/generatedEs3.js @@ -505,8 +505,9 @@ var handleLongPress = function handleLongPress(target) { hasLongPressed = true; sendMessage({ type: 'longPress', - target: target.matches('.header') ? 'header' : 'message', - messageId: getMessageIdFromNode(target) + target: target.matches('.header') ? 'header' : target.matches('a') ? 'link' : 'message', + messageId: getMessageIdFromNode(target), + href: target.matches('a') ? requireAttribute(target, 'href') : null }); }; diff --git a/src/webview/js/js.js b/src/webview/js/js.js index 2da3f1dce01..e434db8bf2f 100644 --- a/src/webview/js/js.js +++ b/src/webview/js/js.js @@ -662,8 +662,9 @@ const handleLongPress = (target: Element) => { sendMessage({ type: 'longPress', - target: target.matches('.header') ? 'header' : 'message', + target: target.matches('.header') ? 'header' : target.matches('a') ? 'link' : 'message', messageId: getMessageIdFromNode(target), + href: target.matches('a') ? requireAttribute(target, 'href') : null, }); }; diff --git a/src/webview/webViewEventHandlers.js b/src/webview/webViewEventHandlers.js index f07c169aaab..42561f84fcb 100644 --- a/src/webview/webViewEventHandlers.js +++ b/src/webview/webViewEventHandlers.js @@ -1,9 +1,11 @@ /* @flow strict-local */ +import { Clipboard } from 'react-native'; import { emojiReactionAdd, emojiReactionRemove, queueMarkAsRead } from '../api'; import config from '../config'; import type { Dispatch, GetText, Message, Narrow } from '../types'; import type { BackgroundData } from './MessageList'; import type { ShowActionSheetWithOptions } from '../message/messageActionSheet'; +import { showToast } from '../utils/info'; import { isUrlAnImage } from '../utils/url'; import { logErrorRemotely } from '../utils/logging'; import { filterUnreadMessagesInRange } from '../utils/unread'; @@ -78,8 +80,9 @@ type MessageListEventUrl = {| type MessageListEventLongPress = {| type: 'longPress', - target: 'message' | 'header', + target: 'message' | 'header' | 'link', messageId: number, + href: string | null, |}; type MessageListEventDebug = {| @@ -151,13 +154,24 @@ const handleImage = (props: Props, src: string, messageId: number) => { } }; -const handleLongPress = (props: Props, _: GetText, isHeader: boolean, messageId: number) => { +const handleLongPress = ( + props: Props, + _: GetText, + target: 'message' | 'header' | 'link', + messageId: number, + href: string | null, +) => { + if (href !== null) { + Clipboard.setString(href); + showToast(_('Link copied to clipboard')); + return; + } const message = props.messages.find(x => x.id === messageId); if (!message) { return; } const { dispatch, showActionSheetWithOptions, backgroundData, narrow } = props; - showActionSheet(isHeader, dispatch, showActionSheetWithOptions, _, { + showActionSheet(target === 'header', dispatch, showActionSheetWithOptions, _, { backgroundData, message, narrow, @@ -188,7 +202,7 @@ export const handleMessageListEvent = (props: Props, _: GetText, event: MessageL break; case 'longPress': - handleLongPress(props, _, event.target === 'header', event.messageId); + handleLongPress(props, _, event.target, event.messageId, event.href); break; case 'url': diff --git a/static/translations/messages_en.json b/static/translations/messages_en.json index 919e381bea2..063bf33eb53 100644 --- a/static/translations/messages_en.json +++ b/static/translations/messages_en.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", From 96f285f06da34e3d15a403f7731e2d47d60ebb97 Mon Sep 17 00:00:00 2001 From: Greg Price Date: Wed, 27 Mar 2019 18:41:10 -0700 Subject: [PATCH 3/3] i18n: Sync translations for new string from Transifex. Happily, for many languages we already have a translation for this string. --- static/translations/messages_ar.json | 1 + static/translations/messages_bg.json | 1 + static/translations/messages_ca.json | 1 + static/translations/messages_cs.json | 1 + static/translations/messages_da.json | 1 + static/translations/messages_de.json | 1 + static/translations/messages_es.json | 1 + static/translations/messages_fa.json | 1 + static/translations/messages_fi.json | 1 + static/translations/messages_fr.json | 1 + static/translations/messages_gl.json | 1 + static/translations/messages_hi.json | 1 + static/translations/messages_hr.json | 1 + static/translations/messages_hu.json | 1 + static/translations/messages_id_ID.json | 1 + static/translations/messages_it.json | 1 + static/translations/messages_ja.json | 1 + static/translations/messages_ko.json | 1 + static/translations/messages_ml.json | 1 + static/translations/messages_nl.json | 1 + static/translations/messages_pl.json | 1 + static/translations/messages_pt.json | 1 + static/translations/messages_ro.json | 1 + static/translations/messages_ru.json | 1 + static/translations/messages_sr.json | 1 + static/translations/messages_sv.json | 1 + static/translations/messages_ta.json | 1 + static/translations/messages_tr.json | 1 + static/translations/messages_uk.json | 1 + static/translations/messages_uz.json | 1 + static/translations/messages_zh-Hans.json | 1 + static/translations/messages_zh-Hant.json | 1 + 32 files changed, 32 insertions(+) diff --git a/static/translations/messages_ar.json b/static/translations/messages_ar.json index 919e381bea2..063bf33eb53 100644 --- a/static/translations/messages_ar.json +++ b/static/translations/messages_ar.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", diff --git a/static/translations/messages_bg.json b/static/translations/messages_bg.json index 072dd20cb08..8b7d4e13264 100644 --- a/static/translations/messages_bg.json +++ b/static/translations/messages_bg.json @@ -50,6 +50,7 @@ "Reply": "Отговори", "Add a reaction": "Добави реакция", "Copy to clipboard": "Копирай в клипборд", + "Link copied to clipboard": "Линкът е копиран в клипборда", "Mute topic": "Заглуши тема", "Unmute topic": "Не заглушавай тема", "Mute stream": "Заглуши канал", diff --git a/static/translations/messages_ca.json b/static/translations/messages_ca.json index 3aad115ab5d..a16100ee45b 100644 --- a/static/translations/messages_ca.json +++ b/static/translations/messages_ca.json @@ -50,6 +50,7 @@ "Reply": "Respondre", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copiar al porta-retalls", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Silenciar tema", "Unmute topic": "Unmute topic", "Mute stream": "Silenciar canal", diff --git a/static/translations/messages_cs.json b/static/translations/messages_cs.json index 17dbe72df4a..9671bbea331 100644 --- a/static/translations/messages_cs.json +++ b/static/translations/messages_cs.json @@ -50,6 +50,7 @@ "Reply": "Odpovědět", "Add a reaction": "Přidat odpověď", "Copy to clipboard": "Kopírovat do schránky", + "Link copied to clipboard": "Odkaz zkopírován do schránky", "Mute topic": "Ztlumit téma", "Unmute topic": "Zrušit ztlumení tématu", "Mute stream": "Ztlumit kanál", diff --git a/static/translations/messages_da.json b/static/translations/messages_da.json index 919e381bea2..063bf33eb53 100644 --- a/static/translations/messages_da.json +++ b/static/translations/messages_da.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", diff --git a/static/translations/messages_de.json b/static/translations/messages_de.json index fba482f9b53..f29f684ba83 100644 --- a/static/translations/messages_de.json +++ b/static/translations/messages_de.json @@ -50,6 +50,7 @@ "Reply": "Antworten", "Add a reaction": "Reaktion hinzufügen", "Copy to clipboard": "In die Ablage kopieren", + "Link copied to clipboard": "Link in die Ablage kopiert", "Mute topic": "Thema stummschalten", "Unmute topic": "Stummschaltung aufheben", "Mute stream": "Stream stummschalten", diff --git a/static/translations/messages_es.json b/static/translations/messages_es.json index 620448f4653..228415684e7 100644 --- a/static/translations/messages_es.json +++ b/static/translations/messages_es.json @@ -50,6 +50,7 @@ "Reply": "Responder", "Add a reaction": "Añadir una reacción", "Copy to clipboard": "Copiar al portapapeles", + "Link copied to clipboard": "Enlace copiado al portapapeles", "Mute topic": "Silenciar tema", "Unmute topic": "No silenciar el tema", "Mute stream": "Silenciar canal", diff --git a/static/translations/messages_fa.json b/static/translations/messages_fa.json index 05aed0202d5..2e72734f92f 100644 --- a/static/translations/messages_fa.json +++ b/static/translations/messages_fa.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", diff --git a/static/translations/messages_fi.json b/static/translations/messages_fi.json index d1fa46ac288..add498d5b27 100644 --- a/static/translations/messages_fi.json +++ b/static/translations/messages_fi.json @@ -50,6 +50,7 @@ "Reply": "Vastaa", "Add a reaction": "Add a reaction", "Copy to clipboard": "Kopioi leikepöydälle", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mykistä aihe", "Unmute topic": "Poista aiheen mykistys", "Mute stream": "Mykistä kanava", diff --git a/static/translations/messages_fr.json b/static/translations/messages_fr.json index a76434ab86b..d17abf0eb3e 100644 --- a/static/translations/messages_fr.json +++ b/static/translations/messages_fr.json @@ -50,6 +50,7 @@ "Reply": "Répondre", "Add a reaction": "Ajouter une réaction", "Copy to clipboard": "Copier dans le presse-papier", + "Link copied to clipboard": "Lien copié vers le presse-papier", "Mute topic": "Rendre le sujet muet", "Unmute topic": "Ne plus rendre le sujet muet", "Mute stream": "Rendre le canal muet ", diff --git a/static/translations/messages_gl.json b/static/translations/messages_gl.json index 00f371b4295..f937396c78b 100644 --- a/static/translations/messages_gl.json +++ b/static/translations/messages_gl.json @@ -50,6 +50,7 @@ "Reply": "Responder", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copiar no portarretallos", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Silenciar este tema", "Unmute topic": "Deixar de silenciar este tema", "Mute stream": "Silenciar o fío", diff --git a/static/translations/messages_hi.json b/static/translations/messages_hi.json index 948db0e46c6..9ddffd6c2cc 100644 --- a/static/translations/messages_hi.json +++ b/static/translations/messages_hi.json @@ -50,6 +50,7 @@ "Reply": "जवाब दें", "Add a reaction": "एक प्रतिक्रिया जोड़ें", "Copy to clipboard": "क्लिपबोर्ड पर कॉपी करें", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "विषय म्यूट करें", "Unmute topic": "विषय अनम्यूट करें", "Mute stream": " धारा म्यूट करें", diff --git a/static/translations/messages_hr.json b/static/translations/messages_hr.json index 919e381bea2..063bf33eb53 100644 --- a/static/translations/messages_hr.json +++ b/static/translations/messages_hr.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", diff --git a/static/translations/messages_hu.json b/static/translations/messages_hu.json index 79a184252ca..3ecafa8bae7 100644 --- a/static/translations/messages_hu.json +++ b/static/translations/messages_hu.json @@ -50,6 +50,7 @@ "Reply": "Válasz", "Add a reaction": "Add a reaction", "Copy to clipboard": "Másolás vágólapra", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Téma némítása", "Unmute topic": "Téma némítás feloldása", "Mute stream": "Üzenetfolyam némítása", diff --git a/static/translations/messages_id_ID.json b/static/translations/messages_id_ID.json index 1192f3245d6..f0bfa16556b 100644 --- a/static/translations/messages_id_ID.json +++ b/static/translations/messages_id_ID.json @@ -50,6 +50,7 @@ "Reply": "Balas", "Add a reaction": "Add a reaction", "Copy to clipboard": "Salin ke clipboard", + "Link copied to clipboard": "Tautan disalin ke clipboard", "Mute topic": "Senyapkan topik", "Unmute topic": "Nyalakan topik", "Mute stream": "Senyapkan stream", diff --git a/static/translations/messages_it.json b/static/translations/messages_it.json index 1c99bdd6d90..fbc4f684444 100644 --- a/static/translations/messages_it.json +++ b/static/translations/messages_it.json @@ -50,6 +50,7 @@ "Reply": "Rispondi", "Add a reaction": "Aggiungi una reazione", "Copy to clipboard": "Copia negli appunti", + "Link copied to clipboard": "Link copiato negli appunti", "Mute topic": "Silenzia il topic", "Unmute topic": "Riattiva audio dell'argomento", "Mute stream": "Zittisci il canale", diff --git a/static/translations/messages_ja.json b/static/translations/messages_ja.json index 601565ab42d..71e83976bf1 100644 --- a/static/translations/messages_ja.json +++ b/static/translations/messages_ja.json @@ -50,6 +50,7 @@ "Reply": "返信", "Add a reaction": "Add a reaction", "Copy to clipboard": "クリップボードにコピー", + "Link copied to clipboard": "リンクをクリップボードにコピー", "Mute topic": "トピックをミュート", "Unmute topic": "トピックのミュートを解除", "Mute stream": "ストリームをミュート", diff --git a/static/translations/messages_ko.json b/static/translations/messages_ko.json index ab0a0f96d7e..3216b298987 100644 --- a/static/translations/messages_ko.json +++ b/static/translations/messages_ko.json @@ -50,6 +50,7 @@ "Reply": "답장", "Add a reaction": "반응 추가", "Copy to clipboard": "클립보드에 복사하기", + "Link copied to clipboard": "링크가 클립보드에 복사되었습니다.", "Mute topic": "주제 뮤트하기", "Unmute topic": "주제 언뮤트하기", "Mute stream": "스트림 뮤트하기", diff --git a/static/translations/messages_ml.json b/static/translations/messages_ml.json index 32e7ac2c762..ce4116211e7 100644 --- a/static/translations/messages_ml.json +++ b/static/translations/messages_ml.json @@ -50,6 +50,7 @@ "Reply": "മറുപടി", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", diff --git a/static/translations/messages_nl.json b/static/translations/messages_nl.json index cd3f76480c3..81eb73fc4ac 100644 --- a/static/translations/messages_nl.json +++ b/static/translations/messages_nl.json @@ -50,6 +50,7 @@ "Reply": "Antwoorden", "Add a reaction": "Add a reaction", "Copy to clipboard": "Kopiëren", + "Link copied to clipboard": "Link gekopieerd naar klembord", "Mute topic": "Onderwerp dempen", "Unmute topic": "Onderwerp aanzetten", "Mute stream": "Kanaal dempen", diff --git a/static/translations/messages_pl.json b/static/translations/messages_pl.json index cddf1e3a996..37842021c16 100644 --- a/static/translations/messages_pl.json +++ b/static/translations/messages_pl.json @@ -50,6 +50,7 @@ "Reply": "Odpowiedz", "Add a reaction": "Dodaj reakcje", "Copy to clipboard": "Kopiuj do schowka", + "Link copied to clipboard": "Link skopiowany do schowka", "Mute topic": "Wycisz wątek", "Unmute topic": "Przywróć powiadomienia w wątku", "Mute stream": "Wycisz kanał", diff --git a/static/translations/messages_pt.json b/static/translations/messages_pt.json index e6529c52085..6ce50379e70 100644 --- a/static/translations/messages_pt.json +++ b/static/translations/messages_pt.json @@ -50,6 +50,7 @@ "Reply": "Responder", "Add a reaction": "Adicionar uma reação", "Copy to clipboard": "Copiar para área de transferência", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Silenciar tópico", "Unmute topic": "Cancelar o silenciamento do tópico", "Mute stream": "Silenciar fluxo", diff --git a/static/translations/messages_ro.json b/static/translations/messages_ro.json index 86eb6db15fb..e544999cd8c 100644 --- a/static/translations/messages_ro.json +++ b/static/translations/messages_ro.json @@ -50,6 +50,7 @@ "Reply": "Răspunde", "Add a reaction": "Reacționează", "Copy to clipboard": "Copiere în clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Dezactivează sunetele pentru subiect", "Unmute topic": "Activează sunetele pentru subiect", "Mute stream": "Dezactivează sunetele pentru flux", diff --git a/static/translations/messages_ru.json b/static/translations/messages_ru.json index 8e98289599f..d99b7876312 100644 --- a/static/translations/messages_ru.json +++ b/static/translations/messages_ru.json @@ -50,6 +50,7 @@ "Reply": "Ответить", "Add a reaction": "Add a reaction", "Copy to clipboard": "Скопировать в буфер обмена", + "Link copied to clipboard": "Ссылка скопирована в буфер обмена", "Mute topic": "Заглушить тему", "Unmute topic": "Включить тему", "Mute stream": "Заглушить канал", diff --git a/static/translations/messages_sr.json b/static/translations/messages_sr.json index aa1933c4ba4..ece5258b546 100644 --- a/static/translations/messages_sr.json +++ b/static/translations/messages_sr.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", diff --git a/static/translations/messages_sv.json b/static/translations/messages_sv.json index 919e381bea2..063bf33eb53 100644 --- a/static/translations/messages_sv.json +++ b/static/translations/messages_sv.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", diff --git a/static/translations/messages_ta.json b/static/translations/messages_ta.json index bf1516c9256..d0a9628d825 100644 --- a/static/translations/messages_ta.json +++ b/static/translations/messages_ta.json @@ -50,6 +50,7 @@ "Reply": "மறுமொழி", "Add a reaction": "Add a reaction", "Copy to clipboard": "நகல் நினைவியை நகலெடுக்கவும்", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "தலைப்பை அமைதியாக்கு", "Unmute topic": "தலைப்பு தடையை நீக்கு", "Mute stream": "தொடரை அமைதியாக்கு", diff --git a/static/translations/messages_tr.json b/static/translations/messages_tr.json index d09b164e178..645dd1cff28 100644 --- a/static/translations/messages_tr.json +++ b/static/translations/messages_tr.json @@ -50,6 +50,7 @@ "Reply": "Yanıtla", "Add a reaction": "Tepki ekle", "Copy to clipboard": "Panoya kopyala", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Konuyu susturun", "Unmute topic": "Konunun sesini açın", "Mute stream": "Kanalı sessize al", diff --git a/static/translations/messages_uk.json b/static/translations/messages_uk.json index 895ff65016b..a723bba544b 100644 --- a/static/translations/messages_uk.json +++ b/static/translations/messages_uk.json @@ -50,6 +50,7 @@ "Reply": "Відповісти", "Add a reaction": "Додати реакцію", "Copy to clipboard": "Копіювати в буфер обміну", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Заглушити тему", "Unmute topic": "Увімкнути сповіщення теми", "Mute stream": "Заглушити канал", diff --git a/static/translations/messages_uz.json b/static/translations/messages_uz.json index 919e381bea2..063bf33eb53 100644 --- a/static/translations/messages_uz.json +++ b/static/translations/messages_uz.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream", diff --git a/static/translations/messages_zh-Hans.json b/static/translations/messages_zh-Hans.json index 54537706d95..4a07120a0c6 100644 --- a/static/translations/messages_zh-Hans.json +++ b/static/translations/messages_zh-Hans.json @@ -50,6 +50,7 @@ "Reply": "回复", "Add a reaction": "添加映射", "Copy to clipboard": "复制到剪贴板", + "Link copied to clipboard": "链接已复制到剪贴板", "Mute topic": "静音主题", "Unmute topic": "非静音主题", "Mute stream": "静音频道", diff --git a/static/translations/messages_zh-Hant.json b/static/translations/messages_zh-Hant.json index 4e9a3beebbb..57ac5e0b910 100644 --- a/static/translations/messages_zh-Hant.json +++ b/static/translations/messages_zh-Hant.json @@ -50,6 +50,7 @@ "Reply": "Reply", "Add a reaction": "Add a reaction", "Copy to clipboard": "Copy to clipboard", + "Link copied to clipboard": "Link copied to clipboard", "Mute topic": "Mute topic", "Unmute topic": "Unmute topic", "Mute stream": "Mute stream",