diff --git a/harbour-fernschreiber.pro b/harbour-fernschreiber.pro
index d0b1d97..5b9e6c7 100644
--- a/harbour-fernschreiber.pro
+++ b/harbour-fernschreiber.pro
@@ -40,6 +40,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/components/ImagePreview.qml \
qml/components/InReplyToRow.qml \
qml/components/LocationPreview.qml \
+ qml/components/PollPreview.qml \
qml/components/StickerPicker.qml \
qml/components/PhotoTextsListItem.qml \
qml/components/WebPagePreview.qml \
@@ -61,6 +62,8 @@ DISTFILES += qml/harbour-fernschreiber.qml \
qml/pages/InitializationPage.qml \
qml/pages/OverviewPage.qml \
qml/pages/AboutPage.qml \
+ qml/pages/PollCreationPage.qml \
+ qml/pages/PollResultsPage.qml \
qml/pages/SettingsPage.qml \
qml/pages/VideoPage.qml \
rpm/harbour-fernschreiber.changes.in \
diff --git a/qml/components/PollPreview.qml b/qml/components/PollPreview.qml
new file mode 100644
index 0000000..fbb3171
--- /dev/null
+++ b/qml/components/PollPreview.qml
@@ -0,0 +1,293 @@
+/*
+ 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.0
+import Sailfish.Silica 1.0
+import QtGraphicalEffects 1.0
+
+import "../js/functions.js" as Functions
+import "../js/twemoji.js" as Emoji
+
+Item {
+ id: pollMessageComponent
+
+ property string chatId
+ property var message:({})
+ property bool isOwnMessage
+
+ property string messageId: message.id
+ property bool canEdit: message.can_be_edited
+ property var pollData: message.content.poll
+ property var chosenPollData:({})
+ property var chosenIndexes: []
+ property bool hasAnswered: {
+ return pollData.options.filter(function(option){
+ return option.is_chosen
+ }).length > 0;
+ }
+ property bool canAnswer: !hasAnswered && !pollData.is_closed
+ property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz"
+ property Item messageItem
+ height: pollColumn.height
+ opacity: 0
+ Behavior on opacity { FadeAnimation {} }
+ function handleChoose(index) {
+ if(!pollData.type.allow_multiple_answers) {
+ chosenIndexes = [index];
+ sendResponse();
+ return;
+ }
+ var indexes = chosenIndexes;
+ var found = indexes.indexOf(index);
+ if(found > -1) { // uncheck
+ indexes.splice(found, 1);
+ } else {
+ indexes.push(index)
+ }
+ chosenIndexes = indexes;
+ }
+ function resetChosen() {
+ chosenIndexes = [];
+ sendResponse();
+ }
+ function sendResponse() {
+ tdLibWrapper.setPollAnswer(chatId, messageId, chosenIndexes);
+ }
+
+ Column {
+ id: pollColumn
+ width: parent.width
+ spacing: Theme.paddingSmall
+ Label {
+ font.pixelSize: Theme.fontSizeSmall
+ width: parent.width
+ visible: text !== ""
+ text: Emoji.emojify(pollData.question, Theme.fontSizeSmall)
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ color: pollMessageComponent.isOwnMessage ? Theme.highlightColor : Theme.primaryColor
+ }
+
+ Label {
+ font.pixelSize: Theme.fontSizeTiny
+ width: parent.width
+ visible: text !== ""
+ text: pollData.is_closed ? qsTr("Final Result:") : (pollData.type.allow_multiple_answers ? qsTr("Multiple Answers are allowed.") : "")
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ color: pollMessageComponent.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
+ }
+
+ Item {
+ visible: !pollMessageComponent.canAnswer
+ width: parent.width
+ height: Theme.paddingSmall
+ }
+
+ Component {
+ id: canAnswerDelegate
+ TextSwitch {
+ id: optionDelegate
+ width: pollMessageComponent.width
+ automaticCheck: false
+ // emojify does not work here :/
+ text: modelData.text
+ checked: pollMessageComponent.chosenIndexes.indexOf(index) > -1
+ onClicked: {
+ pollMessageComponent.handleChoose(index);
+ }
+ }
+ }
+ Component {
+ id: resultDelegate
+ Item {
+ id: optionDelegate
+ width: pollMessageComponent.width
+ height: displayOptionLabel.height + displayOptionStatistics.height
+
+ Rectangle {
+ id: displayOptionChosenMarker
+ height: parent.height
+ width: Theme.horizontalPageMargin/2
+ color: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
+ visible: modelData.is_chosen
+ x: -width
+ }
+ OpacityRampEffect {
+ sourceItem: displayOptionChosenMarker
+ direction: OpacityRamp.LeftToRight
+ }
+ Column {
+ id: iconsColumn
+ width: pollMessageComponent.isQuiz ?Theme.iconSizeSmall + Theme.paddingMedium : Theme.paddingMedium
+
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ }
+
+ Icon {
+ highlighted: pollMessageComponent.isOwnMessage
+ property bool isRight: pollMessageComponent.isQuiz && pollData.type.correct_option_id === index
+ source: "image://theme/icon-s-accept"
+ visible: isRight
+ }
+ }
+
+ Label {
+ id: displayOptionLabel
+ text: Emoji.emojify(modelData.text, Theme.fontSizeMedium)
+
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ anchors {
+ left: iconsColumn.right
+ top: parent.top
+ right: parent.right
+ }
+ color: pollMessageComponent.isOwnMessage ? Theme.highlightColor : Theme.primaryColor
+ }
+ Item {
+ id: displayOptionStatistics
+ height: optionVoterPercentage.height + optionVoterPercentageBar.height
+ anchors {
+ top: displayOptionLabel.bottom
+ left: iconsColumn.right
+ right: parent.right
+ }
+
+ Label {
+ id: optionVoterPercentage
+ font.pixelSize: Theme.fontSizeTiny
+ text: qsTr("%L1\%", "% of votes for option").arg(modelData.vote_percentage)
+ horizontalAlignment: Text.AlignRight
+ anchors {
+ right: parent.right
+ left: parent.horizontalCenter
+ leftMargin: Theme.paddingSmall
+ }
+ color: pollMessageComponent.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
+ }
+ Rectangle {
+ id: optionVoterPercentageBar
+ height: Theme.paddingSmall
+ width: parent.width
+
+ color: Theme.rgba(pollMessageComponent.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor, 0.3)
+ radius: height/2
+ anchors {
+ left: parent.left
+ bottom: parent.bottom
+ }
+
+ Rectangle {
+ height: parent.height
+ color: pollMessageComponent.isOwnMessage ? Theme.highlightColor : Theme.primaryColor
+ radius: height/2
+ width: parent.width * modelData.vote_percentage * 0.01
+ }
+ }
+ }
+ }
+ }
+
+ Repeater {
+ model: pollData.options
+ delegate: pollMessageComponent.canAnswer ? canAnswerDelegate : resultDelegate
+ }
+
+ Row {
+ layoutDirection: Qt.RightToLeft
+ width: parent.width
+ spacing: Theme.paddingMedium
+ Behavior on height { NumberAnimation {}}
+
+
+ Label {
+ id: totalVoterCount
+ font.pixelSize: Theme.fontSizeTiny
+ anchors.verticalCenter: parent.verticalCenter
+ text: qsTr("%L1 vote(s) total", "number of total votes", pollData.total_voter_count).arg(pollData.total_voter_count)
+ width: contentWidth
+ height: contentHeight
+ horizontalAlignment: Text.AlignRight
+ color: pollMessageComponent.isOwnMessage ? Theme.secondaryHighlightColor : Theme.secondaryColor
+ }
+
+ Row {
+ spacing: Theme.paddingSmall
+ width: parent.width - totalVoterCount.width - parent.spacing
+ IconButton {
+ visible: !pollData.is_closed && pollMessageComponent.chosenIndexes.length > 0 && pollData.type.allow_multiple_answers && !pollMessageComponent.hasAnswered
+ opacity: visible ? 1.0 : 0.0
+ Behavior on opacity { FadeAnimation {}}
+ icon.source: "image://theme/icon-m-send"
+ onClicked: {
+ pollMessageComponent.sendResponse()
+ }
+ }
+
+
+ IconButton {
+ visible: !pollMessageComponent.canAnswer && !pollData.is_anonymous && pollData.total_voter_count > 0
+ icon.source: "image://theme/icon-m-media-artists"
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("../pages/PollResultsPage.qml"), { chatId:chatId, message:pollMessageComponent.message});
+ }
+ Icon {
+ opacity: 0.8
+ source: "image://theme/icon-s-maybe"
+ anchors {
+ right: parent.right
+ top: parent.top
+ }
+ }
+ }
+ }
+ }
+
+ }
+ Component {
+ id: closePollMenuItemComponent
+ MenuItem {
+ text: qsTr("Close Poll")
+ onClicked: {
+ tdLibWrapper.stopPoll(pollMessageComponent.chatId, pollMessageComponent.messageId);
+ }
+ }
+ }
+ Component {
+ id: resetAnswerMenuItemComponent
+ MenuItem {
+ text: qsTr("Reset Answer")
+ onClicked: {
+ pollMessageComponent.resetChosen()
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ opacity = 1;
+ if(messageItem && messageItem.menu ) { // workaround to add menu entries
+ if(!pollData.is_closed && pollMessageComponent.canEdit) {
+ closePollMenuItemComponent.createObject(messageItem.menu._contentColumn);
+ }
+ if(!pollData.is_closed && !pollMessageComponent.isQuiz && pollMessageComponent.hasAnswered) {
+ resetAnswerMenuItemComponent.createObject(messageItem.menu._contentColumn);
+ }
+ }
+ }
+}
diff --git a/qml/js/functions.js b/qml/js/functions.js
index 771d836..b62ffb9 100644
--- a/qml/js/functions.js
+++ b/qml/js/functions.js
@@ -97,6 +97,18 @@ function getMessageText(message, simple, myself) {
if (message.content['@type'] === 'messageChatChangeTitle') {
return myself ? qsTr("changed the chat title to %1", "myself").arg(message.content.title) : qsTr("changed the chat title to %1").arg(message.content.title);
}
+ if (message.content['@type'] === 'messagePoll') {
+ if(message.content.poll.type['@type'] === "pollTypeQuiz") {
+ if(message.content.poll.is_anonymous) {
+ return myself ? qsTr("sent an anonymous quiz", "myself") : qsTr("sent an anonymous quiz");
+ }
+ return myself ? qsTr("sent a quiz", "myself") : qsTr("sent a quiz");
+ }
+ if(message.content.poll.is_anonymous) {
+ return myself ? qsTr("sent an anonymous poll", "myself") : qsTr("sent an anonymous poll");
+ }
+ return myself ? qsTr("sent a poll", "myself") : qsTr("sent a poll");
+ }
return qsTr("Unsupported message: %1").arg(message.content['@type'].substring(7));
}
diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml
index bc9d48b..ce8ff10 100644
--- a/qml/pages/ChatPage.qml
+++ b/qml/pages/ChatPage.qml
@@ -220,7 +220,6 @@ Page {
tdLibWrapper.openChat(chatInformation.id);
break;
case PageStatus.Active:
- console.log("CHAT opendirectly?", chatPage.isInitialized)
if (!chatPage.isInitialized) {
chatModel.initialize(chatInformation);
chatPage.isInitialized = true;
@@ -537,6 +536,7 @@ Page {
property bool containsAudio: (( display.content['@type'] === "messageVoiceNote" ) || ( display.content['@type'] === "messageAudio" ));
property bool containsDocument: ( display.content['@type'] === "messageDocument" )
property bool containsLocation: ( display.content['@type'] === "messageLocation" || ( display.content['@type'] === "messageVenue" ))
+ property bool containsPoll: display.content['@type'] === "messagePoll"
menu: ContextMenu {
MenuItem {
@@ -594,6 +594,7 @@ Page {
audioPreviewLoader.active = messageListItem.containsAudio;
documentPreviewLoader.active = messageListItem.containsDocument;
locationPreviewLoader.active = messageListItem.containsLocation;
+ pollPreviewLoader.active = messageListItem.containsPoll;
forwardedInformationLoader.active = messageListItem.isForwarded;
}
}
@@ -921,6 +922,25 @@ Page {
}
}
+ Loader {
+ id: pollPreviewLoader
+ active: false
+ asynchronous: true
+ width: parent.width
+// height: messageListItem.containsLocation ? (item ? item.height : (parent.width * 2 / 3)) : 0
+ sourceComponent: Component {
+ id: pollPreviewComponent
+ PollPreview {
+ id: messageLocationPreview
+ width: parent.width
+ chatId: chatInformation.id
+ isOwnMessage: messageListItem.isOwnMessage
+ message: display
+ messageItem: messageListItem
+ }
+ }
+ }
+
Timer {
id: messageDateUpdater
interval: 60000
@@ -1159,6 +1179,17 @@ Page {
stickerPickerLoader.active = !stickerPickerLoader.active;
}
}
+ IconButton {
+ visible: !chatPage.isPrivateChat &&
+ (chatGroupInformation.status["@type"] === "chatMemberStatusCreator"
+ || chatGroupInformation.status["@type"] === "chatMemberStatusAdministrator"
+ || (chatGroupInformation.status["@type"] === "chatMemberStatusMember" && chatInformation.permissions.can_send_polls))
+ icon.source: "image://theme/icon-m-question"
+ onClicked: {
+ pageStack.push(Qt.resolvedUrl("../pages/PollCreationPage.qml"), { "chatId" : chatInformation.id, groupName: chatInformation.title});
+ attachmentOptionsRow.visible = false;
+ }
+ }
}
Row {
diff --git a/qml/pages/ImagePage.qml b/qml/pages/ImagePage.qml
index 06edac7..5d99eb3 100644
--- a/qml/pages/ImagePage.qml
+++ b/qml/pages/ImagePage.qml
@@ -91,11 +91,9 @@ Page {
}
SilicaFlickable {
- id: imageFlickable
anchors.fill: parent
- clip: true
- contentWidth: imagePinchArea.width;
- contentHeight: imagePinchArea.height;
+ flickableDirection: Flickable.VerticalFlick
+ interactive: !imageOnly
PullDownMenu {
visible: !imageOnly && imageUrl
@@ -107,80 +105,89 @@ Page {
}
}
- transitions: Transition {
- NumberAnimation { properties: "contentX, contentY"; easing.type: Easing.Linear }
- }
-
AppNotification {
id: imageNotification
}
- MouseArea {
+ SilicaFlickable {
+ id: imageFlickable
anchors.fill: parent
- visible: singleImage.visible
- onClicked: imageOnly = !imageOnly // Toggle "Image only" mode on tap
- }
+ clip: true
+ contentWidth: imagePinchArea.width
+ contentHeight: imagePinchArea.height
+ flickableDirection: Flickable.HorizontalAndVerticalFlick
+ quickScrollEnabled: false
- PinchArea {
- id: imagePinchArea
- width: Math.max( singleImage.width * singleImage.scale, imageFlickable.width )
- height: Math.max( singleImage.height * singleImage.scale, imageFlickable.height )
+ PinchArea {
+ id: imagePinchArea
+ width: Math.max( singleImage.width * singleImage.scale, imageFlickable.width )
+ height: Math.max( singleImage.height * singleImage.scale, imageFlickable.height )
- enabled: singleImage.visible
- pinch {
- target: singleImage
- minimumScale: 1
- maximumScale: 4
- }
+ enabled: singleImage.status === Image.Ready
+ pinch {
+ target: singleImage
+ minimumScale: 1
+ maximumScale: 4
+ }
- onPinchUpdated: {
- imagePage.centerX = pinch.center.x;
- imagePage.centerY = pinch.center.y;
- }
+ onPinchUpdated: {
+ imagePage.centerX = pinch.center.x
+ imagePage.centerY = pinch.center.y
+ imageFlickable.returnToBounds()
+ }
- Image {
- id: singleImage
- source: imageUrl
- width: imagePage.imageWidth * imagePage.sizingFactor
- height: imagePage.imageHeight * imagePage.sizingFactor
- anchors.centerIn: parent
+ Image {
+ id: singleImage
+ source: imageUrl
+ width: imagePage.imageWidth * imagePage.sizingFactor
+ height: imagePage.imageHeight * imagePage.sizingFactor
+ anchors.centerIn: parent
- fillMode: Image.PreserveAspectFit
- asynchronous: true
+ fillMode: Image.PreserveAspectFit
+ asynchronous: true
- visible: status === Image.Ready ? true : false
- opacity: status === Image.Ready ? 1 : 0
- Behavior on opacity { NumberAnimation {} }
- onScaleChanged: {
- var newWidth = singleImage.width * singleImage.scale;
- var newHeight = singleImage.height * singleImage.scale;
- var oldWidth = singleImage.width * imagePage.previousScale;
- var oldHeight = singleImage.height * imagePage.previousScale;
- var widthDifference = newWidth - oldWidth;
- var heightDifference = newHeight - oldHeight;
+ visible: opacity > 0
+ opacity: status === Image.Ready ? 1 : 0
+ Behavior on opacity { FadeAnimation {} }
+ onScaleChanged: {
+ var newWidth = singleImage.width * singleImage.scale;
+ var newHeight = singleImage.height * singleImage.scale;
+ var oldWidth = singleImage.width * imagePage.previousScale;
+ var oldHeight = singleImage.height * imagePage.previousScale;
+ var widthDifference = newWidth - oldWidth;
+ var heightDifference = newHeight - oldHeight;
- if (oldWidth > imageFlickable.width || newWidth > imageFlickable.width) {
- var xRatioNew = imagePage.centerX / newWidth;
- var xRatioOld = imagePage.centerX / oldHeight;
- imageFlickable.contentX = imageFlickable.contentX + ( xRatioNew * widthDifference );
- }
- if (oldHeight > imageFlickable.height || newHeight > imageFlickable.height) {
- var yRatioNew = imagePage.centerY / newHeight;
- var yRatioOld = imagePage.centerY / oldHeight;
- imageFlickable.contentY = imageFlickable.contentY + ( yRatioNew * heightDifference );
+ if (oldWidth > imageFlickable.width || newWidth > imageFlickable.width) {
+ var xRatioNew = imagePage.centerX / newWidth;
+ var xRatioOld = imagePage.centerX / oldHeight;
+ imageFlickable.contentX = imageFlickable.contentX + ( xRatioNew * widthDifference );
+ }
+ if (oldHeight > imageFlickable.height || newHeight > imageFlickable.height) {
+ var yRatioNew = imagePage.centerY / newHeight;
+ var yRatioOld = imagePage.centerY / oldHeight;
+ imageFlickable.contentY = imageFlickable.contentY + ( yRatioNew * heightDifference );
+ }
+
+ imagePage.previousScale = singleImage.scale;
+ imagePage.oldCenterX = imagePage.centerX;
+ imagePage.oldCenterY = imagePage.centerY;
}
+ }
- imagePage.previousScale = singleImage.scale;
- imagePage.oldCenterX = imagePage.centerX;
- imagePage.oldCenterY = imagePage.centerY;
+ MouseArea {
+ anchors.fill: parent
+ visible: singleImage.visible
+
+ onClicked: imageOnly = !imageOnly // Toggle "Image only" mode on tap
+ onDoubleClicked: ; // This introduces a delay before onClicked is invoked
}
}
- }
+ ScrollDecorator { flickable: imageFlickable }
+ }
}
BackgroundImage {
visible: singleImage.status !== Image.Ready
}
-
}
diff --git a/qml/pages/OverviewPage.qml b/qml/pages/OverviewPage.qml
index f3533f5..cda297f 100644
--- a/qml/pages/OverviewPage.qml
+++ b/qml/pages/OverviewPage.qml
@@ -154,7 +154,6 @@ Page {
}
onChatReceived: {
if(chat["@extra"] === "openDirectly") {
- console.log("ON CHAT RECEIVED", JSON.stringify(chat, null, 2));
if (status !== PageStatus.Active) {
pageStack.pop(pageStack.find( function(page){ return(page._depth === 0)} ), PageStackAction.Immediate);
}
diff --git a/qml/pages/PollCreationPage.qml b/qml/pages/PollCreationPage.qml
new file mode 100644
index 0000000..3f630ac
--- /dev/null
+++ b/qml/pages/PollCreationPage.qml
@@ -0,0 +1,351 @@
+/*
+ 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 QtMultimedia 5.0
+import "../components"
+import "../js/functions.js" as Functions
+import "../js/twemoji.js" as Emoji
+
+Dialog {
+ id: pollCreationPage
+ allowedOrientations: Orientation.All
+ property string groupName
+ // poll request data start
+ property string chatId
+ property alias pollQuestion: questionTextArea.text
+ property ListModel options: ListModel {
+ ListElement {
+ text: ""
+ }
+ }
+ property alias anonymous: anonymousSwitch.checked
+ property int correctOption: -1
+ property alias quiz: quizSwitch.checked
+ property alias multiple: multipleSwitch.checked
+ property string replyToMessageId: "0"
+ // poll request data end
+
+ canAccept: validationErrors.length === 0
+ onDone: {
+ }
+ onAcceptPendingChanged: {
+ if(acceptPending) {
+
+ validate();
+
+ if(validationErrors.length > 0) {
+ validationErrorsVisible = true;
+ contentFlickable.scrollToTop();
+ }
+ }
+ }
+
+ property var validationErrorsVisible: false
+ property var validationErrors:[""]
+
+ function validate() {
+ var errors = [];
+ if(pollQuestion.length === 0) {
+ errors.push(qsTr("You have to enter a question."));
+ } else if(pollQuestion.length > 255) {
+ errors.push(qsTr("The question has to be shorter than 256 characters."));
+ }
+
+ if(options.count < 2 || options.count > 10) {
+ errors.push(qsTr("A poll requires 2-10 answers."));
+ } else {
+ for(var i = 0; i < options.count; i += 1) {
+ var len = options.get(i).text.length
+ if(len < 1 || len > 100) {
+ errors.push(qsTr("All answers have to contain 1-100 characters."));
+ break;
+ }
+ }
+ }
+ if(quiz && (correctOption < 0 || correctOption > options.count - 1)) {
+ errors.push(qsTr("To send a quiz, you have to specify the right answer."));
+ }
+ if(errors.length === 0) {
+ validationErrorsVisible = false;
+ }
+
+ validationErrors = errors;
+ }
+ function createNewOption() {
+ if(options.count < 10) {
+ pollCreationPage.options.append({text:""});
+ focusLastOptionTimer.start();
+ }
+ }
+
+ signal focusOption(int focusIndex)
+ DialogHeader {
+ id: header
+ dialog: pollCreationPage
+ title: qsTr("Create a Poll", "Dialog Header")
+ }
+ Label {
+ id: subHeaderLabel
+ anchors {
+ verticalCenter: header.bottom
+ left: parent.left
+ right: parent.right
+ leftMargin: Theme.horizontalPageMargin
+ rightMargin: Theme.horizontalPageMargin
+ }
+
+ color: Theme.secondaryHighlightColor
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ text: qsTr("in %1", "After dialog header… Create a Poll in [group name]").arg(Emoji.emojify(pollCreationPage.groupName, font.pixelSize))
+ font.pixelSize: Theme.fontSizeSmall
+ }
+
+ SilicaFlickable {
+ id: contentFlickable
+ clip: true
+ anchors {
+ top: subHeaderLabel.bottom
+ left: parent.left
+ right: parent.right
+ bottom: parent.bottom
+ }
+
+ contentHeight: contentColumn.height
+
+ Column {
+ id: contentColumn
+ width: parent.width
+ topPadding: Theme.paddingLarge
+ bottomPadding: Theme.paddingLarge
+
+ Item {
+ id: errorItem
+ width: parent.width - Theme.horizontalPageMargin * 2
+ x: Theme.horizontalPageMargin
+ property bool shown: pollCreationPage.validationErrorsVisible && pollCreationPage.validationErrors.length > 0
+ property int visibleHeight: errorContentColumn.height
+ height: pollCreationPage.validationErrorsVisible ? visibleHeight : 0
+ clip: true;
+ opacity: pollCreationPage.validationErrorsVisible ? 1.0 : 0.0
+ Behavior on opacity { FadeAnimation {} }
+ Behavior on height { NumberAnimation {duration: 200; easing.type: Easing.InOutQuad}}
+ Rectangle {
+ color: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
+ anchors.fill: parent
+ radius: Theme.paddingLarge
+ IconButton {
+ icon.source: "image://theme/icon-m-close"
+ anchors {
+ right: parent.right
+ top: parent.top
+ }
+ onClicked: {
+ pollCreationPage.validationErrorsVisible = false
+ }
+ }
+ }
+
+
+ Column {
+ id: errorContentColumn
+ width: parent.width - Theme.paddingLarge * 2 - Theme.itemSizeSmall
+ spacing: Theme.paddingMedium
+ padding: Theme.paddingLarge
+ Repeater {
+ model: pollCreationPage.validationErrors
+ delegate: Label {
+ font.pixelSize: Theme.fontSizeSmall
+ color: Theme.highlightColor
+ width: errorContentColumn.width
+ text: modelData
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ leftPadding: Theme.iconSizeSmall + Theme.paddingSmall
+ Icon {
+ highlighted: true
+ source: "image://theme/icon-s-high-importance"
+ y: Theme.paddingSmall / 2
+ }
+ }
+ }
+
+ }
+ }
+
+ TextArea {
+ id: questionTextArea
+ width: parent.width
+ placeholderText: qsTr("Enter your question here")
+ property int charactersLeft: 255 - text.length
+ color: charactersLeft < 0 ? Theme.errorColor : Theme.highlightColor
+ label: qsTr("Question (%n1 characters left)", "", charactersLeft).arg(charactersLeft)
+ wrapMode: TextEdit.Wrap
+ onFocusChanged: {
+ validate();
+ }
+ }
+ SectionHeader {
+ topPadding: 0
+ text: qsTr("Answers", "Section header")
+ }
+
+ Column {
+ id: optionsListView
+ width: parent.width - Theme.horizontalPageMargin * 2
+ x: Theme.horizontalPageMargin
+ add: Transition {
+ NumberAnimation { properties: "opacity"; from: 0; to: 1; duration: 200; easing.type: Easing.InOutCubic }
+ NumberAnimation { properties: "height"; from: 0; to: ViewTransition.item.childrenRect.height; duration: 200; easing.type: Easing.InOutCubic }
+ }
+ move: Transition {
+ NumberAnimation { properties: "y"; duration: 200; easing.type: Easing.InOutCubic }
+ }
+ Behavior on height { NumberAnimation {duration: 200; easing.type: Easing.InOutCubic}}
+ Repeater {
+ model: pollCreationPage.options
+ delegate: Row {
+ width: parent.width
+ BackgroundItem {
+ id: answerCorrectBackgroundItem
+ width: enabled ? Theme.itemSizeSmall : 0
+ contentItem.radius: height/2
+ height: Theme.itemSizeSmall
+ property bool checked: pollCreationPage.correctOption === index
+ enabled: pollCreationPage.quiz
+ opacity: enabled ? (checked ? 1.0 : 0.5) : 0.0
+ Behavior on opacity { FadeAnimation {} }
+ Behavior on width { NumberAnimation {duration: 500; easing.type: Easing.InOutQuad}}
+ Icon {
+ source: "image://theme/icon-m-accept"
+ anchors.centerIn: parent
+ }
+ onClicked: {
+ pollCreationPage.correctOption = index
+ validate();
+ }
+ }
+
+ TextField {
+ id: answerTextArea
+ textMargin: Theme.paddingSmall
+ width: answerCorrectBackgroundItem.enabled ? parent.width - Theme.itemSizeSmall * 2 : parent.width - Theme.itemSizeSmall
+ Behavior on width { NumberAnimation {duration: 500; easing.type: Easing.InOutCubic}}
+ text: model.text
+ onTextChanged: {
+ pollCreationPage.options.setProperty(index, "text", text)
+ pollCreationPage.validate()
+ }
+ placeholderText: qsTr("Enter an answer here")
+ property int charactersLeft: 100 - text.length
+ color: charactersLeft < 0 ? Theme.errorColor : Theme.highlightColor
+ label: qsTr("Answer (%n1 characters left)", "", charactersLeft).arg(charactersLeft)
+ property bool hasNextOption: index < pollCreationPage.options.count - 1
+ EnterKey.onClicked: {
+ if(hasNextOption) {
+ pollCreationPage.focusOption(index + 1);
+ } else if(pollCreationPage.options.count < 10) {
+ pollCreationPage.createNewOption();
+ } else {
+ focus = false;
+ }
+ }
+ EnterKey.iconSource: hasNextOption ? "image://theme/icon-m-enter-next" : (pollCreationPage.options.count < 10 ? "image://theme/icon-m-add" : "image://theme/icon-m-enter-close")
+
+ onFocusChanged: {
+ validate();
+ }
+ }
+ Connections {
+ target: pollCreationPage
+ onFocusOption: {
+ if(focusIndex === index) answerTextArea.forceActiveFocus()
+ }
+ }
+
+ IconButton {
+ icon.source: "image://theme/icon-m-remove"
+ onClicked: {
+ pollCreationPage.options.remove(index)
+
+ validate();
+ }
+ }
+ }
+ }
+ }
+ ButtonLayout {
+ Button {
+ enabled: pollCreationPage.options.count < 10
+ text: qsTr("Add an answer")
+ onClicked: {
+ pollCreationPage.createNewOption();
+ validate();
+ }
+ }
+ }
+ Timer {
+ id: focusLastOptionTimer
+ interval: 20
+ onTriggered: {
+ pollCreationPage.focusOption(pollCreationPage.options.count - 1);
+ }
+ }
+
+ SectionHeader {
+ text: qsTr("Poll Options", "Section header")
+ }
+ TextSwitch {
+ id: anonymousSwitch
+ text: qsTr("Anonymous answers")
+ }
+ TextSwitch {
+ id: multipleSwitch
+ text: qsTr("Multiple answers allowed")
+ onCheckedChanged: {
+ if(checked) {
+ quizSwitch.checked = false
+ }
+ }
+ }
+ TextSwitch {
+ id: quizSwitch
+ text: qsTr("Quiz Mode")
+ onCheckedChanged: {
+ if(checked) {
+ multipleSwitch.checked = false
+ }
+ validate();
+ }
+ description: qsTr("Quizzes have one correct answer. Participants can't revoke their responses.")
+ }
+ }
+ }
+
+ onAccepted: {
+ var optionsArr = [];
+ for(var i = 0; i < options.count; i += 1) {
+ optionsArr.push(options.get(i).text);
+ }
+
+ tdLibWrapper.sendPollMessage(chatId, pollQuestion, optionsArr, anonymous, quiz ? correctOption : -1, multiple, "0");
+
+ }
+
+
+}
diff --git a/qml/pages/PollResultsPage.qml b/qml/pages/PollResultsPage.qml
new file mode 100644
index 0000000..764754c
--- /dev/null
+++ b/qml/pages/PollResultsPage.qml
@@ -0,0 +1,328 @@
+/*
+ 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 QtMultimedia 5.0
+import "../components"
+import "../js/functions.js" as Functions
+import "../js/twemoji.js" as Emoji
+
+Page {
+ id: pollResultsPage
+ allowedOrientations: Orientation.All
+ property string chatId;
+ property var message: ({});
+
+ property string messageId: message.id;
+
+ property var pollData: message.content.poll
+
+ property var userInformation: tdLibWrapper.getUserInformation(message.sender_user_id)
+
+ property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz"
+
+ property bool hasAnswered: {
+ return pollData.options.filter(function(option){
+ return option.is_chosen
+ }).length > 0;
+ }
+
+ property bool canAnswer: !hasAnswered && !pollData.is_closed
+ onCanAnswerChanged: {
+ if(canAnswer) { // vote removed from another client?
+ pageStack.pop()
+ }
+ }
+
+ SilicaFlickable {
+ anchors.fill: parent
+ contentHeight: pageHeader.height + contentColumn.height
+
+ PageHeader {
+ id: pageHeader
+ title: pollResultsPage.isQuiz ? qsTr("Quiz Results") : qsTr("Poll Results")
+ description: qsTr("%L1 vote(s) total", "number of total votes", pollData.total_voter_count).arg(pollData.total_voter_count)
+ leftMargin: headerPictureThumbnail.width + Theme.paddingLarge + Theme.horizontalPageMargin
+ ProfileThumbnail {
+ id: headerPictureThumbnail
+ photoData: (typeof pollResultsPage.userInformation.profile_photo !== "undefined") ? pollResultsPage.userInformation.profile_photo.small : ""
+ replacementStringHint: Emoji.emojify(Functions.getUserName(pollResultsPage.userInformation), font.pixelSize)
+ width: visible ? Theme.itemSizeSmall : 0
+ height: visible ? Theme.itemSizeSmall : 0
+ anchors {
+ verticalCenter: pageHeader.verticalCenter
+ left: parent.left
+ leftMargin: Theme.horizontalPageMargin
+ }
+ }
+ }
+ Column {
+ id: contentColumn
+ anchors {
+ left: parent.left
+ leftMargin: Theme.horizontalPageMargin
+ right: parent.right
+ rightMargin: Theme.horizontalPageMargin
+ top: pageHeader.bottom
+ }
+ SectionHeader {
+ x: 0
+ text: qsTr("Question", "section header")
+ }
+// Label {
+// width: parent.width
+// font.pixelSize: Theme.fontSizeTiny
+// wrapMode: Text.Wrap
+// color: Theme.secondaryHighlightColor
+// text: JSON.stringify(pollData, null, 2)
+// }
+// Label {
+// width: parent.width
+// font.pixelSize: Theme.fontSizeTiny
+// wrapMode: Text.Wrap
+// color: Theme.secondaryHighlightColor
+// text: JSON.stringify(userInformation, null, 2)
+// }
+ Label {
+ width: parent.width
+ wrapMode: Text.Wrap
+ color: Theme.secondaryHighlightColor
+ text: Emoji.emojify(pollData.question, font.pixelSize)
+ }
+
+ Column {
+ id: resultsColumn
+ width: parent.width
+ topPadding: Theme.paddingLarge
+ bottomPadding: Theme.paddingLarge
+
+ SectionHeader {
+ x: 0
+ text: qsTr("Results", "section header")
+ }
+ Repeater {
+ model: pollData.options
+ delegate: Item {
+ id: optionDelegate
+ width: resultsColumn.width
+ height: displayOptionLabel.height + displayOptionStatistics.height + displayOptionUsers.height + Theme.paddingLarge
+ property ListModel users: ListModel {}
+ property string usersResponseIdentifierString: "pollResults."+pollResultsPage.chatId+"."+pollResultsPage.messageId+"."+index
+ function loadUsers() {
+ if(users.count < modelData.voter_count) {
+ tdLibWrapper.getPollVoters(pollResultsPage.chatId, pollResultsPage.messageId, index, 50, users.length, usersResponseIdentifierString)
+ }
+ }
+ Component.onCompleted: {
+// loadUsers()
+ loadUsersTimer.start()
+ }
+ Timer {
+ id: loadUsersTimer
+ interval: index * 80
+ onTriggered: {
+ optionDelegate.loadUsers();
+ }
+ }
+
+ Connections {
+ target: tdLibWrapper
+ onUsersReceived: {
+ if(extra === optionDelegate.usersResponseIdentifierString) {
+ for(var i = 0; i < userIds.length; i += 1) {
+ optionDelegate.users.append({id: userIds[i], user:tdLibWrapper.getUserInformation(userIds[i])});
+ console.log("APPEND USER", JSON.stringify({id: userIds[i], user:tdLibWrapper.getUserInformation(userIds[i])}));
+ }
+ loadUsersTimer.start();
+ }
+ }
+ }
+ Rectangle {
+ id: displayOptionChosenMarker
+ height: parent.height
+ width: Theme.horizontalPageMargin/2
+ color: Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
+ visible: modelData.is_chosen
+ x: -width
+ }
+ OpacityRampEffect {
+ sourceItem: displayOptionChosenMarker
+ direction: OpacityRamp.LeftToRight
+ }
+ Column {
+ id: iconsColumn
+ width: pollResultsPage.isQuiz ?Theme.iconSizeSmall + Theme.paddingMedium : Theme.paddingMedium
+ height: displayOptionLabel.height + displayOptionStatistics.height
+ anchors {
+ left: parent.left
+// verticalCenter: parent.verticalCenter
+ }
+
+ Icon {
+ highlighted: true
+ property bool isRight: pollResultsPage.isQuiz && pollData.type.correct_option_id === index
+ source: "image://theme/icon-s-accept"
+ visible: isRight
+ anchors.verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Label {
+ id: displayOptionLabel
+ text: Emoji.emojify(modelData.text, Theme.fontSizeMedium)
+ wrapMode: Text.WrapAtWordBoundaryOrAnywhere
+ anchors {
+ left: iconsColumn.right
+ top: parent.top
+ right: parent.right
+ }
+ color: Theme.highlightColor
+ }
+ Item {
+ id: displayOptionStatistics
+ height: optionVoterPercentage.height + optionVoterPercentageBar.height
+ anchors {
+ top: displayOptionLabel.bottom
+ left: iconsColumn.right
+ right: parent.right
+ }
+
+ Label {
+ id: optionVoterCount
+ font.pixelSize: Theme.fontSizeTiny
+ text: modelData.is_chosen ? qsTr("%L1 vote(s) including yours", "number of votes for option", modelData.voter_count).arg(modelData.voter_count) : qsTr("%L1 vote(s)", "number of votes for option", modelData.voter_count).arg(modelData.voter_count)
+ anchors {
+ left: parent.left
+ right: parent.horizontalCenter
+ rightMargin: Theme.paddingSmall
+ }
+ color: Theme.secondaryHighlightColor
+ }
+ Label {
+ id: optionVoterPercentage
+ font.pixelSize: Theme.fontSizeTiny
+ text: qsTr("%L1\%", "% of votes for option").arg(modelData.vote_percentage)
+ horizontalAlignment: Text.AlignRight
+ anchors {
+ right: parent.right
+ left: parent.horizontalCenter
+ leftMargin: Theme.paddingSmall
+ }
+ color: Theme.secondaryHighlightColor
+ }
+ Rectangle {
+ id: optionVoterPercentageBar
+ height: Theme.paddingSmall
+ width: parent.width
+
+ color: Theme.rgba(Theme.secondaryHighlightColor, 0.3)
+ radius: height/2
+ anchors {
+ left: parent.left
+ bottom: parent.bottom
+ }
+
+ Rectangle {
+ height: parent.height
+ color: Theme.highlightColor
+ radius: height/2
+ width: parent.width * modelData.vote_percentage * 0.01
+ }
+ }
+ }
+
+
+ // users voted for this:
+ Flow {
+ id: displayOptionUsers
+ anchors.top: displayOptionStatistics.bottom
+ width: parent.width
+ visible: optionDelegate.users.count > 0
+ topPadding: Theme.paddingLarge
+ spacing: Theme.paddingMedium
+ leftPadding: iconsColumn.width
+ property int itemHeight: Theme.itemSizeExtraSmall / 2
+ Item {
+ height: displayOptionUsers.itemHeight
+ width: chosenByUserText.width
+ Label {
+ id: chosenByUserText
+ font.pixelSize: Theme.fontSizeTiny
+ text: qsTr("Chosen by:", "This answer has been chosen by the following users")
+ width: contentWidth
+ anchors.centerIn: parent
+ color: Theme.secondaryHighlightColor
+ }
+ }
+ Repeater {
+ model: optionDelegate.users
+ delegate:
+ Item {
+ id: chosenByUserItem
+ width: chosenByUserPictureThumbnail.width + chosenByUserLabel.width + Theme.paddingSmall
+ height: displayOptionUsers.itemHeight
+
+ ProfileThumbnail {
+ id: chosenByUserPictureThumbnail
+ photoData: (typeof model.user.profile_photo !== "undefined") ? model.user.profile_photo.small : ""
+ replacementStringHint: chosenByUserLabel.text
+ width: visible ? parent.height : 0
+ height: width
+ anchors {
+ left: parent.left
+ verticalCenter: parent.verticalCenter
+ }
+ }
+
+ Label {
+ id: chosenByUserLabel
+ font.pixelSize: Theme.fontSizeSmall
+ text: Emoji.emojify(Functions.getUserName(model.user), font.pixelSize)
+ width: contentWidth
+ height: contentHeight
+ color: Theme.highlightColor
+ anchors {
+ right: parent.right
+ verticalCenter: parent.verticalCenter
+ }
+ }
+ }
+
+
+ }
+ }
+
+ }
+ }
+
+ }
+
+ }
+ }
+
+ Connections {
+ target: tdLibWrapper
+ onMessageContentUpdated: {
+ if(chatId === pollResultsPage.chatId && messageId === pollResultsPage.messageId) {
+ pollResultsPage.pollData = newContent.poll;
+ }
+ }
+ }
+
+}
diff --git a/src/fernschreiberutils.cpp b/src/fernschreiberutils.cpp
index b52122e..99c05e6 100644
--- a/src/fernschreiberutils.cpp
+++ b/src/fernschreiberutils.cpp
@@ -54,5 +54,11 @@ QString FernschreiberUtils::getMessageShortText(const QVariantMap &messageConten
if (contentType == "messageChatChangeTitle") {
return myself ? tr("changed the chat title", "myself") : tr("changed the chat title");
}
+ if (contentType == "messagePoll") {
+ if(messageContent.value("poll").toMap().value("type").toMap().value("@type").toString() == "pollTypeQuiz") {
+ return myself ? tr("sent a quiz", "myself") : tr("sent a quiz");
+ }
+ return myself ? tr("sent a poll", "myself") : tr("sent a poll");
+ }
return tr("Unsupported message: %1").arg(contentType.mid(7));
}
diff --git a/src/tdlibreceiver.cpp b/src/tdlibreceiver.cpp
index cb80fe1..383108a 100644
--- a/src/tdlibreceiver.cpp
+++ b/src/tdlibreceiver.cpp
@@ -116,9 +116,10 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
handlers.insert("userProfilePhotos", &TDLibReceiver::processUserProfilePhotos);
handlers.insert("updateChatPermissions", &TDLibReceiver::processUpdateChatPermissions);
handlers.insert("updateChatTitle", &TDLibReceiver::processUpdateChatTitle);
+ handlers.insert("users", &TDLibReceiver::processUsers);
}
-void TDLibReceiver::setActive(const bool &active)
+void TDLibReceiver::setActive(bool active)
{
if (active) {
LOG("Activating receiver loop...");
@@ -494,3 +495,9 @@ void TDLibReceiver::processUpdateChatTitle(const QVariantMap &receivedInformatio
LOG("Received UpdateChatTitle");
emit chatTitleUpdated(receivedInformation.value("chat_id").toString(), receivedInformation.value("title").toString());
}
+
+void TDLibReceiver::processUsers(const QVariantMap &receivedInformation)
+{
+ LOG("Received Users");
+ emit usersReceived(receivedInformation.value(EXTRA).toString(), receivedInformation.value("user_ids").toList(), receivedInformation.value("total_count").toInt());
+}
diff --git a/src/tdlibreceiver.h b/src/tdlibreceiver.h
index a8eb27a..36f4fc5 100644
--- a/src/tdlibreceiver.h
+++ b/src/tdlibreceiver.h
@@ -33,7 +33,7 @@ class TDLibReceiver : public QThread
}
public:
explicit TDLibReceiver(void *tdLibClient, QObject *parent = nullptr);
- void setActive(const bool &active);
+ void setActive(bool active);
signals:
void versionDetected(const QString &version);
@@ -48,12 +48,12 @@ signals:
void unreadChatCountUpdated(const QVariantMap &chatCountInformation);
void chatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage);
void chatOrderUpdated(const QString &chatId, const QString &order);
- void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, const int &unreadCount);
+ void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount);
void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId);
void basicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
void superGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
- void chatOnlineMemberCountUpdated(const QString &chatId, const int &onlineMemberCount);
- void messagesReceived(const QVariantList &messages, const int &totalCount);
+ void chatOnlineMemberCountUpdated(const QString &chatId, int onlineMemberCount);
+ void messagesReceived(const QVariantList &messages, int totalCount);
void newMessageReceived(const QString &chatId, const QVariantMap &message);
void messageInformation(const QString &messageId, const QVariantMap &message);
void messageSendSucceeded(const QString &messageId, const QString &oldMessageId, const QVariantMap &message);
@@ -70,16 +70,17 @@ signals:
void installedStickerSetsUpdated(const QVariantList &stickerSetIds);
void stickerSets(const QVariantList &stickerSets);
void stickerSet(const QVariantMap &stickerSet);
- void chatMembers(const QString &extra, const QVariantList &members, const int &totalMembers);
+ void chatMembers(const QString &extra, const QVariantList &members, int totalMembers);
void userFullInfo(const QVariantMap &userFullInfo);
void userFullInfoUpdated(const QString &userId,const QVariantMap &userFullInfo);
void basicGroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo);
void basicGroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo);
void supergroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo);
void supergroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo);
- void userProfilePhotos(const QString &extra, const QVariantList &photos, const int &totalPhotos);
+ void userProfilePhotos(const QString &extra, const QVariantList &photos, int totalPhotos);
void chatPermissionsUpdated(const QString &chatId, const QVariantMap &chatPermissions);
void chatTitleUpdated(const QString &chatId, const QString &title);
+ void usersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
private:
typedef void (TDLibReceiver::*Handler)(const QVariantMap &);
@@ -134,6 +135,7 @@ private:
void processUserProfilePhotos(const QVariantMap &receivedInformation);
void processUpdateChatPermissions(const QVariantMap &receivedInformation);
void processUpdateChatTitle(const QVariantMap &receivedInformation);
+ void processUsers(const QVariantMap &receivedInformation);
};
#endif // TDLIBRECEIVER_H
diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp
index c1d6ffc..6ecdb62 100644
--- a/src/tdlibwrapper.cpp
+++ b/src/tdlibwrapper.cpp
@@ -70,42 +70,41 @@ TDLibWrapper::TDLibWrapper(QObject *parent) : QObject(parent)
connect(this->tdLibReceiver, SIGNAL(newChatDiscovered(QVariantMap)), this, SLOT(handleNewChatDiscovered(QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(unreadMessageCountUpdated(QVariantMap)), this, SLOT(handleUnreadMessageCountUpdated(QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(unreadChatCountUpdated(QVariantMap)), this, SLOT(handleUnreadChatCountUpdated(QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(chatLastMessageUpdated(QString, QString, QVariantMap)), this, SLOT(handleChatLastMessageUpdated(QString, QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(chatOrderUpdated(QString, QString)), this, SLOT(handleChatOrderUpdated(QString, QString)));
- connect(this->tdLibReceiver, SIGNAL(chatReadInboxUpdated(QString, QString, int)), this, SLOT(handleChatReadInboxUpdated(QString, QString, int)));
- connect(this->tdLibReceiver, SIGNAL(chatReadOutboxUpdated(QString, QString)), this, SLOT(handleChatReadOutboxUpdated(QString, QString)));
+ connect(this->tdLibReceiver, SIGNAL(chatLastMessageUpdated(QString, QString, QVariantMap)), this, SIGNAL(chatLastMessageUpdated(QString, QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(chatOrderUpdated(QString, QString)), this, SIGNAL(chatOrderUpdated(QString, QString)));
+ connect(this->tdLibReceiver, SIGNAL(chatReadInboxUpdated(QString, QString, int)), this, SIGNAL(chatReadInboxUpdated(QString, QString, int)));
+ connect(this->tdLibReceiver, SIGNAL(chatReadOutboxUpdated(QString, QString)), this, SIGNAL(chatReadOutboxUpdated(QString, QString)));
connect(this->tdLibReceiver, SIGNAL(basicGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleBasicGroupUpdated(qlonglong, QVariantMap)));
connect(this->tdLibReceiver, SIGNAL(superGroupUpdated(qlonglong, QVariantMap)), this, SLOT(handleSuperGroupUpdated(qlonglong, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(chatOnlineMemberCountUpdated(QString, int)), this, SLOT(handleChatOnlineMemberCountUpdated(QString, int)));
- connect(this->tdLibReceiver, SIGNAL(messagesReceived(QVariantList, int)), this, SLOT(handleMessagesReceived(QVariantList, int)));
- connect(this->tdLibReceiver, SIGNAL(newMessageReceived(QString, QVariantMap)), this, SLOT(handleNewMessageReceived(QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(messageInformation(QString, QVariantMap)), this, SLOT(handleMessageInformation(QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(messageSendSucceeded(QString, QString, QVariantMap)), this, SLOT(handleMessageSendSucceeded(QString, QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(activeNotificationsUpdated(QVariantList)), this, SLOT(handleUpdateActiveNotifications(QVariantList)));
- connect(this->tdLibReceiver, SIGNAL(notificationGroupUpdated(QVariantMap)), this, SLOT(handleUpdateNotificationGroup(QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(notificationUpdated(QVariantMap)), this, SLOT(handleUpdateNotification(QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(chatNotificationSettingsUpdated(QString, QVariantMap)), this, SLOT(handleChatNotificationSettingsUpdated(QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(messageContentUpdated(QString, QString, QVariantMap)), this, SLOT(handleMessageContentUpdated(QString, QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(messagesDeleted(QString, QVariantList)), this, SLOT(handleMessagesDeleted(QString, QVariantList)));
- connect(this->tdLibReceiver, SIGNAL(chats(QVariantMap)), this, SLOT(handleChats(QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(chat(QVariantMap)), this, SLOT(handleChat(QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(recentStickersUpdated(QVariantList)), this, SLOT(handleRecentStickersUpdated(QVariantList)));
- connect(this->tdLibReceiver, SIGNAL(stickers(QVariantList)), this, SLOT(handleStickers(QVariantList)));
- connect(this->tdLibReceiver, SIGNAL(installedStickerSetsUpdated(QVariantList)), this, SLOT(handleInstalledStickerSetsUpdated(QVariantList)));
+ connect(this->tdLibReceiver, SIGNAL(chatOnlineMemberCountUpdated(QString, int)), this, SIGNAL(chatOnlineMemberCountUpdated(QString, int)));
+ connect(this->tdLibReceiver, SIGNAL(messagesReceived(QVariantList, int)), this, SIGNAL(messagesReceived(QVariantList, int)));
+ connect(this->tdLibReceiver, SIGNAL(newMessageReceived(QString, QVariantMap)), this, SIGNAL(newMessageReceived(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(messageInformation(QString, QVariantMap)), this, SIGNAL(receivedMessage(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(messageSendSucceeded(QString, QString, QVariantMap)), this, SIGNAL(messageSendSucceeded(QString, QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(activeNotificationsUpdated(QVariantList)), this, SIGNAL(activeNotificationsUpdated(QVariantList)));
+ connect(this->tdLibReceiver, SIGNAL(notificationGroupUpdated(QVariantMap)), this, SIGNAL(notificationGroupUpdated(QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(notificationUpdated(QVariantMap)), this, SIGNAL(notificationUpdated(QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(chatNotificationSettingsUpdated(QString, QVariantMap)), this, SIGNAL(chatNotificationSettingsUpdated(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(messageContentUpdated(QString, QString, QVariantMap)), this, SIGNAL(messageContentUpdated(QString, QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(messagesDeleted(QString, QVariantList)), this, SIGNAL(messagesDeleted(QString, QVariantList)));
+ connect(this->tdLibReceiver, SIGNAL(chats(QVariantMap)), this, SIGNAL(chatsReceived(QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(chat(QVariantMap)), this, SIGNAL(chatReceived(QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(recentStickersUpdated(QVariantList)), this, SIGNAL(recentStickersUpdated(QVariantList)));
+ connect(this->tdLibReceiver, SIGNAL(stickers(QVariantList)), this, SIGNAL(stickersReceived(QVariantList)));
+ connect(this->tdLibReceiver, SIGNAL(installedStickerSetsUpdated(QVariantList)), this, SIGNAL(installedStickerSetsUpdated(QVariantList)));
connect(this->tdLibReceiver, SIGNAL(stickerSets(QVariantList)), this, SLOT(handleStickerSets(QVariantList)));
- connect(this->tdLibReceiver, SIGNAL(stickerSet(QVariantMap)), this, SLOT(handleStickerSet(QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(chatMembers(QString, QVariantList, int)), this, SLOT(handleChatMembers(QString, QVariantList, int)));
- connect(this->tdLibReceiver, SIGNAL(userFullInfo(QVariantMap)), this, SLOT(handleUserFullInfo(QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(userFullInfoUpdated(QString, QVariantMap)), this, SLOT(handleUserFullInfoUpdated(QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(basicGroupFullInfo(QString, QVariantMap)), this, SLOT(handleBasicGroupFullInfo(QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(basicGroupFullInfoUpdated(QString, QVariantMap)), this, SLOT(handleBasicGroupFullInfoUpdated(QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(supergroupFullInfo(QString, QVariantMap)), this, SLOT(handleSupergroupFullInfo(QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(supergroupFullInfoUpdated(QString, QVariantMap)), this, SLOT(handleSupergroupFullInfoUpdated(QString, QVariantMap)));
- connect(this->tdLibReceiver, SIGNAL(userProfilePhotos(QString, QVariantList, int)), this, SLOT(handleUserProfilePhotos(QString, QVariantList, int)));
- connect(this->tdLibReceiver, SIGNAL(userProfilePhotos(QString, QVariantList, int)), this, SLOT(handleUserProfilePhotos(QString, QVariantList, int)));
- connect(this->tdLibReceiver, SIGNAL(chatPermissionsUpdated(QString, QVariantMap)), this, SLOT(handleChatPermissionsUpdated(QString, QVariantMap)));
-
- connect(this->tdLibReceiver, SIGNAL(chatTitleUpdated(QString, QString)), this, SLOT(handleChatTitleUpdated(QString, QString)));
+ connect(this->tdLibReceiver, SIGNAL(stickerSet(QVariantMap)), this, SIGNAL(stickerSetReceived(QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(chatMembers(QString, QVariantList, int)), this, SIGNAL(chatMembersReceived(QString, QVariantList, int)));
+ connect(this->tdLibReceiver, SIGNAL(userFullInfo(QVariantMap)), this, SIGNAL(userFullInfoReceived(QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(userFullInfoUpdated(QString, QVariantMap)), this, SIGNAL(userFullInfoUpdated(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(basicGroupFullInfo(QString, QVariantMap)), this, SIGNAL(basicGroupFullInfoReceived(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(basicGroupFullInfoUpdated(QString, QVariantMap)), this, SIGNAL(basicGroupFullInfoUpdated(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(supergroupFullInfo(QString, QVariantMap)), this, SIGNAL(supergroupFullInfoReceived(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(supergroupFullInfoUpdated(QString, QVariantMap)), this, SIGNAL(supergroupFullInfoUpdated(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(userProfilePhotos(QString, QVariantList, int)), this, SIGNAL(userProfilePhotosReceived(QString, QVariantList, int)));
+ connect(this->tdLibReceiver, SIGNAL(chatPermissionsUpdated(QString, QVariantMap)), this, SIGNAL(chatPermissionsUpdated(QString, QVariantMap)));
+ connect(this->tdLibReceiver, SIGNAL(chatTitleUpdated(QString, QString)), this, SIGNAL(chatTitleUpdated(QString, QString)));
+ connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
connect(&emojiSearchWorker, SIGNAL(searchCompleted(QString, QVariantList)), this, SLOT(handleEmojiSearchCompleted(QString, QVariantList)));
@@ -245,7 +244,7 @@ void TDLibWrapper::leaveChat(const QString &chatId)
this->sendRequest(requestObject);
}
-void TDLibWrapper::getChatHistory(const QString &chatId, const qlonglong &fromMessageId, const int &offset, const int &limit, const bool &onlyLocal)
+void TDLibWrapper::getChatHistory(const QString &chatId, const qlonglong &fromMessageId, int offset, int limit, bool onlyLocal)
{
LOG("Retrieving chat history" << chatId << fromMessageId << offset << limit << onlyLocal);
QVariantMap requestObject;
@@ -258,7 +257,7 @@ void TDLibWrapper::getChatHistory(const QString &chatId, const qlonglong &fromMe
this->sendRequest(requestObject);
}
-void TDLibWrapper::viewMessage(const QString &chatId, const QString &messageId, const bool &force = false)
+void TDLibWrapper::viewMessage(const QString &chatId, const QString &messageId, bool force)
{
LOG("Mark message as viewed" << chatId << messageId);
QVariantMap requestObject;
@@ -384,6 +383,36 @@ void TDLibWrapper::sendStickerMessage(const QString &chatId, const QString &file
this->sendRequest(requestObject);
}
+void TDLibWrapper::sendPollMessage(const QString &chatId, const QString &question, const QVariantList &options, const bool &anonymous, const int &correctOption, const bool &multiple, const QString &replyToMessageId)
+{
+ LOG("Sending poll message" << chatId << question << replyToMessageId);
+ QVariantMap requestObject;
+ requestObject.insert(_TYPE, "sendMessage");
+ requestObject.insert("chat_id", chatId);
+ if (replyToMessageId != "0") {
+ requestObject.insert("reply_to_message_id", replyToMessageId);
+ }
+ QVariantMap inputMessageContent;
+ inputMessageContent.insert(_TYPE, "inputMessagePoll");
+
+ QVariantMap pollType;
+ if(correctOption > -1) {
+ pollType.insert(_TYPE, "pollTypeQuiz");
+ pollType.insert("correct_option_id", correctOption);
+ } else {
+ pollType.insert(_TYPE, "pollTypeRegular");
+ pollType.insert("allow_multiple_answers", multiple);
+ }
+
+ inputMessageContent.insert("type", pollType);
+ inputMessageContent.insert("question", question);
+ inputMessageContent.insert("options", options);
+ inputMessageContent.insert("is_anonymous", anonymous);
+
+ requestObject.insert("input_message_content", inputMessageContent);
+ this->sendRequest(requestObject);
+}
+
void TDLibWrapper::getMessage(const QString &chatId, const QString &messageId)
{
LOG("Retrieving message" << chatId << messageId);
@@ -394,7 +423,7 @@ void TDLibWrapper::getMessage(const QString &chatId, const QString &messageId)
this->sendRequest(requestObject);
}
-void TDLibWrapper::setOptionInteger(const QString &optionName, const int &optionValue)
+void TDLibWrapper::setOptionInteger(const QString &optionName, int optionValue)
{
LOG("Setting integer option" << optionName << optionValue);
QVariantMap requestObject;
@@ -444,7 +473,7 @@ void TDLibWrapper::deleteMessages(const QString &chatId, const QVariantList mess
this->sendRequest(requestObject);
}
-void TDLibWrapper::getMapThumbnailFile(const QString &chatId, const double &latitude, const double &longitude, const int &width, const int &height)
+void TDLibWrapper::getMapThumbnailFile(const QString &chatId, double latitude, double longitude, int width, int height)
{
LOG("Getting Map Thumbnail File" << chatId);
QVariantMap location;
@@ -491,7 +520,7 @@ void TDLibWrapper::getStickerSet(const QString &setId)
requestObject.insert("set_id", setId);
this->sendRequest(requestObject);
}
-void TDLibWrapper::getSupergroupMembers(const QString &groupId, const int &limit = 200, const int &offset = 0)
+void TDLibWrapper::getSupergroupMembers(const QString &groupId, int limit, int offset)
{
LOG("Retrieving SupergroupMembers");
QVariantMap requestObject;
@@ -503,7 +532,7 @@ void TDLibWrapper::getSupergroupMembers(const QString &groupId, const int &limit
this->sendRequest(requestObject);
}
-void TDLibWrapper::getGroupFullInfo(const QString &groupId, const bool &isSuperGroup)
+void TDLibWrapper::getGroupFullInfo(const QString &groupId, bool isSuperGroup)
{
LOG("Retrieving GroupFullInfo");
QVariantMap requestObject;
@@ -538,7 +567,7 @@ void TDLibWrapper::createPrivateChat(const QString &userId)
this->sendRequest(requestObject);
}
-void TDLibWrapper::getGroupsInCommon(const QString &userId, const int &limit, const int &offset)
+void TDLibWrapper::getGroupsInCommon(const QString &userId, int limit, int offset)
{
LOG("Retrieving Groups in Common");
QVariantMap requestObject;
@@ -550,7 +579,7 @@ void TDLibWrapper::getGroupsInCommon(const QString &userId, const int &limit, co
this->sendRequest(requestObject);
}
-void TDLibWrapper::getUserProfilePhotos(const QString &userId, const int &limit, const int &offset)
+void TDLibWrapper::getUserProfilePhotos(const QString &userId, int limit, int offset)
{
LOG("Retrieving User Profile Photos");
QVariantMap requestObject;
@@ -573,7 +602,7 @@ void TDLibWrapper::setChatPermissions(const QString &chatId, const QVariantMap &
this->sendRequest(requestObject);
}
-void TDLibWrapper::setChatSlowModeDelay(const QString &chatId, const int &delay)
+void TDLibWrapper::setChatSlowModeDelay(const QString &chatId, int delay)
{
LOG("Setting Chat Slow Mode Delay");
@@ -613,7 +642,7 @@ void TDLibWrapper::setBio(const QString &bio)
this->sendRequest(requestObject);
}
-void TDLibWrapper::toggleSupergroupIsAllHistoryAvailable(const QString &groupId, const bool &isAllHistoryAvailable)
+void TDLibWrapper::toggleSupergroupIsAllHistoryAvailable(const QString &groupId, bool isAllHistoryAvailable)
{
LOG("Toggling SupergroupIsAllHistoryAvailable");
QVariantMap requestObject;
@@ -623,6 +652,41 @@ void TDLibWrapper::toggleSupergroupIsAllHistoryAvailable(const QString &groupId,
this->sendRequest(requestObject);
}
+void TDLibWrapper::setPollAnswer(const QString &chatId, const qlonglong &messageId, QVariantList optionIds)
+{
+ LOG("Setting Poll Answer");
+ QVariantMap requestObject;
+ requestObject.insert(_TYPE, "setPollAnswer");
+ requestObject.insert("chat_id", chatId);
+ requestObject.insert("message_id", messageId);
+ requestObject.insert("option_ids", optionIds);
+ this->sendRequest(requestObject);
+}
+
+void TDLibWrapper::stopPoll(const QString &chatId, const qlonglong &messageId)
+{
+ LOG("Stopping Poll");
+ QVariantMap requestObject;
+ requestObject.insert(_TYPE, "stopPoll");
+ requestObject.insert("chat_id", chatId);
+ requestObject.insert("message_id", messageId);
+ this->sendRequest(requestObject);
+}
+
+void TDLibWrapper::getPollVoters(const QString &chatId, const qlonglong &messageId, const int &optionId, const int &limit, const int &offset, const QString &extra)
+{
+ LOG("Retrieving Poll Voters");
+ QVariantMap requestObject;
+ requestObject.insert(_TYPE, "getPollVoters");
+ requestObject.insert(_EXTRA, extra);
+ requestObject.insert("chat_id", chatId);
+ requestObject.insert("message_id", messageId);
+ requestObject.insert("option_id", optionId);
+ requestObject.insert("offset", offset);
+ requestObject.insert("limit", limit); //max 50
+ this->sendRequest(requestObject);
+}
+
void TDLibWrapper::searchEmoji(const QString &queryString)
{
LOG("Searching emoji" << queryString);
@@ -717,7 +781,7 @@ void TDLibWrapper::openFileOnDevice(const QString &filePath)
}
}
-void TDLibWrapper::controlScreenSaver(const bool &enabled)
+void TDLibWrapper::controlScreenSaver(bool enabled)
{
LOG("Controlling device screen saver" << enabled);
QDBusConnection dbusConnection = QDBusConnection::connectToBus(QDBusConnection::SystemBus, "system");
@@ -878,26 +942,6 @@ void TDLibWrapper::handleUnreadChatCountUpdated(const QVariantMap &chatCountInfo
}
}
-void TDLibWrapper::handleChatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage)
-{
- emit chatLastMessageUpdated(chatId, order, lastMessage);
-}
-
-void TDLibWrapper::handleChatOrderUpdated(const QString &chatId, const QString &order)
-{
- emit chatOrderUpdated(chatId, order);
-}
-
-void TDLibWrapper::handleChatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, const int &unreadCount)
-{
- emit chatReadInboxUpdated(chatId, lastReadInboxMessageId, unreadCount);
-}
-
-void TDLibWrapper::handleChatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId)
-{
- emit chatReadOutboxUpdated(chatId, lastReadOutboxMessageId);
-}
-
void TDLibWrapper::handleBasicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation)
{
emit basicGroupUpdated(updateGroup(groupId, groupInformation, &basicGroups)->groupId);
@@ -908,86 +952,6 @@ void TDLibWrapper::handleSuperGroupUpdated(qlonglong groupId, const QVariantMap
emit superGroupUpdated(updateGroup(groupId, groupInformation, &superGroups)->groupId);
}
-void TDLibWrapper::handleChatOnlineMemberCountUpdated(const QString &chatId, const int &onlineMemberCount)
-{
- emit chatOnlineMemberCountUpdated(chatId, onlineMemberCount);
-}
-
-void TDLibWrapper::handleMessagesReceived(const QVariantList &messages, const int &totalCount)
-{
- emit messagesReceived(messages, totalCount);
-}
-
-void TDLibWrapper::handleNewMessageReceived(const QString &chatId, const QVariantMap &message)
-{
- emit newMessageReceived(chatId, message);
-}
-
-void TDLibWrapper::handleMessageInformation(const QString &messageId, const QVariantMap &message)
-{
- emit receivedMessage(messageId, message);
-}
-
-void TDLibWrapper::handleMessageSendSucceeded(const QString &messageId, const QString &oldMessageId, const QVariantMap &message)
-{
- emit messageSendSucceeded(messageId, oldMessageId, message);
-}
-
-void TDLibWrapper::handleUpdateActiveNotifications(const QVariantList notificationGroups)
-{
- emit activeNotificationsUpdated(notificationGroups);
-}
-
-void TDLibWrapper::handleUpdateNotificationGroup(const QVariantMap notificationGroupUpdate)
-{
- emit notificationGroupUpdated(notificationGroupUpdate);
-}
-
-void TDLibWrapper::handleUpdateNotification(const QVariantMap updatedNotification)
-{
- emit notificationUpdated(updatedNotification);
-}
-
-void TDLibWrapper::handleChatNotificationSettingsUpdated(const QString &chatId, const QVariantMap &chatNotificationSettings)
-{
- emit chatNotificationSettingsUpdated(chatId, chatNotificationSettings);
-}
-
-void TDLibWrapper::handleMessageContentUpdated(const QString &chatId, const QString &messageId, const QVariantMap &newContent)
-{
- emit messageContentUpdated(chatId, messageId, newContent);
-}
-
-void TDLibWrapper::handleMessagesDeleted(const QString &chatId, const QVariantList &messageIds)
-{
- emit messagesDeleted(chatId, messageIds);
-}
-
-void TDLibWrapper::handleChats(const QVariantMap &chats)
-{
- emit this->chatsReceived(chats);
-}
-
-void TDLibWrapper::handleChat(const QVariantMap &chat)
-{
- emit this->chatReceived(chat);
-}
-
-void TDLibWrapper::handleRecentStickersUpdated(const QVariantList &stickerIds)
-{
- emit this->recentStickersUpdated(stickerIds);
-}
-
-void TDLibWrapper::handleStickers(const QVariantList &stickers)
-{
- emit this->stickersReceived(stickers);
-}
-
-void TDLibWrapper::handleInstalledStickerSetsUpdated(const QVariantList &stickerSetIds)
-{
- emit this->installedStickerSetsUpdated(stickerSetIds);
-}
-
void TDLibWrapper::handleStickerSets(const QVariantList &stickerSets)
{
QListIterator stickerSetIterator(stickerSets);
@@ -998,67 +962,12 @@ void TDLibWrapper::handleStickerSets(const QVariantList &stickerSets)
emit this->stickerSetsReceived(stickerSets);
}
-void TDLibWrapper::handleStickerSet(const QVariantMap &stickerSet)
-{
- emit stickerSetReceived(stickerSet);
-}
-
void TDLibWrapper::handleEmojiSearchCompleted(const QString &queryString, const QVariantList &resultList)
{
LOG("Emoji search completed" << queryString);
emit emojiSearchSuccessful(resultList);
}
-void TDLibWrapper::handleChatMembers(const QString &extra, const QVariantList &members, const int &totalMembers)
-{
- emit this->chatMembersReceived(extra, members, totalMembers);
-}
-
-void TDLibWrapper::handleUserFullInfo(const QVariantMap &userFullInfo)
-{
- emit this->userFullInfoReceived(userFullInfo);
-}
-
-void TDLibWrapper::handleUserFullInfoUpdated(const QString &userId, const QVariantMap &userFullInfo)
-{
- emit this->userFullInfoUpdated(userId, userFullInfo);
-}
-
-void TDLibWrapper::handleBasicGroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo)
-{
- emit this->basicGroupFullInfoReceived(groupId, groupFullInfo);
-}
-
-void TDLibWrapper::handleBasicGroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo)
-{
- emit this->basicGroupFullInfoUpdated(groupId, groupFullInfo);
-}
-
-void TDLibWrapper::handleSupergroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo)
-{
- emit this->supergroupFullInfoReceived(groupId, groupFullInfo);
-}
-
-void TDLibWrapper::handleSupergroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo)
-{
- emit this->supergroupFullInfoUpdated(groupId, groupFullInfo);
-}
-
-void TDLibWrapper::handleUserProfilePhotos(const QString &extra, const QVariantList &photos, const int &totalPhotos)
-{
- emit this->userProfilePhotosReceived(extra, photos, totalPhotos);
-}
-
-void TDLibWrapper::handleChatPermissionsUpdated(const QString &chatId, const QVariantMap permissions)
-{
- emit this->chatPermissionsUpdated(chatId, permissions);
-}
-
-void TDLibWrapper::handleChatTitleUpdated(const QString &chatId, const QString title)
-{
- emit this->chatTitleUpdated(chatId, title);
-}
-
void TDLibWrapper::setInitialParameters()
{
LOG("Sending initial parameters to TD Lib");
diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h
index d440b04..677e907 100644
--- a/src/tdlibwrapper.h
+++ b/src/tdlibwrapper.h
@@ -99,7 +99,7 @@ public:
Q_INVOKABLE QVariantMap getChat(const QString &chatId);
Q_INVOKABLE void copyFileToDownloads(const QString &filePath);
Q_INVOKABLE void openFileOnDevice(const QString &filePath);
- Q_INVOKABLE void controlScreenSaver(const bool &enabled);
+ Q_INVOKABLE void controlScreenSaver(bool enabled);
DBusAdaptor *getDBusAdaptor();
@@ -114,34 +114,38 @@ public:
Q_INVOKABLE void openChat(const QString &chatId);
Q_INVOKABLE void closeChat(const QString &chatId);
Q_INVOKABLE void leaveChat(const QString &chatId);
- Q_INVOKABLE void getChatHistory(const QString &chatId, const qlonglong &fromMessageId = 0, const int &offset = 0, const int &limit = 50, const bool &onlyLocal = false);
- Q_INVOKABLE void viewMessage(const QString &chatId, const QString &messageId, const bool &force);
+ Q_INVOKABLE void getChatHistory(const QString &chatId, const qlonglong &fromMessageId = 0, int offset = 0, int limit = 50, bool onlyLocal = false);
+ Q_INVOKABLE void viewMessage(const QString &chatId, const QString &messageId, bool force);
Q_INVOKABLE void sendTextMessage(const QString &chatId, const QString &message, const QString &replyToMessageId = "0");
Q_INVOKABLE void sendPhotoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
Q_INVOKABLE void sendVideoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0");
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 getMessage(const QString &chatId, const QString &messageId);
- Q_INVOKABLE void setOptionInteger(const QString &optionName, const int &optionValue);
+ Q_INVOKABLE void setOptionInteger(const QString &optionName, int optionValue);
Q_INVOKABLE void setChatNotificationSettings(const QString &chatId, const QVariantMap ¬ificationSettings);
Q_INVOKABLE void editMessageText(const QString &chatId, const QString &messageId, const QString &message);
Q_INVOKABLE void deleteMessages(const QString &chatId, const QVariantList messageIds);
- Q_INVOKABLE void getMapThumbnailFile(const QString &chatId, const double &latitude, const double &longitude, const int &width, const int &height);
+ Q_INVOKABLE void getMapThumbnailFile(const QString &chatId, double latitude, double longitude, int width, int height);
Q_INVOKABLE void getRecentStickers();
Q_INVOKABLE void getInstalledStickerSets();
Q_INVOKABLE void getStickerSet(const QString &setId);
- Q_INVOKABLE void getSupergroupMembers(const QString &groupId, const int &limit, const int &offset);
- Q_INVOKABLE void getGroupFullInfo(const QString &groupId, const bool &isSuperGroup);
+ Q_INVOKABLE void getSupergroupMembers(const QString &groupId, int limit, int offset);
+ Q_INVOKABLE void getGroupFullInfo(const QString &groupId, bool isSuperGroup);
Q_INVOKABLE void getUserFullInfo(const QString &userId);
Q_INVOKABLE void createPrivateChat(const QString &userId);
- Q_INVOKABLE void getGroupsInCommon(const QString &userId, const int &limit, const int &offset);
- Q_INVOKABLE void getUserProfilePhotos(const QString &userId, const int &limit, const int &offset);
+ Q_INVOKABLE void getGroupsInCommon(const QString &userId, int limit, int offset);
+ Q_INVOKABLE void getUserProfilePhotos(const QString &userId, int limit, int offset);
Q_INVOKABLE void setChatPermissions(const QString &chatId, const QVariantMap &chatPermissions);
- Q_INVOKABLE void setChatSlowModeDelay(const QString &chatId, const int &delay);
+ Q_INVOKABLE void setChatSlowModeDelay(const QString &chatId, int delay);
Q_INVOKABLE void setChatDescription(const QString &chatId, const QString &description);
Q_INVOKABLE void setChatTitle(const QString &chatId, const QString &title);
Q_INVOKABLE void setBio(const QString &bio);
- Q_INVOKABLE void toggleSupergroupIsAllHistoryAvailable(const QString &groupId, const bool &isAllHistoryAvailable);
+ Q_INVOKABLE void toggleSupergroupIsAllHistoryAvailable(const QString &groupId, bool isAllHistoryAvailable);
+ Q_INVOKABLE void setPollAnswer(const QString &chatId, const qlonglong &messageId, QVariantList optionIds);
+ Q_INVOKABLE void stopPoll(const QString &chatId, const qlonglong &messageId);
+ Q_INVOKABLE void getPollVoters(const QString &chatId, const qlonglong &messageId, const int &optionId, const int &limit, const int &offset, const QString &extra);
// Others (candidates for extraction ;))
Q_INVOKABLE void searchEmoji(const QString &queryString);
@@ -156,19 +160,19 @@ signals:
void authorizationStateChanged(const TDLibWrapper::AuthorizationState &authorizationState, const QVariantMap &authorizationStateData);
void optionUpdated(const QString &optionName, const QVariant &optionValue);
void connectionStateChanged(const TDLibWrapper::ConnectionState &connectionState);
- void fileUpdated(const int fileId, const QVariantMap &fileInformation);
+ void fileUpdated(int fileId, const QVariantMap &fileInformation);
void newChatDiscovered(const QString &chatId, const QVariantMap &chatInformation);
void unreadMessageCountUpdated(const QVariantMap &messageCountInformation);
void unreadChatCountUpdated(const QVariantMap &chatCountInformation);
void chatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage);
void chatOrderUpdated(const QString &chatId, const QString &order);
- void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, const int &unreadCount);
+ void chatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, int unreadCount);
void chatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId);
void userUpdated(const QString &userId, const QVariantMap &userInformation);
void basicGroupUpdated(qlonglong groupId);
void superGroupUpdated(qlonglong groupId);
- void chatOnlineMemberCountUpdated(const QString &chatId, const int &onlineMemberCount);
- void messagesReceived(const QVariantList &messages, const int &totalCount);
+ void chatOnlineMemberCountUpdated(const QString &chatId, int onlineMemberCount);
+ void messagesReceived(const QVariantList &messages, int totalCount);
void newMessageReceived(const QString &chatId, const QVariantMap &message);
void copyToDownloadsSuccessful(const QString &fileName, const QString &filePath);
void copyToDownloadsError(const QString &fileName, const QString &filePath);
@@ -188,16 +192,17 @@ signals:
void stickerSetsReceived(const QVariantList &stickerSets);
void stickerSetReceived(const QVariantMap &stickerSet);
void emojiSearchSuccessful(const QVariantList &result);
- void chatMembersReceived(const QString &extra, const QVariantList &members, const int &totalMembers);
+ void chatMembersReceived(const QString &extra, const QVariantList &members, int totalMembers);
void userFullInfoReceived(const QVariantMap &userFullInfo);
void userFullInfoUpdated(const QString &userId, const QVariantMap &userFullInfo);
void basicGroupFullInfoReceived(const QString &groupId, const QVariantMap &groupFullInfo);
void supergroupFullInfoReceived(const QString &groupId, const QVariantMap &groupFullInfo);
void basicGroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo);
void supergroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo);
- void userProfilePhotosReceived(const QString &extra, const QVariantList &photos, const int &totalPhotos);
+ void userProfilePhotosReceived(const QString &extra, const QVariantList &photos, int totalPhotos);
void chatPermissionsUpdated(const QString &chatId, const QVariantMap &permissions);
void chatTitleUpdated(const QString &chatId, const QString &title);
+ void usersReceived(const QString &extra, const QVariantList &userIds, int totalUsers);
public slots:
void handleVersionDetected(const QString &version);
@@ -210,41 +215,10 @@ public slots:
void handleNewChatDiscovered(const QVariantMap &chatInformation);
void handleUnreadMessageCountUpdated(const QVariantMap &messageCountInformation);
void handleUnreadChatCountUpdated(const QVariantMap &chatCountInformation);
- void handleChatLastMessageUpdated(const QString &chatId, const QString &order, const QVariantMap &lastMessage);
- void handleChatOrderUpdated(const QString &chatId, const QString &order);
- void handleChatReadInboxUpdated(const QString &chatId, const QString &lastReadInboxMessageId, const int &unreadCount);
- void handleChatReadOutboxUpdated(const QString &chatId, const QString &lastReadOutboxMessageId);
void handleBasicGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
void handleSuperGroupUpdated(qlonglong groupId, const QVariantMap &groupInformation);
- void handleChatOnlineMemberCountUpdated(const QString &chatId, const int &onlineMemberCount);
- void handleMessagesReceived(const QVariantList &messages, const int &totalCount);
- void handleNewMessageReceived(const QString &chatId, const QVariantMap &message);
- void handleMessageInformation(const QString &messageId, const QVariantMap &message);
- void handleMessageSendSucceeded(const QString &messageId, const QString &oldMessageId, const QVariantMap &message);
- void handleUpdateActiveNotifications(const QVariantList notificationGroups);
- void handleUpdateNotificationGroup(const QVariantMap notificationGroupUpdate);
- void handleUpdateNotification(const QVariantMap updatedNotification);
- void handleChatNotificationSettingsUpdated(const QString &chatId, const QVariantMap &chatNotificationSettings);
- void handleMessageContentUpdated(const QString &chatId, const QString &messageId, const QVariantMap &newContent);
- void handleMessagesDeleted(const QString &chatId, const QVariantList &messageIds);
- void handleChats(const QVariantMap &chats);
- void handleChat(const QVariantMap &chat);
- void handleRecentStickersUpdated(const QVariantList &stickerIds);
- void handleStickers(const QVariantList &stickers);
- void handleInstalledStickerSetsUpdated(const QVariantList &stickerSetIds);
void handleStickerSets(const QVariantList &stickerSets);
- void handleStickerSet(const QVariantMap &stickerSet);
void handleEmojiSearchCompleted(const QString &queryString, const QVariantList &resultList);
- void handleChatMembers(const QString &extra, const QVariantList &members, const int &totalMembers);
- void handleUserFullInfo(const QVariantMap &userFullInfo);
- void handleUserFullInfoUpdated(const QString &userId, const QVariantMap &userFullInfo);
- void handleBasicGroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo);
- void handleBasicGroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo);
- void handleSupergroupFullInfo(const QString &groupId, const QVariantMap &groupFullInfo);
- void handleSupergroupFullInfoUpdated(const QString &groupId, const QVariantMap &groupFullInfo);
- void handleUserProfilePhotos(const QString &extra, const QVariantList &photos, const int &totalPhotos);
- void handleChatPermissionsUpdated(const QString &chatId, const QVariantMap permissions);
- void handleChatTitleUpdated(const QString &chatId, const QString title);
private:
void setInitialParameters();
diff --git a/translations/harbour-fernschreiber-de.ts b/translations/harbour-fernschreiber-de.ts
index 93e44cf..eaae40c 100644
--- a/translations/harbour-fernschreiber-de.ts
+++ b/translations/harbour-fernschreiber-de.ts
@@ -542,6 +542,24 @@
hat den Chattitel geändert
+
+
+ myself
+ haben eine Umfrage geschickt
+
+
+
+ hat eine Umfrage geschickt
+
+
+
+ myself
+ haben ein Quiz geschickt
+
+
+
+ hat ein Quiz geschickt
+
ImagePage
@@ -685,6 +703,178 @@
Sie haben noch keine Chats.
+
+ PollCreationPage
+
+
+ Alle Antworten müssen 1-100 Zeichen beinhalten.
+
+
+
+ Um ein Quiz zu senden, müssen Sie die richtige Antwort auswählen.
+
+
+
+ Sie müssen eine Frage eingeben.
+
+
+
+ Die Frage muss kürzer als 256 Zeichen sein.
+
+
+
+ Eine Umfrage benötigt 2-10 Antworten.
+
+
+
+ Dialog Header
+ Erstellen Sie eine Umfrage
+
+
+
+ After dialog header… Create a Poll in [group name]
+ in %1
+
+
+
+ Geben Sie Ihre Frage ein
+
+
+
+
+ Frage (%n1 Zeichen übrig)
+ Frage (%n1 Zeichen übrig)
+
+
+
+
+ Section header
+ Antworten
+
+
+
+ Geben Sie eine Antwort ein
+
+
+
+
+ Antwort (%n1 Zeichen übrig)
+ Antwort (%n1 Zeichen übrig)
+
+
+
+
+ Antwort hinzufügen
+
+
+
+ Section header
+ Umfrageoptionen
+
+
+
+ Anonyme Antworten
+
+
+
+ Mehrere Antworten erlaubt
+
+
+
+ Quizmodus
+
+
+
+ Quizze haben eine korrekte Antwort. Teilnehmer können ihre Antwort nicht zurückziehen.
+
+
+
+ PollPreview
+
+
+ % of votes for option
+ %L1%
+
+
+
+ Endergebnis:
+
+
+
+ Mehrfachauswahl ist erlaubt.
+
+
+
+ number of total votes
+
+ %L1 Stimme insgesamt
+ %L1 Stimmen insgesamt
+
+
+
+
+ Umfrage beenden
+
+
+
+ Antwort zurückziehen
+
+
+
+ PollResultsPage
+
+
+ Quizergebnis
+
+
+
+ Umfrageergebnis
+
+
+
+ number of total votes
+
+ %L1 Stimme insgesamt
+ %L1 Stimmen insgesamt
+
+
+
+
+ section header
+ Frage
+
+
+
+ section header
+ Ergebnis
+
+
+
+ number of votes for option
+
+ %L1 Antwort
+ %L1 Antworten
+
+
+
+
+ % of votes for option
+ %L1%
+
+
+
+ This answer has been chosen by the following users
+ Gewählt von:
+
+
+
+ number of votes for option
+
+ %L1 Antwort inklusive Ihrer
+ %L1 Antworten inklusive Ihrer
+
+
+
SettingsPage
@@ -964,5 +1154,41 @@
hat den Chattitel zu %1 geändert
+
+
+ myself
+ haben eine Umfrage gesendet
+
+
+
+ hat eine Umfrage gesendet
+
+
+
+ myself
+ haben ein anonymes Quiz gesendet
+
+
+
+ hat ein anonymes Quiz gesendet
+
+
+
+ myself
+ haben ein Quiz gesendet
+
+
+
+ hat ein Quiz gesendet
+
+
+
+ myself
+ haben eine anonyme Umfrage gesendet
+
+
+
+ hat eine anonyme Umfrage gesendet
+
diff --git a/translations/harbour-fernschreiber-es.ts b/translations/harbour-fernschreiber-es.ts
index 53f5120..2843445 100644
--- a/translations/harbour-fernschreiber-es.ts
+++ b/translations/harbour-fernschreiber-es.ts
@@ -542,6 +542,24 @@
el título del charla se cambió
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
ImagePage
@@ -685,6 +703,172 @@
No hay todavía ninguna charla.
+
+ PollCreationPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialog Header
+
+
+
+
+ After dialog header… Create a Poll in [group name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollPreview
+
+
+ % of votes for option
+
+
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollResultsPage
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+ section header
+
+
+
+
+ section header
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+ % of votes for option
+
+
+
+
+ This answer has been chosen by the following users
+
+
+
+
+ number of votes for option
+
+
+
+
+
SettingsPage
@@ -964,5 +1148,41 @@
se cambió el título de la charla a %1
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
diff --git a/translations/harbour-fernschreiber-fi.ts b/translations/harbour-fernschreiber-fi.ts
index 21b13b2..c7dfa43 100644
--- a/translations/harbour-fernschreiber-fi.ts
+++ b/translations/harbour-fernschreiber-fi.ts
@@ -543,6 +543,24 @@
muutti keskustelun otsikkoa
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
ImagePage
@@ -686,6 +704,178 @@
Sinulla ei ole vielä keskusteluja.
+
+ PollCreationPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialog Header
+
+
+
+
+ After dialog header… Create a Poll in [group name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollPreview
+
+
+ % of votes for option
+
+
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollResultsPage
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+ section header
+
+
+
+
+ section header
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+
+ % of votes for option
+
+
+
+
+ This answer has been chosen by the following users
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
SettingsPage
@@ -965,5 +1155,41 @@
vaihtoi keskustelun otsikoksi %1
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
diff --git a/translations/harbour-fernschreiber-hu.ts b/translations/harbour-fernschreiber-hu.ts
index 5955b06..42c4433 100644
--- a/translations/harbour-fernschreiber-hu.ts
+++ b/translations/harbour-fernschreiber-hu.ts
@@ -542,6 +542,24 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
ImagePage
@@ -685,6 +703,172 @@
+
+ PollCreationPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialog Header
+
+
+
+
+ After dialog header… Create a Poll in [group name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollPreview
+
+
+ % of votes for option
+
+
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollResultsPage
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+ section header
+
+
+
+
+ section header
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+ % of votes for option
+
+
+
+
+ This answer has been chosen by the following users
+
+
+
+
+ number of votes for option
+
+
+
+
+
SettingsPage
@@ -964,5 +1148,41 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
diff --git a/translations/harbour-fernschreiber-it.ts b/translations/harbour-fernschreiber-it.ts
index 4e804ad..7188854 100644
--- a/translations/harbour-fernschreiber-it.ts
+++ b/translations/harbour-fernschreiber-it.ts
@@ -542,6 +542,24 @@
Ha modificato il titolo della chat
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
ImagePage
@@ -685,6 +703,178 @@
Non hai nessuna chat.
+
+ PollCreationPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialog Header
+
+
+
+
+ After dialog header… Create a Poll in [group name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollPreview
+
+
+ % of votes for option
+
+
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollResultsPage
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+ section header
+
+
+
+
+ section header
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+
+ % of votes for option
+
+
+
+
+ This answer has been chosen by the following users
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
SettingsPage
@@ -964,5 +1154,41 @@
ha modificato il titolo della chat in %1
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
diff --git a/translations/harbour-fernschreiber-pl.ts b/translations/harbour-fernschreiber-pl.ts
index 83b1565..0ad2981 100644
--- a/translations/harbour-fernschreiber-pl.ts
+++ b/translations/harbour-fernschreiber-pl.ts
@@ -542,6 +542,24 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
ImagePage
@@ -685,6 +703,184 @@
Nie masz jeszcze żadnych czatów.
+
+ PollCreationPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialog Header
+
+
+
+
+ After dialog header… Create a Poll in [group name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollPreview
+
+
+ % of votes for option
+
+
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollResultsPage
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+ section header
+
+
+
+
+ section header
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+
+
+ % of votes for option
+
+
+
+
+ This answer has been chosen by the following users
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+
SettingsPage
@@ -964,5 +1160,41 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
diff --git a/translations/harbour-fernschreiber-ru.ts b/translations/harbour-fernschreiber-ru.ts
index 263552a..69bf463 100644
--- a/translations/harbour-fernschreiber-ru.ts
+++ b/translations/harbour-fernschreiber-ru.ts
@@ -542,6 +542,24 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
ImagePage
@@ -685,6 +703,184 @@
Тут пока ничего нет
+
+ PollCreationPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialog Header
+
+
+
+
+ After dialog header… Create a Poll in [group name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollPreview
+
+
+ % of votes for option
+
+
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollResultsPage
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+ section header
+
+
+
+
+ section header
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+
+
+ % of votes for option
+
+
+
+
+ This answer has been chosen by the following users
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+
SettingsPage
@@ -964,5 +1160,41 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
diff --git a/translations/harbour-fernschreiber-zh_CN.ts b/translations/harbour-fernschreiber-zh_CN.ts
index a18810d..7ef0098 100644
--- a/translations/harbour-fernschreiber-zh_CN.ts
+++ b/translations/harbour-fernschreiber-zh_CN.ts
@@ -542,6 +542,24 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
ImagePage
@@ -685,6 +703,172 @@
你尚无任何对话。
+
+ PollCreationPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialog Header
+
+
+
+
+ After dialog header… Create a Poll in [group name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollPreview
+
+
+ % of votes for option
+
+
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollResultsPage
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+ section header
+
+
+
+
+ section header
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+ % of votes for option
+
+
+
+
+ This answer has been chosen by the following users
+
+
+
+
+ number of votes for option
+
+
+
+
+
SettingsPage
@@ -964,5 +1148,41 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
diff --git a/translations/harbour-fernschreiber.ts b/translations/harbour-fernschreiber.ts
index da0dd42..48bfa9e 100644
--- a/translations/harbour-fernschreiber.ts
+++ b/translations/harbour-fernschreiber.ts
@@ -542,6 +542,24 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
ImagePage
@@ -685,6 +703,172 @@
+
+ PollCreationPage
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Dialog Header
+
+
+
+
+ After dialog header… Create a Poll in [group name]
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Section header
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollPreview
+
+
+ % of votes for option
+
+
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ PollResultsPage
+
+
+
+
+
+
+
+
+
+
+ number of total votes
+
+
+
+
+
+
+ section header
+
+
+
+
+ section header
+
+
+
+
+ number of votes for option
+
+
+
+
+
+
+ % of votes for option
+
+
+
+
+ This answer has been chosen by the following users
+
+
+
+
+ number of votes for option
+
+
+
+
+
SettingsPage
@@ -964,5 +1148,41 @@
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+
+
+
+ myself
+
+
+
+
+
+