Merge pull request #249 from jgibbon/feature/basic-bot-interaction
support basic bot messages (reply markup)
This commit is contained in:
commit
f7c6f8a399
13 changed files with 217 additions and 7 deletions
|
@ -55,6 +55,7 @@ DISTFILES += qml/harbour-fernschreiber.qml \
|
||||||
qml/components/PinnedMessageItem.qml \
|
qml/components/PinnedMessageItem.qml \
|
||||||
qml/components/PollPreview.qml \
|
qml/components/PollPreview.qml \
|
||||||
qml/components/PressEffect.qml \
|
qml/components/PressEffect.qml \
|
||||||
|
qml/components/ReplyMarkupButtons.qml \
|
||||||
qml/components/StickerPicker.qml \
|
qml/components/StickerPicker.qml \
|
||||||
qml/components/PhotoTextsListItem.qml \
|
qml/components/PhotoTextsListItem.qml \
|
||||||
qml/components/WebPagePreview.qml \
|
qml/components/WebPagePreview.qml \
|
||||||
|
|
28
images/icon-s-link.svg
Normal file
28
images/icon-s-link.svg
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<svg
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xml:space="preserve"
|
||||||
|
style="enable-background:new 0 0 32 32;"
|
||||||
|
viewBox="0 0 32 32"
|
||||||
|
height="32"
|
||||||
|
width="32"
|
||||||
|
y="0px"
|
||||||
|
x="0px"
|
||||||
|
id="Layer_1"
|
||||||
|
version="1.1"><metadata
|
||||||
|
id="metadata19"><rdf:RDF><cc:Work
|
||||||
|
rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
|
||||||
|
id="defs17" />
|
||||||
|
|
||||||
|
<path
|
||||||
|
id="rect853-3-7"
|
||||||
|
d="m 5.2218178,19.08774 c -2.1185651,2.118565 -2.1185651,5.573984 -4e-7,7.692548 2.1185648,2.118565 5.5739836,2.118565 7.6925486,0 l 4.866883,-4.866883 c 2.118565,-2.118565 2.118565,-5.573984 0,-7.692549 -2.118564,-2.118564 -5.573983,-2.118564 -7.692548,0 z m 1.4142135,1.414213 4.8668837,-4.866883 c 1.359552,-1.359552 3.504569,-1.359552 4.864121,0 1.359553,1.359553 1.359552,3.504569 0,4.864121 l -4.866884,4.866883 c -1.359552,1.359553 -3.5045682,1.359554 -4.864121,10e-7 -1.3595521,-1.359552 -1.3595521,-3.504569 3e-7,-4.864122 z"
|
||||||
|
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:0.6;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /><path
|
||||||
|
id="rect853-6"
|
||||||
|
d="m 17.290288,17.295275 c -0.604056,-0.141842 -1.179293,-0.451814 -1.657396,-0.929916 -1.359554,-1.359552 -1.358171,-3.503188 0.0014,-4.86274 l -1.7e-5,-4e-6 4.866884,-4.8668837 c 1.359553,-1.3595528 3.503187,-1.3609338 4.86274,-0.00138 1.359553,1.3595528 1.359553,3.5045687 1e-6,4.8641217 l -4.866884,4.866883 c -0.354012,0.354012 -0.76128,0.615843 -1.19407,0.785494 0.09971,0.686342 0.114666,1.379464 -0.04531,2.08658 0.973641,-0.21685 1.898514,-0.702806 2.653575,-1.457867 l 4.866884,-4.866884 c 2.118565,-2.118565 2.118564,-5.5739835 0,-7.6925482 -2.118565,-2.1185648 -5.572602,-2.1171831 -7.691168,0.00138 l -4.866865,4.8668902 c -2.118564,2.118564 -2.119946,5.572602 -0.0014,7.691167 0.825683,0.825683 1.854427,1.329567 2.927951,1.511652 0.245536,-0.61844 0.301651,-1.33063 0.143675,-1.995945 z"
|
||||||
|
style="color:#000000;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:medium;line-height:normal;font-family:sans-serif;font-variant-ligatures:normal;font-variant-position:normal;font-variant-caps:normal;font-variant-numeric:normal;font-variant-alternates:normal;font-feature-settings:normal;text-indent:0;text-align:start;text-decoration:none;text-decoration-line:none;text-decoration-style:solid;text-decoration-color:#000000;letter-spacing:normal;word-spacing:normal;text-transform:none;writing-mode:lr-tb;direction:ltr;text-orientation:mixed;dominant-baseline:auto;baseline-shift:baseline;text-anchor:start;white-space:normal;shape-padding:0;clip-rule:nonzero;display:inline;overflow:visible;visibility:visible;opacity:1;isolation:auto;mix-blend-mode:normal;color-interpolation:sRGB;color-interpolation-filters:linearRGB;solid-color:#000000;solid-opacity:1;vector-effect:none;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;color-rendering:auto;image-rendering:auto;shape-rendering:auto;text-rendering:auto;enable-background:accumulate" /></svg>
|
After Width: | Height: | Size: 4.5 KiB |
|
@ -123,13 +123,14 @@ Item {
|
||||||
fillMode: Image.PreserveAspectCrop
|
fillMode: Image.PreserveAspectCrop
|
||||||
visible: status === Image.Ready ? true : false
|
visible: status === Image.Ready ? true : false
|
||||||
layer.enabled: audioMessageComponent.highlighted
|
layer.enabled: audioMessageComponent.highlighted
|
||||||
layer.effect: PressEffect { source: singleImage }
|
layer.effect: PressEffect { source: placeholderImage }
|
||||||
}
|
}
|
||||||
|
|
||||||
BackgroundImage {
|
BackgroundImage {
|
||||||
|
id: backgroundImage
|
||||||
visible: placeholderImage.status !== Image.Ready
|
visible: placeholderImage.status !== Image.Ready
|
||||||
layer.enabled: audioMessageComponent.highlighted
|
layer.enabled: audioMessageComponent.highlighted
|
||||||
layer.effect: PressEffect { source: singleImage }
|
layer.effect: PressEffect { source: backgroundImage }
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
@ -140,6 +141,17 @@ Item {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
visible: playButton.visible
|
visible: playButton.visible
|
||||||
}
|
}
|
||||||
|
Label {
|
||||||
|
visible: !!(audioData.performer || audioData.title)
|
||||||
|
color: placeholderBackground.visible ? "white" : Theme.secondaryHighlightColor
|
||||||
|
wrapMode: Text.Wrap
|
||||||
|
anchors {
|
||||||
|
fill: placeholderBackground
|
||||||
|
margins: Theme.paddingSmall
|
||||||
|
}
|
||||||
|
text: audioData.performer + (audioData.performer && audioData.title ? " - " : "") + audioData.title
|
||||||
|
font.pixelSize: Theme.fontSizeTiny
|
||||||
|
}
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
width: parent.width
|
width: parent.width
|
||||||
|
@ -366,7 +378,7 @@ Item {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
width: Theme.iconSizeLarge
|
width: Theme.iconSizeLarge
|
||||||
height: Theme.iconSizeLarge
|
height: Theme.iconSizeLarge
|
||||||
highlighted: videoMessageComponent.highlighted || down
|
highlighted: audioMessageComponent.highlighted || down
|
||||||
icon {
|
icon {
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
source: "image://theme/icon-l-play?white"
|
source: "image://theme/icon-l-play?white"
|
||||||
|
@ -390,7 +402,7 @@ Item {
|
||||||
value: messageAudio.position
|
value: messageAudio.position
|
||||||
enabled: messageAudio.seekable
|
enabled: messageAudio.seekable
|
||||||
visible: (messageAudio.duration > 0)
|
visible: (messageAudio.duration > 0)
|
||||||
highlighted: videoMessageComponent.highlighted || down
|
highlighted: audioMessageComponent.highlighted || down
|
||||||
onReleased: {
|
onReleased: {
|
||||||
messageAudio.seek(Math.floor(value));
|
messageAudio.seek(Math.floor(value));
|
||||||
messageAudio.play();
|
messageAudio.play();
|
||||||
|
|
|
@ -398,7 +398,10 @@ ListItem {
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
onLinkActivated: {
|
onLinkActivated: {
|
||||||
Functions.handleLink(link);
|
var chatCommand = Functions.handleLink(link);
|
||||||
|
if(chatCommand) {
|
||||||
|
tdLibWrapper.sendTextMessage(chatInformation.id, chatCommand);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
horizontalAlignment: messageListItem.textAlign
|
horizontalAlignment: messageListItem.textAlign
|
||||||
linkColor: Theme.highlightColor
|
linkColor: Theme.highlightColor
|
||||||
|
@ -435,6 +438,15 @@ ListItem {
|
||||||
value: messageListItem.highlighted
|
value: messageListItem.highlighted
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: replyMarkupLoader
|
||||||
|
width: parent.width
|
||||||
|
height: active ? (myMessage.reply_markup.rows.length * (Theme.itemSizeSmall + Theme.paddingSmall) - Theme.paddingSmall) : 0
|
||||||
|
asynchronous: true
|
||||||
|
active: !!myMessage.reply_markup && myMessage.reply_markup.rows
|
||||||
|
source: Qt.resolvedUrl("ReplyMarkupButtons.qml")
|
||||||
|
}
|
||||||
|
|
||||||
Timer {
|
Timer {
|
||||||
id: messageDateUpdater
|
id: messageDateUpdater
|
||||||
interval: 60000
|
interval: 60000
|
||||||
|
|
99
qml/components/ReplyMarkupButtons.qml
Normal file
99
qml/components/ReplyMarkupButtons.qml
Normal file
|
@ -0,0 +1,99 @@
|
||||||
|
/*
|
||||||
|
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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
import QtQuick 2.6
|
||||||
|
import Sailfish.Silica 1.0
|
||||||
|
import "../js/twemoji.js" as Emoji
|
||||||
|
import "../js/functions.js" as Functions
|
||||||
|
import "../js/debug.js" as Debug
|
||||||
|
|
||||||
|
Column {
|
||||||
|
width: parent.width
|
||||||
|
height: childrenRect.height
|
||||||
|
spacing: Theme.paddingSmall
|
||||||
|
|
||||||
|
Repeater {
|
||||||
|
model: myMessage.reply_markup.rows
|
||||||
|
delegate: Row {
|
||||||
|
width: parent.width
|
||||||
|
height: Theme.itemSizeSmall
|
||||||
|
spacing: Theme.paddingSmall
|
||||||
|
Repeater {
|
||||||
|
id: buttonsRepeater
|
||||||
|
model: modelData
|
||||||
|
property int itemWidth:precalculatedValues.textColumnWidth / count
|
||||||
|
delegate: MouseArea {
|
||||||
|
/*
|
||||||
|
Unimplemented callback types:
|
||||||
|
inlineKeyboardButtonTypeBuy
|
||||||
|
inlineKeyboardButtonTypeCallbackGame
|
||||||
|
inlineKeyboardButtonTypeCallbackWithPassword
|
||||||
|
inlineKeyboardButtonTypeLoginUrl
|
||||||
|
inlineKeyboardButtonTypeSwitchInline
|
||||||
|
*/
|
||||||
|
property var callbacks: ({
|
||||||
|
inlineKeyboardButtonTypeCallback: function(){
|
||||||
|
tdLibWrapper.getCallbackQueryAnswer(messageListItem.chatId, messageListItem.messageId, {data: modelData.type.data, "@type": "callbackQueryPayloadData"})
|
||||||
|
},
|
||||||
|
inlineKeyboardButtonTypeUrl: function() {
|
||||||
|
Functions.handleLink(modelData.type.url);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
enabled: !!callbacks[modelData.type["@type"]]
|
||||||
|
height: Theme.itemSizeSmall
|
||||||
|
width: (precalculatedValues.textColumnWidth + Theme.paddingSmall) / buttonsRepeater.count - (Theme.paddingSmall)
|
||||||
|
onClicked: {
|
||||||
|
callbacks[modelData.type["@type"]]();
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
radius: Theme.paddingSmall
|
||||||
|
color: parent.pressed ? Theme.rgba(Theme.highlightBackgroundColor, Theme.highlightBackgroundOpacity)
|
||||||
|
: Theme.rgba(Theme.primaryColor, Theme.opacityFaint)
|
||||||
|
opacity: parent.enabled ? 1.0 : Theme.opacityLow
|
||||||
|
|
||||||
|
Label {
|
||||||
|
width: Math.min(parent.width - Theme.paddingSmall*2, contentWidth)
|
||||||
|
truncationMode: TruncationMode.Fade
|
||||||
|
text: Emoji.emojify(modelData.text, Theme.fontSizeSmall)
|
||||||
|
color: parent.pressed ? Theme.highlightColor : Theme.primaryColor
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pixelSize: Theme.fontSizeSmall
|
||||||
|
}
|
||||||
|
Icon {
|
||||||
|
property var sources: ({
|
||||||
|
inlineKeyboardButtonTypeUrl: "../../images/icon-s-link.svg",
|
||||||
|
inlineKeyboardButtonTypeSwitchInline: "image://theme/icon-s-repost",
|
||||||
|
inlineKeyboardButtonTypeCallbackWithPassword: "image://theme/icon-s-asterisk"
|
||||||
|
})
|
||||||
|
visible: !!sources[modelData.type["@type"]]
|
||||||
|
source: sources[modelData.type["@type"]] || ""
|
||||||
|
sourceSize: Qt.size(Theme.iconSizeSmall, Theme.iconSizeSmall)
|
||||||
|
highlighted: parent.pressed
|
||||||
|
anchors {
|
||||||
|
right: parent.right
|
||||||
|
top: parent.top
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -305,6 +305,13 @@ function enhanceMessageText(formattedText, ignoreEntities) {
|
||||||
{ offset: (entity.offset + entity.length), insertionString: "</u>", removeLength: 0 }
|
{ offset: (entity.offset + entity.length), insertionString: "</u>", removeLength: 0 }
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
case "textEntityTypeBotCommand":
|
||||||
|
var command = messageText.substring(entity.offset, entity.offset + entity.length);
|
||||||
|
messageInsertions.push(
|
||||||
|
{ offset: entity.offset, insertionString: "<a href=\"botCommand://" + command + "\">", removeLength: 0 },
|
||||||
|
{ offset: (entity.offset + entity.length), insertionString: "</a>", removeLength: 0 }
|
||||||
|
);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -347,7 +354,9 @@ function handleLink(link) {
|
||||||
} else if (link.indexOf("tg://resolve?domain=") === 0) {
|
} else if (link.indexOf("tg://resolve?domain=") === 0) {
|
||||||
tdLibWrapper.searchPublicChat(link.substring(20));
|
tdLibWrapper.searchPublicChat(link.substring(20));
|
||||||
}
|
}
|
||||||
} else {
|
} else if (link.indexOf("botCommand://") === 0) { // this gets returned to send on ChatPage
|
||||||
|
return link.substring(13);
|
||||||
|
} else {
|
||||||
if (link.indexOf(tMePrefix) === 0) {
|
if (link.indexOf(tMePrefix) === 0) {
|
||||||
if (link.indexOf("joinchat") !== -1) {
|
if (link.indexOf("joinchat") !== -1) {
|
||||||
Debug.log("Joining Chat: ", link);
|
Debug.log("Joining Chat: ", link);
|
||||||
|
|
|
@ -922,7 +922,7 @@ Page {
|
||||||
chatId: chatModel.chatId
|
chatId: chatModel.chatId
|
||||||
myMessage: model.display
|
myMessage: model.display
|
||||||
messageId: model.message_id
|
messageId: model.message_id
|
||||||
extraContentComponentName: chatView.contentComponentNames[model.content_type]
|
extraContentComponentName: chatView.contentComponentNames[model.content_type] || ""
|
||||||
canReplyToMessage: chatPage.canSendMessages
|
canReplyToMessage: chatPage.canSendMessages
|
||||||
onReplyToMessage: {
|
onReplyToMessage: {
|
||||||
newMessageInReplyToRow.inReplyToMessage = myMessage
|
newMessageInReplyToRow.inReplyToMessage = myMessage
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace {
|
||||||
const QString SENDER("sender");
|
const QString SENDER("sender");
|
||||||
const QString USER_ID("user_id");
|
const QString USER_ID("user_id");
|
||||||
const QString PINNED_MESSAGE_ID("pinned_message_id");
|
const QString PINNED_MESSAGE_ID("pinned_message_id");
|
||||||
|
const QString REPLY_MARKUP("reply_markup");
|
||||||
const QString _TYPE("@type");
|
const QString _TYPE("@type");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,6 +55,7 @@ public:
|
||||||
|
|
||||||
static bool lessThan(const MessageData *message1, const MessageData *message2);
|
static bool lessThan(const MessageData *message1, const MessageData *message2);
|
||||||
void setContent(const QVariantMap &content);
|
void setContent(const QVariantMap &content);
|
||||||
|
void setReplyMarkup(const QVariantMap &replyMarkup);
|
||||||
int senderUserId() const;
|
int senderUserId() const;
|
||||||
qlonglong senderChatId() const;
|
qlonglong senderChatId() const;
|
||||||
bool senderIsChat() const;
|
bool senderIsChat() const;
|
||||||
|
@ -90,6 +92,10 @@ void ChatModel::MessageData::setContent(const QVariantMap &content)
|
||||||
{
|
{
|
||||||
messageData.insert(CONTENT, content);
|
messageData.insert(CONTENT, content);
|
||||||
}
|
}
|
||||||
|
void ChatModel::MessageData::setReplyMarkup(const QVariantMap &replyMarkup)
|
||||||
|
{
|
||||||
|
messageData.insert(REPLY_MARKUP, replyMarkup);
|
||||||
|
}
|
||||||
|
|
||||||
bool ChatModel::MessageData::lessThan(const MessageData *message1, const MessageData *message2)
|
bool ChatModel::MessageData::lessThan(const MessageData *message1, const MessageData *message2)
|
||||||
{
|
{
|
||||||
|
@ -112,6 +118,7 @@ ChatModel::ChatModel(TDLibWrapper *tdLibWrapper) :
|
||||||
connect(this->tdLibWrapper, SIGNAL(chatPhotoUpdated(qlonglong, QVariantMap)), this, SLOT(handleChatPhotoUpdated(qlonglong, QVariantMap)));
|
connect(this->tdLibWrapper, SIGNAL(chatPhotoUpdated(qlonglong, QVariantMap)), this, SLOT(handleChatPhotoUpdated(qlonglong, QVariantMap)));
|
||||||
connect(this->tdLibWrapper, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SLOT(handleChatPinnedMessageUpdated(qlonglong, qlonglong)));
|
connect(this->tdLibWrapper, SIGNAL(chatPinnedMessageUpdated(qlonglong, qlonglong)), this, SLOT(handleChatPinnedMessageUpdated(qlonglong, qlonglong)));
|
||||||
connect(this->tdLibWrapper, SIGNAL(messageContentUpdated(qlonglong, qlonglong, QVariantMap)), this, SLOT(handleMessageContentUpdated(qlonglong, qlonglong, QVariantMap)));
|
connect(this->tdLibWrapper, SIGNAL(messageContentUpdated(qlonglong, qlonglong, QVariantMap)), this, SLOT(handleMessageContentUpdated(qlonglong, qlonglong, QVariantMap)));
|
||||||
|
connect(this->tdLibWrapper, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)), this, SLOT(handleMessageEditedUpdated(qlonglong, qlonglong, QVariantMap)));
|
||||||
connect(this->tdLibWrapper, SIGNAL(messagesDeleted(qlonglong, QList<qlonglong>)), this, SLOT(handleMessagesDeleted(qlonglong, QList<qlonglong>)));
|
connect(this->tdLibWrapper, SIGNAL(messagesDeleted(qlonglong, QList<qlonglong>)), this, SLOT(handleMessagesDeleted(qlonglong, QList<qlonglong>)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -420,6 +427,22 @@ void ChatModel::handleMessageContentUpdated(qlonglong chatId, qlonglong messageI
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ChatModel::handleMessageEditedUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &replyMarkup)
|
||||||
|
{
|
||||||
|
LOG("Message edited updated" << chatId << messageId);
|
||||||
|
if (chatId == this->chatId && messageIndexMap.contains(messageId)) {
|
||||||
|
LOG("We know the message that was updated" << messageId);
|
||||||
|
const int pos = messageIndexMap.value(messageId, -1);
|
||||||
|
if (pos >= 0) {
|
||||||
|
messages.at(pos)->setReplyMarkup(replyMarkup);
|
||||||
|
LOG("Message was edited at index" << pos);
|
||||||
|
const QModelIndex messageIndex(index(pos));
|
||||||
|
emit dataChanged(messageIndex, messageIndex);
|
||||||
|
emit messageUpdated(pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ChatModel::handleMessagesDeleted(qlonglong chatId, const QList<qlonglong> &messageIds)
|
void ChatModel::handleMessagesDeleted(qlonglong chatId, const QList<qlonglong> &messageIds)
|
||||||
{
|
{
|
||||||
LOG("Messages were deleted in a chat" << chatId);
|
LOG("Messages were deleted in a chat" << chatId);
|
||||||
|
|
|
@ -71,6 +71,7 @@ private slots:
|
||||||
void handleChatPhotoUpdated(qlonglong chatId, const QVariantMap &photo);
|
void handleChatPhotoUpdated(qlonglong chatId, const QVariantMap &photo);
|
||||||
void handleChatPinnedMessageUpdated(qlonglong chatId, qlonglong pinnedMessageId);
|
void handleChatPinnedMessageUpdated(qlonglong chatId, qlonglong pinnedMessageId);
|
||||||
void handleMessageContentUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &newContent);
|
void handleMessageContentUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &newContent);
|
||||||
|
void handleMessageEditedUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &replyMarkup);
|
||||||
void handleMessagesDeleted(qlonglong chatId, const QList<qlonglong> &messageIds);
|
void handleMessagesDeleted(qlonglong chatId, const QList<qlonglong> &messageIds);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -132,6 +132,7 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
|
||||||
handlers.insert("secretChat", &TDLibReceiver::processSecretChat);
|
handlers.insert("secretChat", &TDLibReceiver::processSecretChat);
|
||||||
handlers.insert("updateSecretChat", &TDLibReceiver::processUpdateSecretChat);
|
handlers.insert("updateSecretChat", &TDLibReceiver::processUpdateSecretChat);
|
||||||
handlers.insert("importedContacts", &TDLibReceiver::processImportedContacts);
|
handlers.insert("importedContacts", &TDLibReceiver::processImportedContacts);
|
||||||
|
handlers.insert("updateMessageEdited", &TDLibReceiver::processUpdateMessageEdited);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TDLibReceiver::setActive(bool active)
|
void TDLibReceiver::setActive(bool active)
|
||||||
|
@ -555,6 +556,14 @@ void TDLibReceiver::processUpdateSecretChat(const QVariantMap &receivedInformati
|
||||||
emit secretChatUpdated(updatedSecretChat.value(ID).toLongLong(), updatedSecretChat);
|
emit secretChatUpdated(updatedSecretChat.value(ID).toLongLong(), updatedSecretChat);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibReceiver::processUpdateMessageEdited(const QVariantMap &receivedInformation)
|
||||||
|
{
|
||||||
|
const qlonglong chatId = receivedInformation.value(CHAT_ID).toLongLong();
|
||||||
|
const qlonglong messageId = receivedInformation.value(MESSAGE_ID).toLongLong();
|
||||||
|
LOG("Message was edited" << chatId << messageId);
|
||||||
|
emit messageEditedUpdated(chatId, messageId, receivedInformation.value("reply_markup").toMap());
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibReceiver::processImportedContacts(const QVariantMap &receivedInformation)
|
void TDLibReceiver::processImportedContacts(const QVariantMap &receivedInformation)
|
||||||
{
|
{
|
||||||
LOG("Contacts were imported");
|
LOG("Contacts were imported");
|
||||||
|
|
|
@ -63,6 +63,7 @@ signals:
|
||||||
void notificationUpdated(const QVariantMap updatedNotification);
|
void notificationUpdated(const QVariantMap updatedNotification);
|
||||||
void chatNotificationSettingsUpdated(const QString &chatId, const QVariantMap updatedChatNotificationSettings);
|
void chatNotificationSettingsUpdated(const QString &chatId, const QVariantMap updatedChatNotificationSettings);
|
||||||
void messageContentUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &newContent);
|
void messageContentUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &newContent);
|
||||||
|
void messageEditedUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &replyMarkup);
|
||||||
void messagesDeleted(qlonglong chatId, const QList<qlonglong> &messageIds);
|
void messagesDeleted(qlonglong chatId, const QList<qlonglong> &messageIds);
|
||||||
void chats(const QVariantMap &chats);
|
void chats(const QVariantMap &chats);
|
||||||
void chat(const QVariantMap &chats);
|
void chat(const QVariantMap &chats);
|
||||||
|
@ -152,6 +153,7 @@ private:
|
||||||
void nop(const QVariantMap &receivedInformation);
|
void nop(const QVariantMap &receivedInformation);
|
||||||
void processSecretChat(const QVariantMap &receivedInformation);
|
void processSecretChat(const QVariantMap &receivedInformation);
|
||||||
void processUpdateSecretChat(const QVariantMap &receivedInformation);
|
void processUpdateSecretChat(const QVariantMap &receivedInformation);
|
||||||
|
void processUpdateMessageEdited(const QVariantMap &receivedInformation);
|
||||||
void processImportedContacts(const QVariantMap &receivedInformation);
|
void processImportedContacts(const QVariantMap &receivedInformation);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -123,6 +123,7 @@ TDLibWrapper::TDLibWrapper(AppSettings *appSettings, MceInterface *mceInterface,
|
||||||
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
connect(this->tdLibReceiver, SIGNAL(usersReceived(QString, QVariantList, int)), this, SIGNAL(usersReceived(QString, QVariantList, int)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(errorReceived(int, QString, QString)), this, SLOT(handleErrorReceived(int, QString, QString)));
|
connect(this->tdLibReceiver, SIGNAL(errorReceived(int, QString, QString)), this, SLOT(handleErrorReceived(int, QString, QString)));
|
||||||
connect(this->tdLibReceiver, SIGNAL(contactsImported(QVariantList, QVariantList)), this, SIGNAL(contactsImported(QVariantList, QVariantList)));
|
connect(this->tdLibReceiver, SIGNAL(contactsImported(QVariantList, QVariantList)), this, SIGNAL(contactsImported(QVariantList, QVariantList)));
|
||||||
|
connect(this->tdLibReceiver, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)), this, SIGNAL(messageEditedUpdated(qlonglong, qlonglong, QVariantMap)));
|
||||||
|
|
||||||
connect(&emojiSearchWorker, SIGNAL(searchCompleted(QString, QVariantList)), this, SLOT(handleEmojiSearchCompleted(QString, QVariantList)));
|
connect(&emojiSearchWorker, SIGNAL(searchCompleted(QString, QVariantList)), this, SLOT(handleEmojiSearchCompleted(QString, QVariantList)));
|
||||||
|
|
||||||
|
@ -545,6 +546,17 @@ void TDLibWrapper::getMessage(const QString &chatId, const QString &messageId)
|
||||||
this->sendRequest(requestObject);
|
this->sendRequest(requestObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void TDLibWrapper::getCallbackQueryAnswer(const QString &chatId, const QString &messageId, const QVariantMap &payload)
|
||||||
|
{
|
||||||
|
LOG("Getting Callback Query Answer" << chatId << messageId);
|
||||||
|
QVariantMap requestObject;
|
||||||
|
requestObject.insert(_TYPE, "getCallbackQueryAnswer");
|
||||||
|
requestObject.insert("chat_id", chatId);
|
||||||
|
requestObject.insert("message_id", messageId);
|
||||||
|
requestObject.insert("payload", payload);
|
||||||
|
this->sendRequest(requestObject);
|
||||||
|
}
|
||||||
|
|
||||||
void TDLibWrapper::getChatPinnedMessage(const qlonglong &chatId)
|
void TDLibWrapper::getChatPinnedMessage(const qlonglong &chatId)
|
||||||
{
|
{
|
||||||
LOG("Retrieving pinned message" << chatId);
|
LOG("Retrieving pinned message" << chatId);
|
||||||
|
|
|
@ -143,6 +143,7 @@ public:
|
||||||
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 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 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 getMessage(const QString &chatId, const QString &messageId);
|
||||||
|
Q_INVOKABLE void getCallbackQueryAnswer(const QString &chatId, const QString &messageId, const QVariantMap &payload);
|
||||||
Q_INVOKABLE void getChatPinnedMessage(const qlonglong &chatId);
|
Q_INVOKABLE void getChatPinnedMessage(const qlonglong &chatId);
|
||||||
Q_INVOKABLE void setOptionInteger(const QString &optionName, int optionValue);
|
Q_INVOKABLE void setOptionInteger(const QString &optionName, int optionValue);
|
||||||
Q_INVOKABLE void setOptionBoolean(const QString &optionName, bool optionValue);
|
Q_INVOKABLE void setOptionBoolean(const QString &optionName, bool optionValue);
|
||||||
|
@ -219,6 +220,7 @@ signals:
|
||||||
void notificationUpdated(const QVariantMap updatedNotification);
|
void notificationUpdated(const QVariantMap updatedNotification);
|
||||||
void chatNotificationSettingsUpdated(const QString &chatId, const QVariantMap chatNotificationSettings);
|
void chatNotificationSettingsUpdated(const QString &chatId, const QVariantMap chatNotificationSettings);
|
||||||
void messageContentUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &newContent);
|
void messageContentUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &newContent);
|
||||||
|
void messageEditedUpdated(qlonglong chatId, qlonglong messageId, const QVariantMap &replyMarkup);
|
||||||
void messagesDeleted(qlonglong chatId, const QList<qlonglong> &messageIds);
|
void messagesDeleted(qlonglong chatId, const QList<qlonglong> &messageIds);
|
||||||
void chatsReceived(const QVariantMap &chats);
|
void chatsReceived(const QVariantMap &chats);
|
||||||
void chatReceived(const QVariantMap &chat);
|
void chatReceived(const QVariantMap &chat);
|
||||||
|
|
Loading…
Reference in a new issue