Update layer 75:
- Add connected websites support. - Add flag supports_streaming to video and inputMessageVideo. - Add new methods for message loading: getRepliedMessage and getChatPinnedMessage. GitOrigin-RevId: 1dc5d367e27722fe9c8d2765f62ed80176eea2ce
This commit is contained in:
parent
ee59648564
commit
154022ebfe
@ -1,6 +1,6 @@
|
||||
cmake_minimum_required(VERSION 3.0.2 FATAL_ERROR)
|
||||
|
||||
project(TDLib VERSION 1.1.1 LANGUAGES CXX C)
|
||||
project(TDLib VERSION 1.1.2 LANGUAGES CXX C)
|
||||
|
||||
option(TD_ENABLE_JNI "Use \"ON\" to enable JNI-compatible TDLib API.")
|
||||
|
||||
|
@ -104,7 +104,7 @@ target_link_libraries(YourTarget PRIVATE Td::TdStatic)
|
||||
|
||||
Or you could install `TDLib` and then reference it in your CMakeLists.txt like this:
|
||||
```
|
||||
find_package(Td 1.1.1 REQUIRED)
|
||||
find_package(Td 1.1.2 REQUIRED)
|
||||
target_link_libraries(YourTarget PRIVATE Td::TdStatic)
|
||||
```
|
||||
See [example/cpp/CMakeLists.txt](https://github.com/tdlib/td/tree/master/example/cpp/CMakeLists.txt).
|
||||
|
@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 3.1 FATAL_ERROR)
|
||||
|
||||
project(TdExample VERSION 1.0 LANGUAGES CXX)
|
||||
|
||||
find_package(Td 1.1.1 REQUIRED)
|
||||
find_package(Td 1.1.2 REQUIRED)
|
||||
|
||||
add_executable(tdjson_example tdjson_example.cpp)
|
||||
target_link_libraries(tdjson_example PRIVATE Td::TdJson)
|
||||
|
@ -203,8 +203,9 @@ photo id:int64 has_stickers:Bool sizes:vector<photoSize> = Photo;
|
||||
sticker set_id:int64 width:int32 height:int32 emoji:string is_mask:Bool mask_position:maskPosition thumbnail:photoSize sticker:file = Sticker;
|
||||
|
||||
//@description Describes a video file @duration Duration of the video, in seconds; as defined by the sender @width Video width; as defined by the sender @height Video height; as defined by the sender
|
||||
//@file_name Original name of the file; as defined by the sender @mime_type MIME type of the file; as defined by the sender @has_stickers True, if stickers were added to the photo @thumbnail Video thumbnail; as defined by the sender; may be null @video File containing the video
|
||||
video duration:int32 width:int32 height:int32 file_name:string mime_type:string has_stickers:Bool thumbnail:photoSize video:file = Video;
|
||||
//@file_name Original name of the file; as defined by the sender @mime_type MIME type of the file; as defined by the sender @has_stickers True, if stickers were added to the photo
|
||||
//@supports_streaming True, if the video should be tried to streamed @thumbnail Video thumbnail; as defined by the sender; may be null @video File containing the video
|
||||
video duration:int32 width:int32 height:int32 file_name:string mime_type:string has_stickers:Bool supports_streaming:Bool thumbnail:photoSize video:file = Video;
|
||||
|
||||
//@description Describes a video note. The video must be equal in width and height, cropped to a circle, and stored in MPEG4 format @duration Duration of the video, in seconds; as defined by the sender @length Video width and height; as defined by the sender @thumbnail Video thumbnail; as defined by the sender; may be null @video File containing the video
|
||||
videoNote duration:int32 length:int32 thumbnail:photoSize video:file = VideoNote;
|
||||
@ -977,9 +978,10 @@ inputMessagePhoto photo:InputFile thumbnail:inputThumbnail added_sticker_file_id
|
||||
//@description A sticker message @sticker Sticker to be sent @thumbnail Sticker thumbnail, if available @width Sticker width @height Sticker height
|
||||
inputMessageSticker sticker:InputFile thumbnail:inputThumbnail width:int32 height:int32 = InputMessageContent;
|
||||
|
||||
//@description A video message @video Video to be sent @thumbnail Video thumbnail, if available @added_sticker_file_ids File identifiers of the stickers added to the video, if applicable @duration Duration of the video, in seconds @width Video width @height Video height @caption Video caption; 0-200 characters
|
||||
//@ttl Video TTL (Time To Live), in seconds (0-60). A non-zero TTL can be specified only in private chats
|
||||
inputMessageVideo video:InputFile thumbnail:inputThumbnail added_sticker_file_ids:vector<int32> duration:int32 width:int32 height:int32 caption:formattedText ttl:int32 = InputMessageContent;
|
||||
//@description A video message @video Video to be sent @thumbnail Video thumbnail, if available @added_sticker_file_ids File identifiers of the stickers added to the video, if applicable
|
||||
//@duration Duration of the video, in seconds @width Video width @height Video height @supports_streaming True, if the video should be tried to streamed
|
||||
//@caption Video caption; 0-200 characters @ttl Video TTL (Time To Live), in seconds (0-60). A non-zero TTL can be specified only in private chats
|
||||
inputMessageVideo video:InputFile thumbnail:inputThumbnail added_sticker_file_ids:vector<int32> duration:int32 width:int32 height:int32 supports_streaming:Bool caption:formattedText ttl:int32 = InputMessageContent;
|
||||
|
||||
//@description A video note message @video_note Video note to be sent @thumbnail Video thumbnail, if available @duration Duration of the video, in seconds @length Video width and height; must be positive and not greater than 640
|
||||
inputMessageVideoNote video_note:InputFile thumbnail:inputThumbnail duration:int32 length:int32 = InputMessageContent;
|
||||
@ -1512,9 +1514,12 @@ userPrivacySettingAllowCalls = UserPrivacySetting;
|
||||
accountTtl days:int32 = AccountTtl;
|
||||
|
||||
|
||||
//@description Contains information about one session in a Telegram application used by the current user @id Session identifier @is_current True, if this session is the current session @api_id Telegram API identifier, as provided by the application @application_name Name of the application, as provided by the application
|
||||
//@application_version The version of the application, as provided by the application @is_official_application True, if the application is an official application or uses the api_id of an official application @device_model Model of the device the application has been run or is running on, as provided by the application @platform Operating system the application has been run or is running on, as provided by the application
|
||||
//@system_version Version of the operating system the application has been run or is running on, as provided by the application @log_in_date Point in time (Unix timestamp) when the user has logged in @last_active_date Point in time (Unix timestamp) when the session was last used @ip IP address from which the session was created, in human-readable format
|
||||
//@description Contains information about one session in a Telegram application used by the current user @id Session identifier @is_current True, if this session is the current session
|
||||
//@api_id Telegram API identifier, as provided by the application @application_name Name of the application, as provided by the application
|
||||
//@application_version The version of the application, as provided by the application @is_official_application True, if the application is an official application or uses the api_id of an official application
|
||||
//@device_model Model of the device the application has been run or is running on, as provided by the application @platform Operating system the application has been run or is running on, as provided by the application
|
||||
//@system_version Version of the operating system the application has been run or is running on, as provided by the application @log_in_date Point in time (Unix timestamp) when the user has logged in
|
||||
//@last_active_date Point in time (Unix timestamp) when the session was last used @ip IP address from which the session was created, in human-readable format
|
||||
//@country A two-letter country code for the country from which the session was created, based on the IP address @region Region code from which the session was created, based on the IP address
|
||||
session id:int64 is_current:Bool api_id:int32 application_name:string application_version:string is_official_application:Bool device_model:string platform:string system_version:string log_in_date:int32 last_active_date:int32 ip:string country:string region:string = Session;
|
||||
|
||||
@ -1522,6 +1527,22 @@ session id:int64 is_current:Bool api_id:int32 application_name:string applicatio
|
||||
sessions sessions:vector<session> = Sessions;
|
||||
|
||||
|
||||
//@description Contains information about one website the current user is logged in with Telegram
|
||||
//@id Website identifier
|
||||
//@domain_name The domain name of the website
|
||||
//@bot_user_id User identifier of a bot linked with the website
|
||||
//@browser The version of a browser used to log in
|
||||
//@platform Operating system the browser is running on
|
||||
//@log_in_date Point in time (Unix timestamp) when the user was logged in
|
||||
//@last_active_date Point in time (Unix timestamp) when obtained authorization was last used
|
||||
//@ip IP address from which the user was logged in, in human-readable format
|
||||
//@location Human-readable description of a country and a region, from which the user was logged in, based on the IP address
|
||||
connectedWebsite id:int64 domain_name:string bot_user_id:int32 browser:string platform:string log_in_date:int32 last_active_date:int32 ip:string location:string = ConnectedWebsite;
|
||||
|
||||
//@description Contains a list of websites the current user is logged in with Telegram @websites List of connected websites
|
||||
connectedWebsites websites:vector<connectedWebsite> = ConnectedWebsites;
|
||||
|
||||
|
||||
//@description Contains information about the availability of the "Report spam" action for a chat @can_report_spam True, if a prompt with the "Report spam" action should be shown to the user
|
||||
chatReportSpamState can_report_spam:Bool = ChatReportSpamState;
|
||||
|
||||
@ -2022,6 +2043,12 @@ getChat chat_id:int53 = Chat;
|
||||
//@description Returns information about a message @chat_id Identifier of the chat the message belongs to @message_id Identifier of the message to get
|
||||
getMessage chat_id:int53 message_id:int53 = Message;
|
||||
|
||||
//@description Returns information about a message that is replied by given message @chat_id Identifier of the chat the message belongs to @message_id Identifier of the message reply to which get
|
||||
getRepliedMessage chat_id:int53 message_id:int53 = Message;
|
||||
|
||||
//@description Returns information about a pinned chat message @chat_id Identifier of the chat the message belongs to
|
||||
getChatPinnedMessage chat_id:int53 = Message;
|
||||
|
||||
//@description Returns information about messages. If a message is not found, returns null on the corresponding position of the result @chat_id Identifier of the chat the messages belong to @message_ids Identifiers of the messages to get
|
||||
getMessages chat_id:int53 message_ids:vector<int53> = Messages;
|
||||
|
||||
@ -2561,6 +2588,16 @@ terminateSession session_id:int64 = Ok;
|
||||
terminateAllOtherSessions = Ok;
|
||||
|
||||
|
||||
//@description Returns all website where the current user used Telegram to log in
|
||||
getConnectedWebsites = ConnectedWebsites;
|
||||
|
||||
//@description Disconnects website from the current user's Telegram account @website_id Website identifier
|
||||
disconnectWebsite website_id:int64 = Ok;
|
||||
|
||||
//@description Disconnects all websites from the current user's Telegram account
|
||||
disconnectAllWebsites = Ok;
|
||||
|
||||
|
||||
//@description Toggles the "All members are admins" setting in basic groups; requires creator privileges in the group @basic_group_id Identifier of the basic group @everyone_is_administrator New value of everyone_is_administrator
|
||||
toggleBasicGroupAdministrators basic_group_id:int32 everyone_is_administrator:Bool = Ok;
|
||||
|
||||
|
Binary file not shown.
@ -438,7 +438,7 @@ accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
|
||||
documentAttributeImageSize#6c37c15c w:int h:int = DocumentAttribute;
|
||||
documentAttributeAnimated#11b58939 = DocumentAttribute;
|
||||
documentAttributeSticker#6319d612 flags:# mask:flags.1?true alt:string stickerset:InputStickerSet mask_coords:flags.0?MaskCoords = DocumentAttribute;
|
||||
documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeVideo#ef02ce6 flags:# round_message:flags.0?true supports_streaming:flags.1?true duration:int w:int h:int = DocumentAttribute;
|
||||
documentAttributeAudio#9852f9c6 flags:# voice:flags.10?true duration:int title:flags.0?string performer:flags.1?string waveform:flags.2?bytes = DocumentAttribute;
|
||||
documentAttributeFilename#15590068 file_name:string = DocumentAttribute;
|
||||
documentAttributeHasStickers#9801d2f7 = DocumentAttribute;
|
||||
@ -822,6 +822,14 @@ help.recentMeUrls#e0310d7 urls:Vector<RecentMeUrl> chats:Vector<Chat> users:Vect
|
||||
|
||||
inputSingleMedia#1cc6e91f flags:# media:InputMedia random_id:long message:string entities:flags.0?Vector<MessageEntity> = InputSingleMedia;
|
||||
|
||||
webAuthorization#cac943f2 hash:long bot_id:int domain:string browser:string platform:string date_created:int date_active:int ip:string region:string = WebAuthorization;
|
||||
|
||||
account.webAuthorizations#ed56c9fc authorizations:Vector<WebAuthorization> users:Vector<User> = account.WebAuthorizations;
|
||||
|
||||
inputMessageID#a676a322 id:int = InputMessage;
|
||||
inputMessageReplyTo#bad88395 id:int = InputMessage;
|
||||
inputMessagePinned#86872538 = InputMessage;
|
||||
|
||||
---functions---
|
||||
|
||||
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
|
||||
@ -875,6 +883,9 @@ account.updatePasswordSettings#fa7c4b86 current_password_hash:bytes new_settings
|
||||
account.sendConfirmPhoneCode#1516d7bd flags:# allow_flashcall:flags.0?true hash:string current_number:flags.0?Bool = auth.SentCode;
|
||||
account.confirmPhone#5f2178c3 phone_code_hash:string phone_code:string = Bool;
|
||||
account.getTmpPassword#4a82327e password_hash:bytes period:int = account.TmpPassword;
|
||||
account.getWebAuthorizations#182e6d6f = account.WebAuthorizations;
|
||||
account.resetWebAuthorization#2d01b9ef hash:long = Bool;
|
||||
account.resetWebAuthorizations#682d2594 = Bool;
|
||||
|
||||
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
|
||||
users.getFullUser#ca30a5b1 id:InputUser = UserFull;
|
||||
@ -895,7 +906,7 @@ contacts.getTopPeers#d4982db5 flags:# correspondents:flags.0?true bots_pm:flags.
|
||||
contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool;
|
||||
contacts.resetSaved#879537f1 = Bool;
|
||||
|
||||
messages.getMessages#4222fa74 id:Vector<int> = messages.Messages;
|
||||
messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
|
||||
messages.getDialogs#191ba9c5 flags:# exclude_pinned:flags.0?true offset_date:int offset_id:int offset_peer:InputPeer limit:int = messages.Dialogs;
|
||||
messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
|
||||
messages.search#39e9ea0 flags:# peer:InputPeer q:string from_id:flags.0?InputUser filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
|
||||
@ -1023,7 +1034,7 @@ channels.readHistory#cc104937 channel:InputChannel max_id:int = Bool;
|
||||
channels.deleteMessages#84c1fd4e channel:InputChannel id:Vector<int> = messages.AffectedMessages;
|
||||
channels.deleteUserHistory#d10dd71b channel:InputChannel user_id:InputUser = messages.AffectedHistory;
|
||||
channels.reportSpam#fe087810 channel:InputChannel user_id:InputUser id:Vector<int> = Bool;
|
||||
channels.getMessages#93d7b347 channel:InputChannel id:Vector<int> = messages.Messages;
|
||||
channels.getMessages#ad8c9a23 channel:InputChannel id:Vector<InputMessage> = messages.Messages;
|
||||
channels.getParticipants#123e05e9 channel:InputChannel filter:ChannelParticipantsFilter offset:int limit:int hash:int = channels.ChannelParticipants;
|
||||
channels.getParticipant#546dd7a6 channel:InputChannel user_id:InputUser = channels.ChannelParticipant;
|
||||
channels.getChannels#a7f6bbb id:Vector<InputChannel> = messages.Chats;
|
||||
|
Binary file not shown.
@ -281,7 +281,8 @@ tl_object_ptr<telegram_api::InputMedia> AnimationsManager::get_input_media(
|
||||
string mime_type = animation->mime_type;
|
||||
if (animation->mime_type == "video/mp4") {
|
||||
attributes.push_back(make_tl_object<telegram_api::documentAttributeVideo>(
|
||||
0, false /*ignored*/, animation->duration, animation->dimensions.width, animation->dimensions.height));
|
||||
0, false /*ignored*/, false /*ignored*/, animation->duration, animation->dimensions.width,
|
||||
animation->dimensions.height));
|
||||
} else if (animation->dimensions.width != 0 && animation->dimensions.height != 0) {
|
||||
if (!begins_with(mime_type, "image/")) {
|
||||
mime_type = "image/gif";
|
||||
|
@ -191,7 +191,7 @@ class ResetAuthorizationsQuery : public Td::ResultHandler {
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::account_resetAuthorization>(packet);
|
||||
auto result_ptr = fetch_result<telegram_api::auth_resetAuthorizations>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
@ -206,6 +206,108 @@ class ResetAuthorizationsQuery : public Td::ResultHandler {
|
||||
}
|
||||
};
|
||||
|
||||
class GetWebAuthorizationsQuery : public Td::ResultHandler {
|
||||
Promise<tl_object_ptr<td_api::connectedWebsites>> promise_;
|
||||
|
||||
public:
|
||||
explicit GetWebAuthorizationsQuery(Promise<tl_object_ptr<td_api::connectedWebsites>> &&promise)
|
||||
: promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send() {
|
||||
send_query(G()->net_query_creator().create(create_storer(telegram_api::account_getWebAuthorizations())));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::account_getWebAuthorizations>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
auto ptr = result_ptr.move_as_ok();
|
||||
LOG(INFO) << "Receive result for GetWebAuthorizationsQuery: " << to_string(ptr);
|
||||
|
||||
td->contacts_manager_->on_get_users(std::move(ptr->users_));
|
||||
|
||||
auto results = make_tl_object<td_api::connectedWebsites>();
|
||||
results->websites_.reserve(ptr->authorizations_.size());
|
||||
for (auto &authorization : ptr->authorizations_) {
|
||||
CHECK(authorization != nullptr);
|
||||
UserId bot_user_id(authorization->bot_id_);
|
||||
if (!bot_user_id.is_valid()) {
|
||||
LOG(ERROR) << "Receive invalid bot " << bot_user_id;
|
||||
bot_user_id = UserId();
|
||||
}
|
||||
|
||||
results->websites_.push_back(make_tl_object<td_api::connectedWebsite>(
|
||||
authorization->hash_, authorization->domain_,
|
||||
td->contacts_manager_->get_user_id_object(bot_user_id, "GetWebAuthorizationsQuery"), authorization->browser_,
|
||||
authorization->platform_, authorization->date_created_, authorization->date_active_, authorization->ip_,
|
||||
authorization->region_));
|
||||
}
|
||||
|
||||
promise_.set_value(std::move(results));
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class ResetWebAuthorizationQuery : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
|
||||
public:
|
||||
explicit ResetWebAuthorizationQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(int64 hash) {
|
||||
send_query(G()->net_query_creator().create(create_storer(telegram_api::account_resetWebAuthorization(hash))));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::account_resetWebAuthorization>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
bool result = result_ptr.move_as_ok();
|
||||
LOG_IF(WARNING, !result) << "Failed to disconnect website";
|
||||
promise_.set_value(Unit());
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class ResetWebAuthorizationsQuery : public Td::ResultHandler {
|
||||
Promise<Unit> promise_;
|
||||
|
||||
public:
|
||||
explicit ResetWebAuthorizationsQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send() {
|
||||
send_query(G()->net_query_creator().create(create_storer(telegram_api::account_resetWebAuthorizations())));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
auto result_ptr = fetch_result<telegram_api::account_resetWebAuthorizations>(packet);
|
||||
if (result_ptr.is_error()) {
|
||||
return on_error(id, result_ptr.move_as_error());
|
||||
}
|
||||
|
||||
bool result = result_ptr.move_as_ok();
|
||||
LOG_IF(WARNING, !result) << "Failed to disconnect all websites";
|
||||
promise_.set_value(Unit());
|
||||
}
|
||||
|
||||
void on_error(uint64 id, Status status) override {
|
||||
promise_.set_error(std::move(status));
|
||||
}
|
||||
};
|
||||
|
||||
class BlockUserQuery : public Td::ResultHandler {
|
||||
public:
|
||||
void send(tl_object_ptr<telegram_api::InputUser> &&user) {
|
||||
@ -2930,6 +3032,18 @@ void ContactsManager::terminate_all_other_sessions(Promise<Unit> &&promise) cons
|
||||
td_->create_handler<ResetAuthorizationsQuery>(std::move(promise))->send();
|
||||
}
|
||||
|
||||
void ContactsManager::get_connected_websites(Promise<tl_object_ptr<td_api::connectedWebsites>> &&promise) const {
|
||||
td_->create_handler<GetWebAuthorizationsQuery>(std::move(promise))->send();
|
||||
}
|
||||
|
||||
void ContactsManager::disconnect_website(int64 website_id, Promise<Unit> &&promise) const {
|
||||
td_->create_handler<ResetWebAuthorizationQuery>(std::move(promise))->send(website_id);
|
||||
}
|
||||
|
||||
void ContactsManager::disconnect_all_websites(Promise<Unit> &&promise) const {
|
||||
td_->create_handler<ResetWebAuthorizationsQuery>(std::move(promise))->send();
|
||||
}
|
||||
|
||||
Status ContactsManager::block_user(UserId user_id) {
|
||||
if (user_id == get_my_id("block_user")) {
|
||||
return Status::Error(5, "Can't block self");
|
||||
@ -4108,6 +4222,14 @@ string ContactsManager::get_channel_invite_link(ChannelId channel_id) const {
|
||||
return channel_full->invite_link;
|
||||
}
|
||||
|
||||
MessageId ContactsManager::get_channel_pinned_message_id(ChannelId channel_id) const {
|
||||
auto channel_full = get_channel_full(channel_id);
|
||||
if (channel_full == nullptr) {
|
||||
return MessageId();
|
||||
}
|
||||
return channel_full->pinned_message_id;
|
||||
}
|
||||
|
||||
void ContactsManager::delete_chat_participant(ChatId chat_id, UserId user_id, Promise<Unit> &&promise) {
|
||||
const Chat *c = get_chat(chat_id);
|
||||
if (c == nullptr) {
|
||||
|
@ -213,6 +213,10 @@ class ContactsManager : public Actor {
|
||||
void terminate_session(int64 session_id, Promise<Unit> &&promise) const;
|
||||
void terminate_all_other_sessions(Promise<Unit> &&promise) const;
|
||||
|
||||
void get_connected_websites(Promise<tl_object_ptr<td_api::connectedWebsites>> &&promise) const;
|
||||
void disconnect_website(int64 authorizations_id, Promise<Unit> &&promise) const;
|
||||
void disconnect_all_websites(Promise<Unit> &&promise) const;
|
||||
|
||||
Status block_user(UserId user_id);
|
||||
|
||||
Status unblock_user(UserId user_id);
|
||||
@ -302,6 +306,8 @@ class ContactsManager : public Actor {
|
||||
|
||||
string get_channel_invite_link(ChannelId channel_id) const;
|
||||
|
||||
MessageId get_channel_pinned_message_id(ChannelId channel_id) const;
|
||||
|
||||
ChannelId migrate_chat_to_megagroup(ChatId chat_id, Promise<Unit> &promise);
|
||||
|
||||
vector<DialogId> get_created_public_dialogs(Promise<Unit> &&promise);
|
||||
|
@ -124,6 +124,7 @@ std::pair<DocumentsManager::DocumentType, FileId> DocumentsManager::on_get_docum
|
||||
auto document_type = DocumentType::General;
|
||||
FileType file_type = FileType::Document;
|
||||
Slice default_extension;
|
||||
bool supports_streaming = false;
|
||||
if (type_attributes == 1) { // not a general document
|
||||
if (animated != nullptr) {
|
||||
document_type = DocumentType::Animation;
|
||||
@ -154,6 +155,7 @@ std::pair<DocumentsManager::DocumentType, FileId> DocumentsManager::on_get_docum
|
||||
} else {
|
||||
document_type = DocumentType::Video;
|
||||
file_type = FileType::Video;
|
||||
supports_streaming = (video->flags_ & telegram_api::documentAttributeVideo::SUPPORTS_STREAMING_MASK) != 0;
|
||||
}
|
||||
default_extension = "mp4";
|
||||
}
|
||||
@ -260,7 +262,8 @@ std::pair<DocumentsManager::DocumentType, FileId> DocumentsManager::on_get_docum
|
||||
break;
|
||||
case DocumentType::Video:
|
||||
td_->videos_manager_->create_video(file_id, std::move(thumbnail), has_stickers, vector<FileId>(),
|
||||
std::move(file_name), std::move(mime_type), video_duration, dimensions, true);
|
||||
std::move(file_name), std::move(mime_type), video_duration, dimensions,
|
||||
supports_streaming, true);
|
||||
break;
|
||||
case DocumentType::VideoNote:
|
||||
td_->video_notes_manager_->create_video_note(file_id, std::move(thumbnail), video_duration, dimensions, true);
|
||||
|
@ -1022,7 +1022,8 @@ tl_object_ptr<td_api::sticker> copy(const td_api::sticker &obj) {
|
||||
template <>
|
||||
tl_object_ptr<td_api::video> copy(const td_api::video &obj) {
|
||||
return make_tl_object<td_api::video>(obj.duration_, obj.width_, obj.height_, obj.file_name_, obj.mime_type_,
|
||||
obj.has_stickers_, copy(obj.thumbnail_), copy(obj.video_));
|
||||
obj.has_stickers_, obj.supports_streaming_, copy(obj.thumbnail_),
|
||||
copy(obj.video_));
|
||||
}
|
||||
|
||||
template <>
|
||||
@ -1561,7 +1562,7 @@ void InlineQueriesManager::on_get_inline_query_results(UserId bot_user_id, uint6
|
||||
auto video = make_tl_object<td_api::inlineQueryResultVideo>();
|
||||
video->id_ = std::move(result->id_);
|
||||
td_->videos_manager_->create_video(file_id, std::move(thumbnail), false, {}, std::move(file_name),
|
||||
std::move(result->content_type_), duration, dimensions, false);
|
||||
std::move(result->content_type_), duration, dimensions, false, false);
|
||||
video->video_ = td_->videos_manager_->get_video_object(file_id);
|
||||
video->title_ = std::move(result->title_);
|
||||
video->description_ = std::move(result->description_);
|
||||
|
@ -248,9 +248,9 @@ class GetMessagesQuery : public Td::ResultHandler {
|
||||
explicit GetMessagesQuery(Promise<Unit> &&promise) : promise_(std::move(promise)) {
|
||||
}
|
||||
|
||||
void send(vector<MessageId> &&message_ids) {
|
||||
send_query(G()->net_query_creator().create(
|
||||
create_storer(telegram_api::messages_getMessages(MessagesManager::get_server_message_ids(message_ids)))));
|
||||
void send(vector<tl_object_ptr<telegram_api::InputMessage>> &&message_ids) {
|
||||
send_query(
|
||||
G()->net_query_creator().create(create_storer(telegram_api::messages_getMessages(std::move(message_ids)))));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
@ -313,11 +313,11 @@ class GetChannelMessagesQuery : public Td::ResultHandler {
|
||||
}
|
||||
|
||||
void send(ChannelId channel_id, tl_object_ptr<telegram_api::InputChannel> &&input_channel,
|
||||
vector<MessageId> &&message_ids) {
|
||||
vector<tl_object_ptr<telegram_api::InputMessage>> &&message_ids) {
|
||||
channel_id_ = channel_id;
|
||||
CHECK(input_channel != nullptr);
|
||||
send_query(G()->net_query_creator().create(create_storer(telegram_api::channels_getMessages(
|
||||
std::move(input_channel), MessagesManager::get_server_message_ids(message_ids)))));
|
||||
send_query(G()->net_query_creator().create(
|
||||
create_storer(telegram_api::channels_getMessages(std::move(input_channel), std::move(message_ids)))));
|
||||
}
|
||||
|
||||
void on_result(uint64 id, BufferSlice packet) override {
|
||||
@ -4671,12 +4671,11 @@ vector<MessageId> MessagesManager::get_message_ids(const vector<int64> &input_me
|
||||
}
|
||||
|
||||
vector<int32> MessagesManager::get_server_message_ids(const vector<MessageId> &message_ids) {
|
||||
vector<int32> server_message_ids;
|
||||
server_message_ids.reserve(message_ids.size());
|
||||
for (auto &message_id : message_ids) {
|
||||
server_message_ids.push_back(message_id.get_server_message_id().get());
|
||||
}
|
||||
return server_message_ids;
|
||||
return transform(message_ids, [](MessageId message_id) { return message_id.get_server_message_id().get(); });
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::InputMessage> MessagesManager::get_input_message(MessageId message_id) {
|
||||
return make_tl_object<telegram_api::inputMessageID>(message_id.get_server_message_id().get());
|
||||
}
|
||||
|
||||
tl_object_ptr<telegram_api::InputPeer> MessagesManager::get_input_peer(DialogId dialog_id,
|
||||
@ -10890,39 +10889,103 @@ MessagesManager::Message *MessagesManager::get_message_force(FullMessageId full_
|
||||
return get_message_force(d, full_message_id.get_message_id());
|
||||
}
|
||||
|
||||
bool MessagesManager::get_message(FullMessageId full_message_id, Promise<Unit> &&promise) {
|
||||
Dialog *d = get_dialog_force(full_message_id.get_dialog_id());
|
||||
if (d == nullptr) {
|
||||
promise.set_error(Status::Error(6, "Chat not found"));
|
||||
return false;
|
||||
MessageId MessagesManager::get_replied_message_id(const Message *m) {
|
||||
switch (m->content->get_id()) {
|
||||
case MessagePinMessage::ID:
|
||||
CHECK(!m->reply_to_message_id.is_valid());
|
||||
return static_cast<const MessagePinMessage *>(m->content.get())->message_id;
|
||||
case MessageGameScore::ID:
|
||||
CHECK(!m->reply_to_message_id.is_valid());
|
||||
return static_cast<const MessageGameScore *>(m->content.get())->game_message_id;
|
||||
case MessagePaymentSuccessful::ID:
|
||||
CHECK(!m->reply_to_message_id.is_valid());
|
||||
return static_cast<const MessagePaymentSuccessful *>(m->content.get())->invoice_message_id;
|
||||
default:
|
||||
return m->reply_to_message_id;
|
||||
}
|
||||
}
|
||||
|
||||
auto message_id = full_message_id.get_message_id();
|
||||
auto message = get_message_force(d, message_id);
|
||||
if (message == nullptr && message_id.is_valid() && message_id.is_server()) {
|
||||
void MessagesManager::get_message_force_from_server(Dialog *d, MessageId message_id, Promise<Unit> &&promise) {
|
||||
auto m = get_message_force(d, message_id);
|
||||
if (m == nullptr && message_id.is_valid() && message_id.is_server()) {
|
||||
auto dialog_type = d->dialog_id.get_type();
|
||||
if (d->last_new_message_id != MessageId() && message_id.get() > d->last_new_message_id.get()) {
|
||||
// message will not be added to the dialog anyway
|
||||
if (d->dialog_id.get_type() == DialogType::Channel) {
|
||||
if (dialog_type == DialogType::Channel) {
|
||||
// so we try to force channel difference first
|
||||
postponed_get_message_requests_[d->dialog_id].emplace_back(message_id, std::move(promise));
|
||||
get_channel_difference(d->dialog_id, d->pts, true, "get_message");
|
||||
} else {
|
||||
promise.set_value(Unit());
|
||||
}
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (d->deleted_message_ids.count(message_id)) {
|
||||
promise.set_value(Unit());
|
||||
return false;
|
||||
if (d->deleted_message_ids.count(message_id) == 0 && dialog_type != DialogType::SecretChat) {
|
||||
return get_messages_from_server({FullMessageId(d->dialog_id, message_id)}, std::move(promise));
|
||||
}
|
||||
|
||||
get_messages_from_server({full_message_id}, std::move(promise));
|
||||
return false;
|
||||
}
|
||||
|
||||
promise.set_value(Unit());
|
||||
return true;
|
||||
}
|
||||
|
||||
void MessagesManager::get_message(FullMessageId full_message_id, Promise<Unit> &&promise) {
|
||||
Dialog *d = get_dialog_force(full_message_id.get_dialog_id());
|
||||
if (d == nullptr) {
|
||||
return promise.set_error(Status::Error(6, "Chat not found"));
|
||||
}
|
||||
|
||||
get_message_force_from_server(d, full_message_id.get_message_id(), std::move(promise));
|
||||
}
|
||||
|
||||
MessageId MessagesManager::get_replied_message(DialogId dialog_id, MessageId message_id, bool force,
|
||||
Promise<Unit> &&promise) {
|
||||
Dialog *d = get_dialog_force(dialog_id);
|
||||
if (d == nullptr) {
|
||||
promise.set_error(Status::Error(6, "Chat not found"));
|
||||
return MessageId();
|
||||
}
|
||||
|
||||
auto m = get_message_force(d, message_id);
|
||||
if (m == nullptr) {
|
||||
if (force) {
|
||||
promise.set_value(Unit());
|
||||
} else {
|
||||
get_message_force_from_server(d, message_id, std::move(promise));
|
||||
}
|
||||
return MessageId();
|
||||
}
|
||||
|
||||
auto replied_message_id = get_replied_message_id(m);
|
||||
get_message_force_from_server(d, replied_message_id, std::move(promise));
|
||||
return replied_message_id;
|
||||
}
|
||||
|
||||
MessageId MessagesManager::get_dialog_pinned_message(DialogId dialog_id, bool force, Promise<Unit> &&promise) {
|
||||
Dialog *d = get_dialog_force(dialog_id);
|
||||
if (d == nullptr) {
|
||||
promise.set_error(Status::Error(6, "Chat not found"));
|
||||
return MessageId();
|
||||
}
|
||||
|
||||
if (dialog_id.get_type() != DialogType::Channel) {
|
||||
promise.set_value(Unit());
|
||||
return MessageId();
|
||||
}
|
||||
|
||||
auto channel_id = dialog_id.get_channel_id();
|
||||
auto message_id = td_->contacts_manager_->get_channel_pinned_message_id(channel_id);
|
||||
if (!message_id.is_valid()) {
|
||||
if (force) {
|
||||
promise.set_value(Unit());
|
||||
} else {
|
||||
td_->contacts_manager_->get_channel_full(channel_id, std::move(promise));
|
||||
}
|
||||
return MessageId();
|
||||
}
|
||||
|
||||
get_message_force_from_server(d, message_id, std::move(promise));
|
||||
return message_id;
|
||||
}
|
||||
|
||||
bool MessagesManager::get_messages(DialogId dialog_id, const vector<MessageId> &message_ids, Promise<Unit> &&promise) {
|
||||
@ -10932,6 +10995,7 @@ bool MessagesManager::get_messages(DialogId dialog_id, const vector<MessageId> &
|
||||
return false;
|
||||
}
|
||||
|
||||
bool is_secret = dialog_id.get_type() == DialogType::SecretChat;
|
||||
vector<FullMessageId> missed_message_ids;
|
||||
for (auto message_id : message_ids) {
|
||||
if (!message_id.is_valid()) {
|
||||
@ -10940,11 +11004,9 @@ bool MessagesManager::get_messages(DialogId dialog_id, const vector<MessageId> &
|
||||
}
|
||||
|
||||
auto message = get_message_force(d, message_id);
|
||||
if (message == nullptr) {
|
||||
if (message_id.is_server()) {
|
||||
missed_message_ids.emplace_back(dialog_id, message_id);
|
||||
continue;
|
||||
}
|
||||
if (message == nullptr && message_id.is_server() && !is_secret) {
|
||||
missed_message_ids.emplace_back(dialog_id, message_id);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
@ -10962,8 +11024,8 @@ void MessagesManager::get_messages_from_server(vector<FullMessageId> &&message_i
|
||||
LOG(ERROR) << "Empty message_ids";
|
||||
return;
|
||||
}
|
||||
vector<MessageId> ordinary_message_ids;
|
||||
std::unordered_map<ChannelId, vector<MessageId>, ChannelIdHash> channel_message_ids;
|
||||
vector<tl_object_ptr<telegram_api::InputMessage>> ordinary_message_ids;
|
||||
std::unordered_map<ChannelId, vector<tl_object_ptr<telegram_api::InputMessage>>, ChannelIdHash> channel_message_ids;
|
||||
for (auto &full_message_id : message_ids) {
|
||||
auto dialog_id = full_message_id.get_dialog_id();
|
||||
auto message_id = full_message_id.get_message_id();
|
||||
@ -10974,10 +11036,10 @@ void MessagesManager::get_messages_from_server(vector<FullMessageId> &&message_i
|
||||
switch (dialog_id.get_type()) {
|
||||
case DialogType::User:
|
||||
case DialogType::Chat:
|
||||
ordinary_message_ids.push_back(message_id);
|
||||
ordinary_message_ids.push_back(get_input_message(message_id));
|
||||
break;
|
||||
case DialogType::Channel:
|
||||
channel_message_ids[dialog_id.get_channel_id()].push_back(message_id);
|
||||
channel_message_ids[dialog_id.get_channel_id()].push_back(get_input_message(message_id));
|
||||
break;
|
||||
case DialogType::SecretChat:
|
||||
LOG(ERROR) << "Can't get secret chat message from server";
|
||||
@ -15299,7 +15361,8 @@ Result<MessagesManager::InputMessageContent> MessagesManager::process_input_mess
|
||||
bool has_stickers = !sticker_file_ids.empty();
|
||||
td_->videos_manager_->create_video(file_id, thumbnail, has_stickers, std::move(sticker_file_ids),
|
||||
std::move(file_name), std::move(mime_type), input_video->duration_,
|
||||
get_dimensions(input_video->width_, input_video->height_), false);
|
||||
get_dimensions(input_video->width_, input_video->height_),
|
||||
input_video->supports_streaming_, false);
|
||||
|
||||
content = make_unique<MessageVideo>(file_id, std::move(caption));
|
||||
break;
|
||||
@ -19900,8 +19963,8 @@ static auto secret_to_telegram(secret_api::documentAttributeSticker &sticker) {
|
||||
|
||||
// documentAttributeVideo #5910cccb duration:int w:int h:int = DocumentAttribute;
|
||||
static auto secret_to_telegram(secret_api::documentAttributeVideo &video) {
|
||||
return make_tl_object<telegram_api::documentAttributeVideo>(0, false /*ignored*/, video.duration_, video.w_,
|
||||
video.h_);
|
||||
return make_tl_object<telegram_api::documentAttributeVideo>(0, false /*ignored*/, false /*ignored*/, video.duration_,
|
||||
video.w_, video.h_);
|
||||
}
|
||||
|
||||
// documentAttributeFilename #15590068 file_name:string = DocumentAttribute;
|
||||
@ -19918,7 +19981,7 @@ static auto secret_to_telegram(secret_api::documentAttributeVideo66 &video) {
|
||||
(video.flags_ & secret_api::documentAttributeVideo66::ROUND_MESSAGE_MASK) != 0
|
||||
? telegram_api::documentAttributeVideo::ROUND_MESSAGE_MASK
|
||||
: 0,
|
||||
video.round_message_, video.duration_, video.w_, video.h_);
|
||||
video.round_message_, false, video.duration_, video.w_, video.h_);
|
||||
}
|
||||
|
||||
static auto telegram_documentAttributeAudio(bool is_voice_note, int duration, string title, string performer,
|
||||
|
@ -815,11 +815,12 @@ class MessagesManager : public Actor {
|
||||
MessagesManager &operator=(MessagesManager &&) = delete;
|
||||
~MessagesManager() override;
|
||||
|
||||
static vector<MessageId> get_message_ids(const vector<int32> &input_message_ids);
|
||||
static vector<MessageId> get_message_ids(const vector<int64> &input_message_ids);
|
||||
|
||||
static vector<int32> get_server_message_ids(const vector<MessageId> &message_ids);
|
||||
|
||||
static tl_object_ptr<telegram_api::InputMessage> get_input_message(MessageId message_id);
|
||||
|
||||
static MessageId get_message_id(const tl_object_ptr<telegram_api::Message> &message_ptr);
|
||||
|
||||
DialogId get_message_dialog_id(const tl_object_ptr<telegram_api::Message> &message_ptr) const;
|
||||
@ -1100,7 +1101,11 @@ class MessagesManager : public Actor {
|
||||
|
||||
bool have_message(FullMessageId full_message_id);
|
||||
|
||||
bool get_message(FullMessageId full_message_id, Promise<Unit> &&promise);
|
||||
void get_message(FullMessageId full_message_id, Promise<Unit> &&promise);
|
||||
|
||||
MessageId get_replied_message(DialogId dialog_id, MessageId message_id, bool force, Promise<Unit> &&promise);
|
||||
|
||||
MessageId get_dialog_pinned_message(DialogId dialog_id, bool force, Promise<Unit> &&promise);
|
||||
|
||||
bool get_messages(DialogId dialog_id, const vector<MessageId> &message_ids, Promise<Unit> &&promise);
|
||||
|
||||
@ -1797,6 +1802,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
MessageId get_persistent_message_id(const Dialog *d, MessageId message_id) const;
|
||||
|
||||
static MessageId get_replied_message_id(const Message *m);
|
||||
|
||||
MessageId get_reply_to_message_id(Dialog *d, MessageId message_id);
|
||||
|
||||
bool can_set_game_score(DialogId dialog_id, const Message *m) const;
|
||||
@ -2162,6 +2169,8 @@ class MessagesManager : public Actor {
|
||||
|
||||
Message *get_message_force(FullMessageId full_message_id);
|
||||
|
||||
void get_message_force_from_server(Dialog *d, MessageId message_id, Promise<Unit> &&promise);
|
||||
|
||||
Message *on_get_message_from_database(DialogId dialog_id, Dialog *d, const BufferSlice &value);
|
||||
|
||||
void get_dialog_message_by_date_from_server(const Dialog *d, int32 date, int64 random_id, bool after_database_search,
|
||||
|
@ -683,6 +683,55 @@ class TerminateAllOtherSessionsRequest : public RequestOnceActor {
|
||||
}
|
||||
};
|
||||
|
||||
class GetConnectedWebsitesRequest : public RequestActor<tl_object_ptr<td_api::connectedWebsites>> {
|
||||
tl_object_ptr<td_api::connectedWebsites> connected_websites_;
|
||||
|
||||
void do_run(Promise<tl_object_ptr<td_api::connectedWebsites>> &&promise) override {
|
||||
if (get_tries() < 2) {
|
||||
promise.set_value(std::move(connected_websites_));
|
||||
return;
|
||||
}
|
||||
|
||||
td->contacts_manager_->get_connected_websites(std::move(promise));
|
||||
}
|
||||
|
||||
void do_set_result(tl_object_ptr<td_api::connectedWebsites> &&result) override {
|
||||
connected_websites_ = std::move(result);
|
||||
}
|
||||
|
||||
void do_send_result() override {
|
||||
CHECK(connected_websites_ != nullptr);
|
||||
send_result(std::move(connected_websites_));
|
||||
}
|
||||
|
||||
public:
|
||||
GetConnectedWebsitesRequest(ActorShared<Td> td, uint64 request_id) : RequestActor(std::move(td), request_id) {
|
||||
}
|
||||
};
|
||||
|
||||
class DisconnectWebsiteRequest : public RequestOnceActor {
|
||||
int64 website_id_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) override {
|
||||
td->contacts_manager_->disconnect_website(website_id_, std::move(promise));
|
||||
}
|
||||
|
||||
public:
|
||||
DisconnectWebsiteRequest(ActorShared<Td> td, uint64 request_id, int64 website_id)
|
||||
: RequestOnceActor(std::move(td), request_id), website_id_(website_id) {
|
||||
}
|
||||
};
|
||||
|
||||
class DisconnectAllWebsitesRequest : public RequestOnceActor {
|
||||
void do_run(Promise<Unit> &&promise) override {
|
||||
td->contacts_manager_->disconnect_all_websites(std::move(promise));
|
||||
}
|
||||
|
||||
public:
|
||||
DisconnectAllWebsitesRequest(ActorShared<Td> td, uint64 request_id) : RequestOnceActor(std::move(td), request_id) {
|
||||
}
|
||||
};
|
||||
|
||||
class GetUserRequest : public RequestActor<> {
|
||||
UserId user_id_;
|
||||
|
||||
@ -985,6 +1034,49 @@ class GetMessageRequest : public RequestOnceActor {
|
||||
}
|
||||
};
|
||||
|
||||
class GetRepliedMessageRequest : public RequestOnceActor {
|
||||
DialogId dialog_id_;
|
||||
MessageId message_id_;
|
||||
|
||||
MessageId replied_message_id_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) override {
|
||||
replied_message_id_ =
|
||||
td->messages_manager_->get_replied_message(dialog_id_, message_id_, get_tries() < 3, std::move(promise));
|
||||
}
|
||||
|
||||
void do_send_result() override {
|
||||
send_result(td->messages_manager_->get_message_object({dialog_id_, replied_message_id_}));
|
||||
}
|
||||
|
||||
public:
|
||||
GetRepliedMessageRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id, int64 message_id)
|
||||
: RequestOnceActor(std::move(td), request_id), dialog_id_(dialog_id), message_id_(message_id) {
|
||||
set_tries(3);
|
||||
}
|
||||
};
|
||||
|
||||
class GetChatPinnedMessageRequest : public RequestActor<> {
|
||||
DialogId dialog_id_;
|
||||
|
||||
MessageId pinned_message_id_;
|
||||
|
||||
void do_run(Promise<Unit> &&promise) override {
|
||||
pinned_message_id_ =
|
||||
td->messages_manager_->get_dialog_pinned_message(dialog_id_, get_tries() < 3, std::move(promise));
|
||||
}
|
||||
|
||||
void do_send_result() override {
|
||||
send_result(td->messages_manager_->get_message_object({dialog_id_, pinned_message_id_}));
|
||||
}
|
||||
|
||||
public:
|
||||
GetChatPinnedMessageRequest(ActorShared<Td> td, uint64 request_id, int64 dialog_id)
|
||||
: RequestActor<>(std::move(td), request_id), dialog_id_(dialog_id) {
|
||||
set_tries(3);
|
||||
}
|
||||
};
|
||||
|
||||
class GetMessagesRequest : public RequestOnceActor {
|
||||
DialogId dialog_id_;
|
||||
vector<MessageId> message_ids_;
|
||||
@ -4724,6 +4816,24 @@ void Td::on_request(uint64 id, const td_api::terminateAllOtherSessions &request)
|
||||
CREATE_NO_ARGS_REQUEST(TerminateAllOtherSessionsRequest);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getConnectedWebsites &request) {
|
||||
CHECK_AUTH();
|
||||
CHECK_IS_USER();
|
||||
CREATE_NO_ARGS_REQUEST(GetConnectedWebsitesRequest);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::disconnectWebsite &request) {
|
||||
CHECK_AUTH();
|
||||
CHECK_IS_USER();
|
||||
CREATE_REQUEST(DisconnectWebsiteRequest, request.website_id_);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::disconnectAllWebsites &request) {
|
||||
CHECK_AUTH();
|
||||
CHECK_IS_USER();
|
||||
CREATE_NO_ARGS_REQUEST(DisconnectAllWebsitesRequest);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getMe &) {
|
||||
CHECK_AUTH();
|
||||
|
||||
@ -4777,6 +4887,16 @@ void Td::on_request(uint64 id, const td_api::getMessage &request) {
|
||||
CREATE_REQUEST(GetMessageRequest, request.chat_id_, request.message_id_);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getRepliedMessage &request) {
|
||||
CHECK_AUTH();
|
||||
CREATE_REQUEST(GetRepliedMessageRequest, request.chat_id_, request.message_id_);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getChatPinnedMessage &request) {
|
||||
CHECK_AUTH();
|
||||
CREATE_REQUEST(GetChatPinnedMessageRequest, request.chat_id_);
|
||||
}
|
||||
|
||||
void Td::on_request(uint64 id, const td_api::getMessages &request) {
|
||||
CHECK_AUTH();
|
||||
CREATE_REQUEST(GetMessagesRequest, request.chat_id_, request.message_ids_);
|
||||
|
@ -191,7 +191,7 @@ class Td final : public NetQueryCallback {
|
||||
static td_api::object_ptr<td_api::Object> static_request(td_api::object_ptr<td_api::Function> function);
|
||||
|
||||
private:
|
||||
static constexpr const char *tdlib_version = "1.1.1";
|
||||
static constexpr const char *tdlib_version = "1.1.2";
|
||||
static constexpr int32 ONLINE_TIMEOUT = 240;
|
||||
|
||||
void send_result(uint64 id, tl_object_ptr<td_api::Object> object);
|
||||
@ -346,6 +346,12 @@ class Td final : public NetQueryCallback {
|
||||
|
||||
void on_request(uint64 id, const td_api::terminateAllOtherSessions &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getConnectedWebsites &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::disconnectWebsite &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::disconnectAllWebsites &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getMe &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getUser &request);
|
||||
@ -366,6 +372,10 @@ class Td final : public NetQueryCallback {
|
||||
|
||||
void on_request(uint64 id, const td_api::getMessage &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getRepliedMessage &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getChatPinnedMessage &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getMessages &request);
|
||||
|
||||
void on_request(uint64 id, const td_api::getPublicMessageLink &request);
|
||||
|
@ -214,8 +214,8 @@ tl_object_ptr<telegram_api::InputMedia> VideoNotesManager::get_input_media(
|
||||
|
||||
vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes;
|
||||
attributes.push_back(make_tl_object<telegram_api::documentAttributeVideo>(
|
||||
telegram_api::documentAttributeVideo::ROUND_MESSAGE_MASK, false /*ignored*/, video_note->duration,
|
||||
video_note->dimensions.width ? video_note->dimensions.width : 240,
|
||||
telegram_api::documentAttributeVideo::ROUND_MESSAGE_MASK, false /*ignored*/, false /*ignored*/,
|
||||
video_note->duration, video_note->dimensions.width ? video_note->dimensions.width : 240,
|
||||
video_note->dimensions.height ? video_note->dimensions.height : 240));
|
||||
int32 flags = 0;
|
||||
if (input_thumbnail != nullptr) {
|
||||
|
@ -45,6 +45,7 @@ tl_object_ptr<td_api::video> VideosManager::get_video_object(FileId file_id) {
|
||||
|
||||
return make_tl_object<td_api::video>(video->duration, video->dimensions.width, video->dimensions.height,
|
||||
video->file_name, video->mime_type, video->has_stickers,
|
||||
video->supports_streaming,
|
||||
get_photo_size_object(td_->file_manager_.get(), &video->thumbnail),
|
||||
td_->file_manager_->get_file_object(video->file_id));
|
||||
}
|
||||
@ -62,10 +63,12 @@ FileId VideosManager::on_get_video(std::unique_ptr<Video> new_video, bool replac
|
||||
v->mime_type = new_video->mime_type;
|
||||
v->is_changed = true;
|
||||
}
|
||||
if (v->duration != new_video->duration || v->dimensions != new_video->dimensions) {
|
||||
if (v->duration != new_video->duration || v->dimensions != new_video->dimensions ||
|
||||
v->supports_streaming != new_video->supports_streaming) {
|
||||
LOG(DEBUG) << "Video " << file_id << " info has changed";
|
||||
v->duration = new_video->duration;
|
||||
v->dimensions = new_video->dimensions;
|
||||
v->supports_streaming = new_video->supports_streaming;
|
||||
v->is_changed = true;
|
||||
}
|
||||
if (v->file_name != new_video->file_name) {
|
||||
@ -173,7 +176,7 @@ bool VideosManager::merge_videos(FileId new_id, FileId old_id, bool can_delete_o
|
||||
|
||||
void VideosManager::create_video(FileId file_id, PhotoSize thumbnail, bool has_stickers,
|
||||
vector<FileId> &&sticker_file_ids, string file_name, string mime_type, int32 duration,
|
||||
Dimensions dimensions, bool replace) {
|
||||
Dimensions dimensions, bool supports_streaming, bool replace) {
|
||||
auto v = make_unique<Video>();
|
||||
v->file_id = file_id;
|
||||
v->file_name = std::move(file_name);
|
||||
@ -181,6 +184,7 @@ void VideosManager::create_video(FileId file_id, PhotoSize thumbnail, bool has_s
|
||||
v->duration = std::max(duration, 0);
|
||||
v->dimensions = dimensions;
|
||||
v->thumbnail = std::move(thumbnail);
|
||||
v->supports_streaming = supports_streaming;
|
||||
v->has_stickers = has_stickers;
|
||||
v->sticker_file_ids = std::move(sticker_file_ids);
|
||||
on_get_video(std::move(v), replace);
|
||||
@ -245,9 +249,15 @@ tl_object_ptr<telegram_api::InputMedia> VideosManager::get_input_media(
|
||||
const Video *video = get_video(file_id);
|
||||
CHECK(video != nullptr);
|
||||
|
||||
int32 attribute_flags = 0;
|
||||
if (video->supports_streaming) {
|
||||
attribute_flags |= telegram_api::documentAttributeVideo::SUPPORTS_STREAMING_MASK;
|
||||
}
|
||||
|
||||
vector<tl_object_ptr<telegram_api::DocumentAttribute>> attributes;
|
||||
attributes.push_back(make_tl_object<telegram_api::documentAttributeVideo>(
|
||||
0, false /*ignored*/, video->duration, video->dimensions.width, video->dimensions.height));
|
||||
attribute_flags, false /*ignored*/, false /*ignored*/, video->duration, video->dimensions.width,
|
||||
video->dimensions.height));
|
||||
if (!video->file_name.empty()) {
|
||||
attributes.push_back(make_tl_object<telegram_api::documentAttributeFilename>(video->file_name));
|
||||
}
|
||||
|
@ -33,7 +33,8 @@ class VideosManager {
|
||||
tl_object_ptr<td_api::video> get_video_object(FileId file_id);
|
||||
|
||||
void create_video(FileId file_id, PhotoSize thumbnail, bool has_stickers, vector<FileId> &&sticker_file_ids,
|
||||
string file_name, string mime_type, int32 duration, Dimensions dimensions, bool replace);
|
||||
string file_name, string mime_type, int32 duration, Dimensions dimensions, bool supports_streaming,
|
||||
bool replace);
|
||||
|
||||
tl_object_ptr<telegram_api::InputMedia> get_input_media(FileId file_id,
|
||||
tl_object_ptr<telegram_api::InputFile> input_file,
|
||||
@ -69,6 +70,8 @@ class VideosManager {
|
||||
Dimensions dimensions;
|
||||
PhotoSize thumbnail;
|
||||
|
||||
bool supports_streaming = false;
|
||||
|
||||
bool has_stickers = false;
|
||||
vector<FileId> sticker_file_ids;
|
||||
|
||||
|
@ -22,6 +22,7 @@ void VideosManager::store_video(FileId file_id, T &storer) const {
|
||||
const Video *video = it->second.get();
|
||||
BEGIN_STORE_FLAGS();
|
||||
STORE_FLAG(video->has_stickers);
|
||||
STORE_FLAG(video->supports_streaming);
|
||||
END_STORE_FLAGS();
|
||||
store(video->file_name, storer);
|
||||
store(video->mime_type, storer);
|
||||
@ -39,6 +40,7 @@ FileId VideosManager::parse_video(T &parser) {
|
||||
auto video = make_unique<Video>();
|
||||
BEGIN_PARSE_FLAGS();
|
||||
PARSE_FLAG(video->has_stickers);
|
||||
PARSE_FLAG(video->supports_streaming);
|
||||
END_PARSE_FLAGS();
|
||||
parse(video->file_name, parser);
|
||||
parse(video->mime_type, parser);
|
||||
|
@ -395,7 +395,11 @@ class CliClient final : public Actor {
|
||||
}
|
||||
|
||||
static int64 as_message_id(Slice str) {
|
||||
return to_integer<int64>(trim(str));
|
||||
str = trim(str);
|
||||
if (!str.empty() && str.back() == 's') {
|
||||
return to_integer<int32>(str) << 20;
|
||||
}
|
||||
return to_integer<int64>(str);
|
||||
}
|
||||
|
||||
static vector<int64> as_message_ids(Slice message_ids_string, char delimiter = ' ') {
|
||||
@ -1479,6 +1483,12 @@ class CliClient final : public Actor {
|
||||
send_request(make_tl_object<td_api::terminateSession>(to_integer<int64>(args)));
|
||||
} else if (op == "TerminateAllOtherSessions") {
|
||||
send_request(make_tl_object<td_api::terminateAllOtherSessions>());
|
||||
} else if (op == "gcw") {
|
||||
send_request(make_tl_object<td_api::getConnectedWebsites>());
|
||||
} else if (op == "dw") {
|
||||
send_request(make_tl_object<td_api::disconnectWebsite>(to_integer<int64>(args)));
|
||||
} else if (op == "daw") {
|
||||
send_request(make_tl_object<td_api::disconnectAllWebsites>());
|
||||
} else if (op == "gw") {
|
||||
send_request(make_tl_object<td_api::getWallpapers>());
|
||||
} else if (op == "git") {
|
||||
@ -1797,6 +1807,14 @@ class CliClient final : public Actor {
|
||||
string message_id;
|
||||
std::tie(chat_id, message_id) = split(args);
|
||||
send_request(make_tl_object<td_api::getMessage>(as_chat_id(chat_id), as_message_id(message_id)));
|
||||
} else if (op == "grm") {
|
||||
string chat_id;
|
||||
string message_id;
|
||||
std::tie(chat_id, message_id) = split(args);
|
||||
send_request(make_tl_object<td_api::getRepliedMessage>(as_chat_id(chat_id), as_message_id(message_id)));
|
||||
} else if (op == "gcpm") {
|
||||
string chat_id = args;
|
||||
send_request(make_tl_object<td_api::getChatPinnedMessage>(as_chat_id(chat_id)));
|
||||
} else if (op == "gms") {
|
||||
string chat_id;
|
||||
string message_ids;
|
||||
@ -2408,9 +2426,9 @@ class CliClient final : public Actor {
|
||||
sticker_file_ids = to_integers<int32>(sticker_file_ids_str, ',');
|
||||
}
|
||||
|
||||
send_message(chat_id,
|
||||
make_tl_object<td_api::inputMessageVideo>(as_local_file(video_path), nullptr,
|
||||
std::move(sticker_file_ids), 1, 2, 3, as_caption(""), 0));
|
||||
send_message(chat_id, make_tl_object<td_api::inputMessageVideo>(as_local_file(video_path), nullptr,
|
||||
std::move(sticker_file_ids), 1, 2, 3, true,
|
||||
as_caption(""), 0));
|
||||
} else if (op == "svn") {
|
||||
string chat_id;
|
||||
string video_path;
|
||||
|
Loading…
Reference in New Issue
Block a user