diff --git a/qml/pages/ChatPage.qml b/qml/pages/ChatPage.qml index 13cd035..2b989a4 100644 --- a/qml/pages/ChatPage.qml +++ b/qml/pages/ChatPage.qml @@ -440,7 +440,8 @@ Page { Component.onDestruction: { if (chatPage.canSendMessages && !chatPage.isDeletedUser) { - tdLibWrapper.setChatDraftMessage(chatInformation.id, 0, newMessageColumn.replyToMessageId, newMessageTextField.text); + tdLibWrapper.setChatDraftMessage(chatInformation.id, 0, newMessageColumn.replyToMessageId, newMessageTextField.text, + newMessageInReplyToRow.inReplyToMessage ? newMessageInReplyToRow.inReplyToMessage.id : 0); } fernschreiberUtils.stopGeoLocationUpdates(); tdLibWrapper.closeChat(chatInformation.id); diff --git a/src/tdlibreceiver.cpp b/src/tdlibreceiver.cpp index ba035e9..11a46dc 100644 --- a/src/tdlibreceiver.cpp +++ b/src/tdlibreceiver.cpp @@ -64,6 +64,7 @@ namespace { const QString REPLY_TO("reply_to"); const QString REPLY_IN_CHAT_ID("reply_in_chat_id"); const QString REPLY_TO_MESSAGE_ID("reply_to_message_id"); + const QString DRAFT_MESSAGE("draft_message"); const QString _TYPE("@type"); const QString _EXTRA("@extra"); @@ -77,6 +78,8 @@ namespace { const QString TYPE_MESSAGE_REPLY_TO_MESSAGE("messageReplyToMessage"); const QString TYPE_MESSAGE_ANIMATED_EMOJI("messageAnimatedEmoji"); const QString TYPE_ANIMATED_EMOJI("animatedEmoji"); + const QString TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE("inputMessageReplyToMessage"); + const QString TYPE_DRAFT_MESSAGE("draftMessage"); } static QString getChatPositionOrder(const QVariantMap &position) @@ -445,7 +448,7 @@ void TDLibReceiver::processMessageSendSucceeded(const QVariantMap &receivedInfor const QVariantMap message = receivedInformation.value(MESSAGE).toMap(); const qlonglong messageId = message.value(ID).toLongLong(); LOG("Message send succeeded" << messageId << oldMessageId); - emit messageSendSucceeded(messageId, oldMessageId, message); + emit messageSendSucceeded(messageId, oldMessageId, cleanupMap(message)); } void TDLibReceiver::processUpdateActiveNotifications(const QVariantMap &receivedInformation) @@ -672,7 +675,7 @@ void TDLibReceiver::processUpdateChatIsMarkedAsUnread(const QVariantMap &receive void TDLibReceiver::processUpdateChatDraftMessage(const QVariantMap &receivedInformation) { LOG("Draft message was updated"); - emit chatDraftMessageUpdated(receivedInformation.value(CHAT_ID).toLongLong(), receivedInformation.value("draft_message").toMap(), findChatPositionOrder(receivedInformation.value(POSITIONS).toList())); + emit chatDraftMessageUpdated(receivedInformation.value(CHAT_ID).toLongLong(), cleanupMap(receivedInformation.value(DRAFT_MESSAGE).toMap()), findChatPositionOrder(receivedInformation.value(POSITIONS).toList())); } void TDLibReceiver::processInlineQueryResults(const QVariantMap &receivedInformation) @@ -815,6 +818,24 @@ const QVariantMap TDLibReceiver::cleanupMap(const QVariantMap& map, bool *update if (updated) *updated = true; return message; } + } else if (type == TYPE_DRAFT_MESSAGE) { + QVariantMap draftMessage(map); + QVariantMap reply_to(draftMessage.value(REPLY_TO).toMap()); + // In TdLib 1.8.21 reply_to_message_id has been replaced with reply_to + if (reply_to.value(_TYPE).toString() == TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE) { + if (reply_to.contains(MESSAGE_ID) && + !draftMessage.contains(REPLY_TO_MESSAGE_ID)) { + // reply_to_message_id is what QML (still) expects + draftMessage.insert(REPLY_TO_MESSAGE_ID, reply_to.value(MESSAGE_ID)); + } + reply_to.remove(_TYPE); + reply_to.insert(_TYPE, TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE); // Shared value + draftMessage.insert(REPLY_TO, reply_to); + draftMessage.remove(_TYPE); + draftMessage.insert(_TYPE, DRAFT_MESSAGE); // Shared value + if (updated) *updated = true; + return draftMessage; + } } else if (type == TYPE_MESSAGE_STICKER) { bool cleaned = false; const QVariantMap content(cleanupMap(map.value(CONTENT).toMap(), &cleaned)); diff --git a/src/tdlibwrapper.cpp b/src/tdlibwrapper.cpp index 6cedc4d..509e7cc 100644 --- a/src/tdlibwrapper.cpp +++ b/src/tdlibwrapper.cpp @@ -51,6 +51,8 @@ namespace { const QString THREAD_ID("thread_id"); const QString VALUE("value"); const QString CHAT_LIST_TYPE("chat_list_type"); + const QString REPLY_TO_MESSAGE_ID("reply_to_message_id"); + const QString REPLY_TO("reply_to"); const QString _TYPE("@type"); const QString _EXTRA("@extra"); const QString CHAT_LIST_MAIN("chatListMain"); @@ -61,6 +63,8 @@ namespace { const QString REACTION_TYPE("reaction_type"); const QString REACTION_TYPE_EMOJI("reactionTypeEmoji"); const QString EMOJI("emoji"); + const QString TYPE_MESSAGE_REPLY_TO_MESSAGE("messageReplyToMessage"); + const QString TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE("inputMessageReplyToMessage"); } TDLibWrapper::TDLibWrapper(AppSettings *settings, MceInterface *mce, QObject *parent) @@ -401,15 +405,33 @@ static bool compareReplacements(const QVariant &replacement1, const QVariant &re } } -void TDLibWrapper::sendTextMessage(const QString &chatId, const QString &message, const QString &replyToMessageId) +QVariantMap TDLibWrapper::newSendMessageRequest(qlonglong chatId, qlonglong replyToMessageId) +{ + QVariantMap request; + request.insert(_TYPE, "sendMessage"); + request.insert(CHAT_ID, chatId); + if (replyToMessageId) { + if (versionNumber > VERSION_NUMBER(1,8,14)) { + QVariantMap replyTo; + if (versionNumber > VERSION_NUMBER(1,8,20)) { + replyTo.insert(_TYPE, TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE); + } else { + replyTo.insert(_TYPE, TYPE_MESSAGE_REPLY_TO_MESSAGE); + } + replyTo.insert(CHAT_ID, chatId); + replyTo.insert(MESSAGE_ID, replyToMessageId); + request.insert(REPLY_TO, replyTo); + } else { + request.insert(REPLY_TO_MESSAGE_ID, replyToMessageId); + } + } + return request; +} + +void TDLibWrapper::sendTextMessage(qlonglong chatId, const QString &message, qlonglong replyToMessageId) { LOG("Sending text message" << chatId << message << replyToMessageId); - QVariantMap requestObject; - requestObject.insert(_TYPE, "sendMessage"); - requestObject.insert(CHAT_ID, chatId); - if (replyToMessageId != "0") { - requestObject.insert("reply_to_message_id", replyToMessageId); - } + QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId)); QVariantMap inputMessageContent; inputMessageContent.insert(_TYPE, "inputMessageText"); @@ -462,17 +484,13 @@ void TDLibWrapper::sendTextMessage(const QString &chatId, const QString &message this->sendRequest(requestObject); } -void TDLibWrapper::sendPhotoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId) +void TDLibWrapper::sendPhotoMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId) { LOG("Sending photo message" << chatId << filePath << message << replyToMessageId); - QVariantMap requestObject; - requestObject.insert(_TYPE, "sendMessage"); - requestObject.insert(CHAT_ID, chatId); - if (replyToMessageId != "0") { - requestObject.insert("reply_to_message_id", replyToMessageId); - } + QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId)); QVariantMap inputMessageContent; inputMessageContent.insert(_TYPE, "inputMessagePhoto"); + QVariantMap formattedText; formattedText.insert("text", message); formattedText.insert(_TYPE, "formattedText"); @@ -486,17 +504,13 @@ void TDLibWrapper::sendPhotoMessage(const QString &chatId, const QString &filePa this->sendRequest(requestObject); } -void TDLibWrapper::sendVideoMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId) +void TDLibWrapper::sendVideoMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId) { LOG("Sending video message" << chatId << filePath << message << replyToMessageId); - QVariantMap requestObject; - requestObject.insert(_TYPE, "sendMessage"); - requestObject.insert(CHAT_ID, chatId); - if (replyToMessageId != "0") { - requestObject.insert("reply_to_message_id", replyToMessageId); - } + QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId)); QVariantMap inputMessageContent; inputMessageContent.insert(_TYPE, "inputMessageVideo"); + QVariantMap formattedText; formattedText.insert("text", message); formattedText.insert(_TYPE, "formattedText"); @@ -510,17 +524,13 @@ void TDLibWrapper::sendVideoMessage(const QString &chatId, const QString &filePa this->sendRequest(requestObject); } -void TDLibWrapper::sendDocumentMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId) +void TDLibWrapper::sendDocumentMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId) { LOG("Sending document message" << chatId << filePath << message << replyToMessageId); - QVariantMap requestObject; - requestObject.insert(_TYPE, "sendMessage"); - requestObject.insert(CHAT_ID, chatId); - if (replyToMessageId != "0") { - requestObject.insert("reply_to_message_id", replyToMessageId); - } + QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId)); QVariantMap inputMessageContent; inputMessageContent.insert(_TYPE, "inputMessageDocument"); + QVariantMap formattedText; formattedText.insert("text", message); formattedText.insert(_TYPE, "formattedText"); @@ -534,17 +544,13 @@ void TDLibWrapper::sendDocumentMessage(const QString &chatId, const QString &fil this->sendRequest(requestObject); } -void TDLibWrapper::sendVoiceNoteMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId) +void TDLibWrapper::sendVoiceNoteMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId) { LOG("Sending voice note message" << chatId << filePath << message << replyToMessageId); - QVariantMap requestObject; - requestObject.insert(_TYPE, "sendMessage"); - requestObject.insert(CHAT_ID, chatId); - if (replyToMessageId != "0") { - requestObject.insert("reply_to_message_id", replyToMessageId); - } + QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId)); QVariantMap inputMessageContent; inputMessageContent.insert(_TYPE, "inputMessageVoiceNote"); + QVariantMap formattedText; formattedText.insert("text", message); formattedText.insert(_TYPE, "formattedText"); @@ -558,24 +564,19 @@ void TDLibWrapper::sendVoiceNoteMessage(const QString &chatId, const QString &fi this->sendRequest(requestObject); } -void TDLibWrapper::sendLocationMessage(const QString &chatId, double latitude, double longitude, double horizontalAccuracy, const QString &replyToMessageId) +void TDLibWrapper::sendLocationMessage(qlonglong chatId, double latitude, double longitude, double horizontalAccuracy, qlonglong replyToMessageId) { LOG("Sending location message" << chatId << latitude << longitude << horizontalAccuracy << replyToMessageId); - QVariantMap requestObject; - requestObject.insert(_TYPE, "sendMessage"); - requestObject.insert(CHAT_ID, chatId); - if (replyToMessageId != "0") { - requestObject.insert("reply_to_message_id", replyToMessageId); - } + QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId)); QVariantMap inputMessageContent; inputMessageContent.insert(_TYPE, "inputMessageLocation"); + QVariantMap location; location.insert("latitude", latitude); location.insert("longitude", longitude); location.insert("horizontal_accuracy", horizontalAccuracy); location.insert(_TYPE, "location"); inputMessageContent.insert("location", location); - inputMessageContent.insert("live_period", 0); inputMessageContent.insert("heading", 0); inputMessageContent.insert("proximity_alert_radius", 0); @@ -584,15 +585,10 @@ void TDLibWrapper::sendLocationMessage(const QString &chatId, double latitude, d this->sendRequest(requestObject); } -void TDLibWrapper::sendStickerMessage(const QString &chatId, const QString &fileId, const QString &replyToMessageId) +void TDLibWrapper::sendStickerMessage(qlonglong chatId, const QString &fileId, qlonglong replyToMessageId) { LOG("Sending sticker message" << chatId << fileId << replyToMessageId); - QVariantMap requestObject; - requestObject.insert(_TYPE, "sendMessage"); - requestObject.insert(CHAT_ID, chatId); - if (replyToMessageId != "0") { - requestObject.insert("reply_to_message_id", replyToMessageId); - } + QVariantMap requestObject(newSendMessageRequest(chatId, replyToMessageId)); QVariantMap inputMessageContent; inputMessageContent.insert(_TYPE, "inputMessageSticker"); @@ -606,15 +602,10 @@ void TDLibWrapper::sendStickerMessage(const QString &chatId, const QString &file this->sendRequest(requestObject); } -void TDLibWrapper::sendPollMessage(const QString &chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &explanation, const QString &replyToMessageId) +void TDLibWrapper::sendPollMessage(qlonglong chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &explanation, qlonglong 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 requestObject(newSendMessageRequest(chatId, replyToMessageId)); QVariantMap inputMessageContent; inputMessageContent.insert(_TYPE, "inputMessagePoll"); @@ -1187,9 +1178,18 @@ void TDLibWrapper::setChatDraftMessage(qlonglong chatId, qlonglong threadId, qlo inputMessageContent.insert(_TYPE, "inputMessageText"); inputMessageContent.insert("text", formattedText); draftMessage.insert(_TYPE, "draftMessage"); - draftMessage.insert("reply_to_message_id", replyToMessageId); draftMessage.insert("input_message_text", inputMessageContent); + if (versionNumber > VERSION_NUMBER(1,8,20)) { + QVariantMap replyTo; + replyTo.insert(_TYPE, TYPE_INPUT_MESSAGE_REPLY_TO_MESSAGE); + replyTo.insert(CHAT_ID, chatId); + replyTo.insert(MESSAGE_ID, replyToMessageId); + draftMessage.insert(REPLY_TO, replyTo); + } else { + draftMessage.insert(REPLY_TO_MESSAGE_ID, replyToMessageId); + } + requestObject.insert("draft_message", draftMessage); this->sendRequest(requestObject); } diff --git a/src/tdlibwrapper.h b/src/tdlibwrapper.h index 4caff11..33e29b4 100644 --- a/src/tdlibwrapper.h +++ b/src/tdlibwrapper.h @@ -176,14 +176,14 @@ public: Q_INVOKABLE void viewMessage(qlonglong chatId, qlonglong messageId, bool force); Q_INVOKABLE void pinMessage(const QString &chatId, const QString &messageId, bool disableNotification = false); Q_INVOKABLE void unpinMessage(const QString &chatId, const QString &messageId); - 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 sendVoiceNoteMessage(const QString &chatId, const QString &filePath, const QString &message, const QString &replyToMessageId = "0"); - Q_INVOKABLE void sendLocationMessage(const QString &chatId, double latitude, double longitude, double horizontalAccuracy, 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, bool anonymous, int correctOption, bool multiple, const QString &explanation, const QString &replyToMessageId = "0"); + Q_INVOKABLE void sendTextMessage(qlonglong chatId, const QString &message, qlonglong replyToMessageId = 0); + Q_INVOKABLE void sendPhotoMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId = 0); + Q_INVOKABLE void sendVideoMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId = 0); + Q_INVOKABLE void sendDocumentMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId = 0); + Q_INVOKABLE void sendVoiceNoteMessage(qlonglong chatId, const QString &filePath, const QString &message, qlonglong replyToMessageId = 0); + Q_INVOKABLE void sendLocationMessage(qlonglong chatId, double latitude, double longitude, double horizontalAccuracy, qlonglong replyToMessageId = 0); + Q_INVOKABLE void sendStickerMessage(qlonglong chatId, const QString &fileId, qlonglong replyToMessageId = 0); + Q_INVOKABLE void sendPollMessage(qlonglong chatId, const QString &question, const QVariantList &options, bool anonymous, int correctOption, bool multiple, const QString &explanation, qlonglong replyToMessageId = 0); Q_INVOKABLE void forwardMessages(const QString &chatId, const QString &fromChatId, const QVariantList &messageIds, bool sendCopy, bool removeCaption); Q_INVOKABLE void getMessage(qlonglong chatId, qlonglong messageId); Q_INVOKABLE void getMessageLinkInfo(const QString &url, const QString &extra = ""); @@ -375,6 +375,7 @@ private: void setLogVerbosityLevel(); QVariantMap &fillTdlibParameters(QVariantMap ¶meters); const Group *updateGroup(qlonglong groupId, const QVariantMap &groupInfo, QHash *groups); + QVariantMap newSendMessageRequest(qlonglong chatId, qlonglong replyToMessageId); void initializeTDLibReceiver(); private: