mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Allow select/deselect all in filter link boxes.
This commit is contained in:
parent
f05f1f4359
commit
1ffbc122e1
4 changed files with 138 additions and 9 deletions
|
@ -3598,7 +3598,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_filters_by_link_add_button" = "Add {folder}";
|
||||
"lng_filters_by_link_add_no" = "Do not add this folder";
|
||||
"lng_filters_by_link_more" = "Add Chats to Folder";
|
||||
"lng_filters_by_link_more_sure" = "Do you want to join chats and add them to your folder {folder}?";
|
||||
"lng_filters_by_link_more_sure" = "Do you want to join chats and add them to the folder {folder}?";
|
||||
"lng_filters_by_link_about" = "You can deselect the chats you don't want to join.";
|
||||
"lng_filters_by_link_join_button" = "Join Chats";
|
||||
"lng_filters_by_link_join_no" = "Do not join any chats";
|
||||
|
|
|
@ -63,6 +63,7 @@ private:
|
|||
void setupAboveWidget();
|
||||
void setupBelowWidget();
|
||||
void initDesiredHeightValue();
|
||||
void toggleAllSelected(bool select);
|
||||
|
||||
const not_null<Window::SessionController*> _window;
|
||||
Ui::RpWidget *_addedTopWidget = nullptr;
|
||||
|
@ -259,8 +260,6 @@ ToggleChatsController::ToggleChatsController(
|
|||
}
|
||||
|
||||
void ToggleChatsController::prepare() {
|
||||
setupAboveWidget();
|
||||
setupBelowWidget();
|
||||
auto selected = base::flat_set<not_null<PeerData*>>();
|
||||
const auto add = [&](not_null<PeerData*> peer, bool additional = false) {
|
||||
auto row = std::make_unique<PeerListRow>(peer);
|
||||
|
@ -292,6 +291,8 @@ void ToggleChatsController::prepare() {
|
|||
for (const auto &peer : _additional) {
|
||||
add(peer, true);
|
||||
}
|
||||
setupAboveWidget();
|
||||
setupBelowWidget();
|
||||
initDesiredHeightValue();
|
||||
delegate()->peerListRefreshRows();
|
||||
_selected = std::move(selected);
|
||||
|
@ -339,7 +340,13 @@ void ToggleChatsController::setupAboveWidget() {
|
|||
: _chats.empty()
|
||||
? _additional.size()
|
||||
: _chats.size();
|
||||
AddSubsectionTitle(
|
||||
const auto selectableCount = delegate()->peerListFullRowsCount()
|
||||
- (_action == ToggleAction::Adding ? int(_additional.size()) : 0);
|
||||
auto selectedCount = _selected.value(
|
||||
) | rpl::map([](const base::flat_set<not_null<PeerData*>> &selected) {
|
||||
return int(selected.size());
|
||||
});
|
||||
AddFilterSubtitleWithToggles(
|
||||
realAbove,
|
||||
(_action == ToggleAction::Removing
|
||||
? tr::lng_filters_by_link_quit
|
||||
|
@ -348,12 +355,41 @@ void ToggleChatsController::setupAboveWidget() {
|
|||
: tr::lng_filters_by_link_join)(
|
||||
lt_count,
|
||||
rpl::single(float64(count))),
|
||||
st::filterLinkSubsectionTitlePadding);
|
||||
selectableCount,
|
||||
std::move(selectedCount),
|
||||
[=](bool select) { toggleAllSelected(select); });
|
||||
|
||||
_aboveHeight = realAbove->heightValue();
|
||||
delegate()->peerListSetAboveWidget(std::move(wrap));
|
||||
}
|
||||
|
||||
void ToggleChatsController::toggleAllSelected(bool select) {
|
||||
auto selected = _selected.current();
|
||||
if (!select) {
|
||||
if (selected.empty()) {
|
||||
return;
|
||||
}
|
||||
for (const auto &peer : selected) {
|
||||
const auto row = delegate()->peerListFindRow(peer->id.value);
|
||||
Assert(row != nullptr);
|
||||
delegate()->peerListSetRowChecked(row, false);
|
||||
}
|
||||
selected = {};
|
||||
} else {
|
||||
const auto count = delegate()->peerListFullRowsCount();
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
const auto row = delegate()->peerListRowAt(i);
|
||||
const auto peer = row->peer();
|
||||
if (_action != ToggleAction::Adding ||
|
||||
!ranges::contains(_additional, peer)) {
|
||||
delegate()->peerListSetRowChecked(row, true);
|
||||
selected.emplace(peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
_selected = std::move(selected);
|
||||
}
|
||||
|
||||
void ToggleChatsController::setupBelowWidget() {
|
||||
if (_chats.empty()) {
|
||||
auto widget = object_ptr<Ui::RpWidget>((QWidget*)nullptr);
|
||||
|
|
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/controls/invite_link_label.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/input_fields.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
|
@ -507,6 +508,7 @@ private:
|
|||
void setupBelowWidget();
|
||||
void addHeader(not_null<Ui::VerticalLayout*> container);
|
||||
void addLinkBlock(not_null<Ui::VerticalLayout*> container);
|
||||
void toggleAllSelected(bool select);
|
||||
|
||||
const not_null<Window::SessionController*> _window;
|
||||
InviteLinkData _data;
|
||||
|
@ -684,8 +686,6 @@ void LinkController::addLinkBlock(not_null<Ui::VerticalLayout*> container) {
|
|||
void LinkController::prepare() {
|
||||
Expects(!_data.url.isEmpty() || _data.chats.empty());
|
||||
|
||||
setupAboveWidget();
|
||||
setupBelowWidget();
|
||||
for (const auto &history : _data.chats) {
|
||||
const auto peer = history->peer;
|
||||
auto row = std::make_unique<ChatRow>(
|
||||
|
@ -716,6 +716,8 @@ void LinkController::prepare() {
|
|||
_denied.emplace(peer);
|
||||
}
|
||||
}
|
||||
setupAboveWidget();
|
||||
setupBelowWidget();
|
||||
delegate()->peerListRefreshRows();
|
||||
_selected = _initial;
|
||||
}
|
||||
|
@ -744,6 +746,34 @@ void LinkController::rowClicked(not_null<PeerListRow*> row) {
|
|||
}
|
||||
}
|
||||
|
||||
void LinkController::toggleAllSelected(bool select) {
|
||||
auto selected = _selected.current();
|
||||
if (!select) {
|
||||
if (selected.empty()) {
|
||||
return;
|
||||
}
|
||||
for (const auto &peer : selected) {
|
||||
const auto row = delegate()->peerListFindRow(peer->id.value);
|
||||
Assert(row != nullptr);
|
||||
delegate()->peerListSetRowChecked(row, false);
|
||||
}
|
||||
selected = {};
|
||||
} else {
|
||||
const auto count = delegate()->peerListFullRowsCount();
|
||||
for (auto i = 0; i != count; ++i) {
|
||||
const auto row = delegate()->peerListRowAt(i);
|
||||
const auto peer = row->peer();
|
||||
if (!_denied.contains(peer)) {
|
||||
delegate()->peerListSetRowChecked(row, true);
|
||||
selected.emplace(peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto has = (_initial != selected);
|
||||
_selected = std::move(selected);
|
||||
_hasChanges = has;
|
||||
}
|
||||
|
||||
void LinkController::showFinished() {
|
||||
_showFinished.fire({});
|
||||
}
|
||||
|
@ -770,10 +800,18 @@ void LinkController::setupAboveWidget() {
|
|||
lt_count,
|
||||
float64(selected.size()));
|
||||
});
|
||||
Settings::AddSubsectionTitle(
|
||||
const auto mayBeSelected = delegate()->peerListFullRowsCount()
|
||||
- int(_denied.size());
|
||||
auto selectedCount = _selected.value(
|
||||
) | rpl::map([](const base::flat_set<not_null<PeerData*>> &selected) {
|
||||
return int(selected.size());
|
||||
});
|
||||
AddFilterSubtitleWithToggles(
|
||||
container,
|
||||
std::move(subtitle),
|
||||
st::filterLinkSubsectionTitlePadding);
|
||||
mayBeSelected,
|
||||
std::move(selectedCount),
|
||||
[=](bool select) { toggleAllSelected(select); });
|
||||
|
||||
// Fix label cutting on text change from smaller to longer.
|
||||
_selected.changes() | rpl::start_with_next([=] {
|
||||
|
@ -1206,3 +1244,51 @@ void SetupFilterLinks(
|
|||
delegate->setContent(content);
|
||||
controller->setDelegate(delegate);
|
||||
}
|
||||
|
||||
void AddFilterSubtitleWithToggles(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
rpl::producer<QString> text,
|
||||
int selectableCount,
|
||||
rpl::producer<int> selectedCount,
|
||||
Fn<void(bool select)> toggle) {
|
||||
using namespace rpl::mappers;
|
||||
|
||||
const auto selectable = (selectableCount > 0);
|
||||
auto padding = st::filterLinkSubsectionTitlePadding;
|
||||
if (selectable) {
|
||||
const auto font = st::boxLinkButton.font;
|
||||
padding.setRight(padding.right() + font->spacew + std::max(
|
||||
font->width(tr::lng_filters_by_link_select(tr::now)),
|
||||
font->width(tr::lng_filters_by_link_deselect(tr::now))));
|
||||
}
|
||||
const auto title = Settings::AddSubsectionTitle(
|
||||
container,
|
||||
std::move(text),
|
||||
padding);
|
||||
if (!selectable) {
|
||||
return;
|
||||
}
|
||||
const auto link = Ui::CreateChild<Ui::LinkButton>(
|
||||
container.get(),
|
||||
tr::lng_filters_by_link_select(tr::now),
|
||||
st::boxLinkButton);
|
||||
const auto canSelect = link->lifetime().make_state<rpl::variable<bool>>(
|
||||
std::move(selectedCount) | rpl::map(_1 < selectableCount));
|
||||
canSelect->value(
|
||||
) | rpl::start_with_next([=](bool can) {
|
||||
link->setText(can
|
||||
? tr::lng_filters_by_link_select(tr::now)
|
||||
: tr::lng_filters_by_link_deselect(tr::now));
|
||||
}, link->lifetime());
|
||||
link->setClickedCallback([=] {
|
||||
toggle(canSelect->current());
|
||||
});
|
||||
|
||||
rpl::combine(
|
||||
container->widthValue(),
|
||||
title->topValue(),
|
||||
link->widthValue()
|
||||
) | rpl::start_with_next([=](int outer, int y, int width) {
|
||||
link->move(outer - st::boxRowPadding.right() - width, y);
|
||||
}, link->lifetime());
|
||||
}
|
||||
|
|
|
@ -47,3 +47,10 @@ void SetupFilterLinks(
|
|||
not_null<Window::SessionController*> window,
|
||||
rpl::producer<std::vector<Data::ChatFilterLink>> value,
|
||||
Fn<Data::ChatFilter()> currentFilter);
|
||||
|
||||
void AddFilterSubtitleWithToggles(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
rpl::producer<QString> text,
|
||||
int selectableCount,
|
||||
rpl::producer<int> selectedCount,
|
||||
Fn<void(bool select)> toggle);
|
||||
|
|
Loading…
Add table
Reference in a new issue