From 5c7d2723edd6f41e489d7448872c6bbb956534ff Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 6 Feb 2026 13:24:04 +0400 Subject: [PATCH] Update API scheme to layer 223. Owners. --- Telegram/Resources/langs/lang.strings | 2 + .../SourceFiles/api/api_text_entities.cpp | 1 + .../peers/channel_ownership_transfer.cpp | 40 ++-- .../boxes/peers/channel_ownership_transfer.h | 2 - .../boxes/select_future_owner_box.cpp | 216 +++++++++++++----- .../boxes/select_future_owner_box.h | 3 +- .../export/data/export_data_types.cpp | 3 +- Telegram/SourceFiles/mtproto/scheme/api.tl | 14 +- .../SourceFiles/window/window_peer_menu.cpp | 17 +- 9 files changed, 192 insertions(+), 106 deletions(-) diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index eae8c30d18..a14ec5350e 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1655,6 +1655,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_leave_next_owner_box_title_group" = "Leave Group?"; "lng_leave_next_owner_box_about" = "If you leave, **{user}** will become the new owner of **{chat}** in **1 week**."; "lng_leave_next_owner_box_about_admin" = "If you leave, **{user}** will become the new admin of **{chat}** in **1 week**."; +"lng_leave_next_owner_box_about_legacy" = "If you leave, **{user}** will immediately become the new owner of **{chat}**."; +"lng_leave_next_owner_box_about_admin_legacy" = "If you leave, **{user}** will immediately become the new admin of **{chat}**."; "lng_select_next_owner_box" = "Appoint Another Owner"; "lng_select_next_owner_box_admin" = "Appoint Another Admin"; "lng_select_next_owner_box_title" = "Appoint New Owner"; diff --git a/Telegram/SourceFiles/api/api_text_entities.cpp b/Telegram/SourceFiles/api/api_text_entities.cpp index f3d6db8b40..ae9e30c22e 100644 --- a/Telegram/SourceFiles/api/api_text_entities.cpp +++ b/Telegram/SourceFiles/api/api_text_entities.cpp @@ -238,6 +238,7 @@ EntitiesInText EntitiesFromMTP( d.vlength().v, d.is_collapsed() ? u"1"_q : QString(), }); + }, [&](const MTPDmessageEntityFormattedDate &d) { }); } return result; diff --git a/Telegram/SourceFiles/boxes/peers/channel_ownership_transfer.cpp b/Telegram/SourceFiles/boxes/peers/channel_ownership_transfer.cpp index 990636ed77..2153db1df7 100644 --- a/Telegram/SourceFiles/boxes/peers/channel_ownership_transfer.cpp +++ b/Telegram/SourceFiles/boxes/peers/channel_ownership_transfer.cpp @@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "apiwrap.h" #include "boxes/passcode_box.h" #include "core/core_cloud_password.h" -#include "data/data_channel.h" #include "data/data_user.h" #include "lang/lang_keys.h" #include "main/main_session.h" @@ -47,21 +46,10 @@ bool ChannelOwnershipTransfer::handleTransferPasswordError( } void ChannelOwnershipTransfer::start() { - if (const auto chat = _peer->asChatNotMigrated()) { - _peer->session().api().migrateChat(chat, [=]( - not_null channel) { - startTransfer(channel); - }); - } else if (const auto channel = _peer->asChannelOrMigrated()) { - startTransfer(channel); - } -} - -void ChannelOwnershipTransfer::startTransfer(not_null channel) { - const auto api = &channel->session().api(); + const auto api = &_peer->session().api(); api->cloudPassword().reload(); - api->request(MTPchannels_EditCreator( - channel->inputChannel(), + api->request(MTPmessages_EditChatCreator( + _peer->input(), MTP_inputUserEmpty(), MTP_inputCheckPasswordEmpty() )).fail([=](const MTP::Error &error) { @@ -78,7 +66,7 @@ void ChannelOwnershipTransfer::startTransfer(not_null channel) { .text = tr::lng_rights_transfer_about( tr::now, lt_group, - tr::bold(channel->name()), + tr::bold(_peer->name()), lt_user, tr::bold(_selectedUser->shortName()), tr::rich), @@ -110,20 +98,16 @@ void ChannelOwnershipTransfer::requestPassword() { void ChannelOwnershipTransfer::sendRequest( base::weak_qptr box, const Core::CloudPasswordResult &result) { - const auto channel = _peer->asChannelOrMigrated(); - if (!channel) { - return; - } - const auto api = &channel->session().api(); - api->request(MTPchannels_EditCreator( - channel->inputChannel(), + const auto api = &_peer->session().api(); + api->request(MTPmessages_EditChatCreator( + _peer->input(), _selectedUser->inputUser(), result.result )).done([=](const MTPUpdates &result) { api->applyUpdates(result); const auto currentShow = box ? box->uiShow() : _show; currentShow->showToast( - (channel->isBroadcast() + (_peer->isBroadcast() ? tr::lng_rights_transfer_done_channel : tr::lng_rights_transfer_done_group)( tr::now, @@ -143,11 +127,13 @@ void ChannelOwnershipTransfer::sendRequest( } else if (type == u"CHANNELS_ADMIN_LOCATED_TOO_MUCH"_q) { return tr::lng_channels_too_much_located_other(tr::now); } else if (type == u"ADMINS_TOO_MUCH"_q) { - return (channel->isBroadcast() + return (_peer->isBroadcast() ? tr::lng_error_admin_limit_channel : tr::lng_error_admin_limit)(tr::now); - } else if (type == u"CHANNEL_INVALID"_q) { - return (channel->isBroadcast() + } else if (type == u"CHANNEL_INVALID"_q + || type == u"CHAT_CREATOR_REQUIRED"_q + || type == u"PARTICIPANT_MISSING"_q) { + return (_peer->isBroadcast() ? tr::lng_channel_not_accessible : tr::lng_group_not_accessible)(tr::now); } diff --git a/Telegram/SourceFiles/boxes/peers/channel_ownership_transfer.h b/Telegram/SourceFiles/boxes/peers/channel_ownership_transfer.h index 73c7709cc9..2fca0750fd 100644 --- a/Telegram/SourceFiles/boxes/peers/channel_ownership_transfer.h +++ b/Telegram/SourceFiles/boxes/peers/channel_ownership_transfer.h @@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -class ChannelData; class UserData; namespace Ui { @@ -36,7 +35,6 @@ private: void sendRequest( base::weak_qptr box, const Core::CloudPasswordResult &result); - void startTransfer(not_null channel); const not_null _peer; const not_null _selectedUser; diff --git a/Telegram/SourceFiles/boxes/select_future_owner_box.cpp b/Telegram/SourceFiles/boxes/select_future_owner_box.cpp index e040b20cf1..dcefc7d68c 100644 --- a/Telegram/SourceFiles/boxes/select_future_owner_box.cpp +++ b/Telegram/SourceFiles/boxes/select_future_owner_box.cpp @@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "core/application.h" #include "core/core_cloud_password.h" #include "data/data_channel.h" +#include "data/data_chat.h" #include "dialogs/ui/chat_search_empty.h" #include "boxes/peers/channel_ownership_transfer.h" #include "data/data_session.h" @@ -44,58 +45,25 @@ enum class ParticipantType { Members }; -class ParticipantsController : public PeerListController { +class FutureOwnerController : public PeerListController { public: - ParticipantsController( - not_null window, - not_null channel, - ParticipantType type); - - Main::Session &session() const override; - void prepare() override; void rowClicked(not_null row) override; - void loadMoreRows() override; void itemDeselectedHook(not_null peer) override; void setOnRowClicked(Fn callback); rpl::producer<> itemDeselected() const; private: - const not_null _window; - const not_null _channel; - const ParticipantType _type; - MTP::Sender _api; Fn _onRowClicked; rpl::event_stream<> _itemDeselected; - mtpRequestId _loadRequestId = 0; - int _offset = 0; - bool _allLoaded = false; }; -ParticipantsController::ParticipantsController( - not_null window, - not_null channel, - ParticipantType type) -: _window(window) -, _channel(channel) -, _type(type) -, _api(&channel->session().mtp()) { -} - -Main::Session &ParticipantsController::session() const { - return _channel->session(); -} - -void ParticipantsController::setOnRowClicked(Fn callback) { +void FutureOwnerController::setOnRowClicked(Fn callback) { _onRowClicked = callback; } -void ParticipantsController::prepare() { - loadMoreRows(); -} - -void ParticipantsController::rowClicked(not_null row) { +void FutureOwnerController::rowClicked(not_null row) { delegate()->peerListSetRowChecked( row, !delegate()->peerListIsRowChecked(row)); @@ -110,14 +78,51 @@ void ParticipantsController::rowClicked(not_null row) { } } -void ParticipantsController::itemDeselectedHook(not_null peer) { +void FutureOwnerController::itemDeselectedHook(not_null peer) { _itemDeselected.fire({}); } -rpl::producer<> ParticipantsController::itemDeselected() const { +rpl::producer<> FutureOwnerController::itemDeselected() const { return _itemDeselected.events(); } +class ParticipantsController : public FutureOwnerController { +public: + ParticipantsController( + not_null channel, + ParticipantType type); + + Main::Session &session() const override; + void prepare() override; + void loadMoreRows() override; + +private: + const not_null _channel; + const ParticipantType _type; + MTP::Sender _api; + + mtpRequestId _loadRequestId = 0; + int _offset = 0; + bool _allLoaded = false; + +}; + +ParticipantsController::ParticipantsController( + not_null channel, + ParticipantType type) +: _channel(channel) +, _type(type) +, _api(&channel->session().mtp()) { +} + +Main::Session &ParticipantsController::session() const { + return _channel->session(); +} + +void ParticipantsController::prepare() { + loadMoreRows(); +} + void ParticipantsController::loadMoreRows() { if (_loadRequestId || _allLoaded) { return; @@ -191,13 +196,71 @@ void ParticipantsController::loadMoreRows() { }).send(); } +class LegacyParticipantsController : public FutureOwnerController { +public: + LegacyParticipantsController( + not_null chat, + ParticipantType type); + + Main::Session &session() const override; + void prepare() override; + void loadMoreRows() override; + +private: + const not_null _chat; + const ParticipantType _type; + +}; + +LegacyParticipantsController::LegacyParticipantsController( + not_null chat, + ParticipantType type) +: _chat(chat) +, _type(type) { +} + +Main::Session &LegacyParticipantsController::session() const { + return _chat->session(); +} + +void LegacyParticipantsController::prepare() { + if (_chat->noParticipantInfo()) { + _chat->updateFullForced(); + } + const auto &source = (_type == ParticipantType::Admins) + ? _chat->admins + : _chat->participants; + for (const auto &user : source) { + if (user->isBot()) { + continue; + } + if (user->id == peerFromUser(_chat->creator)) { + continue; + } + if (_type == ParticipantType::Members + && _chat->admins.contains(user)) { + continue; + } + delegate()->peerListAppendRow( + std::make_unique(user)); + } + delegate()->peerListRefreshRows(); +} + +void LegacyParticipantsController::loadMoreRows() { +} + } // namespace void SelectFutureOwnerbox( not_null box, - not_null channel, + not_null peer, not_null user) { const auto content = box->verticalLayout(); + const auto channel = peer->asChannel(); + const auto chat = peer->asChat(); + const auto isGroup = peer->isMegagroup() || peer->isChat(); + const auto isLegacy = (chat != nullptr); Ui::AddSkip(content); Ui::AddSkip(content); content->add( @@ -205,7 +268,7 @@ void SelectFutureOwnerbox( content, rpl::single(std::vector>{ user->session().user(), - channel, + peer, }), user, UserpicsTransferType::ChannelFutureOwner), @@ -215,24 +278,36 @@ void SelectFutureOwnerbox( content->add( object_ptr( content, - channel->isMegagroup() + isGroup ? tr::lng_leave_next_owner_box_title_group() : tr::lng_leave_next_owner_box_title(), box->getDelegate()->style().title), st::boxRowPadding); Ui::AddSkip(content); Ui::AddSkip(content); - const auto adminsAreEqual = (channel->adminsCount() <= 1); + const auto adminsCount = [&] { + if (channel) { + return channel->adminsCount(); + } else if (chat) { + return int(chat->admins.size()) + 1; + } + return 0; + }(); + const auto adminsAreEqual = (adminsCount <= 1); content->add( object_ptr( content, - (adminsAreEqual - ? tr::lng_leave_next_owner_box_about - : tr::lng_leave_next_owner_box_about_admin)( + (isLegacy + ? (adminsAreEqual + ? tr::lng_leave_next_owner_box_about_legacy + : tr::lng_leave_next_owner_box_about_admin_legacy) + : (adminsAreEqual + ? tr::lng_leave_next_owner_box_about + : tr::lng_leave_next_owner_box_about_admin))( lt_user, Info::Profile::NameValue(user) | rpl::map(tr::marked), lt_chat, - Info::Profile::NameValue(channel) | rpl::map(tr::marked), + Info::Profile::NameValue(peer) | rpl::map(tr::marked), tr::rich), st::boxLabel), st::boxRowPadding); @@ -264,14 +339,14 @@ void SelectFutureOwnerbox( const auto leave = content->add( object_ptr( content, - channel->isMegagroup() + isGroup ? tr::lng_profile_leave_group() : tr::lng_profile_leave_channel(), st::attentionBoxButton), st::boxRowPadding, style::al_justify); leave->setClickedCallback([=, revoke = false] { - channel->session().api().deleteConversation(channel, revoke); + peer->session().api().deleteConversation(peer, revoke); box->closeBox(); }); select->setClickedCallback([=] { @@ -283,16 +358,31 @@ void SelectFutureOwnerbox( return; } - auto adminsOwned = std::make_unique( - sessionController, - channel, - ParticipantType::Admins); - - auto membersOwned = std::make_unique( - sessionController, - channel, - ParticipantType::Members); - + using Pair = std::pair< + std::unique_ptr, + std::unique_ptr>; + auto makeControllers = [&]() -> Pair { + if (channel) { + return { + std::make_unique( + channel, + ParticipantType::Admins), + std::make_unique( + channel, + ParticipantType::Members), + }; + } else { + return { + std::make_unique( + chat, + ParticipantType::Admins), + std::make_unique( + chat, + ParticipantType::Members), + }; + } + }; + auto [adminsOwned, membersOwned] = makeControllers(); const auto admins = adminsOwned.get(); const auto members = membersOwned.get(); @@ -331,14 +421,14 @@ void SelectFutureOwnerbox( 0, CreatePeerListSectionSubtitle( selectBox, - !channel->isMegagroup() + !isGroup ? tr::lng_select_next_owner_box_sub_admins() : tr::lng_select_next_owner_box_sub_admins_group())); const auto separatorMembers = selectBox->addSeparatorBefore( 1, CreatePeerListSectionSubtitle( selectBox, - !channel->isMegagroup() + !isGroup ? tr::lng_select_next_owner_box_sub_members() : tr::lng_select_next_owner_box_sub_members_group())); rpl::combine( @@ -407,13 +497,13 @@ void SelectFutureOwnerbox( if (const auto user = selected.front()->asUser()) { auto &lifetime = selectBox->lifetime(); lifetime.make_state( - channel, + peer, user, selectBox->uiShow(), [=](std::shared_ptr show) { const auto revoke = false; - channel->session().api().deleteConversation( - channel, + peer->session().api().deleteConversation( + peer, revoke); show->hideLayer(); })->start(); diff --git a/Telegram/SourceFiles/boxes/select_future_owner_box.h b/Telegram/SourceFiles/boxes/select_future_owner_box.h index 7f48bf64c1..a0e1aa716b 100644 --- a/Telegram/SourceFiles/boxes/select_future_owner_box.h +++ b/Telegram/SourceFiles/boxes/select_future_owner_box.h @@ -7,7 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -class ChannelData; class PeerData; class UserData; @@ -18,5 +17,5 @@ class Show; void SelectFutureOwnerbox( not_null box, - not_null channel, + not_null peer, not_null user); diff --git a/Telegram/SourceFiles/export/data/export_data_types.cpp b/Telegram/SourceFiles/export/data/export_data_types.cpp index 7af24dd128..66fdf9261a 100644 --- a/Telegram/SourceFiles/export/data/export_data_types.cpp +++ b/Telegram/SourceFiles/export/data/export_data_types.cpp @@ -303,7 +303,8 @@ std::vector ParseText( return Type::Blockquote; }, [](const MTPDmessageEntityBankCard&) { return Type::BankCard; }, [](const MTPDmessageEntitySpoiler&) { return Type::Spoiler; }, - [](const MTPDmessageEntityCustomEmoji&) { return Type::CustomEmoji; }); + [](const MTPDmessageEntityCustomEmoji&) { return Type::CustomEmoji; }, + [](const MTPDmessageEntityFormattedDate&) { return Type::Unknown; }); part.text = mid(start, length); part.additional = entity.match( [](const MTPDmessageEntityPre &data) { diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 77968bd224..54b9b683b9 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -33,7 +33,7 @@ inputMediaUploadedPhoto#1e287d04 flags:# spoiler:flags.2?true file:InputFile sti inputMediaPhoto#b3ba0635 flags:# spoiler:flags.1?true id:InputPhoto ttl_seconds:flags.0?int = InputMedia; inputMediaGeoPoint#f9c44144 geo_point:InputGeoPoint = InputMedia; inputMediaContact#f8ab7dfb phone_number:string first_name:string last_name:string vcard:string = InputMedia; -inputMediaUploadedDocument#37c9330 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector stickers:flags.0?Vector video_cover:flags.6?InputPhoto video_timestamp:flags.7?int ttl_seconds:flags.1?int = InputMedia; +inputMediaUploadedDocument#37c9330 flags:# nosound_video:flags.3?true force_file:flags.4?true spoiler:flags.5?true live_photo:flags.8?true file:InputFile thumb:flags.2?InputFile mime_type:string attributes:Vector stickers:flags.0?Vector video_cover:flags.6?InputPhoto video_timestamp:flags.7?int ttl_seconds:flags.1?int = InputMedia; inputMediaDocument#a8763ab5 flags:# spoiler:flags.2?true id:InputDocument video_cover:flags.3?InputPhoto video_timestamp:flags.4?int ttl_seconds:flags.0?int query:flags.1?string = InputMedia; inputMediaVenue#c13d1c11 geo_point:InputGeoPoint title:string address:string provider:string venue_id:string venue_type:string = InputMedia; inputMediaPhotoExternal#e5bbfe1a flags:# spoiler:flags.1?true url:string ttl_seconds:flags.0?int = InputMedia; @@ -126,7 +126,7 @@ messageMediaPhoto#695150d7 flags:# spoiler:flags.3?true photo:flags.0?Photo ttl_ messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia; messageMediaContact#70322949 phone_number:string first_name:string last_name:string vcard:string user_id:long = MessageMedia; messageMediaUnsupported#9f84f49e = MessageMedia; -messageMediaDocument#52d8ccd9 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true document:flags.0?Document alt_documents:flags.5?Vector video_cover:flags.9?Photo video_timestamp:flags.10?int ttl_seconds:flags.2?int = MessageMedia; +messageMediaDocument#52d8ccd9 flags:# nopremium:flags.3?true spoiler:flags.4?true video:flags.6?true round:flags.7?true voice:flags.8?true live_photo:flags.11?true document:flags.0?Document alt_documents:flags.5?Vector video_cover:flags.9?Photo video_timestamp:flags.10?int ttl_seconds:flags.2?int = MessageMedia; messageMediaWebPage#ddf10c3b flags:# force_large_media:flags.0?true force_small_media:flags.1?true manual:flags.3?true safe:flags.4?true webpage:WebPage = MessageMedia; messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia; messageMediaGame#fdb19008 game:Game = MessageMedia; @@ -255,7 +255,7 @@ inputReportReasonFake#f5ddd6e7 = ReportReason; inputReportReasonIllegalDrugs#a8eb2be = ReportReason; inputReportReasonPersonalDetails#9ec7863d = ReportReason; -userFull#a02bc13e flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true display_gifts_button:flags2.16?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme:flags.15?ChatTheme private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long disallowed_gifts:flags2.15?DisallowedGiftsSettings stars_rating:flags2.17?StarsRating stars_my_pending_rating:flags2.18?StarsRating stars_my_pending_rating_date:flags2.18?int main_tab:flags2.20?ProfileTab saved_music:flags2.21?Document note:flags2.22?TextWithEntities = UserFull; +userFull#a02bc13e flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true voice_messages_forbidden:flags.20?true translations_disabled:flags.23?true stories_pinned_available:flags.26?true blocked_my_stories_from:flags.27?true wallpaper_overridden:flags.28?true contact_require_premium:flags.29?true read_dates_private:flags.30?true flags2:# sponsored_enabled:flags2.7?true can_view_revenue:flags2.9?true bot_can_manage_emoji_status:flags2.10?true display_gifts_button:flags2.16?true noforwards_my_enabled:flags2.23?true noforwards_peer_enabled:flags2.24?true id:long about:flags.1?string settings:PeerSettings personal_photo:flags.21?Photo profile_photo:flags.2?Photo fallback_photo:flags.22?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int ttl_period:flags.14?int theme:flags.15?ChatTheme private_forward_name:flags.16?string bot_group_admin_rights:flags.17?ChatAdminRights bot_broadcast_admin_rights:flags.18?ChatAdminRights wallpaper:flags.24?WallPaper stories:flags.25?PeerStories business_work_hours:flags2.0?BusinessWorkHours business_location:flags2.1?BusinessLocation business_greeting_message:flags2.2?BusinessGreetingMessage business_away_message:flags2.3?BusinessAwayMessage business_intro:flags2.4?BusinessIntro birthday:flags2.5?Birthday personal_channel_id:flags2.6?long personal_channel_message:flags2.6?int stargifts_count:flags2.8?int starref_program:flags2.11?StarRefProgram bot_verification:flags2.12?BotVerification send_paid_messages_stars:flags2.14?long disallowed_gifts:flags2.15?DisallowedGiftsSettings stars_rating:flags2.17?StarsRating stars_my_pending_rating:flags2.18?StarsRating stars_my_pending_rating_date:flags2.18?int main_tab:flags2.20?ProfileTab saved_music:flags2.21?Document note:flags2.22?TextWithEntities = UserFull; contact#145ade0b user_id:long mutual:Bool = Contact; @@ -457,6 +457,7 @@ updateStarGiftAuctionState#48e246c2 gift_id:long state:StarGiftAuctionState = Up updateStarGiftAuctionUserState#dc58f31e gift_id:long user_state:StarGiftAuctionUserState = Update; updateEmojiGameInfo#fb9c547a info:messages.EmojiGameInfo = Update; updateStarGiftCraftFail#ac072444 = Update; +updatePeerHistoryNoForwards#5736b39a flags:# my_enabled:flags.0?true peer_enabled:flags.1?true peer:Peer = Update; updates.state#a56c2a3e pts:int qts:int date:int seq:int unread_count:int = updates.State; @@ -727,6 +728,7 @@ messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity; messageEntitySpoiler#32ca960f offset:int length:int = MessageEntity; messageEntityCustomEmoji#c8cf05f8 offset:int length:int document_id:long = MessageEntity; messageEntityBlockquote#f1ccaaac flags:# collapsed:flags.0?true offset:int length:int = MessageEntity; +messageEntityFormattedDate#904ac7c7 flags:# relative:flags.0?true short_time:flags.1?true long_time:flags.2?true short_date:flags.3?true long_date:flags.4?true offset:int length:int date:int = MessageEntity; inputChannelEmpty#ee8c1e86 = InputChannel; inputChannel#f35aec28 channel_id:long access_hash:long = InputChannel; @@ -2565,6 +2567,8 @@ messages.createForumTopic#2f98c3d5 flags:# title_missing:flags.4?true peer:Input messages.deleteTopicHistory#d2816f10 peer:InputPeer top_msg_id:int = messages.AffectedHistory; messages.getEmojiGameInfo#fb7e8ca7 = messages.EmojiGameInfo; messages.summarizeText#9d4104e2 flags:# peer:InputPeer id:int to_lang:flags.0?string = TextWithEntities; +messages.editChatCreator#f743b857 peer:InputPeer user_id:InputUser password:InputCheckPasswordSRP = Updates; +messages.getFutureChatCreatorAfterLeave#3b7d0ea6 peer:InputPeer = User; updates.getState#edd4882a = updates.State; updates.getDifference#19c2f763 flags:# pts:int pts_limit:flags.1?int pts_total_limit:flags.0?int date:int qts:int qts_limit:flags.2?int = updates.Difference; @@ -2641,7 +2645,6 @@ channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Upd channels.getLeftChannels#8341ecc0 offset:int = messages.Chats; channels.getGroupsForDiscussion#f5dad378 = messages.Chats; channels.setDiscussionGroup#40582bb2 broadcast:InputChannel group:InputChannel = Bool; -channels.editCreator#8f38cd1f channel:InputChannel user_id:InputUser password:InputCheckPasswordSRP = Updates; channels.editLocation#58e63f6d channel:InputChannel geo_point:InputGeoPoint address:string = Bool; channels.toggleSlowMode#edd49ef0 channel:InputChannel seconds:int = Updates; channels.getInactiveChannels#11e831ee = messages.InactiveChats; @@ -2670,7 +2673,6 @@ channels.toggleAutotranslation#167fc0a1 channel:InputChannel enabled:Bool = Upda channels.getMessageAuthor#ece2a0e6 channel:InputChannel id:int = User; channels.checkSearchPostsFlood#22567115 flags:# query:flags.0?string = SearchPostsFlood; channels.setMainProfileTab#3583fcb1 channel:InputChannel tab:ProfileTab = Bool; -channels.getFutureCreatorAfterLeave#a00918af channel:InputChannel = User; bots.sendCustomRequest#aa2769ed custom_method:string params:DataJSON = DataJSON; bots.answerWebhookJSONQuery#e6213f4d query_id:long data:DataJSON = Bool; @@ -2903,4 +2905,4 @@ smsjobs.finishJob#4f1ebf24 flags:# job_id:string error:flags.0?string = Bool; fragment.getCollectibleInfo#be1e85ba collectible:InputCollectible = fragment.CollectibleInfo; -// LAYER 222 +// LAYER 223 diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index a6ad45c90b..83a197b615 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -3656,20 +3656,27 @@ Fn ClearHistoryHandler( Fn DeleteAndLeaveHandler( not_null controller, not_null peer) { - if (const auto channel = peer->asChannel(); - channel && channel->amCreator()) { + const auto isCreator = [&] { + if (const auto channel = peer->asChannel()) { + return channel->amCreator(); + } else if (const auto chat = peer->asChat()) { + return chat->amCreator(); + } + return false; + }(); + if (isCreator) { const auto requestId = std::make_shared(0); return [=] { if (controller->showFrozenError() || (*requestId > 0)) { return; } *requestId = peer->session().api().request( - MTPchannels_GetFutureCreatorAfterLeave( - channel->inputChannel() + MTPmessages_GetFutureChatCreatorAfterLeave( + peer->input() )).done([=](const MTPUser &result) { *requestId = 0; const auto user = peer->owner().processUser(result); - controller->show(Box(SelectFutureOwnerbox, channel, user)); + controller->show(Box(SelectFutureOwnerbox, peer, user)); }).fail([=](const MTP::Error &error) { *requestId = 0; controller->show(Box(DeleteChatBox, peer));