diff --git a/harbour-fernschreiber.pro b/harbour-fernschreiber.pro
index 2961f7c..da474a4 100644
--- a/harbour-fernschreiber.pro
+++ b/harbour-fernschreiber.pro
@@ -64,6 +64,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/js/functions.js \
qml/pages/ChatInformationPage.qml \
qml/pages/ChatPage.qml \
+ qml/pages/ChatSelectionPage.qml \
qml/pages/CoverPage.qml \
qml/pages/InitializationPage.qml \
qml/pages/OverviewPage.qml \
diff --git a/images/icon-m-copy.svg b/images/icon-m-copy.svg
new file mode 100644
index 0000000..ae927d1
--- /dev/null
+++ b/images/icon-m-copy.svg
@@ -0,0 +1,41 @@
+
+
diff --git a/qml/components/ChatListViewItem.qml b/qml/components/ChatListViewItem.qml
index 0e4abcc..b584d00 100644
--- a/qml/components/ChatListViewItem.qml
+++ b/qml/components/ChatListViewItem.qml
@@ -7,7 +7,7 @@ import "../js/functions.js" as Functions
PhotoTextsListItem {
id: listItem
pictureThumbnail {
- photoData: photo_small
+ photoData: photo_small || ({})
}
property int ownUserId
property url emojiBase: "../js/emoji/"
diff --git a/qml/components/MessageListViewItem.qml b/qml/components/MessageListViewItem.qml
index 5acd458..65393b8 100644
--- a/qml/components/MessageListViewItem.qml
+++ b/qml/components/MessageListViewItem.qml
@@ -31,16 +31,31 @@ ListItem {
readonly property color textColor: isOwnMessage ? Theme.highlightColor : Theme.primaryColor
readonly property int textAlign: isOwnMessage ? Text.AlignRight : Text.AlignLeft
readonly property Page page: precalculatedValues.page
-
+ readonly property bool isSelected: messageListItem.precalculatedValues.pageIsSelecting && page.selectedMessages.some(function(existingMessage) {
+ return existingMessage.id === myMessage.id;
+ });
readonly property bool isOwnMessage: page.myUserId === myMessage.sender_user_id
readonly property string extraContentComponentName: typeof myMessage.content !== "undefined"
&& typeof chatView.contentComponentNames[myMessage.content['@type']] !== "undefined" ?
chatView.contentComponentNames[myMessage.content['@type']] : ""
readonly property ObjectModel additionalContextItems: ObjectModel {}
+ highlighted: down || isSelected
+ openMenuOnPressAndHold: !messageListItem.precalculatedValues.pageIsSelecting
+
+ onClicked: {
+ if(messageListItem.precalculatedValues.pageIsSelecting) {
+ page.toggleMessageSelection(myMessage);
+ }
+ }
onPressAndHold: {
- contextMenuLoader.active = true;
+ if(messageListItem.precalculatedValues.pageIsSelecting) {
+ page.selectedMessages = [];
+ page.state = ""
+ } else {
+ contextMenuLoader.active = true;
+ }
}
Loader {
id: contextMenuLoader
@@ -80,6 +95,12 @@ ListItem {
}
text: qsTr("Copy Message to Clipboard")
}
+ MenuItem {
+ onClicked: {
+ page.toggleMessageSelection(myMessage);
+ }
+ text: qsTr("Select Message")
+ }
MenuItem {
onClicked: {
var chatId = page.chatInformation.id;
@@ -171,13 +192,14 @@ ListItem {
sourceComponent: Component {
ProfileThumbnail {
id: messagePictureThumbnail
- photoData: (typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : ""
+ photoData: (typeof messageListItem.userInformation.profile_photo !== "undefined") ? messageListItem.userInformation.profile_photo.small : ({})
replacementStringHint: userText.text
width: Theme.itemSizeSmall
height: Theme.itemSizeSmall
visible: precalculatedValues.showUserInfo
MouseArea {
anchors.fill: parent
+ enabled: !messageListItem.precalculatedValues.pageIsSelecting
onClicked: {
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id);
}
@@ -234,6 +256,7 @@ ListItem {
visible: precalculatedValues.showUserInfo
MouseArea {
anchors.fill: parent
+ enabled: !messageListItem.precalculatedValues.pageIsSelecting
onClicked: {
tdLibWrapper.createPrivateChat(messageListItem.userInformation.id);
}
@@ -272,11 +295,11 @@ ListItem {
Component.onCompleted: {
if (myMessage.forward_info.origin["@type"] === "messageForwardOriginChannel") {
var otherChatInformation = tdLibWrapper.getChat(myMessage.forward_info.origin.chat_id);
- forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : "";
+ forwardedThumbnail.photoData = (typeof otherChatInformation.photo !== "undefined") ? otherChatInformation.photo.small : {};
forwardedChannelText.text = Emoji.emojify(otherChatInformation.title, Theme.fontSizeExtraSmall);
} else if (myMessage.forward_info.origin["@type"] === "messageForwardOriginUser") {
var otherUserInformation = tdLibWrapper.getUserInformation(myMessage.forward_info.origin.sender_user_id);
- forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : "";
+ forwardedThumbnail.photoData = (typeof otherUserInformation.profile_photo !== "undefined") ? otherUserInformation.profile_photo.small : {};
forwardedChannelText.text = Emoji.emojify(Functions.getUserName(otherUserInformation), Theme.fontSizeExtraSmall);
} else {
forwardedChannelText.text = Emoji.emojify(myMessage.forward_info.origin.sender_name, Theme.fontSizeExtraSmall);
@@ -405,6 +428,7 @@ ListItem {
text: getMessageStatusText(myMessage, index, chatView.lastReadSentIndex, messageDateText.useElapsed)
MouseArea {
anchors.fill: parent
+ enabled: !messageListItem.precalculatedValues.pageIsSelecting
onClicked: {
messageDateText.useElapsed = !messageDateText.useElapsed;
messageDateText.text = getMessageStatusText(myMessage, index, chatView.lastReadSentIndex, messageDateText.useElapsed);
diff --git a/qml/js/functions.js b/qml/js/functions.js
index ae90266..8a8a9ca 100644
--- a/qml/js/functions.js
+++ b/qml/js/functions.js
@@ -367,3 +367,30 @@ function getVideoHeight(videoWidth, videoData) {
function replaceUrlsWithLinks(string) {
return string.replace(/((\w+):\/\/[\w?=&.\/-;#~%-]+(?![\w\s?&.\/;#~%"=-]*>))/g, "$1");
}
+
+function sortMessagesArrayByDate(messages) {
+ messages.sort(function(a, b) {
+ return a.date - b.date;
+ });
+}
+
+function getMessagesArrayIds(messages) {
+ sortMessagesArrayByDate(messages);
+ return messages.map(function(message){return message.id.toString()});
+}
+
+function getMessagesArrayText(messages) {
+ sortMessagesArrayByDate(messages);
+ var lastSenderName = "";
+ var lines = [];
+ for(var i = 0; i < messages.length; i += 1) {
+ var senderName = getUserName(tdLibWrapper.getUserInformation(messages[i].sender_user_id));
+ if(senderName !== lastSenderName) {
+ lines.push(senderName);
+ }
+ lastSenderName = senderName;
+ lines.push(getMessageText(messages[i], true, false));
+ lines.push("");
+ }
+ return lines.join("\n");
+}
diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml
index 1ed395e..f773afc 100644
--- a/qml/pages/ChatPage.qml
+++ b/qml/pages/ChatPage.qml
@@ -49,6 +49,55 @@ Page {
|| (chatGroupInformation.status["@type"] === "chatMemberStatusRestricted" && chatGroupInformation.status.is_member)
|| (chatGroupInformation.status["@type"] === "chatMemberStatusCreator" && chatGroupInformation.status.is_member)
)
+ property var selectedMessages: []
+ states: [
+ State {
+ name: "selectMessages"
+ when: selectedMessages.length > 0
+ PropertyChanges {
+ target: newMessageColumn
+ visible: false
+ opacity: 0
+ }
+ PropertyChanges {
+ target: chatNameText
+ text: qsTr("Select Messages")
+ }
+ PropertyChanges {
+ target: chatStatusText
+ text: qsTr("%n messages selected", "number of messages selected", chatPage.selectedMessages.length).arg(chatPage.selectedMessages.length)
+ }
+ PropertyChanges {
+ target: selectedMessagesActions
+ height: Theme.itemSizeMedium
+ active: true
+ opacity: 1.0//selectedMessages.length > 0 ? 1.0 : 0.5
+ }
+ PropertyChanges {
+ target: newMessageTextField
+ focus: false
+ }
+ }
+
+ ]
+ function toggleMessageSelection(message) {
+ var selectionArray = selectedMessages;
+ var foundIndex = -1
+ if(selectionArray.length > 0) {
+ for(var i = 0; i < selectionArray.length; i += 1) {
+ if(selectionArray[i].id === message.id) {
+ foundIndex = i;
+ continue;
+ }
+ }
+ }
+ if(foundIndex > -1) {
+ selectionArray.splice(foundIndex, 1);
+ } else {
+ selectionArray.push(message);
+ }
+ selectedMessages = selectionArray;
+ }
function updateChatPartnerStatusText() {
var statusText = Functions.getChatPartnerStatusText(chatPartnerInformation.status['@type'], chatPartnerInformation.status.was_online);
@@ -211,6 +260,26 @@ Page {
newMessageTextField.cursorPosition = newIndex;
lostFocusTimer.start();
}
+ function forwardMessages(fromChatId, messageIds) {
+ forwardMessagesTimer.fromChatId = fromChatId;
+ forwardMessagesTimer.messageIds = messageIds;
+ forwardMessagesTimer.start();
+ }
+ Timer {
+ id: forwardMessagesTimer
+ interval: 200
+
+ property string fromChatId
+ property var messageIds
+ onTriggered: {
+ if(chatPage.loading) {
+ forwardMessagesTimer.start()
+ } else {
+ var forwardedToSecretChat = chatInformation.type["@type"] === "chatTypeSecret";
+ tdLibWrapper.forwardMessages(chatInformation.id, fromChatId, messageIds, forwardedToSecretChat, false);
+ }
+ }
+ }
Component.onCompleted: {
initializePage();
@@ -430,19 +499,22 @@ Page {
height: headerRow.height
width: parent.width
onClicked: {
- pageStack.push(Qt.resolvedUrl("../pages/ChatInformationPage.qml"), { "chatInformation" : chatInformation, "privateChatUserInformation": chatPartnerInformation, "groupInformation": chatGroupInformation, "chatOnlineMemberCount": chatOnlineMemberCount});
+ if(chatPage.state === "selectMessages") {
+ chatPage.selectedMessages = [];
+ } else {
+ pageStack.push(Qt.resolvedUrl("../pages/ChatInformationPage.qml"), { "chatInformation" : chatInformation, "privateChatUserInformation": chatPartnerInformation, "groupInformation": chatGroupInformation, "chatOnlineMemberCount": chatOnlineMemberCount});
+ }
}
}
Column {
id: chatColumn
width: parent.width
height: parent.height
- spacing: Theme.paddingSmall
Row {
id: headerRow
width: parent.width - (3 * Theme.horizontalPageMargin)
- height: chatOverviewColumn.height + Theme.paddingLarge
+ height: chatOverviewColumn.height + Theme.paddingLarge + Theme.paddingSmall
anchors.horizontalCenter: parent.horizontalCenter
spacing: Theme.paddingMedium
@@ -491,7 +563,7 @@ Page {
Item {
id: chatViewItem
width: parent.width
- height: parent.height - headerRow.height - Theme.paddingSmall - ( chatPage.isChannel ? 0 : ( newMessageColumn.height + Theme.paddingSmall ) )
+ height: parent.height - headerRow.height - newMessageColumn.height - selectedMessagesActions.height
property int previousHeight;
@@ -522,7 +594,7 @@ Page {
anchors.fill: parent
opacity: chatPage.loading ? 0 : 1
- Behavior on opacity { NumberAnimation {} }
+ Behavior on opacity { FadeAnimation {} }
clip: true
highlightMoveDuration: 0
highlightResizeDuration: 0
@@ -542,6 +614,8 @@ Page {
readonly property int textColumnWidth: backgroundWidth - Theme.horizontalPageMargin
readonly property int messageInReplyToHeight: Theme.fontSizeExtraSmall * 2.571428571 + Theme.paddingSmall;
readonly property int webPagePreviewHeight: ( (textColumnWidth * 2 / 3) + (6 * Theme.fontSizeExtraSmall) + ( 7 * Theme.paddingSmall) )
+ readonly property bool pageIsSelecting: chatPage.state === "selectMessages"
+
}
function handleScrollPositionChanged() {
@@ -725,10 +799,12 @@ Page {
Column {
id: newMessageColumn
spacing: Theme.paddingSmall
-
+ topPadding: Theme.paddingSmall
width: parent.width - ( 2 * Theme.horizontalPageMargin )
anchors.horizontalCenter: parent.horizontalCenter
visible: !chatPage.isChannel
+ height: visible ? implicitHeight : 0
+ Behavior on opacity { FadeAnimation {} }
property string replyToMessageId: "0";
property string editMessageId: "0";
@@ -1050,6 +1126,103 @@ Page {
}
}
}
+ Loader {
+ id: selectedMessagesActions
+ asynchronous: true
+ active: false
+ height: 0
+ opacity: 0
+ width: parent.width - Theme.horizontalPageMargin
+ Behavior on opacity { FadeAnimation {} }
+ sourceComponent: Component {
+ Item {
+ clip: true
+
+ IconButton {
+ id: cancelSelectionButton
+ anchors {
+ left: parent.left
+ leftMargin: Theme.horizontalPageMargin
+ verticalCenter: parent.verticalCenter
+ }
+ icon.source: "image://theme/icon-m-cancel"
+ onClicked: {
+ chatPage.selectedMessages = [];
+ }
+ }
+
+ IconButton {
+ id: messagesCopyButton
+ anchors {
+ right: messagesForwardButton.left
+ leftMargin: Theme.paddingSmall
+ verticalCenter: parent.verticalCenter
+ }
+ icon.source: "../../images/icon-m-copy.svg"
+ icon.sourceSize {
+ width: Theme.iconSizeMedium
+ height: Theme.iconSizeMedium
+ }
+ onClicked: {
+ Clipboard.text = Functions.getMessagesArrayText(chatPage.selectedMessages);
+ appNotification.show(qsTr("%n messages have been copied", "", selectedMessages.length).arg(selectedMessages.length));
+ chatPage.selectedMessages = [];
+ }
+ }
+
+ IconButton {
+ id: messagesForwardButton
+
+ anchors {
+ right: messagesDeleteButton.left
+ leftMargin: visible ? Theme.paddingSmall : 0
+ verticalCenter: parent.verticalCenter
+ }
+ visible: chatPage.chatInformation.can_be_forwarded && selectedMessages.every(function(message){
+ return message.can_be_forwarded
+ })
+ width: visible ? Theme.itemSizeMedium : 0
+ icon.source: "image://theme/icon-m-forward"
+ onClicked: {
+ var ids = Functions.getMessagesArrayIds(chatPage.selectedMessages);
+
+ var chatId = chatInformation.id;
+
+ pageStack.push(Qt.resolvedUrl("../pages/ChatSelectionPage.qml"), {
+ headerDescription: qsTr("Forward %n messages", "dialog header", ids.length).arg(ids.length),
+ payload: {fromChatId: chatId, messageIds:ids},
+ state: "forwardMessages"
+ });
+ }
+
+ }
+ IconButton {
+ id: messagesDeleteButton
+ anchors {
+ right: parent.right
+ leftMargin: visible ? Theme.paddingSmall : 0
+ verticalCenter: parent.verticalCenter
+ }
+
+ icon.source: "image://theme/icon-m-delete"
+ visible: chatInformation.id === chatPage.myUserId || selectedMessages.every(function(message){
+ return message.can_be_deleted_for_all_users
+ })
+ width: visible ? Theme.itemSizeMedium : 0
+ onClicked: {
+ var ids = Functions.getMessagesArrayIds(selectedMessages);
+ var chatId = chatInformation.id
+ var wrapper = tdLibWrapper;
+ Remorse.popupAction(chatPage, qsTr("%n Messages deleted", "", ids.length).arg(ids.length), function() {
+ wrapper.deleteMessages(chatId, ids);
+ });
+ chatPage.selectedMessages = [];
+ }
+ }
+ }
+ }
+ }
+
}
}
diff --git a/qml/pages/ChatSelectionPage.qml b/qml/pages/ChatSelectionPage.qml
new file mode 100644
index 0000000..4dec379
--- /dev/null
+++ b/qml/pages/ChatSelectionPage.qml
@@ -0,0 +1,88 @@
+/*
+ Copyright (C) 2020 Sebastian J. Wolf and other contributors
+
+ This file is part of Fernschreiber.
+
+ Fernschreiber is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ Fernschreiber 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Fernschreiber. If not, see .
+*/
+import QtQuick 2.6
+import Sailfish.Silica 1.0
+import "../components"
+
+import "../js/twemoji.js" as Emoji
+import "../js/functions.js" as Functions
+
+Dialog {
+ id: chatSelectionPage
+ allowedOrientations: Orientation.All
+ canAccept: false
+ acceptDestinationAction: PageStackAction.Replace
+ acceptDestinationReplaceTarget: pageStack.find( function(page){ return(page._depth === 0)} )
+ property alias headerTitle: pageHeader.title
+ property alias headerDescription: pageHeader.description
+ property var payload: ({})
+
+ onAccepted: {
+ switch(chatSelectionPage.state) {
+ case "forwardMessages":
+ acceptDestinationInstance.forwardMessages(payload.fromChatId, payload.messageIds)
+ break;
+ }
+ }
+
+ PageHeader {
+ id: pageHeader
+ title: qsTr("Select Chat")
+ width: parent.width
+ }
+
+ SilicaListView {
+ id: chatListView
+
+ anchors {
+ top: pageHeader.bottom
+ bottom: parent.bottom
+ left: parent.left
+ right: parent.right
+ }
+
+ clip: true
+
+ model: chatListModel
+ delegate: ChatListViewItem {
+ ownUserId: overviewPage.ownUserId
+
+ onClicked: {
+ var chat = tdLibWrapper.getChat(display.id);
+ switch(chatSelectionPage.state) {
+ case "forwardMessages":
+ chatSelectionPage.acceptDestinationProperties = { "chatInformation" : chat};
+ chatSelectionPage.acceptDestination = Qt.resolvedUrl("../pages/ChatPage.qml");
+ break;
+ }
+ chatSelectionPage.canAccept = true;
+ chatSelectionPage.accept();
+ }
+ }
+
+ ViewPlaceholder {
+ enabled: chatListView.count === 0
+ text: qsTr("You don't have any chats yet.")
+ }
+
+ VerticalScrollDecorator {}
+ }
+
+
+}
diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp
index a7ed828..28a18d9 100644
--- a/src/tdlibwrapper.cpp
+++ b/src/tdlibwrapper.cpp
@@ -433,6 +433,20 @@ void TDLibWrapper::sendPollMessage(const QString &chatId, const QString &questio
this->sendRequest(requestObject);
}
+void TDLibWrapper::forwardMessages(const QString &chatId, const QString &fromChatId, const QVariantList &messageIds, const bool sendCopy, const bool removeCaption)
+{
+ LOG("Forwarding messages" << chatId << fromChatId << messageIds);
+ QVariantMap requestObject;
+ requestObject.insert(_TYPE, "forwardMessages");
+ requestObject.insert("chat_id", chatId);
+ requestObject.insert("from_chat_id", fromChatId);
+ requestObject.insert("message_ids", messageIds);
+ requestObject.insert("send_copy", sendCopy);
+ requestObject.insert("remove_caption", removeCaption);
+
+ this->sendRequest(requestObject);
+}
+
void TDLibWrapper::getMessage(const QString &chatId, const QString &messageId)
{
LOG("Retrieving message" << chatId << messageId);
diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h
index a03e837..ce63261 100644
--- a/src/tdlibwrapper.h
+++ b/src/tdlibwrapper.h
@@ -128,6 +128,7 @@ public:
Q_INVOKABLE void sendDocumentMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
Q_INVOKABLE void sendStickerMessage(const QString &chatId, const QString &fileId, const QString &replyToMessageId = "0");
Q_INVOKABLE void sendPollMessage(const QString &chatId, const QString &question, const QVariantList &options, const bool &anonymous, const int &correctOption, const bool &multiple, const QString &replyToMessageId = "0");
+ Q_INVOKABLE void forwardMessages(const QString &chatId, const QString &fromChatId, const QVariantList &messageIds, const bool sendCopy, const bool removeCaption);
Q_INVOKABLE void getMessage(const QString &chatId, const QString &messageId);
Q_INVOKABLE void setOptionInteger(const QString &optionName, int optionValue);
Q_INVOKABLE void setChatNotificationSettings(const QString &chatId, const QVariantMap ¬ificationSettings);
diff --git a/translations/harbour-fernschreiber-de.ts b/translations/harbour-fernschreiber-de.ts
index 464503a..e171b9d 100644
--- a/translations/harbour-fernschreiber-de.ts
+++ b/translations/harbour-fernschreiber-de.ts
@@ -313,6 +313,51 @@
Sie sind dem Chat %1 beigetreten.
+
+
+ Nachrichtenauswahl
+
+
+
+
+ %n Nachrichten gelöscht
+
+
+
+
+
+
+ %n Nachrichten wurden kopiert
+
+
+
+
+
+ number of messages selected
+
+ %n Nachricht ausgewählt
+ %n Nachrichten ausgewählt
+
+
+
+
+ dialog header
+
+ %n Nachricht weiterleiten
+ %n Nachrichten weiterleiten
+
+
+
+
+ ChatSelectionPage
+
+
+ Chat auswählen
+
+
+
+ Sie haben noch keine Chats.
+
CoverPage
@@ -790,6 +835,10 @@
Weitergeleitete Nachricht
+
+
+ Nachricht auswählen
+
MessageListViewItemSimple
@@ -1052,7 +1101,7 @@
- Hintergrund für Sticker anzeigen und sie wie Bilder mittig platzieren.
+ Hintergrund für Sticker anzeigen und sie wie Bilder mittig platzieren
diff --git a/translations/harbour-fernschreiber-es.ts b/translations/harbour-fernschreiber-es.ts
index 31f588a..8e2c148 100644
--- a/translations/harbour-fernschreiber-es.ts
+++ b/translations/harbour-fernschreiber-es.ts
@@ -313,6 +313,47 @@
Te uniste a charla
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+ No hay todavía ninguna charla.
+
CoverPage
@@ -790,6 +831,10 @@
Mensaje reenviado
+
+
+
+
MessageListViewItemSimple
diff --git a/translations/harbour-fernschreiber-fi.ts b/translations/harbour-fernschreiber-fi.ts
index 8b22cc1..242b0cf 100644
--- a/translations/harbour-fernschreiber-fi.ts
+++ b/translations/harbour-fernschreiber-fi.ts
@@ -313,6 +313,51 @@
Liityit keskusteluun %1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+ Sinulla ei ole vielä keskusteluja.
+
CoverPage
@@ -791,6 +836,10 @@
Välitetty viesti
+
+
+
+
MessageListViewItemSimple
diff --git a/translations/harbour-fernschreiber-hu.ts b/translations/harbour-fernschreiber-hu.ts
index 2f53bd1..c21807c 100644
--- a/translations/harbour-fernschreiber-hu.ts
+++ b/translations/harbour-fernschreiber-hu.ts
@@ -313,6 +313,47 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+
+
CoverPage
@@ -790,6 +831,10 @@
+
+
+
+
MessageListViewItemSimple
diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts
index 3438ce5..8253169 100644
--- a/translations/harbour-fernschreiber-it.ts
+++ b/translations/harbour-fernschreiber-it.ts
@@ -313,6 +313,51 @@
Sei entrato nella chat %1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+ Non hai nessuna chat.
+
CoverPage
@@ -790,6 +835,10 @@
Messaggio inoltrato
+
+
+
+
MessageListViewItemSimple
diff --git a/translations/harbour-fernschreiber-pl.ts b/translations/harbour-fernschreiber-pl.ts
index a455839..d5f4697 100644
--- a/translations/harbour-fernschreiber-pl.ts
+++ b/translations/harbour-fernschreiber-pl.ts
@@ -313,6 +313,55 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+ Nie masz jeszcze żadnych czatów.
+
CoverPage
@@ -790,6 +839,10 @@
+
+
+
+
MessageListViewItemSimple
diff --git a/translations/harbour-fernschreiber-ru.ts b/translations/harbour-fernschreiber-ru.ts
index 1f4e1ab..9fb40ef 100644
--- a/translations/harbour-fernschreiber-ru.ts
+++ b/translations/harbour-fernschreiber-ru.ts
@@ -313,6 +313,55 @@
Вы зашли в чат «%1»
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+ Тут пока ничего нет
+
CoverPage
@@ -790,6 +839,10 @@
Пересланное сообщение
+
+
+
+
MessageListViewItemSimple
diff --git a/translations/harbour-fernschreiber-sv.ts b/translations/harbour-fernschreiber-sv.ts
index 8d1d2bc..4b704b7 100644
--- a/translations/harbour-fernschreiber-sv.ts
+++ b/translations/harbour-fernschreiber-sv.ts
@@ -313,6 +313,51 @@
Du anslöt till chatten %1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+ Du har inga chattar än.
+
CoverPage
@@ -790,6 +835,10 @@
Vidarebefordrat meddelande
+
+
+
+
MessageListViewItemSimple
diff --git a/translations/harbour-fernschreiber-zh_CN.ts b/translations/harbour-fernschreiber-zh_CN.ts
index 9885cb8..78d7364 100644
--- a/translations/harbour-fernschreiber-zh_CN.ts
+++ b/translations/harbour-fernschreiber-zh_CN.ts
@@ -313,6 +313,47 @@
你已加入对话 %1
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+ 你还没有任何对话。
+
CoverPage
@@ -790,6 +831,10 @@
转发消息
+
+
+
+
MessageListViewItemSimple
diff --git a/translations/harbour-fernschreiber.ts b/translations/harbour-fernschreiber.ts
index fc853ed..c2f3861 100644
--- a/translations/harbour-fernschreiber.ts
+++ b/translations/harbour-fernschreiber.ts
@@ -313,6 +313,51 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ number of messages selected
+
+
+
+
+
+
+
+ dialog header
+
+
+
+
+
+
+
+ ChatSelectionPage
+
+
+
+
+
+
+
+
CoverPage
@@ -790,6 +835,10 @@
+
+
+
+
MessageListViewItemSimple
@@ -892,6 +941,7 @@
+
@@ -907,6 +957,7 @@
+
@@ -955,6 +1006,7 @@
number of total votes
+
@@ -981,6 +1033,7 @@
number of total votes
+
@@ -998,6 +1051,7 @@
number of votes for option
+
@@ -1015,6 +1069,7 @@
number of votes for option
+