mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow deleting revoked invite links.
This commit is contained in:
parent
144bad6c74
commit
819cd4a099
5 changed files with 281 additions and 33 deletions
|
@ -1192,6 +1192,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_group_invite_context_revoke" = "Revoke";
|
"lng_group_invite_context_revoke" = "Revoke";
|
||||||
"lng_group_invite_context_delete" = "Delete";
|
"lng_group_invite_context_delete" = "Delete";
|
||||||
"lng_group_invite_context_delete_all" = "Delete all";
|
"lng_group_invite_context_delete_all" = "Delete all";
|
||||||
|
"lng_group_invite_delete_sure" = "Are you sure you want to delete that revoked link?";
|
||||||
|
"lng_group_invite_delete_all_sure" = "Are you sure you want to delete all revoked links? This action cannot be undone.";
|
||||||
"lng_group_invite_revoked_title" = "Revoked links";
|
"lng_group_invite_revoked_title" = "Revoked links";
|
||||||
"lng_group_invite_revoke_about" = "Are you sure you want to revoke that invite link?";
|
"lng_group_invite_revoke_about" = "Are you sure you want to revoke that invite link?";
|
||||||
"lng_group_invite_link_expired" = "Expired";
|
"lng_group_invite_link_expired" = "Expired";
|
||||||
|
|
|
@ -122,25 +122,34 @@ auto InviteLinks::prepend(
|
||||||
}
|
}
|
||||||
auto &links = i->second;
|
auto &links = i->second;
|
||||||
const auto permanent = lookupPermanent(links);
|
const auto permanent = lookupPermanent(links);
|
||||||
if (link.permanent) {
|
const auto hadPermanent = (permanent != nullptr);
|
||||||
auto update = Update{ .peer = peer };
|
auto updateOldPermanent = Update{ .peer = peer };
|
||||||
if (permanent) {
|
if (link.permanent && hadPermanent) {
|
||||||
update.was = permanent->link;
|
updateOldPermanent.was = permanent->link;
|
||||||
permanent->revoked = true;
|
updateOldPermanent.now = *permanent;
|
||||||
}
|
updateOldPermanent.now->revoked = true;
|
||||||
editPermanentLink(peer, link.link);
|
links.links.erase(begin(links.links));
|
||||||
if (permanent) {
|
if (links.count > 0) {
|
||||||
update.now = *permanent;
|
--links.count;
|
||||||
_updates.fire(std::move(update));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Must not dereference 'permanent' pointer after that.
|
||||||
|
|
||||||
++links.count;
|
++links.count;
|
||||||
if (permanent && !link.permanent) {
|
if (hadPermanent && !link.permanent) {
|
||||||
links.links.insert(begin(links.links) + 1, link);
|
links.links.insert(begin(links.links) + 1, link);
|
||||||
} else {
|
} else {
|
||||||
links.links.insert(begin(links.links), link);
|
links.links.insert(begin(links.links), link);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (link.permanent) {
|
||||||
|
editPermanentLink(peer, link.link);
|
||||||
|
}
|
||||||
notify(peer);
|
notify(peer);
|
||||||
|
|
||||||
|
if (updateOldPermanent.now) {
|
||||||
|
_updates.fire(std::move(updateOldPermanent));
|
||||||
|
}
|
||||||
_updates.fire(Update{ .peer = peer, .now = link });
|
_updates.fire(Update{ .peer = peer, .now = link });
|
||||||
return link;
|
return link;
|
||||||
}
|
}
|
||||||
|
@ -162,7 +171,10 @@ void InviteLinks::performEdit(
|
||||||
TimeId expireDate,
|
TimeId expireDate,
|
||||||
int usageLimit) {
|
int usageLimit) {
|
||||||
const auto key = LinkKey{ peer, link };
|
const auto key = LinkKey{ peer, link };
|
||||||
if (const auto i = _editCallbacks.find(key); i != end(_editCallbacks)) {
|
if (_deleteCallbacks.contains(key)) {
|
||||||
|
return;
|
||||||
|
} else if (const auto i = _editCallbacks.find(key)
|
||||||
|
; i != end(_editCallbacks)) {
|
||||||
if (done) {
|
if (done) {
|
||||||
i->second.push_back(std::move(done));
|
i->second.push_back(std::move(done));
|
||||||
}
|
}
|
||||||
|
@ -184,7 +196,7 @@ void InviteLinks::performEdit(
|
||||||
}
|
}
|
||||||
|
|
||||||
using Flag = MTPmessages_EditExportedChatInvite::Flag;
|
using Flag = MTPmessages_EditExportedChatInvite::Flag;
|
||||||
const auto requestId = _api->request(MTPmessages_EditExportedChatInvite(
|
_api->request(MTPmessages_EditExportedChatInvite(
|
||||||
MTP_flags((revoke ? Flag::f_revoked : Flag(0))
|
MTP_flags((revoke ? Flag::f_revoked : Flag(0))
|
||||||
| ((!revoke && expireDate) ? Flag::f_expire_date : Flag(0))
|
| ((!revoke && expireDate) ? Flag::f_expire_date : Flag(0))
|
||||||
| ((!revoke && usageLimit) ? Flag::f_usage_limit : Flag(0))),
|
| ((!revoke && usageLimit) ? Flag::f_usage_limit : Flag(0))),
|
||||||
|
@ -205,8 +217,14 @@ void InviteLinks::performEdit(
|
||||||
key.link,
|
key.link,
|
||||||
&Link::link);
|
&Link::link);
|
||||||
if (j != end(i->second.links)) {
|
if (j != end(i->second.links)) {
|
||||||
*j = link;
|
if (link.revoked && !j->revoked) {
|
||||||
notify(peer);
|
i->second.links.erase(j);
|
||||||
|
if (i->second.count > 0) {
|
||||||
|
--i->second.count;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
*j = link;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (const auto &callback : *callbacks) {
|
for (const auto &callback : *callbacks) {
|
||||||
|
@ -215,7 +233,7 @@ void InviteLinks::performEdit(
|
||||||
_updates.fire(Update{
|
_updates.fire(Update{
|
||||||
.peer = peer,
|
.peer = peer,
|
||||||
.was = key.link,
|
.was = key.link,
|
||||||
.now = link
|
.now = link,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}).fail([=](const RPCError &error) {
|
}).fail([=](const RPCError &error) {
|
||||||
|
@ -236,6 +254,72 @@ void InviteLinks::revokePermanent(
|
||||||
performCreate(peer, std::move(done), true);
|
performCreate(peer, std::move(done), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void InviteLinks::destroy(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const QString &link,
|
||||||
|
Fn<void()> done) {
|
||||||
|
const auto key = LinkKey{ peer, link };
|
||||||
|
|
||||||
|
if (const auto i = _deleteCallbacks.find(key)
|
||||||
|
; i != end(_deleteCallbacks)) {
|
||||||
|
if (done) {
|
||||||
|
i->second.push_back(std::move(done));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto &callbacks = _deleteCallbacks[key];
|
||||||
|
if (done) {
|
||||||
|
callbacks.push_back(std::move(done));
|
||||||
|
}
|
||||||
|
|
||||||
|
_api->request(MTPmessages_DeleteExportedChatInvite(
|
||||||
|
peer->input,
|
||||||
|
MTP_string(link)
|
||||||
|
)).done([=](const MTPBool &result) {
|
||||||
|
const auto callbacks = _deleteCallbacks.take(key);
|
||||||
|
if (callbacks) {
|
||||||
|
for (const auto &callback : *callbacks) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_updates.fire(Update{
|
||||||
|
.peer = peer,
|
||||||
|
.was = key.link,
|
||||||
|
});
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
_deleteCallbacks.erase(key);
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
|
void InviteLinks::destroyAllRevoked(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Fn<void()> done) {
|
||||||
|
if (const auto i = _deleteRevokedCallbacks.find(peer)
|
||||||
|
; i != end(_deleteRevokedCallbacks)) {
|
||||||
|
if (done) {
|
||||||
|
i->second.push_back(std::move(done));
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto &callbacks = _deleteRevokedCallbacks[peer];
|
||||||
|
if (done) {
|
||||||
|
callbacks.push_back(std::move(done));
|
||||||
|
}
|
||||||
|
|
||||||
|
_api->request(MTPmessages_DeleteRevokedExportedChatInvites(
|
||||||
|
peer->input
|
||||||
|
)).done([=](const MTPBool &result) {
|
||||||
|
if (const auto callbacks = _deleteRevokedCallbacks.take(peer)) {
|
||||||
|
for (const auto &callback : *callbacks) {
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_allRevokedDestroyed.fire_copy(peer);
|
||||||
|
}).fail([=](const RPCError &error) {
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
||||||
void InviteLinks::requestLinks(not_null<PeerData*> peer) {
|
void InviteLinks::requestLinks(not_null<PeerData*> peer) {
|
||||||
if (_firstSliceRequests.contains(peer)) {
|
if (_firstSliceRequests.contains(peer)) {
|
||||||
return;
|
return;
|
||||||
|
@ -317,6 +401,15 @@ auto InviteLinks::updates(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<> InviteLinks::allRevokedDestroyed(
|
||||||
|
not_null<PeerData*> peer) const {
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
return _allRevokedDestroyed.events(
|
||||||
|
) | rpl::filter(
|
||||||
|
_1 == peer
|
||||||
|
) | rpl::to_empty;
|
||||||
|
}
|
||||||
|
|
||||||
void InviteLinks::requestJoinedFirstSlice(LinkKey key) {
|
void InviteLinks::requestJoinedFirstSlice(LinkKey key) {
|
||||||
if (_firstJoinedRequests.contains(key)) {
|
if (_firstJoinedRequests.contains(key)) {
|
||||||
return;
|
return;
|
||||||
|
@ -351,26 +444,63 @@ void InviteLinks::setPermanent(
|
||||||
i = _firstSlices.emplace(peer).first;
|
i = _firstSlices.emplace(peer).first;
|
||||||
}
|
}
|
||||||
auto &links = i->second;
|
auto &links = i->second;
|
||||||
|
auto updateOldPermanent = Update{ .peer = peer };
|
||||||
if (const auto permanent = lookupPermanent(links)) {
|
if (const auto permanent = lookupPermanent(links)) {
|
||||||
if (permanent->link == link.link) {
|
if (permanent->link == link.link) {
|
||||||
if (permanent->usage != link.usage) {
|
if (permanent->usage != link.usage) {
|
||||||
permanent->usage = link.usage;
|
permanent->usage = link.usage;
|
||||||
notify(peer);
|
_updates.fire(Update{
|
||||||
|
.peer = peer,
|
||||||
|
.was = link.link,
|
||||||
|
.now = *permanent
|
||||||
|
});
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
permanent->revoked = true;
|
updateOldPermanent.was = permanent->link;
|
||||||
|
updateOldPermanent.now = *permanent;
|
||||||
|
updateOldPermanent.now->revoked = true;
|
||||||
|
links.links.erase(begin(links.links));
|
||||||
|
if (links.count > 0) {
|
||||||
|
--links.count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
links.links.insert(begin(links.links), link);
|
links.links.insert(begin(links.links), link);
|
||||||
|
|
||||||
editPermanentLink(peer, link.link);
|
editPermanentLink(peer, link.link);
|
||||||
notify(peer);
|
notify(peer);
|
||||||
|
|
||||||
|
if (updateOldPermanent.now) {
|
||||||
|
_updates.fire(std::move(updateOldPermanent));
|
||||||
|
}
|
||||||
|
_updates.fire(Update{ .peer = peer, .now = link });
|
||||||
}
|
}
|
||||||
|
|
||||||
void InviteLinks::clearPermanent(not_null<PeerData*> peer) {
|
void InviteLinks::clearPermanent(not_null<PeerData*> peer) {
|
||||||
if (const auto permanent = lookupPermanent(peer)) {
|
auto i = _firstSlices.find(peer);
|
||||||
permanent->revoked = true;
|
if (i == end(_firstSlices)) {
|
||||||
editPermanentLink(peer, QString());
|
return;
|
||||||
notify(peer);
|
}
|
||||||
|
auto &links = i->second;
|
||||||
|
const auto permanent = lookupPermanent(links);
|
||||||
|
if (!permanent) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto updateOldPermanent = Update{ .peer = peer };
|
||||||
|
updateOldPermanent.was = permanent->link;
|
||||||
|
updateOldPermanent.now = *permanent;
|
||||||
|
updateOldPermanent.now->revoked = true;
|
||||||
|
links.links.erase(begin(links.links));
|
||||||
|
if (links.count > 0) {
|
||||||
|
--links.count;
|
||||||
|
}
|
||||||
|
|
||||||
|
editPermanentLink(peer, QString());
|
||||||
|
notify(peer);
|
||||||
|
|
||||||
|
if (updateOldPermanent.now) {
|
||||||
|
_updates.fire(std::move(updateOldPermanent));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,6 +70,13 @@ public:
|
||||||
void revokePermanent(
|
void revokePermanent(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
Fn<void(Link)> done = nullptr);
|
Fn<void(Link)> done = nullptr);
|
||||||
|
void destroy(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
const QString &link,
|
||||||
|
Fn<void()> done = nullptr);
|
||||||
|
void destroyAllRevoked(
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Fn<void()> done = nullptr);
|
||||||
|
|
||||||
void setPermanent(
|
void setPermanent(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
@ -85,6 +92,8 @@ public:
|
||||||
int fullCount);
|
int fullCount);
|
||||||
[[nodiscard]] rpl::producer<Update> updates(
|
[[nodiscard]] rpl::producer<Update> updates(
|
||||||
not_null<PeerData*> peer) const;
|
not_null<PeerData*> peer) const;
|
||||||
|
[[nodiscard]] rpl::producer<> allRevokedDestroyed(
|
||||||
|
not_null<PeerData*> peer) const;
|
||||||
|
|
||||||
void requestMoreLinks(
|
void requestMoreLinks(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
@ -159,8 +168,13 @@ private:
|
||||||
not_null<PeerData*>,
|
not_null<PeerData*>,
|
||||||
std::vector<Fn<void(Link)>>> _createCallbacks;
|
std::vector<Fn<void(Link)>>> _createCallbacks;
|
||||||
base::flat_map<LinkKey, std::vector<Fn<void(Link)>>> _editCallbacks;
|
base::flat_map<LinkKey, std::vector<Fn<void(Link)>>> _editCallbacks;
|
||||||
|
base::flat_map<LinkKey, std::vector<Fn<void()>>> _deleteCallbacks;
|
||||||
|
base::flat_map<
|
||||||
|
not_null<PeerData*>,
|
||||||
|
std::vector<Fn<void()>>> _deleteRevokedCallbacks;
|
||||||
|
|
||||||
rpl::event_stream<Update> _updates;
|
rpl::event_stream<Update> _updates;
|
||||||
|
rpl::event_stream<not_null<PeerData*>> _allRevokedDestroyed;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -311,6 +311,36 @@ void EditLink(not_null<PeerData*> peer, const InviteLinkData &data) {
|
||||||
Ui::LayerOption::KeepOther);
|
Ui::LayerOption::KeepOther);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void DeleteLink(not_null<PeerData*> peer, const QString &link) {
|
||||||
|
const auto box = std::make_shared<QPointer<ConfirmBox>>();
|
||||||
|
const auto sure = [=] {
|
||||||
|
const auto finish = [=] {
|
||||||
|
if (*box) {
|
||||||
|
(*box)->closeBox();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
peer->session().api().inviteLinks().destroy(peer, link, finish);
|
||||||
|
};
|
||||||
|
*box = Ui::show(
|
||||||
|
Box<ConfirmBox>(tr::lng_group_invite_delete_sure(tr::now), sure),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
|
}
|
||||||
|
|
||||||
|
void DeleteAllRevoked(not_null<PeerData*> peer) {
|
||||||
|
const auto box = std::make_shared<QPointer<ConfirmBox>>();
|
||||||
|
const auto sure = [=] {
|
||||||
|
const auto finish = [=] {
|
||||||
|
if (*box) {
|
||||||
|
(*box)->closeBox();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
peer->session().api().inviteLinks().destroyAllRevoked(peer, finish);
|
||||||
|
};
|
||||||
|
*box = Ui::show(
|
||||||
|
Box<ConfirmBox>(tr::lng_group_invite_delete_all_sure(tr::now), sure),
|
||||||
|
Ui::LayerOption::KeepOther);
|
||||||
|
}
|
||||||
|
|
||||||
not_null<Ui::SettingsButton*> AddCreateLinkButton(
|
not_null<Ui::SettingsButton*> AddCreateLinkButton(
|
||||||
not_null<Ui::VerticalLayout*> container) {
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
const auto result = container->add(
|
const auto result = container->add(
|
||||||
|
@ -445,6 +475,7 @@ public:
|
||||||
Controller(not_null<PeerData*> peer, bool revoked);
|
Controller(not_null<PeerData*> peer, bool revoked);
|
||||||
|
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
|
void loadMoreRows() override;
|
||||||
void rowClicked(not_null<PeerListRow*> row) override;
|
void rowClicked(not_null<PeerListRow*> row) override;
|
||||||
void rowActionClicked(not_null<PeerListRow*> row) override;
|
void rowActionClicked(not_null<PeerListRow*> row) override;
|
||||||
base::unique_qptr<Ui::PopupMenu> rowContextMenu(
|
base::unique_qptr<Ui::PopupMenu> rowContextMenu(
|
||||||
|
@ -467,6 +498,7 @@ private:
|
||||||
void updateRow(const InviteLinkData &data, TimeId now);
|
void updateRow(const InviteLinkData &data, TimeId now);
|
||||||
bool removeRow(const QString &link);
|
bool removeRow(const QString &link);
|
||||||
|
|
||||||
|
void appendSlice(const InviteLinksSlice &slice);
|
||||||
void checkExpiringTimer(not_null<Row*> row);
|
void checkExpiringTimer(not_null<Row*> row);
|
||||||
void expiringProgressTimer();
|
void expiringProgressTimer();
|
||||||
|
|
||||||
|
@ -474,10 +506,14 @@ private:
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<PeerListRow*> row);
|
not_null<PeerListRow*> row);
|
||||||
|
|
||||||
not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
bool _revoked = false;
|
const bool _revoked = false;
|
||||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||||
|
|
||||||
|
QString _offsetLink;
|
||||||
|
bool _requesting = false;
|
||||||
|
bool _allLoaded = false;
|
||||||
|
|
||||||
base::flat_set<not_null<Row*>> _expiringRows;
|
base::flat_set<not_null<Row*>> _expiringRows;
|
||||||
base::Timer _updateExpiringTimer;
|
base::Timer _updateExpiringTimer;
|
||||||
|
|
||||||
|
@ -501,8 +537,7 @@ Controller::Controller(not_null<PeerData*> peer, bool revoked)
|
||||||
peer
|
peer
|
||||||
) | rpl::start_with_next([=](const Api::InviteLinkUpdate &update) {
|
) | rpl::start_with_next([=](const Api::InviteLinkUpdate &update) {
|
||||||
const auto now = base::unixtime::now();
|
const auto now = base::unixtime::now();
|
||||||
if (!update.now
|
if (!update.now || update.now->revoked != _revoked) {
|
||||||
|| (!update.was.isEmpty() && update.now->revoked != _revoked)) {
|
|
||||||
if (removeRow(update.was)) {
|
if (removeRow(update.was)) {
|
||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
}
|
}
|
||||||
|
@ -513,15 +548,63 @@ Controller::Controller(not_null<PeerData*> peer, bool revoked)
|
||||||
updateRow(*update.now, now);
|
updateRow(*update.now, now);
|
||||||
}
|
}
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
|
if (_revoked) {
|
||||||
|
peer->session().api().inviteLinks().allRevokedDestroyed(
|
||||||
|
peer
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
_requesting = false;
|
||||||
|
_allLoaded = true;
|
||||||
|
while (delegate()->peerListFullRowsCount()) {
|
||||||
|
delegate()->peerListRemoveRow(delegate()->peerListRowAt(0));
|
||||||
|
}
|
||||||
|
delegate()->peerListRefreshRows();
|
||||||
|
}, _lifetime);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::prepare() {
|
void Controller::prepare() {
|
||||||
|
if (!_revoked) {
|
||||||
|
appendSlice(_peer->session().api().inviteLinks().links(_peer));
|
||||||
|
}
|
||||||
|
if (!delegate()->peerListFullRowsCount()) {
|
||||||
|
loadMoreRows();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::loadMoreRows() {
|
||||||
|
if (_requesting || _allLoaded) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_requesting = true;
|
||||||
|
const auto done = [=](const InviteLinksSlice &slice) {
|
||||||
|
if (!_requesting) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_requesting = false;
|
||||||
|
if (slice.links.empty()) {
|
||||||
|
_allLoaded = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
appendSlice(slice);
|
||||||
|
};
|
||||||
|
_peer->session().api().inviteLinks().requestMoreLinks(
|
||||||
|
_peer,
|
||||||
|
_offsetLink,
|
||||||
|
_revoked,
|
||||||
|
crl::guard(this, done));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::appendSlice(const InviteLinksSlice &slice) {
|
||||||
const auto now = base::unixtime::now();
|
const auto now = base::unixtime::now();
|
||||||
const auto &links = _peer->session().api().inviteLinks().links(_peer);
|
for (const auto &link : slice.links) {
|
||||||
for (const auto &link : links.links) {
|
|
||||||
if (!link.permanent || link.revoked) {
|
if (!link.permanent || link.revoked) {
|
||||||
appendRow(link, now);
|
appendRow(link, now);
|
||||||
}
|
}
|
||||||
|
_offsetLink = link.link;
|
||||||
|
}
|
||||||
|
if (slice.links.size() >= slice.count) {
|
||||||
|
_allLoaded = true;
|
||||||
}
|
}
|
||||||
delegate()->peerListRefreshRows();
|
delegate()->peerListRefreshRows();
|
||||||
}
|
}
|
||||||
|
@ -559,9 +642,9 @@ base::unique_qptr<Ui::PopupMenu> Controller::createRowContextMenu(
|
||||||
const auto link = data.link;
|
const auto link = data.link;
|
||||||
auto result = base::make_unique_q<Ui::PopupMenu>(parent);
|
auto result = base::make_unique_q<Ui::PopupMenu>(parent);
|
||||||
if (data.revoked) {
|
if (data.revoked) {
|
||||||
//result->addAction(tr::lng_group_invite_context_delete(tr::now), [=] {
|
result->addAction(tr::lng_group_invite_context_delete(tr::now), [=] {
|
||||||
// // #TODO links delete
|
DeleteLink(_peer, link);
|
||||||
//});
|
});
|
||||||
} else {
|
} else {
|
||||||
result->addAction(tr::lng_group_invite_context_copy(tr::now), [=] {
|
result->addAction(tr::lng_group_invite_context_copy(tr::now), [=] {
|
||||||
CopyLink(link);
|
CopyLink(link);
|
||||||
|
@ -576,7 +659,6 @@ base::unique_qptr<Ui::PopupMenu> Controller::createRowContextMenu(
|
||||||
const auto box = std::make_shared<QPointer<ConfirmBox>>();
|
const auto box = std::make_shared<QPointer<ConfirmBox>>();
|
||||||
const auto revoke = crl::guard(this, [=] {
|
const auto revoke = crl::guard(this, [=] {
|
||||||
const auto done = crl::guard(this, [=](InviteLinkData data) {
|
const auto done = crl::guard(this, [=](InviteLinkData data) {
|
||||||
// #TODO links add to revoked, remove from list
|
|
||||||
if (*box) {
|
if (*box) {
|
||||||
(*box)->closeBox();
|
(*box)->closeBox();
|
||||||
}
|
}
|
||||||
|
@ -946,6 +1028,23 @@ void ManageInviteLinksBox(
|
||||||
st::inviteLinkRevokedTitlePadding));
|
st::inviteLinkRevokedTitlePadding));
|
||||||
const auto revoked = AddLinksList(container, peer, true);
|
const auto revoked = AddLinksList(container, peer, true);
|
||||||
|
|
||||||
|
const auto deleteAll = Ui::CreateChild<Ui::LinkButton>(
|
||||||
|
container.get(),
|
||||||
|
tr::lng_group_invite_context_delete_all(tr::now),
|
||||||
|
st::boxLinkButton);
|
||||||
|
rpl::combine(
|
||||||
|
header->topValue(),
|
||||||
|
container->widthValue()
|
||||||
|
) | rpl::start_with_next([=](int top, int outerWidth) {
|
||||||
|
deleteAll->moveToRight(
|
||||||
|
st::inviteLinkRevokedTitlePadding.left(),
|
||||||
|
top + st::inviteLinkRevokedTitlePadding.top(),
|
||||||
|
outerWidth);
|
||||||
|
}, deleteAll->lifetime());
|
||||||
|
deleteAll->setClickedCallback([=] {
|
||||||
|
DeleteAllRevoked(peer);
|
||||||
|
});
|
||||||
|
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
list->heightValue(),
|
list->heightValue(),
|
||||||
revoked->heightValue()
|
revoked->heightValue()
|
||||||
|
@ -953,5 +1052,8 @@ void ManageInviteLinksBox(
|
||||||
dividerAbout->toggle(!list, anim::type::instant);
|
dividerAbout->toggle(!list, anim::type::instant);
|
||||||
divider->toggle(list > 0 && revoked > 0, anim::type::instant);
|
divider->toggle(list > 0 && revoked > 0, anim::type::instant);
|
||||||
header->toggle(revoked > 0, anim::type::instant);
|
header->toggle(revoked > 0, anim::type::instant);
|
||||||
|
deleteAll->setVisible(revoked > 0);
|
||||||
}, header->lifetime());
|
}, header->lifetime());
|
||||||
|
|
||||||
|
box->addButton(tr::lng_about_done(), [=] { box->closeBox(); });
|
||||||
}
|
}
|
||||||
|
|
|
@ -916,6 +916,6 @@ inviteLinkList: PeerList(defaultPeerList) {
|
||||||
inviteLinkIconSkip: 7px;
|
inviteLinkIconSkip: 7px;
|
||||||
inviteLinkIconStroke: 2px;
|
inviteLinkIconStroke: 2px;
|
||||||
inviteLinkIcon: icon {{ "info/edit/links_link", mediaviewFileExtFg }};
|
inviteLinkIcon: icon {{ "info/edit/links_link", mediaviewFileExtFg }};
|
||||||
inviteLinkThreeDotsSkip: 8px;
|
inviteLinkThreeDotsSkip: 12px;
|
||||||
inviteLinkRevokedTitlePadding: margins(22px, 16px, 10px, 9px);
|
inviteLinkRevokedTitlePadding: margins(22px, 16px, 10px, 9px);
|
||||||
inviteLinkLimitMargin: margins(22px, 8px, 22px, 8px);
|
inviteLinkLimitMargin: margins(22px, 8px, 22px, 8px);
|
||||||
|
|
Loading…
Add table
Reference in a new issue