commit
00287ea89c
22 changed files with 5204 additions and 2554 deletions
|
@ -42,7 +42,9 @@ const char TDLIB_API_HASH[] = "1234567890abcdef1234567890abcdef";
|
||||||
|
|
||||||
You get the Telegram API ID and hash as soon as you've registered your own application on [https://my.telegram.org](https://my.telegram.org).
|
You get the Telegram API ID and hash as soon as you've registered your own application on [https://my.telegram.org](https://my.telegram.org).
|
||||||
|
|
||||||
Moreover, you need to have a compiled version of [TDLib](https://github.com/tdlib/td) in the sub-directory `tdlib`. This sub-directory must contain another sub-directory that fits to the target device architecture (e.g. armv7hl, i486). Within this directory, there needs to be a folder called `lib` that contains at least `libtdjson.so`. For armv7hl the relative path would consequently be `tdlib/armv7hl/lib`.
|
Moreover, you need to have a compiled version of [TDLib 1.7](https://github.com/tdlib/td) in the sub-directory `tdlib`. This sub-directory must contain another sub-directory that fits to the target device architecture (e.g. armv7hl, i486). Within this directory, there needs to be a folder called `lib` that contains at least `libtdjson.so`. For armv7hl the relative path would consequently be `tdlib/armv7hl/lib`.
|
||||||
|
|
||||||
|
In case you encounter strange performance issues on startup (several seconds delay, app seems to do nothing), please be sure to [follow the instructions from the respective GitHub issue](https://github.com/tdlib/td/issues/1322), i.e. let TDLib build SQLite with `-DOMIT_MEMLOCK` and be sure to comment the two lines 22558 (`#ifndef OMIT_MEMLOCK`) and 22567 (`#endif`) in the file `sqlite/sqlite/sqlite3.c`.
|
||||||
|
|
||||||
## Debug
|
## Debug
|
||||||
Fernschreiber does only output a few TDLib messages by default. To get its own debug log messages, you can either run a debug build to see all of them or use the environment variable `QT_LOGGING_RULES` to specify/filter which messages you'd like to see.
|
Fernschreiber does only output a few TDLib messages by default. To get its own debug log messages, you can either run a debug build to see all of them or use the environment variable `QT_LOGGING_RULES` to specify/filter which messages you'd like to see.
|
||||||
|
|
|
@ -36,8 +36,8 @@ Row {
|
||||||
|
|
||||||
onInReplyToMessageChanged: {
|
onInReplyToMessageChanged: {
|
||||||
if (inReplyToMessage) {
|
if (inReplyToMessage) {
|
||||||
inReplyToUserText.text = (inReplyToRow.inReplyToMessage.sender_user_id !== inReplyToRow.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(inReplyToRow.inReplyToMessage.sender_user_id)), inReplyToUserText.font.pixelSize) : qsTr("You");
|
inReplyToUserText.text = (inReplyToRow.inReplyToMessage.sender.user_id !== inReplyToRow.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(inReplyToRow.inReplyToMessage.sender.user_id)), inReplyToUserText.font.pixelSize) : qsTr("You");
|
||||||
inReplyToMessageText.text = Emoji.emojify(Functions.getMessageText(inReplyToRow.inReplyToMessage, true, inReplyToRow.inReplyToMessage.sender_user_id === inReplyToRow.myUserId, false), inReplyToMessageText.font.pixelSize);
|
inReplyToMessageText.text = Emoji.emojify(Functions.getMessageText(inReplyToRow.inReplyToMessage, true, inReplyToRow.inReplyToMessage.sender.user_id === inReplyToRow.myUserId, false), inReplyToMessageText.font.pixelSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +77,10 @@ Row {
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
|
linkColor: Theme.highlightColor
|
||||||
|
onLinkActivated: {
|
||||||
|
Functions.handleLink(link);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ ListItem {
|
||||||
property var messageId
|
property var messageId
|
||||||
property var myMessage
|
property var myMessage
|
||||||
property bool canReplyToMessage
|
property bool canReplyToMessage
|
||||||
readonly property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender_user_id)
|
readonly property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender.user_id)
|
||||||
property QtObject precalculatedValues: ListView.view.precalculatedValues
|
property QtObject precalculatedValues: ListView.view.precalculatedValues
|
||||||
readonly property color textColor: isOwnMessage ? Theme.highlightColor : Theme.primaryColor
|
readonly property color textColor: isOwnMessage ? Theme.highlightColor : Theme.primaryColor
|
||||||
readonly property int textAlign: isOwnMessage ? Text.AlignRight : Text.AlignLeft
|
readonly property int textAlign: isOwnMessage ? Text.AlignRight : Text.AlignLeft
|
||||||
|
@ -37,7 +37,7 @@ ListItem {
|
||||||
readonly property bool isSelected: messageListItem.precalculatedValues.pageIsSelecting && page.selectedMessages.some(function(existingMessage) {
|
readonly property bool isSelected: messageListItem.precalculatedValues.pageIsSelecting && page.selectedMessages.some(function(existingMessage) {
|
||||||
return existingMessage.id === messageId
|
return existingMessage.id === messageId
|
||||||
});
|
});
|
||||||
readonly property bool isOwnMessage: page.myUserId === myMessage.sender_user_id
|
readonly property bool isOwnMessage: page.myUserId === myMessage.sender.user_id
|
||||||
property string extraContentComponentName
|
property string extraContentComponentName
|
||||||
|
|
||||||
highlighted: (down || isSelected) && !menuOpen
|
highlighted: (down || isSelected) && !menuOpen
|
||||||
|
|
|
@ -24,8 +24,8 @@ import "../js/functions.js" as Functions
|
||||||
Item {
|
Item {
|
||||||
id: messageListItem
|
id: messageListItem
|
||||||
property var myMessage: display
|
property var myMessage: display
|
||||||
property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender_user_id)
|
property var userInformation: tdLibWrapper.getUserInformation(myMessage.sender.user_id)
|
||||||
property bool isOwnMessage: chatPage.myUserId === myMessage.sender_user_id
|
property bool isOwnMessage: chatPage.myUserId === myMessage.sender.user_id
|
||||||
height: backgroundRectangle.height + Theme.paddingMedium
|
height: backgroundRectangle.height + Theme.paddingMedium
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
|
@ -31,8 +31,8 @@ Flickable {
|
||||||
|
|
||||||
property var overlayMessage;
|
property var overlayMessage;
|
||||||
property bool showHeader: true
|
property bool showHeader: true
|
||||||
readonly property var userInformation: tdLibWrapper.getUserInformation(overlayMessage.sender_user_id);
|
readonly property var userInformation: tdLibWrapper.getUserInformation(overlayMessage.sender.user_id);
|
||||||
readonly property bool isOwnMessage: tdLibWrapper.getUserInformation().id === overlayMessage.sender_user_id;
|
readonly property bool isOwnMessage: tdLibWrapper.getUserInformation().id === overlayMessage.sender.user_id;
|
||||||
readonly property string extraContentComponentName: (typeof overlayMessage.content !== "undefined" && typeof chatView.contentComponentNames[overlayMessage.content['@type']] !== "undefined" )
|
readonly property string extraContentComponentName: (typeof overlayMessage.content !== "undefined" && typeof chatView.contentComponentNames[overlayMessage.content['@type']] !== "undefined" )
|
||||||
? chatView.contentComponentNames[overlayMessage.content['@type']] : ""
|
? chatView.contentComponentNames[overlayMessage.content['@type']] : ""
|
||||||
signal requestClose;
|
signal requestClose;
|
||||||
|
@ -43,7 +43,7 @@ Flickable {
|
||||||
var otherChatInformation = tdLibWrapper.getChat(forwardInformation.origin.chat_id);
|
var otherChatInformation = tdLibWrapper.getChat(forwardInformation.origin.chat_id);
|
||||||
return Emoji.emojify(otherChatInformation.title, fontSize);
|
return Emoji.emojify(otherChatInformation.title, fontSize);
|
||||||
case "messageForwardOriginUser":
|
case "messageForwardOriginUser":
|
||||||
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender_user_id);
|
var otherUserInformation = tdLibWrapper.getUserInformation(forwardInformation.origin.sender.user_id);
|
||||||
return Emoji.emojify(Functions.getUserName(otherUserInformation), fontSize);
|
return Emoji.emojify(Functions.getUserName(otherUserInformation), fontSize);
|
||||||
default:
|
default:
|
||||||
return Emoji.emojify(forwardInformation.origin.sender_name, fontSize);
|
return Emoji.emojify(forwardInformation.origin.sender_name, fontSize);
|
||||||
|
|
|
@ -33,9 +33,9 @@ Item {
|
||||||
onPinnedMessageChanged: {
|
onPinnedMessageChanged: {
|
||||||
if (pinnedMessage) {
|
if (pinnedMessage) {
|
||||||
Debug.log("[ChatPage] Activating pinned message");
|
Debug.log("[ChatPage] Activating pinned message");
|
||||||
var messageUserText = (pinnedMessage.sender_user_id !== chatPage.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(pinnedMessage.sender_user_id)), pinnedMessageUserText.font.pixelSize) : qsTr("You");
|
var messageUserText = (pinnedMessage.sender.user_id !== chatPage.myUserId) ? Emoji.emojify(Functions.getUserName(tdLibWrapper.getUserInformation(pinnedMessage.sender.user_id)), pinnedMessageUserText.font.pixelSize) : qsTr("You");
|
||||||
pinnedMessageUserText.text = (messageUserText === "" ? qsTr("Pinned Message") : messageUserText );
|
pinnedMessageUserText.text = (messageUserText === "" ? qsTr("Pinned Message") : messageUserText );
|
||||||
pinnedMessageText.text = Emoji.emojify(Functions.getMessageText(pinnedMessage, true, pinnedMessage.sender_user_id === chatPage.myUserId, false), pinnedMessageText.font.pixelSize);
|
pinnedMessageText.text = Emoji.emojify(Functions.getMessageText(pinnedMessage, true, pinnedMessage.sender.user_id === chatPage.myUserId, false), pinnedMessageText.font.pixelSize);
|
||||||
pinnedMessageItem.visible = true;
|
pinnedMessageItem.visible = true;
|
||||||
} else {
|
} else {
|
||||||
pinnedMessageItem.visible = false;
|
pinnedMessageItem.visible = false;
|
||||||
|
|
|
@ -91,7 +91,7 @@ Item {
|
||||||
height: recentStickersGridView.cellHeight
|
height: recentStickersGridView.cellHeight
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
source: modelData.thumbnail.photo.local.path
|
source: modelData.thumbnail.file.local.path
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
|
@ -144,9 +144,9 @@ Item {
|
||||||
|
|
||||||
Image {
|
Image {
|
||||||
id: singleStickerImage
|
id: singleStickerImage
|
||||||
source: modelData.thumbnail.photo.local.is_downloading_completed ? modelData.thumbnail.photo.local.path : ""
|
source: modelData.thumbnail.file.local.is_downloading_completed ? modelData.thumbnail.file.local.path : ""
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
visible: modelData.thumbnail.photo.local.is_downloading_completed
|
visible: modelData.thumbnail.file.local.is_downloading_completed
|
||||||
asynchronous: true
|
asynchronous: true
|
||||||
onStatusChanged: {
|
onStatusChanged: {
|
||||||
if (status === Image.Ready) {
|
if (status === Image.Ready) {
|
||||||
|
@ -160,7 +160,7 @@ Item {
|
||||||
maximumLineCount: 1
|
maximumLineCount: 1
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
text: Emoji.emojify(modelData.emoji, font.pixelSize)
|
text: Emoji.emojify(modelData.emoji, font.pixelSize)
|
||||||
visible: !modelData.thumbnail.photo.local.is_downloading_completed
|
visible: !modelData.thumbnail.file.local.is_downloading_completed
|
||||||
}
|
}
|
||||||
|
|
||||||
MouseArea {
|
MouseArea {
|
||||||
|
|
|
@ -89,10 +89,14 @@ Item {
|
||||||
|
|
||||||
videoMessageComponent.videoType = videoMessageComponent.isVideoNote ? "video" : videoData['@type'];
|
videoMessageComponent.videoType = videoMessageComponent.isVideoNote ? "video" : videoData['@type'];
|
||||||
videoFileId = videoData[videoType].id;
|
videoFileId = videoData[videoType].id;
|
||||||
if (typeof videoData.thumbnail !== "undefined") {
|
if (rawMessage.content['@type'] === "messageAnimation") {
|
||||||
previewFileId = videoData.thumbnail.photo.id;
|
playButton.visible = true;
|
||||||
if (videoData.thumbnail.photo.local.is_downloading_completed) {
|
fullscreenButton.visible = !videoMessageComponent.fullscreen;
|
||||||
placeholderImage.source = videoData.thumbnail.photo.local.path;
|
handlePlay();
|
||||||
|
} else if (typeof videoData.thumbnail !== "undefined") {
|
||||||
|
previewFileId = videoData.thumbnail.file.id;
|
||||||
|
if (videoData.thumbnail.file.local.is_downloading_completed) {
|
||||||
|
placeholderImage.source = videoData.thumbnail.file.local.path;
|
||||||
} else {
|
} else {
|
||||||
tdLibWrapper.downloadFile(previewFileId);
|
tdLibWrapper.downloadFile(previewFileId);
|
||||||
}
|
}
|
||||||
|
|
|
@ -103,13 +103,17 @@ Column {
|
||||||
id: descriptionText
|
id: descriptionText
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
text: webPageData.description ? Emoji.emojify(webPageData.description, font.pixelSize) : ""
|
text: webPageData.description ? Emoji.emojify(Functions.enhanceMessageText(webPageData.description), font.pixelSize) : ""
|
||||||
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
|
font.pixelSize: webPagePreviewColumn.largerFontSize ? Theme.fontSizeSmall : Theme.fontSizeExtraSmall
|
||||||
truncationMode: TruncationMode.Fade
|
truncationMode: TruncationMode.Fade
|
||||||
wrapMode: Text.Wrap
|
wrapMode: Text.Wrap
|
||||||
maximumLineCount: 3
|
maximumLineCount: 3
|
||||||
textFormat: Text.StyledText
|
textFormat: Text.StyledText
|
||||||
visible: (text !== "")
|
visible: (text !== "")
|
||||||
|
linkColor: Theme.highlightColor
|
||||||
|
onLinkActivated: {
|
||||||
|
Functions.handleLink(link);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
|
|
|
@ -401,7 +401,7 @@ function getMessagesArrayText(messages) {
|
||||||
var lastSenderName = "";
|
var lastSenderName = "";
|
||||||
var lines = [];
|
var lines = [];
|
||||||
for(var i = 0; i < messages.length; i += 1) {
|
for(var i = 0; i < messages.length; i += 1) {
|
||||||
var senderName = getUserName(tdLibWrapper.getUserInformation(messages[i].sender_user_id));
|
var senderName = getUserName(tdLibWrapper.getUserInformation(messages[i].sender.user_id));
|
||||||
if(senderName !== lastSenderName) {
|
if(senderName !== lastSenderName) {
|
||||||
lines.push(senderName);
|
lines.push(senderName);
|
||||||
}
|
}
|
||||||
|
|
|
@ -186,7 +186,7 @@ Page {
|
||||||
messageStatusSuffix += " - " + qsTr("edited");
|
messageStatusSuffix += " - " + qsTr("edited");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (chatPage.myUserId === message.sender_user_id) {
|
if (chatPage.myUserId === message.sender.user_id) {
|
||||||
messageStatusSuffix += " "
|
messageStatusSuffix += " "
|
||||||
if (listItemIndex <= lastReadSentIndex) {
|
if (listItemIndex <= lastReadSentIndex) {
|
||||||
// Read by other party
|
// Read by other party
|
||||||
|
@ -475,7 +475,7 @@ Page {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onNewMessageReceived: {
|
onNewMessageReceived: {
|
||||||
if (chatView.manuallyScrolledToBottom || message.sender_user_id === chatPage.myUserId) {
|
if (chatView.manuallyScrolledToBottom || message.sender.user_id === chatPage.myUserId) {
|
||||||
Debug.log("[ChatPage] Own message received or was scrolled to bottom, scrolling down to see it...");
|
Debug.log("[ChatPage] Own message received or was scrolled to bottom, scrolling down to see it...");
|
||||||
chatView.scrollToIndex(chatView.count - 1);
|
chatView.scrollToIndex(chatView.count - 1);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ Page {
|
||||||
|
|
||||||
property var pollData: message.content.poll
|
property var pollData: message.content.poll
|
||||||
|
|
||||||
property var userInformation: tdLibWrapper.getUserInformation(message.sender_user_id)
|
property var userInformation: tdLibWrapper.getUserInformation(message.sender.user_id)
|
||||||
|
|
||||||
property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz"
|
property bool isQuiz: pollData.type['@type'] === "pollTypeQuiz"
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,8 @@ namespace {
|
||||||
const QString CHAT_ID("chat_id");
|
const QString CHAT_ID("chat_id");
|
||||||
const QString CONTENT("content");
|
const QString CONTENT("content");
|
||||||
const QString LAST_MESSAGE("last_message");
|
const QString LAST_MESSAGE("last_message");
|
||||||
const QString SENDER_USER_ID("sender_user_id");
|
const QString SENDER("sender");
|
||||||
|
const QString USER_ID("user_id");
|
||||||
const QString BASIC_GROUP_ID("basic_group_id");
|
const QString BASIC_GROUP_ID("basic_group_id");
|
||||||
const QString SUPERGROUP_ID("supergroup_id");
|
const QString SUPERGROUP_ID("supergroup_id");
|
||||||
const QString UNREAD_COUNT("unread_count");
|
const QString UNREAD_COUNT("unread_count");
|
||||||
|
@ -81,6 +82,8 @@ public:
|
||||||
QVariant photoSmall() const;
|
QVariant photoSmall() const;
|
||||||
qlonglong lastReadInboxMessageId() const;
|
qlonglong lastReadInboxMessageId() const;
|
||||||
qlonglong senderUserId() const;
|
qlonglong senderUserId() const;
|
||||||
|
qlonglong senderChatId() const;
|
||||||
|
bool senderIsChat() const;
|
||||||
qlonglong senderMessageDate() const;
|
qlonglong senderMessageDate() const;
|
||||||
QString senderMessageText() const;
|
QString senderMessageText() const;
|
||||||
QString senderMessageStatus() const;
|
QString senderMessageStatus() const;
|
||||||
|
@ -176,7 +179,17 @@ qlonglong ChatListModel::ChatData::lastReadInboxMessageId() const
|
||||||
|
|
||||||
qlonglong ChatListModel::ChatData::senderUserId() const
|
qlonglong ChatListModel::ChatData::senderUserId() const
|
||||||
{
|
{
|
||||||
return lastMessage(SENDER_USER_ID).toLongLong();
|
return lastMessage(SENDER).toMap().value(USER_ID).toLongLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
qlonglong ChatListModel::ChatData::senderChatId() const
|
||||||
|
{
|
||||||
|
return lastMessage(SENDER).toMap().value(CHAT_ID).toLongLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatListModel::ChatData::senderIsChat() const
|
||||||
|
{
|
||||||
|
return lastMessage(SENDER).toMap().value(_TYPE).toString() == "messageSenderChat";
|
||||||
}
|
}
|
||||||
|
|
||||||
qlonglong ChatListModel::ChatData::senderMessageDate() const
|
qlonglong ChatListModel::ChatData::senderMessageDate() const
|
||||||
|
|
|
@ -35,7 +35,8 @@ namespace {
|
||||||
const QString UNREAD_COUNT("unread_count");
|
const QString UNREAD_COUNT("unread_count");
|
||||||
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
|
const QString LAST_READ_INBOX_MESSAGE_ID("last_read_inbox_message_id");
|
||||||
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
|
const QString LAST_READ_OUTBOX_MESSAGE_ID("last_read_outbox_message_id");
|
||||||
const QString SENDER_USER_ID("sender_user_id");
|
const QString SENDER("sender");
|
||||||
|
const QString USER_ID("user_id");
|
||||||
const QString PINNED_MESSAGE_ID("pinned_message_id");
|
const QString PINNED_MESSAGE_ID("pinned_message_id");
|
||||||
const QString _TYPE("@type");
|
const QString _TYPE("@type");
|
||||||
}
|
}
|
||||||
|
@ -54,6 +55,8 @@ 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);
|
||||||
int senderUserId() const;
|
int senderUserId() const;
|
||||||
|
qlonglong senderChatId() const;
|
||||||
|
bool senderIsChat() const;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
QVariantMap messageData;
|
QVariantMap messageData;
|
||||||
|
@ -70,7 +73,17 @@ ChatModel::MessageData::MessageData(const QVariantMap &data, qlonglong msgid) :
|
||||||
|
|
||||||
int ChatModel::MessageData::senderUserId() const
|
int ChatModel::MessageData::senderUserId() const
|
||||||
{
|
{
|
||||||
return messageData.value(SENDER_USER_ID).toInt();
|
return messageData.value(SENDER).toMap().value(USER_ID).toInt();
|
||||||
|
}
|
||||||
|
|
||||||
|
qlonglong ChatModel::MessageData::senderChatId() const
|
||||||
|
{
|
||||||
|
return messageData.value(SENDER).toMap().value(CHAT_ID).toLongLong();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChatModel::MessageData::senderIsChat() const
|
||||||
|
{
|
||||||
|
return messageData.value(SENDER).toMap().value(_TYPE).toString() == "messageSenderChat";
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatModel::MessageData::setContent(const QVariantMap &content)
|
void ChatModel::MessageData::setContent(const QVariantMap &content)
|
||||||
|
|
|
@ -43,7 +43,8 @@ namespace {
|
||||||
const QString MESSAGE("message");
|
const QString MESSAGE("message");
|
||||||
const QString FIRST_NAME("first_name");
|
const QString FIRST_NAME("first_name");
|
||||||
const QString LAST_NAME("last_name");
|
const QString LAST_NAME("last_name");
|
||||||
const QString SENDER_USER_ID("sender_user_id");
|
const QString SENDER("sender");
|
||||||
|
const QString USER_ID("user_id");
|
||||||
const QString NOTIFICATIONS("notifications");
|
const QString NOTIFICATIONS("notifications");
|
||||||
const QString NOTIFICATION_GROUP_ID("notification_group_id");
|
const QString NOTIFICATION_GROUP_ID("notification_group_id");
|
||||||
const QString ADDED_NOTIFICATIONS("added_notifications");
|
const QString ADDED_NOTIFICATIONS("added_notifications");
|
||||||
|
@ -336,10 +337,17 @@ void NotificationManager::publishNotification(const NotificationGroup *notificat
|
||||||
if (chatInformation && (chatInformation->type == TDLibWrapper::ChatTypeBasicGroup ||
|
if (chatInformation && (chatInformation->type == TDLibWrapper::ChatTypeBasicGroup ||
|
||||||
(chatInformation->type == TDLibWrapper::ChatTypeSupergroup && !chatInformation->isChannel))) {
|
(chatInformation->type == TDLibWrapper::ChatTypeSupergroup && !chatInformation->isChannel))) {
|
||||||
// Add author
|
// Add author
|
||||||
const QVariantMap authorInformation = tdLibWrapper->getUserInformation(messageMap.value(SENDER_USER_ID).toString());
|
const QVariantMap senderInformation = messageMap.value(SENDER).toMap();
|
||||||
const QString firstName = authorInformation.value(FIRST_NAME).toString();
|
QString fullName;
|
||||||
const QString lastName = authorInformation.value(LAST_NAME).toString();
|
if (senderInformation.value(_TYPE).toString() == "messageSenderChat") {
|
||||||
const QString fullName = firstName + " " + lastName;
|
fullName = tdLibWrapper->getChat(senderInformation.value(CHAT_ID).toString()).value(TITLE).toString();
|
||||||
|
} else {
|
||||||
|
const QVariantMap authorInformation = tdLibWrapper->getUserInformation(senderInformation.value(USER_ID).toString());
|
||||||
|
const QString firstName = authorInformation.value(FIRST_NAME).toString();
|
||||||
|
const QString lastName = authorInformation.value(LAST_NAME).toString();
|
||||||
|
fullName = firstName + " " + lastName;
|
||||||
|
}
|
||||||
|
|
||||||
notificationBody = notificationBody + fullName.trimmed() + ": ";
|
notificationBody = notificationBody + fullName.trimmed() + ": ";
|
||||||
}
|
}
|
||||||
notificationBody += getNotificationText(messageMap.value(CONTENT).toMap());
|
notificationBody += getNotificationText(messageMap.value(CONTENT).toMap());
|
||||||
|
|
|
@ -121,7 +121,7 @@ void StickerManager::handleStickerSetReceived(const QVariantMap &stickerSet)
|
||||||
QListIterator<QVariant> stickerIterator(stickerList);
|
QListIterator<QVariant> stickerIterator(stickerList);
|
||||||
while (stickerIterator.hasNext()) {
|
while (stickerIterator.hasNext()) {
|
||||||
QVariantMap singleSticker = stickerIterator.next().toMap();
|
QVariantMap singleSticker = stickerIterator.next().toMap();
|
||||||
QVariantMap thumbnailFile = singleSticker.value("thumbnail").toMap().value("photo").toMap();
|
QVariantMap thumbnailFile = singleSticker.value("thumbnail").toMap().value("file").toMap();
|
||||||
QVariantMap thumbnailLocalFile = thumbnailFile.value("local").toMap();
|
QVariantMap thumbnailLocalFile = thumbnailFile.value("local").toMap();
|
||||||
if (!thumbnailLocalFile.value("is_downloading_completed").toBool()) {
|
if (!thumbnailLocalFile.value("is_downloading_completed").toBool()) {
|
||||||
tdLibWrapper->downloadFile(thumbnailFile.value("id").toInt());
|
tdLibWrapper->downloadFile(thumbnailFile.value("id").toInt());
|
||||||
|
|
|
@ -120,7 +120,7 @@ TDLibReceiver::TDLibReceiver(void *tdLibClient, QObject *parent) : QThread(paren
|
||||||
handlers.insert("updateBasicGroupFullInfo", &TDLibReceiver::processUpdateBasicGroupFullInfo);
|
handlers.insert("updateBasicGroupFullInfo", &TDLibReceiver::processUpdateBasicGroupFullInfo);
|
||||||
handlers.insert("supergroupFullInfo", &TDLibReceiver::processSupergroupFullInfo);
|
handlers.insert("supergroupFullInfo", &TDLibReceiver::processSupergroupFullInfo);
|
||||||
handlers.insert("updateSupergroupFullInfo", &TDLibReceiver::processUpdateSupergroupFullInfo);
|
handlers.insert("updateSupergroupFullInfo", &TDLibReceiver::processUpdateSupergroupFullInfo);
|
||||||
handlers.insert("userProfilePhotos", &TDLibReceiver::processUserProfilePhotos);
|
handlers.insert("chatPhotos", &TDLibReceiver::processUserProfilePhotos);
|
||||||
handlers.insert("updateChatPermissions", &TDLibReceiver::processUpdateChatPermissions);
|
handlers.insert("updateChatPermissions", &TDLibReceiver::processUpdateChatPermissions);
|
||||||
handlers.insert("updateChatPhoto", &TDLibReceiver::processUpdateChatPhoto);
|
handlers.insert("updateChatPhoto", &TDLibReceiver::processUpdateChatPhoto);
|
||||||
handlers.insert("updateChatTitle", &TDLibReceiver::processUpdateChatTitle);
|
handlers.insert("updateChatTitle", &TDLibReceiver::processUpdateChatTitle);
|
||||||
|
|
|
@ -22,10 +22,10 @@ namespace td {
|
||||||
* The TDLib instance is created for the lifetime of the Client object.
|
* The TDLib instance is created for the lifetime of the Client object.
|
||||||
* Requests to TDLib can be sent using the Client::send method from any thread.
|
* Requests to TDLib can be sent using the Client::send method from any thread.
|
||||||
* New updates and responses to requests can be received using the Client::receive method from any thread,
|
* New updates and responses to requests can be received using the Client::receive method from any thread,
|
||||||
* this function shouldn't be called simultaneously from two different threads. Also note that all updates and
|
* this function must not be called simultaneously from two different threads. Also note that all updates and
|
||||||
* responses to requests should be applied in the same order as they were received, to ensure consistency.
|
* responses to requests should be applied in the same order as they were received, to ensure consistency.
|
||||||
* Given this information, it's advisable to call this function from a dedicated thread.
|
* Given this information, it's advisable to call this function from a dedicated thread.
|
||||||
* Some service TDLib requests can be executed synchronously from any thread by using the Client::execute method.
|
* Some service TDLib requests can be executed synchronously from any thread using the Client::execute method.
|
||||||
*
|
*
|
||||||
* General pattern of usage:
|
* General pattern of usage:
|
||||||
* \code
|
* \code
|
||||||
|
@ -84,7 +84,7 @@ class Client final {
|
||||||
*/
|
*/
|
||||||
struct Response {
|
struct Response {
|
||||||
/**
|
/**
|
||||||
* TDLib request identifier, which corresponds to the response or 0 for incoming updates from TDLib.
|
* TDLib request identifier, which corresponds to the response, or 0 for incoming updates from TDLib.
|
||||||
*/
|
*/
|
||||||
std::uint64_t id;
|
std::uint64_t id;
|
||||||
|
|
||||||
|
@ -131,4 +131,138 @@ class Client final {
|
||||||
std::unique_ptr<Impl> impl_;
|
std::unique_ptr<Impl> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The future native C++ interface for interaction with TDLib.
|
||||||
|
*
|
||||||
|
* A TDLib client instance can be created through the method ClientManager::create_client_id.
|
||||||
|
* Requests can be sent using the method ClientManager::send from any thread.
|
||||||
|
* New updates and responses to requests can be received using the method ClientManager::receive from any thread after
|
||||||
|
* the first request has been sent to the client instance. ClientManager::receive must not be called simultaneously from
|
||||||
|
* two different threads. Also note that all updates and responses to requests should be applied in the same order as
|
||||||
|
* they were received, to ensure consistency.
|
||||||
|
* Some TDLib requests can be executed synchronously from any thread using the method ClientManager::execute.
|
||||||
|
*
|
||||||
|
* General pattern of usage:
|
||||||
|
* \code
|
||||||
|
* td::ClientManager manager;
|
||||||
|
* auto client_id = manager.create_client_id();
|
||||||
|
* // somehow share the manager and the client_id with other threads,
|
||||||
|
* // which will be able to send requests via manager.send(client_id, ...)
|
||||||
|
*
|
||||||
|
* // send some dummy requests to the new instance to activate it
|
||||||
|
* manager.send(client_id, ...);
|
||||||
|
*
|
||||||
|
* const double WAIT_TIMEOUT = 10.0; // seconds
|
||||||
|
* while (true) {
|
||||||
|
* auto response = manager.receive(WAIT_TIMEOUT);
|
||||||
|
* if (response.object == nullptr) {
|
||||||
|
* continue;
|
||||||
|
* }
|
||||||
|
*
|
||||||
|
* if (response.request_id == 0) {
|
||||||
|
* // process response.object as an incoming update of the type td_api::Update for the client response.client_id
|
||||||
|
* } else {
|
||||||
|
* // process response.object as an answer to a request response.request_id for the client response.client_id
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
class ClientManager final {
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* Creates a new TDLib client manager.
|
||||||
|
*/
|
||||||
|
ClientManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opaque TDLib client instance identifier.
|
||||||
|
*/
|
||||||
|
using ClientId = std::int32_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request identifier.
|
||||||
|
* Responses to TDLib requests will have the same request id as the corresponding request.
|
||||||
|
* Updates from TDLib will have the request_id == 0, incoming requests are thus not allowed to have request_id == 0.
|
||||||
|
*/
|
||||||
|
using RequestId = std::uint64_t;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an opaque identifier of a new TDLib instance.
|
||||||
|
* The TDLib instance will not send updates until the first request is sent to it.
|
||||||
|
* \return Opaque identifier of a new TDLib instance.
|
||||||
|
*/
|
||||||
|
ClientId create_client_id();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends request to TDLib. May be called from any thread.
|
||||||
|
* \param[in] client_id TDLib client instance identifier.
|
||||||
|
* \param[in] request_id Request identifier. Must be non-zero.
|
||||||
|
* \param[in] request Request to TDLib.
|
||||||
|
*/
|
||||||
|
void send(ClientId client_id, RequestId request_id, td_api::object_ptr<td_api::Function> &&request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A response to a request, or an incoming update from TDLib.
|
||||||
|
*/
|
||||||
|
struct Response {
|
||||||
|
/**
|
||||||
|
* TDLib client instance identifier, for which the response was received.
|
||||||
|
*/
|
||||||
|
ClientId client_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request identifier, to which the response corresponds, or 0 for incoming updates from TDLib.
|
||||||
|
*/
|
||||||
|
RequestId request_id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TDLib API object representing a response to a TDLib request or an incoming update.
|
||||||
|
*/
|
||||||
|
td_api::object_ptr<td_api::Object> object;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives incoming updates and responses to requests from TDLib. May be called from any thread, but must not be
|
||||||
|
* called simultaneously from two different threads.
|
||||||
|
* \param[in] timeout The maximum number of seconds allowed for this function to wait for new data.
|
||||||
|
* \return An incoming update or response to a request. The object returned in the response may be a nullptr
|
||||||
|
* if the timeout expires.
|
||||||
|
*/
|
||||||
|
Response receive(double timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronously executes a TDLib request.
|
||||||
|
* A request can be executed synchronously, only if it is documented with "Can be called synchronously".
|
||||||
|
* \param[in] request Request to the TDLib.
|
||||||
|
* \return The request response.
|
||||||
|
*/
|
||||||
|
static td_api::object_ptr<td_api::Object> execute(td_api::object_ptr<td_api::Function> &&request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroys the client manager and all TDLib client instances managed by it.
|
||||||
|
*/
|
||||||
|
~ClientManager();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move constructor.
|
||||||
|
*/
|
||||||
|
ClientManager(ClientManager &&other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Move assignment operator.
|
||||||
|
*/
|
||||||
|
ClientManager &operator=(ClientManager &&other);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a pointer to a singleton ClientManager instance.
|
||||||
|
* \return A unique singleton ClientManager instance.
|
||||||
|
*/
|
||||||
|
static ClientManager *get_manager_singleton();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class Client;
|
||||||
|
class Impl;
|
||||||
|
std::unique_ptr<Impl> impl_;
|
||||||
|
};
|
||||||
|
|
||||||
} // namespace td
|
} // namespace td
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
@ -13,19 +13,19 @@
|
||||||
* and is able to work with JSON.
|
* and is able to work with JSON.
|
||||||
*
|
*
|
||||||
* The JSON serialization of TDLib API objects is straightforward: all API objects are represented as JSON objects with
|
* The JSON serialization of TDLib API objects is straightforward: all API objects are represented as JSON objects with
|
||||||
* the same keys as the API object field names. The object type name is stored in the special field '@type' which is
|
* the same keys as the API object field names. The object type name is stored in the special field "@type" which is
|
||||||
* optional in places where type is uniquely determined by the context.
|
* optional in places where type is uniquely determined by the context.
|
||||||
* Fields of Bool type are stored as Boolean, fields of int32, int53, and double types are stored as Number, fields of
|
* Fields of Bool type are stored as Boolean, fields of int32, int53, and double types are stored as Number, fields of
|
||||||
* int64 and string types are stored as String, fields of bytes type are base64 encoded and then stored as String,
|
* int64 and string types are stored as String, fields of bytes type are base64 encoded and then stored as String,
|
||||||
* fields of vector type are stored as Array.
|
* fields of array type are stored as Array.
|
||||||
* The main TDLib interface is asynchronous. To match requests with a corresponding response a field "@extra" can
|
* The main TDLib interface is asynchronous. To match requests with a corresponding response a field "@extra" can
|
||||||
* be added to the request object. The corresponding response will have an "@extra" field with exactly the same value.
|
* be added to the request object. The corresponding response will have an "@extra" field with exactly the same value.
|
||||||
*
|
*
|
||||||
* A TDLib client instance should be created through td_json_client_create.
|
* A TDLib client instance can be created through td_json_client_create.
|
||||||
* Requests then can be sent using td_json_client_send from any thread.
|
* Requests then can be sent using td_json_client_send from any thread.
|
||||||
* New updates and request responses can be received through td_json_client_receive from any thread. This function
|
* New updates and request responses can be received through td_json_client_receive from any thread. This function
|
||||||
* shouldn't be called simultaneously from two different threads. Also note that all updates and request responses
|
* must not be called simultaneously from two different threads. Also note that all updates and request responses
|
||||||
* should be applied in the order they were received to ensure consistency.
|
* must be applied in the order they were received to ensure consistency.
|
||||||
* Given this information, it's advisable to call this function from a dedicated thread.
|
* Given this information, it's advisable to call this function from a dedicated thread.
|
||||||
* Some service TDLib requests can be executed synchronously from any thread by using td_json_client_execute.
|
* Some service TDLib requests can be executed synchronously from any thread by using td_json_client_execute.
|
||||||
* The TDLib client instance can be destroyed via td_json_client_destroy.
|
* The TDLib client instance can be destroyed via td_json_client_destroy.
|
||||||
|
@ -68,7 +68,7 @@ TDJSON_EXPORT void td_json_client_send(void *client, const char *request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Receives incoming updates and request responses from the TDLib client. May be called from any thread, but
|
* Receives incoming updates and request responses from the TDLib client. May be called from any thread, but
|
||||||
* shouldn't be called simultaneously from two different threads.
|
* must not be called simultaneously from two different threads.
|
||||||
* Returned pointer will be deallocated by TDLib during next call to td_json_client_receive or td_json_client_execute
|
* Returned pointer will be deallocated by TDLib during next call to td_json_client_receive or td_json_client_execute
|
||||||
* in the same thread, so it can't be used after that.
|
* in the same thread, so it can't be used after that.
|
||||||
* \param[in] client The client.
|
* \param[in] client The client.
|
||||||
|
@ -84,16 +84,78 @@ TDJSON_EXPORT const char *td_json_client_receive(void *client, double timeout);
|
||||||
* in the same thread, so it can't be used after that.
|
* in the same thread, so it can't be used after that.
|
||||||
* \param[in] client The client. Currently ignored for all requests, so NULL can be passed.
|
* \param[in] client The client. Currently ignored for all requests, so NULL can be passed.
|
||||||
* \param[in] request JSON-serialized null-terminated request to TDLib.
|
* \param[in] request JSON-serialized null-terminated request to TDLib.
|
||||||
* \return JSON-serialized null-terminated request response. May be NULL if the request can't be parsed.
|
* \return JSON-serialized null-terminated request response.
|
||||||
*/
|
*/
|
||||||
TDJSON_EXPORT const char *td_json_client_execute(void *client, const char *request);
|
TDJSON_EXPORT const char *td_json_client_execute(void *client, const char *request);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Destroys the TDLib client instance. After this is called the client instance shouldn't be used anymore.
|
* Destroys the TDLib client instance. After this is called the client instance must not be used anymore.
|
||||||
* \param[in] client The client.
|
* \param[in] client The client.
|
||||||
*/
|
*/
|
||||||
TDJSON_EXPORT void td_json_client_destroy(void *client);
|
TDJSON_EXPORT void td_json_client_destroy(void *client);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* New TDLib JSON interface.
|
||||||
|
*
|
||||||
|
* The main TDLib interface is asynchronous. To match requests with a corresponding response, the field "@extra" can
|
||||||
|
* be added to the request object. The corresponding response will have an "@extra" field with exactly the same value.
|
||||||
|
* Each returned object will have an "@client_id" field, containing the identifier of the client for which
|
||||||
|
* a response or an update was received.
|
||||||
|
*
|
||||||
|
* A TDLib client instance can be created through td_create_client_id.
|
||||||
|
* Requests can be sent using td_send and the received client identifier.
|
||||||
|
* New updates and responses to requests can be received through td_receive from any thread after the first request
|
||||||
|
* has been sent to the client instance. This function must not be called simultaneously from two different threads.
|
||||||
|
* Also note that all updates and responses to requests must be applied in the order they were received for consistency.
|
||||||
|
* Some TDLib requests can be executed synchronously from any thread using td_execute.
|
||||||
|
* TDLib client instances are destroyed automatically after they are closed.
|
||||||
|
*
|
||||||
|
* General pattern of usage:
|
||||||
|
* \code
|
||||||
|
* int client_id = td_create_client_id();
|
||||||
|
* // share the client_id with other threads, which will be able to send requests via td_send
|
||||||
|
*
|
||||||
|
* const double WAIT_TIMEOUT = 10.0; // seconds
|
||||||
|
* while (true) {
|
||||||
|
* const char *result = td_receive(WAIT_TIMEOUT);
|
||||||
|
* if (result) {
|
||||||
|
* // parse the result as a JSON object and process it as an incoming update or the answer to a previously sent request
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* \endcode
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns an opaque identifier of a new TDLib instance.
|
||||||
|
* The TDLib instance will not send updates until the first request is sent to it.
|
||||||
|
* \return Opaque identifier of a new TDLib instance.
|
||||||
|
*/
|
||||||
|
TDJSON_EXPORT int td_create_client_id();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sends request to the TDLib client. May be called from any thread.
|
||||||
|
* \param[in] client_id TDLib client identifier.
|
||||||
|
* \param[in] request JSON-serialized null-terminated request to TDLib.
|
||||||
|
*/
|
||||||
|
TDJSON_EXPORT void td_send(int client_id, const char *request);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receives incoming updates and request responses. Must not be called simultaneously from two different threads.
|
||||||
|
* The returned pointer can be used until the next call to td_receive or td_execute, after which it will be deallocated by TDLib.
|
||||||
|
* \param[in] timeout The maximum number of seconds allowed for this function to wait for new data.
|
||||||
|
* \return JSON-serialized null-terminated incoming update or request response. May be NULL if the timeout expires.
|
||||||
|
*/
|
||||||
|
TDJSON_EXPORT const char *td_receive(double timeout);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Synchronously executes a TDLib request.
|
||||||
|
* A request can be executed synchronously, only if it is documented with "Can be called synchronously".
|
||||||
|
* The returned pointer can be used until the next call to td_receive or td_execute, after which it will be deallocated by TDLib.
|
||||||
|
* \param[in] request JSON-serialized null-terminated request to TDLib.
|
||||||
|
* \return JSON-serialized null-terminated request response.
|
||||||
|
*/
|
||||||
|
TDJSON_EXPORT const char *td_execute(const char *request);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -13,7 +13,6 @@
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
@ -88,9 +87,7 @@ class TlObject {
|
||||||
virtual ~TlObject() = default;
|
virtual ~TlObject() = default;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/// @cond UNDOCUMENTED
|
||||||
* A smart wrapper to store a pointer to a TL-object.
|
|
||||||
*/
|
|
||||||
namespace tl {
|
namespace tl {
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
|
@ -116,15 +113,16 @@ class unique_ptr {
|
||||||
}
|
}
|
||||||
explicit unique_ptr(T *ptr) noexcept : ptr_(ptr) {
|
explicit unique_ptr(T *ptr) noexcept : ptr_(ptr) {
|
||||||
}
|
}
|
||||||
template <class S, class = std::enable_if_t<std::is_base_of<T, S>::value>>
|
template <class S, class = typename std::enable_if<std::is_base_of<T, S>::value>::type>
|
||||||
unique_ptr(unique_ptr<S> &&other) noexcept : ptr_(static_cast<S *>(other.release())) {
|
unique_ptr(unique_ptr<S> &&other) noexcept : ptr_(static_cast<S *>(other.release())) {
|
||||||
}
|
}
|
||||||
template <class S, class = std::enable_if_t<std::is_base_of<T, S>::value>>
|
template <class S, class = typename std::enable_if<std::is_base_of<T, S>::value>::type>
|
||||||
unique_ptr &operator=(unique_ptr<S> &&other) noexcept {
|
unique_ptr &operator=(unique_ptr<S> &&other) noexcept {
|
||||||
reset(static_cast<T *>(other.release()));
|
reset(static_cast<T *>(other.release()));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
void reset(T *new_ptr = nullptr) noexcept {
|
void reset(T *new_ptr = nullptr) noexcept {
|
||||||
|
static_assert(sizeof(T) > 0, "Can't destroy unique_ptr with incomplete type");
|
||||||
delete ptr_;
|
delete ptr_;
|
||||||
ptr_ = new_ptr;
|
ptr_ = new_ptr;
|
||||||
}
|
}
|
||||||
|
@ -177,6 +175,11 @@ bool operator!=(const unique_ptr<T> &p, std::nullptr_t) {
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace tl
|
} // namespace tl
|
||||||
|
/// @endcond
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A smart wrapper to store a pointer to a TL-object.
|
||||||
|
*/
|
||||||
template <class Type>
|
template <class Type>
|
||||||
using tl_object_ptr = tl::unique_ptr<Type>;
|
using tl_object_ptr = tl::unique_ptr<Type>;
|
||||||
|
|
||||||
|
@ -186,8 +189,8 @@ using tl_object_ptr = tl::unique_ptr<Type>;
|
||||||
* \code
|
* \code
|
||||||
* auto get_authorization_state_request = td::make_tl_object<td::td_api::getAuthorizationState>();
|
* auto get_authorization_state_request = td::make_tl_object<td::td_api::getAuthorizationState>();
|
||||||
* auto message_text = td::make_tl_object<td::td_api::formattedText>("Hello, world!!!",
|
* auto message_text = td::make_tl_object<td::td_api::formattedText>("Hello, world!!!",
|
||||||
* std::vector<td::tl_object_ptr<td::td_api::textEntity>>());
|
* td::td_api::array<td::tl_object_ptr<td::td_api::textEntity>>());
|
||||||
* auto send_message_request = td::make_tl_object<td::td_api::sendMessage>(chat_id, 0, nullptr, nullptr,
|
* auto send_message_request = td::make_tl_object<td::td_api::sendMessage>(chat_id, 0, 0, nullptr, nullptr,
|
||||||
* td::make_tl_object<td::td_api::inputMessageText>(std::move(message_text), false, true));
|
* td::make_tl_object<td::td_api::inputMessageText>(std::move(message_text), false, true));
|
||||||
* \endcode
|
* \endcode
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in a new issue