Added quick actions for folders to menu from chats list.
This commit is contained in:
parent
eabe7a3411
commit
d224b3d301
|
@ -216,6 +216,8 @@ PRIVATE
|
||||||
boxes/background_preview_box.h
|
boxes/background_preview_box.h
|
||||||
boxes/change_phone_box.cpp
|
boxes/change_phone_box.cpp
|
||||||
boxes/change_phone_box.h
|
boxes/change_phone_box.h
|
||||||
|
boxes/choose_filter_box.cpp
|
||||||
|
boxes/choose_filter_box.h
|
||||||
boxes/connection_box.cpp
|
boxes/connection_box.cpp
|
||||||
boxes/connection_box.h
|
boxes/connection_box.h
|
||||||
boxes/create_poll_box.cpp
|
boxes/create_poll_box.cpp
|
||||||
|
|
|
@ -3082,6 +3082,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_filters_context_remove" = "Remove";
|
"lng_filters_context_remove" = "Remove";
|
||||||
"lng_filters_remove_sure" = "This will remove the folder, your chats will not be deleted.";
|
"lng_filters_remove_sure" = "This will remove the folder, your chats will not be deleted.";
|
||||||
"lng_filters_remove_yes" = "Remove";
|
"lng_filters_remove_yes" = "Remove";
|
||||||
|
"lng_filters_menu_add" = "Add to folder";
|
||||||
|
"lng_filters_menu_remove" = "Remove from folder";
|
||||||
|
"lng_filters_add_box_title" = "Add to...";
|
||||||
|
|
||||||
"lng_chat_theme_change" = "Change colors";
|
"lng_chat_theme_change" = "Change colors";
|
||||||
"lng_chat_theme_none" = "No\nTheme";
|
"lng_chat_theme_none" = "No\nTheme";
|
||||||
|
|
|
@ -0,0 +1,184 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#include "boxes/choose_filter_box.h"
|
||||||
|
|
||||||
|
#include "apiwrap.h"
|
||||||
|
#include "data/data_chat_filters.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "history/history.h"
|
||||||
|
#include "lang/lang_keys.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "ui/filter_icons.h"
|
||||||
|
#include "ui/layers/generic_box.h"
|
||||||
|
#include "ui/widgets/buttons.h"
|
||||||
|
#include "styles/style_settings.h"
|
||||||
|
#include "styles/style_payments.h" // paymentsSectionButton
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
class FolderButton : public Ui::SettingsButton {
|
||||||
|
public:
|
||||||
|
FolderButton(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
const Data::ChatFilter &filter);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Ui::FilterIcon _icon;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
FolderButton::FolderButton(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
const Data::ChatFilter &filter)
|
||||||
|
: SettingsButton(
|
||||||
|
parent,
|
||||||
|
rpl::single(filter.title()),
|
||||||
|
st::paymentsSectionButton)
|
||||||
|
, _icon(Ui::ComputeFilterIcon(filter)) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void FolderButton::paintEvent(QPaintEvent *e) {
|
||||||
|
SettingsButton::paintEvent(e);
|
||||||
|
|
||||||
|
Painter p(this);
|
||||||
|
const auto over = isOver() || isDown();
|
||||||
|
const auto icon = Ui::LookupFilterIcon(_icon).normal;
|
||||||
|
icon->paint(
|
||||||
|
p,
|
||||||
|
st::settingsFilterIconLeft,
|
||||||
|
(height() - icon->height()) / 2,
|
||||||
|
width(),
|
||||||
|
(over
|
||||||
|
? st::dialogsUnreadBgMutedOver
|
||||||
|
: st::dialogsUnreadBgMuted)->c);
|
||||||
|
}
|
||||||
|
|
||||||
|
Data::ChatFilter ChangedFilter(
|
||||||
|
const Data::ChatFilter &filter,
|
||||||
|
not_null<History*> history,
|
||||||
|
bool add) {
|
||||||
|
auto always = base::duplicate(filter.always());
|
||||||
|
if (add) {
|
||||||
|
always.insert(history);
|
||||||
|
} else {
|
||||||
|
always.remove(history);
|
||||||
|
}
|
||||||
|
auto never = base::duplicate(filter.never());
|
||||||
|
if (add) {
|
||||||
|
never.remove(history);
|
||||||
|
} else {
|
||||||
|
never.insert(history);
|
||||||
|
}
|
||||||
|
return Data::ChatFilter(
|
||||||
|
filter.id(),
|
||||||
|
filter.title(),
|
||||||
|
filter.iconEmoji(),
|
||||||
|
filter.flags(),
|
||||||
|
std::move(always),
|
||||||
|
filter.pinned(),
|
||||||
|
std::move(never));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChangeFilterById(
|
||||||
|
FilterId filterId,
|
||||||
|
not_null<History*> history,
|
||||||
|
bool add) {
|
||||||
|
const auto list = history->owner().chatsFilters().list();
|
||||||
|
const auto i = ranges::find(list, filterId, &Data::ChatFilter::id);
|
||||||
|
if (i != end(list)) {
|
||||||
|
const auto was = *i;
|
||||||
|
const auto filter = ChangedFilter(was, history, add);
|
||||||
|
history->owner().chatsFilters().set(filter);
|
||||||
|
history->session().api().request(MTPmessages_UpdateDialogFilter(
|
||||||
|
MTP_flags(MTPmessages_UpdateDialogFilter::Flag::f_filter),
|
||||||
|
MTP_int(filter.id()),
|
||||||
|
filter.tl()
|
||||||
|
)).fail([=](const MTP::Error &error) {
|
||||||
|
// Revert filter on fail.
|
||||||
|
history->owner().chatsFilters().set(was);
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
ChooseFilterValidator::ChooseFilterValidator(not_null<History*> history)
|
||||||
|
: _history(history) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChooseFilterValidator::canAdd() const {
|
||||||
|
for (const auto &filter : _history->owner().chatsFilters().list()) {
|
||||||
|
if (!filter.contains(_history)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ChooseFilterValidator::canRemove(FilterId filterId) const {
|
||||||
|
const auto list = _history->owner().chatsFilters().list();
|
||||||
|
const auto i = ranges::find(list, filterId, &Data::ChatFilter::id);
|
||||||
|
if (i != end(list)) {
|
||||||
|
const auto &filter = *i;
|
||||||
|
return filter.contains(_history)
|
||||||
|
&& ((filter.always().size() > 1) || filter.flags());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChooseFilterValidator::add(FilterId filterId) const {
|
||||||
|
ChangeFilterById(filterId, _history, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChooseFilterValidator::remove(FilterId filterId) const {
|
||||||
|
ChangeFilterById(filterId, _history, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ChooseFilterBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<History*> history) {
|
||||||
|
box->setTitle(tr::lng_filters_add_box_title());
|
||||||
|
|
||||||
|
const auto validator = ChooseFilterValidator(history);
|
||||||
|
|
||||||
|
const auto container = box->verticalLayout()->add(
|
||||||
|
object_ptr<Ui::VerticalLayout>(box->verticalLayout()));
|
||||||
|
|
||||||
|
const auto rebuild = [=] {
|
||||||
|
while (container->count()) {
|
||||||
|
delete container->widgetAt(0);
|
||||||
|
}
|
||||||
|
for (const auto &filter : history->owner().chatsFilters().list()) {
|
||||||
|
if (filter.contains(history)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
container->add(
|
||||||
|
object_ptr<FolderButton>(box, filter),
|
||||||
|
style::margins()
|
||||||
|
)->setClickedCallback([=, id = filter.id()] {
|
||||||
|
validator.add(id);
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
container->resizeToWidth(box->verticalLayout()->width());
|
||||||
|
if (!container->count()) {
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
history->owner().chatsFilters().changed(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
rebuild();
|
||||||
|
}, box->lifetime());
|
||||||
|
rebuild();
|
||||||
|
|
||||||
|
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
This file is part of Telegram Desktop,
|
||||||
|
the official desktop application for the Telegram messaging service.
|
||||||
|
|
||||||
|
For license and copyright information please follow this link:
|
||||||
|
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
*/
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class GenericBox;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
class History;
|
||||||
|
|
||||||
|
class ChooseFilterValidator final {
|
||||||
|
public:
|
||||||
|
ChooseFilterValidator(not_null<History*> history);
|
||||||
|
|
||||||
|
[[nodiscard]] bool canAdd() const;
|
||||||
|
[[nodiscard]] bool canRemove(FilterId filterId) const;
|
||||||
|
|
||||||
|
void add(FilterId filterId) const;
|
||||||
|
void remove(FilterId filterId) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const not_null<History*> _history;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
void ChooseFilterBox(
|
||||||
|
not_null<Ui::GenericBox*> box,
|
||||||
|
not_null<History*> history);
|
|
@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/max_invite_box.h"
|
#include "boxes/max_invite_box.h"
|
||||||
#include "boxes/mute_settings_box.h"
|
#include "boxes/mute_settings_box.h"
|
||||||
#include "boxes/add_contact_box.h"
|
#include "boxes/add_contact_box.h"
|
||||||
|
#include "boxes/choose_filter_box.h"
|
||||||
#include "boxes/create_poll_box.h"
|
#include "boxes/create_poll_box.h"
|
||||||
#include "boxes/pin_messages_box.h"
|
#include "boxes/pin_messages_box.h"
|
||||||
#include "boxes/peers/add_bot_to_chat_box.h"
|
#include "boxes/peers/add_bot_to_chat_box.h"
|
||||||
|
@ -180,7 +181,7 @@ private:
|
||||||
void addToggleMuteSubmenu(bool addSeparator);
|
void addToggleMuteSubmenu(bool addSeparator);
|
||||||
void addSupportInfo();
|
void addSupportInfo();
|
||||||
void addInfo();
|
void addInfo();
|
||||||
//void addToFolder();
|
void addToggleFolder();
|
||||||
void addToggleUnreadMark();
|
void addToggleUnreadMark();
|
||||||
void addToggleArchive();
|
void addToggleArchive();
|
||||||
void addClearHistory();
|
void addClearHistory();
|
||||||
|
@ -425,8 +426,30 @@ void Filler::addInfo() {
|
||||||
}, peer->isUser() ? &st::menuIconProfile : &st::menuIconInfo);
|
}, peer->isUser() ? &st::menuIconProfile : &st::menuIconInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
//void Filler::addToFolder() {
|
void Filler::addToggleFolder() {
|
||||||
//}
|
const auto history = _request.key.history();
|
||||||
|
if (!history) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (!_request.filterId) {
|
||||||
|
if (!ChooseFilterValidator(history).canAdd()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto window = _controller;
|
||||||
|
_addAction(tr::lng_filters_menu_add(tr::now), [=] {
|
||||||
|
window->show(Box(ChooseFilterBox, history));
|
||||||
|
}, nullptr);
|
||||||
|
} else {
|
||||||
|
const auto id = _request.filterId;
|
||||||
|
const auto validator = ChooseFilterValidator(history);
|
||||||
|
if (!validator.canRemove(id)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_addAction(tr::lng_filters_menu_remove(tr::now), [=] {
|
||||||
|
validator.remove(id);
|
||||||
|
}, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Filler::addToggleUnreadMark() {
|
void Filler::addToggleUnreadMark() {
|
||||||
const auto peer = _peer;
|
const auto peer = _peer;
|
||||||
|
@ -817,7 +840,7 @@ void Filler::fillChatsListActions() {
|
||||||
}
|
}
|
||||||
addToggleMuteSubmenu(false);
|
addToggleMuteSubmenu(false);
|
||||||
addToggleUnreadMark();
|
addToggleUnreadMark();
|
||||||
// addToFolder();
|
addToggleFolder();
|
||||||
if (const auto user = _peer->asUser()) {
|
if (const auto user = _peer->asUser()) {
|
||||||
if (!user->isContact()) {
|
if (!user->isContact()) {
|
||||||
addBlockUser();
|
addBlockUser();
|
||||||
|
|
Loading…
Reference in New Issue