From d188ab671932ec9efc8712437b800302ee271126 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 5 Feb 2021 21:35:29 +0400 Subject: [PATCH] Fix other admins links management. --- Telegram/SourceFiles/api/api_invite_links.cpp | 43 ++++++----- Telegram/SourceFiles/api/api_invite_links.h | 10 ++- Telegram/SourceFiles/boxes/boxes.style | 3 + .../boxes/peers/edit_peer_info_box.cpp | 30 ++++---- .../boxes/peers/edit_peer_invite_link.cpp | 53 +++++++++----- .../boxes/peers/edit_peer_invite_link.h | 5 ++ .../boxes/peers/edit_peer_invite_links.cpp | 72 ++++++++++++++++--- .../boxes/peers/edit_peer_invite_links.h | 4 +- .../boxes/peers/edit_peer_type_box.cpp | 2 +- 9 files changed, 160 insertions(+), 62 deletions(-) diff --git a/Telegram/SourceFiles/api/api_invite_links.cpp b/Telegram/SourceFiles/api/api_invite_links.cpp index a4d007f2a..2b945fd55 100644 --- a/Telegram/SourceFiles/api/api_invite_links.cpp +++ b/Telegram/SourceFiles/api/api_invite_links.cpp @@ -115,19 +115,19 @@ void InviteLinks::performCreate( }).send(); } -auto InviteLinks::lookupPermanent(not_null peer) -> Link* { +auto InviteLinks::lookupMyPermanent(not_null peer) -> Link* { auto i = _firstSlices.find(peer); - return (i != end(_firstSlices)) ? lookupPermanent(i->second) : nullptr; + return (i != end(_firstSlices)) ? lookupMyPermanent(i->second) : nullptr; } -auto InviteLinks::lookupPermanent(Links &links) -> Link* { +auto InviteLinks::lookupMyPermanent(Links &links) -> Link* { const auto first = links.links.begin(); return (first != end(links.links) && first->permanent && !first->revoked) ? &*first : nullptr; } -auto InviteLinks::lookupPermanent(const Links &links) const -> const Link* { +auto InviteLinks::lookupMyPermanent(const Links &links) const -> const Link* { const auto first = links.links.begin(); return (first != end(links.links) && first->permanent && !first->revoked) ? &*first @@ -139,12 +139,29 @@ auto InviteLinks::prepend( not_null admin, const MTPExportedChatInvite &invite) -> Link { const auto link = parse(peer, invite); + if (admin->isSelf()) { + prependMyToFirstSlice(peer, admin, link); + } + _updates.fire(Update{ + .peer = peer, + .admin = admin, + .now = link + }); + return link; +} + +void InviteLinks::prependMyToFirstSlice( + not_null peer, + not_null admin, + const Link &link) { + Expects(admin->isSelf()); + auto i = _firstSlices.find(peer); if (i == end(_firstSlices)) { i = _firstSlices.emplace(peer).first; } auto &links = i->second; - const auto permanent = lookupPermanent(links); + const auto permanent = lookupMyPermanent(links); const auto hadPermanent = (permanent != nullptr); auto updateOldPermanent = Update{ .peer = peer, @@ -176,12 +193,6 @@ auto InviteLinks::prepend( if (updateOldPermanent.now) { _updates.fire(std::move(updateOldPermanent)); } - _updates.fire(Update{ - .peer = peer, - .admin = admin, - .now = link - }); - return link; } void InviteLinks::edit( @@ -383,14 +394,14 @@ void InviteLinks::requestMyLinks(not_null peer) { auto slice = parseSlice(peer, result); auto i = _firstSlices.find(peer); const auto permanent = (i != end(_firstSlices)) - ? lookupPermanent(i->second) + ? lookupMyPermanent(i->second) : nullptr; if (!permanent) { BringPermanentToFront(slice); const auto j = _firstSlices.emplace_or_assign( peer, std::move(slice)).first; - if (const auto permanent = lookupPermanent(j->second)) { + if (const auto permanent = lookupMyPermanent(j->second)) { editPermanentLink(peer, permanent->link); } } else { @@ -506,7 +517,7 @@ void InviteLinks::setMyPermanent( .peer = peer, .admin = peer->session().user(), }; - if (const auto permanent = lookupPermanent(links)) { + if (const auto permanent = lookupMyPermanent(links)) { if (permanent->link == link.link) { if (permanent->usage != link.usage) { permanent->usage = link.usage; @@ -548,7 +559,7 @@ void InviteLinks::clearMyPermanent(not_null peer) { return; } auto &links = i->second; - const auto permanent = lookupPermanent(links); + const auto permanent = lookupMyPermanent(links); if (!permanent) { return; } @@ -590,7 +601,7 @@ auto InviteLinks::parseSlice( const MTPmessages_ExportedChatInvites &slice) const -> Links { auto i = _firstSlices.find(peer); const auto permanent = (i != end(_firstSlices)) - ? lookupPermanent(i->second) + ? lookupMyPermanent(i->second) : nullptr; auto result = Links(); slice.match([&](const MTPDmessages_exportedChatInvites &data) { diff --git a/Telegram/SourceFiles/api/api_invite_links.h b/Telegram/SourceFiles/api/api_invite_links.h index df29731e4..38f673f8a 100644 --- a/Telegram/SourceFiles/api/api_invite_links.h +++ b/Telegram/SourceFiles/api/api_invite_links.h @@ -140,13 +140,17 @@ private: [[nodiscard]] Link parse( not_null peer, const MTPExportedChatInvite &invite) const; - [[nodiscard]] Link *lookupPermanent(not_null peer); - [[nodiscard]] Link *lookupPermanent(Links &links); - [[nodiscard]] const Link *lookupPermanent(const Links &links) const; + [[nodiscard]] Link *lookupMyPermanent(not_null peer); + [[nodiscard]] Link *lookupMyPermanent(Links &links); + [[nodiscard]] const Link *lookupMyPermanent(const Links &links) const; Link prepend( not_null peer, not_null admin, const MTPExportedChatInvite &invite); + void prependMyToFirstSlice( + not_null peer, + not_null admin, + const Link &link); void notify(not_null peer); void editPermanentLink( diff --git a/Telegram/SourceFiles/boxes/boxes.style b/Telegram/SourceFiles/boxes/boxes.style index 1c76ebaeb..46807672e 100644 --- a/Telegram/SourceFiles/boxes/boxes.style +++ b/Telegram/SourceFiles/boxes/boxes.style @@ -928,6 +928,9 @@ peerListWithInviteViaLink: PeerList(peerListBox) { 0px, membersMarginBottom); } +peerListSingleRow: PeerList(peerListBox) { + padding: margins(0px, 0px, 0px, 0px); +} scheduleHeight: 95px; scheduleDateTop: 38px; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index 44c8ab463..739477483 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -1073,24 +1073,26 @@ void Controller::fillManageSection() { st::infoIconPermissions); } if (canEditInviteLinks) { + auto count = Info::Profile::MigratedOrMeValue( + _peer + ) | rpl::map([=](not_null peer) { + peer->session().api().inviteLinks().requestMyLinks(peer); + return peer->session().changes().peerUpdates( + peer, + Data::PeerUpdate::Flag::InviteLinks + ) | rpl::map([=] { + return peer->session().api().inviteLinks().myLinks( + peer).count; + }); + }) | rpl::flatten_latest( + ) | rpl::start_spawning(_controls.buttonsLayout->lifetime()); + AddButtonWithCount( _controls.buttonsLayout, tr::lng_manage_peer_invite_links(), - Info::Profile::MigratedOrMeValue( - _peer - ) | rpl::map([=](not_null peer) { - peer->session().api().inviteLinks().requestMyLinks(peer); - return peer->session().changes().peerUpdates( - peer, - Data::PeerUpdate::Flag::InviteLinks - ) | rpl::map([=] { - return peer->session().api().inviteLinks().myLinks( - peer).count; - }); - }) | rpl::flatten_latest( - ) | ToPositiveNumberString(), + rpl::duplicate(count) | ToPositiveNumberString(), [=] { Ui::show( - Box(ManageInviteLinksBox, _peer, _peer->session().user()), + Box(ManageInviteLinksBox, _peer, _peer->session().user(), 0, 0), Ui::LayerOption::KeepOther); }, st::infoIconInviteLinks); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp index 035eaaf7b..69dca4252 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp @@ -37,6 +37,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "window/window_session_controller.h" #include "settings/settings_common.h" #include "mtproto/sender.h" +#include "styles/style_boxes.h" #include "styles/style_info.h" #include @@ -75,7 +76,9 @@ private: class SingleRowController final : public PeerListController { public: - SingleRowController(not_null peer, TimeId date); + SingleRowController( + not_null peer, + rpl::producer status); void prepare() override; void loadMoreRows() override; @@ -84,7 +87,8 @@ public: private: const not_null _peer; - TimeId _date = 0; + rpl::producer _status; + rpl::lifetime _lifetime; }; @@ -164,23 +168,15 @@ void AddHeader( } else { AddDivider(container); } + AddSkip(container); } - AddSkip(container); AddSubsectionTitle( container, tr::lng_group_invite_created_by()); - - const auto delegate = container->lifetime().make_state< - PeerListContentDelegateSimple - >(); - const auto controller = container->lifetime().make_state< - SingleRowController - >(data.admin, data.date); - const auto content = container->add(object_ptr( + AddSinglePeerRow( container, - controller)); - delegate->setContent(content); - controller->setDelegate(delegate); + data.admin, + rpl::single(langDateTime(base::unixtime::parse(data.date)))); } Controller::Controller(not_null peer, const LinkData &data) @@ -258,14 +254,19 @@ Main::Session &Controller::session() const { SingleRowController::SingleRowController( not_null peer, - TimeId date) + rpl::producer status) : _peer(peer) -, _date(date) { +, _status(std::move(status)) { } void SingleRowController::prepare() { auto row = std::make_unique(_peer); - row->setCustomStatus(langDateTime(base::unixtime::parse(_date))); + const auto raw = row.get(); + std::move( + _status + ) | rpl::start_with_next([=](const QString &status) { + raw->setCustomStatus(status); + }, _lifetime); delegate()->peerListAppendRow(std::move(row)); delegate()->peerListRefreshRows(); } @@ -283,6 +284,24 @@ Main::Session &SingleRowController::session() const { } // namespace +void AddSinglePeerRow( + not_null container, + not_null peer, + rpl::producer status) { + const auto delegate = container->lifetime().make_state< + PeerListContentDelegateSimple + >(); + const auto controller = container->lifetime().make_state< + SingleRowController + >(peer, std::move(status)); + controller->setStyleOverrides(&st::peerListSingleRow); + const auto content = container->add(object_ptr( + container, + controller)); + delegate->setContent(content); + controller->setDelegate(delegate); +} + void AddPermanentLinkBlock( not_null container, not_null peer, diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.h b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.h index 3cab90224..50e4da743 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.h @@ -19,6 +19,11 @@ namespace Ui { class VerticalLayout; } // namespace Ui +void AddSinglePeerRow( + not_null container, + not_null peer, + rpl::producer status); + void AddPermanentLinkBlock( not_null container, not_null peer, diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.cpp index b5872a8fb..8cff8a49e 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.cpp @@ -341,7 +341,16 @@ crl::time Row::updateExpireIn() const { QString Row::generateName() { auto result = _data.link; - return result.replace(qstr("https://"), QString()); + return result.replace( + qstr("https://"), + QString() + ).replace( + qstr("t.me/+"), + QString() + ).replace( + qstr("t.me/joinchat/"), + QString() + ); } QString Row::generateShortName() { @@ -393,8 +402,13 @@ public: LinksController( not_null peer, not_null admin, + int count, bool revoked); + [[nodiscard]] rpl::producer fullCountValue() const { + return _count.value(); + } + void prepare() override; void loadMoreRows() override; void rowClicked(not_null row) override; @@ -434,6 +448,7 @@ private: const not_null _peer; const not_null _admin; const bool _revoked = false; + rpl::variable _count; base::unique_qptr _menu; QString _offsetLink; @@ -453,10 +468,12 @@ private: LinksController::LinksController( not_null peer, not_null admin, + int count, bool revoked) : _peer(peer) , _admin(admin) , _revoked(revoked) +, _count(count) , _updateExpiringTimer([=] { expiringProgressTimer(); }) { style::PaletteChanged( ) | rpl::start_with_next([=] { @@ -475,7 +492,9 @@ LinksController::LinksController( delegate()->peerListRefreshRows(); } } else if (update.was.isEmpty()) { - if (!update.now->permanent || update.now->revoked) { + if (update.now->permanent && !update.now->revoked) { + _permanentFound.fire_copy(*update.now); + } else { prependRow(*update.now, now); delegate()->peerListRefreshRows(); } @@ -547,6 +566,9 @@ void LinksController::appendSlice(const InviteLinksSlice &slice) { if (slice.links.size() >= slice.count) { _allLoaded = true; } + const auto rowsCount = delegate()->peerListFullRowsCount(); + const auto minimalCount = _revoked ? rowsCount : (rowsCount + 1); + _count = _allLoaded ? minimalCount : std::max(slice.count, minimalCount); delegate()->peerListRefreshRows(); } @@ -797,7 +819,7 @@ void AdminsController::loadMoreRows() { void AdminsController::rowClicked(not_null row) { Ui::show( - Box(ManageInviteLinksBox, _peer, row->peer()->asUser()), + Box(ManageInviteLinksBox, _peer, row->peer()->asUser(), 0, 0), Ui::LayerOption::KeepOther); } @@ -816,13 +838,14 @@ void AdminsController::appendRow(not_null user, int count) { struct LinksList { not_null widget; - rpl::producer permanentFound; + not_null controller; }; LinksList AddLinksList( not_null container, not_null peer, not_null admin, + int count, bool revoked) { auto &lifetime = container->lifetime(); const auto delegate = lifetime.make_state< @@ -831,6 +854,7 @@ LinksList AddLinksList( const auto controller = lifetime.make_state( peer, admin, + count, revoked); controller->setStyleOverrides(&st::inviteLinkList); const auto content = container->add(object_ptr( @@ -839,7 +863,7 @@ LinksList AddLinksList( delegate->setContent(content); controller->setDelegate(delegate); - return { content, controller->permanentFound() }; + return { content, controller }; } not_null AddAdminsList( @@ -866,7 +890,9 @@ not_null AddAdminsList( void ManageInviteLinksBox( not_null box, not_null peer, - not_null admin) { + not_null admin, + int count, + int revokedCount) { using namespace Settings; box->setTitle(tr::lng_group_invite_title()); @@ -875,6 +901,22 @@ void ManageInviteLinksBox( const auto permanentFromList = box->lifetime().make_state< rpl::event_stream >(); + const auto countValue = box->lifetime().make_state>( + count); + + if (!admin->isSelf()) { + auto status = countValue->value() | rpl::map([](int count) { + // #TODO links + return (count == 1) + ? "1 link" + : QString::number(count) + " links"; + }); + AddSinglePeerRow( + container, + admin, + std::move(status)); + } + AddSubsectionTitle(container, tr::lng_create_permanent_link_title()); AddPermanentLinkBlock( container, @@ -899,10 +941,15 @@ void ManageInviteLinksBox( st::inviteLinkRevokedTitlePadding)); } - auto [list, newPermanent] = AddLinksList(container, peer, admin, false); + auto [list, controller] = AddLinksList( + container, + peer, + admin, + count, + false); + *countValue = controller->fullCountValue(); - std::move( - newPermanent + controller->permanentFound( ) | rpl::start_with_next([=](InviteLinkData &&data) { permanentFromList->fire(std::move(data)); }, container->lifetime()); @@ -940,7 +987,12 @@ void ManageInviteLinksBox( tr::lng_group_invite_revoked_title(), st::settingsSubsectionTitle), st::inviteLinkRevokedTitlePadding)); - const auto revoked = AddLinksList(container, peer, admin, true).widget; + const auto revoked = AddLinksList( + container, + peer, + admin, + revokedCount, + true).widget; const auto deleteAll = Ui::CreateChild( container.get(), diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.h b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.h index 2f1050317..c16db91b4 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_links.h @@ -14,4 +14,6 @@ class PeerData; void ManageInviteLinksBox( not_null box, not_null peer, - not_null admin); + not_null admin, + int count, + int revokedCount); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp index 52e11b80c..876882bcd 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp @@ -193,7 +193,7 @@ void Controller::createContent() { tr::lng_group_invite_manage(), rpl::single(QString()), [=] { Ui::show( - Box(ManageInviteLinksBox, _peer, _peer->session().user()), + Box(ManageInviteLinksBox, _peer, _peer->session().user(), 0, 0), Ui::LayerOption::KeepOther); }, st::manageGroupButton,