diff --git a/CMakeLists.txt b/CMakeLists.txt index b3e31012627ae46ef04c2af3aab50045fc197392..01f1d658dfc87f6c3f89f9234adcde22506c413a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -347,6 +347,7 @@ SET(libringclient_api_LIB_HDRS src/api/contact.h src/api/call.h src/api/account.h + src/api/chatview.h src/api/lrc.h src/api/avmodel.h src/api/pluginmodel.h diff --git a/src/api/chatview.h b/src/api/chatview.h new file mode 100644 index 0000000000000000000000000000000000000000..9a0a70eb7eab58b0fff3316117da40611f40e654 --- /dev/null +++ b/src/api/chatview.h @@ -0,0 +1,77 @@ +/**************************************************************************** + * Copyright (C) 2020 Savoir-faire Linux Inc. * + * Author: Sébastien Blin <sebastien.blin@savoirfairelinux.com> * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of the GNU Lesser General Public * + * License as published by the Free Software Foundation; either * + * version 2.1 of the License, or (at your option) any later version. * + * * + * This library is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program. If not, see <http://www.gnu.org/licenses/>. * + ***************************************************************************/ +#pragma once + +// Qt +#include <QObject> +#include <QVariantMap> +#include <QString> + +namespace lrc { + +namespace api { + +namespace chatview { + +QVariantMap +getTranslatedStrings() +{ + return { + {"Hide chat view", QObject::tr("Hide chat view")}, + {"Place video call", QObject::tr("Place video call")}, + {"Place audio call", QObject::tr("Place audio call")}, + {"Add to conversations", QObject::tr("Add to conversations")}, + {"Unban contact", QObject::tr("Unban contact")}, + {"Send", QObject::tr("Send")}, + {"Options", QObject::tr("Options")}, + {"Jump to latest", QObject::tr("Jump to latest")}, + {"Send file", QObject::tr("Send file")}, + {"Leave video message", QObject::tr("Leave video message")}, + {"Leave audio message", QObject::tr("Leave audio message")}, + {"Accept", QObject::tr("Accept")}, + {"Refuse", QObject::tr("Refuse")}, + {"Block", QObject::tr("Block")}, + {"Type a message", QObject::tr("Type a message")}, + {"Note: an interaction will create a new contact.", + QObject::tr("Note: an interaction will create a new contact.")}, + {"is not in your contacts", QObject::tr("is not in your contacts")}, + {"Note: you can automatically accept this invitation by sending a message.", + QObject::tr("Note: you can automatically accept this invitation by sending a message.")}, +#if defined(WIN32) + {"%d days ago", QObject::tr("{0} days ago")}, + {"%d hours ago", QObject::tr("{0} hours ago")}, + {"%d minutes ago", QObject::tr("{0} minutes ago")}, +#else + {"%d days ago", QObject::tr("%d days ago")}, + {"%d hours ago", QObject::tr("%d hours ago")}, + {"%d minutes ago", QObject::tr("%d minutes ago")}, +#endif + {"one day ago", QObject::tr("one day ago")}, + {"one hour ago", QObject::tr("one hour ago")}, + {"just now", QObject::tr("just now")}, + {"Failure", QObject::tr("Failure")}, + {"Accept", QObject::tr("Accept")}, + {"Refuse", QObject::tr("Refuse")}, + {"Delete", QObject::tr("Delete")}, + {"Retry", QObject::tr("Retry")}, + }; +} + +} // namespace chatview +} // namespace api +} // namespace lrc diff --git a/src/web-chatview/chatview.js b/src/web-chatview/chatview.js index 94d4afc5615736bc312ae3d18fd550319578b828..8d88ec4e69f476cfda03ca1a1c6130d68959b6b4 100644 --- a/src/web-chatview/chatview.js +++ b/src/web-chatview/chatview.js @@ -133,7 +133,16 @@ function init_i18n(data) { if (data === undefined) { i18n = new Jed({ locale_data: { "messages": { "": {} } } }) // eslint-disable-line no-undef } else { - i18n = new Jed(data) // eslint-disable-line no-undef + var domain = { + "" : { + // Domain name + "domain" : "messages", + } + } + for (var key in data) { + domain[key] = [data[key]] + } + i18n = new Jed({ locale_data: { "messages": domain } }) } reset_message_bar_input() set_titles() @@ -142,20 +151,20 @@ function init_i18n(data) { function set_titles() { if (use_qt){ - backButton.title = i18nStringData["backButtonTitle"] - placeCallButton.title = i18nStringData["placeCallButtonTitle"] - placeAudioCallButton.title = i18nStringData["placeAudioCallButtonTitle"] - addToConversationsButton.title = i18nStringData["addToConversationsButtonTitle"] - unbanButton.title = i18nStringData["unbanButtonTitle"] - sendButton.title = i18nStringData["sendButtonTitle"] - optionsButton.title = i18nStringData["optionsButtonTitle"] - backToBottomBtn.innerHTML = `${i18nStringData["backToBottomBtnInnerHTML"]} ▼` - sendFileButton.title = i18nStringData["sendFileButtonTitle"] - videoRecordButton.title = i18nStringData["videoRecordButtonTitle"] - audioRecordButton.title = i18nStringData["audioRecordButtonTitle"] - acceptButton.title = i18nStringData["acceptButtonTitle"] - refuseButton.title = i18nStringData["refuseButtonTitle"] - blockButton.title = i18nStringData["blockButtonTitle"] + backButton.title = i18nStringData["Hide chat view"] + placeCallButton.title = i18nStringData["Place video call"] + placeAudioCallButton.title = i18nStringData["Place audio call"] + addToConversationsButton.title = i18nStringData["Add to conversations"] + unbanButton.title = i18nStringData["Unban contact"] + sendButton.title = i18nStringData["Send"] + optionsButton.title = i18nStringData["Options"] + backToBottomBtn.innerHTML = `${i18nStringData["Jump to latest"]} ▼` + sendFileButton.title = i18nStringData["Send file"] + videoRecordButton.title = i18nStringData["Leave video message"] + audioRecordButton.title = i18nStringData["Leave audio message"] + acceptButton.title = i18nStringData["Accept"] + refuseButton.title = i18nStringData["Refuse"] + blockButton.title = i18nStringData["Block"] } else { backButton.title = i18n.gettext("Hide chat view") placeCallButton.title = i18n.gettext("Place video call") @@ -176,7 +185,7 @@ function set_titles() { function reset_message_bar_input() { messageBarInput.placeholder = use_qt ? - i18nStringData["messageBarInputPlaceholder"] : i18n.gettext("Type a message") + i18nStringData["Type a message"] : i18n.gettext("Type a message") } function onScrolled_() { @@ -301,7 +310,8 @@ function update_chatview_frame(accountEnabled, banned, temporary, alias, bestid) isTemporary = temporary if (temporary) { addToConvButton.style.display = "flex" - messageBarInput.placeholder = use_qt ? i18nStringData["placeHolderTemporaryContact"] : + messageBarInput.placeholder = use_qt ? + i18nStringData["Note: an interaction will create a new contact."] : i18n.gettext("Note: an interaction will create a new contact.") } else { addToConvButton.style.display = "" @@ -343,10 +353,11 @@ function showInvitation(contactAlias, contactId) { } } invitationText.innerHTML = "<b>" - + contactAlias + use_qt ? i18nStringData["isNotInYourContacts"] : + + contactAlias + use_qt ? i18nStringData["is not in your contacts"] : i18n.sprintf(i18n.gettext("%s is not in your contacts"), contactAlias) + "</b><br/>" - + use_qt ? i18nStringData["automaticallyAcceptInvitation"] : + + use_qt ? + i18nStringData["Note: you can automatically accept this invitation by sending a message."] : i18n.gettext("Note: you can automatically accept this invitation by sending a message.") hasInvitation = true invitation.style.visibility = "visible" @@ -552,20 +563,20 @@ function formatDate(date) { if (interval > 5) return date.toLocaleDateString() if (interval > 1) - return "\u200E " + i18nStringData["daysAgo"].format(interval) + return "\u200E " + i18nStringData["%d days ago"].format(interval) if (interval === 1) - return "\u200E " + i18nStringData["oneDayAgo"] + return "\u200E " + i18nStringData["one day ago"] interval = Math.floor(seconds / 3600) if (interval > 1) - return "\u200E " + i18nStringData["hoursAgo"].format(interval) + return "\u200E " + i18nStringData["%d hours ago"].format(interval) if (interval === 1) - return "\u200E " + i18nStringData["oneHourAgo"] + return "\u200E " + i18nStringData["one hour ago"] interval = Math.floor(seconds / 60) if (interval > 1) - return "\u200E " + i18nStringData["minutesAgo"].format(interval) - return i18nStringData["justNow"] + return "\u200E " + i18nStringData["%d minutes ago"].format(interval) + return i18nStringData["just now"] } else { if (interval > 5) { return date.toLocaleDateString() @@ -759,7 +770,7 @@ function getMessageDeliveryStatusText(message_delivery_status) { var formatted_delivery_status = message_delivery_status if (message_delivery_status === "failure") { - formatted_delivery_status = use_qt ? i18nStringData["failureString"] : i18n.gettext("Failure") + + formatted_delivery_status = use_qt ? i18nStringData["Failure"] : i18n.gettext("Failure") + "<svg overflow='visible' viewBox='0 -2 16 14' height='16px' width='16px'><path class='status-x x-first' stroke='#AA0000' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' fill='none' d='M4,4 L12,12'/><path class='status-x x-second' stroke='#AA0000' stroke-linecap='round' stroke-linejoin='round' stroke-width='3' fill='none' d='M12,4 L4,12'/></svg>" } else { formatted_delivery_status = "" @@ -1168,7 +1179,7 @@ function updateFileInteraction(message_div, message_object, forceTypeToFile = fa // add buttons to accept or refuse a call. var accept_button = document.createElement("div") accept_button.innerHTML = acceptSvg - accept_button.setAttribute("title", use_qt ? i18nStringData["acceptString"] : + accept_button.setAttribute("title", use_qt ? i18nStringData["Accept"] : i18n.gettext("Accept")) accept_button.setAttribute("class", "flat-button accept") accept_button.onclick = function () { @@ -1183,7 +1194,7 @@ function updateFileInteraction(message_div, message_object, forceTypeToFile = fa var refuse_button = document.createElement("div") refuse_button.innerHTML = refuseSvg - refuse_button.setAttribute("title", use_qt ? i18nStringData["refuseString"] : + refuse_button.setAttribute("title", use_qt ? i18nStringData["Refuse"] : i18n.gettext("Refuse")) refuse_button.setAttribute("class", "flat-button refuse") refuse_button.onclick = function () { @@ -1560,7 +1571,7 @@ function buildMessageDropdown(message_id) { const remove = document.createElement("div") remove.setAttribute("class", "menuoption") - remove.innerHTML = use_qt ? i18nStringData["deleteString"] : i18n.gettext("Delete") + remove.innerHTML = use_qt ? i18nStringData["Delete"] : i18n.gettext("Delete") remove.msg_id = message_id remove.onclick = function () { if (use_qt) { @@ -1801,7 +1812,7 @@ function addOrUpdateMessage(message_object, new_message, insert_after = true, me if (!dropdown.querySelector(".retry")) { const retry = document.createElement("div") retry.setAttribute("class", "retry") - retry.innerHTML = use_qt ? i18nStringData["retryString"] : i18n.gettext("Retry") + retry.innerHTML = use_qt ? i18nStringData["Retry"] : i18n.gettext("Retry") retry.msg_id = message_id retry.onclick = function () { if (use_qt) {