First version of the filters side bar.
|
@ -937,6 +937,8 @@ PRIVATE
|
||||||
window/window_connecting_widget.h
|
window/window_connecting_widget.h
|
||||||
window/window_controller.cpp
|
window/window_controller.cpp
|
||||||
window/window_controller.h
|
window/window_controller.h
|
||||||
|
window/window_filters_menu.cpp
|
||||||
|
window/window_filters_menu.h
|
||||||
window/window_history_hider.cpp
|
window/window_history_hider.cpp
|
||||||
window/window_history_hider.h
|
window/window_history_hider.h
|
||||||
window/window_lock_widgets.cpp
|
window/window_lock_widgets.cpp
|
||||||
|
|
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 2.3 KiB |
After Width: | Height: | Size: 3.4 KiB |
After Width: | Height: | Size: 877 B |
After Width: | Height: | Size: 1.7 KiB |
After Width: | Height: | Size: 2.5 KiB |
After Width: | Height: | Size: 492 B |
After Width: | Height: | Size: 938 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 382 B |
After Width: | Height: | Size: 750 B |
After Width: | Height: | Size: 1.2 KiB |
After Width: | Height: | Size: 232 B |
After Width: | Height: | Size: 493 B |
After Width: | Height: | Size: 916 B |
After Width: | Height: | Size: 683 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 470 B |
After Width: | Height: | Size: 936 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 864 B |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 2.7 KiB |
After Width: | Height: | Size: 677 B |
After Width: | Height: | Size: 1.4 KiB |
After Width: | Height: | Size: 2.1 KiB |
|
@ -82,12 +82,10 @@ int PinnedDialogsCount(not_null<Dialogs::IndexedList*> list) {
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct InnerWidget::CollapsedRow {
|
struct InnerWidget::CollapsedRow {
|
||||||
CollapsedRow(Data::Folder *folder, FilterId filterId)
|
CollapsedRow(Data::Folder *folder) : folder(folder) {
|
||||||
: folder(folder), filterId(filterId) {
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Data::Folder *folder = nullptr;
|
Data::Folder *folder = nullptr;
|
||||||
FilterId filterId = 0;
|
|
||||||
BasicRow row;
|
BasicRow row;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -121,10 +119,6 @@ InnerWidget::InnerWidget(
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||||
#endif // OS_MAC_OLD
|
#endif // OS_MAC_OLD
|
||||||
|
|
||||||
_filterId = Global::DialogsFiltersEnabled()
|
|
||||||
? Global::DialogsFilterId()
|
|
||||||
: 0;
|
|
||||||
|
|
||||||
_addContactLnk->addClickHandler([] { App::wnd()->onShowAddContact(); });
|
_addContactLnk->addClickHandler([] { App::wnd()->onShowAddContact(); });
|
||||||
_cancelSearchInChat->setClickedCallback([=] { cancelSearchInChat(); });
|
_cancelSearchInChat->setClickedCallback([=] { cancelSearchInChat(); });
|
||||||
_cancelSearchInChat->hide();
|
_cancelSearchInChat->hide();
|
||||||
|
@ -262,6 +256,11 @@ InnerWidget::InnerWidget(
|
||||||
updateDialogRow(next);
|
updateDialogRow(next);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
_controller->activeChatsFilter(
|
||||||
|
) | rpl::start_with_next([=](FilterId filterId) {
|
||||||
|
switchToFilter(filterId);
|
||||||
|
}, lifetime());
|
||||||
|
|
||||||
refreshWithCollapsedRows(true);
|
refreshWithCollapsedRows(true);
|
||||||
|
|
||||||
setupShortcuts();
|
setupShortcuts();
|
||||||
|
@ -294,21 +293,6 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) {
|
||||||
_collapsedSelected = -1;
|
_collapsedSelected = -1;
|
||||||
|
|
||||||
_collapsedRows.clear();
|
_collapsedRows.clear();
|
||||||
if (!_openedFolder && Global::DialogsFiltersEnabled()) {
|
|
||||||
const auto &list = session().data().chatsFilters().list();
|
|
||||||
if (_filterId
|
|
||||||
&& ranges::find(list, _filterId, &Data::ChatFilter::id) == end(list)) {
|
|
||||||
switchToFilter(0);
|
|
||||||
}
|
|
||||||
if (_filterId) {
|
|
||||||
_collapsedRows.push_back(std::make_unique<CollapsedRow>(nullptr, 0));
|
|
||||||
} else {
|
|
||||||
for (const auto &filter : session().data().chatsFilters().list()) {
|
|
||||||
_collapsedRows.push_back(
|
|
||||||
std::make_unique<CollapsedRow>(nullptr, filter.id()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const auto list = shownDialogs();
|
const auto list = shownDialogs();
|
||||||
const auto archive = !list->empty()
|
const auto archive = !list->empty()
|
||||||
? (*list->begin())->folder()
|
? (*list->begin())->folder()
|
||||||
|
@ -323,7 +307,8 @@ void InnerWidget::refreshWithCollapsedRows(bool toTop) {
|
||||||
}
|
}
|
||||||
_skipTopDialogs = 1;
|
_skipTopDialogs = 1;
|
||||||
if (!inMainMenu && !_filterId) {
|
if (!inMainMenu && !_filterId) {
|
||||||
_collapsedRows.push_back(std::make_unique<CollapsedRow>(archive, 0));
|
_collapsedRows.push_back(
|
||||||
|
std::make_unique<CollapsedRow>(archive));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_skipTopDialogs = 0;
|
_skipTopDialogs = 0;
|
||||||
|
@ -394,7 +379,7 @@ void InnerWidget::changeOpenedFolder(Data::Folder *folder) {
|
||||||
//const auto lastMousePosition = _lastMousePosition;
|
//const auto lastMousePosition = _lastMousePosition;
|
||||||
clearSelection();
|
clearSelection();
|
||||||
_openedFolder = folder;
|
_openedFolder = folder;
|
||||||
_filterId = _openedFolder ? 0 : Global::DialogsFilterId();
|
_filterId = _openedFolder ? 0 : _controller->activeChatsFilterCurrent();
|
||||||
refreshWithCollapsedRows(true);
|
refreshWithCollapsedRows(true);
|
||||||
// This doesn't work, because we clear selection in leaveEvent on hide.
|
// This doesn't work, because we clear selection in leaveEvent on hide.
|
||||||
//if (mouseSelection && lastMousePosition) {
|
//if (mouseSelection && lastMousePosition) {
|
||||||
|
@ -706,23 +691,14 @@ void InnerWidget::paintCollapsedRow(
|
||||||
Painter &p,
|
Painter &p,
|
||||||
not_null<const CollapsedRow*> row,
|
not_null<const CollapsedRow*> row,
|
||||||
bool selected) const {
|
bool selected) const {
|
||||||
|
Expects(row->folder != nullptr);
|
||||||
|
|
||||||
const auto smallWidth = st::dialogsPadding.x()
|
const auto smallWidth = st::dialogsPadding.x()
|
||||||
+ st::dialogsPhotoSize
|
+ st::dialogsPhotoSize
|
||||||
+ st::dialogsPhotoPadding;
|
+ st::dialogsPhotoPadding;
|
||||||
const auto narrow = (width() <= smallWidth);
|
const auto narrow = (width() <= smallWidth);
|
||||||
const auto text = row->folder
|
const auto text = row->folder->chatListName();
|
||||||
? row->folder->chatListName()
|
const auto unread = row->folder->chatListUnreadCount();
|
||||||
: _filterId
|
|
||||||
? (narrow ? "Show" : tr::lng_dialogs_show_all_chats(tr::now))
|
|
||||||
: ranges::find(
|
|
||||||
session().data().chatsFilters().list(),
|
|
||||||
row->filterId,
|
|
||||||
&Data::ChatFilter::id)->title();
|
|
||||||
const auto unread = row->folder
|
|
||||||
? row->folder->chatListUnreadCount()
|
|
||||||
: _filterId
|
|
||||||
? session().data().unreadOnlyMutedBadge()
|
|
||||||
: 0;
|
|
||||||
Layout::PaintCollapsedRow(
|
Layout::PaintCollapsedRow(
|
||||||
p,
|
p,
|
||||||
row->row,
|
row->row,
|
||||||
|
@ -1721,12 +1697,6 @@ FilterId InnerWidget::filterId() const {
|
||||||
return _filterId;
|
return _filterId;
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::closeFilter() {
|
|
||||||
if (_filterId) {
|
|
||||||
switchToFilter(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InnerWidget::clearSelection() {
|
void InnerWidget::clearSelection() {
|
||||||
_mouseSelection = false;
|
_mouseSelection = false;
|
||||||
_lastMousePosition = std::nullopt;
|
_lastMousePosition = std::nullopt;
|
||||||
|
@ -2551,11 +2521,8 @@ bool InnerWidget::chooseCollapsedRow() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto &row = _collapsedRows[_collapsedSelected];
|
const auto &row = _collapsedRows[_collapsedSelected];
|
||||||
if (row->folder) {
|
Assert(row->folder != nullptr);
|
||||||
_controller->openFolder(row->folder);
|
_controller->openFolder(row->folder);
|
||||||
} else {
|
|
||||||
switchToFilter(row->filterId);
|
|
||||||
}
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2568,9 +2535,7 @@ void InnerWidget::switchToFilter(FilterId filterId) {
|
||||||
&Data::ChatFilter::id)) {
|
&Data::ChatFilter::id)) {
|
||||||
filterId = 0;
|
filterId = 0;
|
||||||
}
|
}
|
||||||
Global::SetDialogsFilterId(filterId);
|
_filterId = filterId;
|
||||||
_filterId = Global::DialogsFilterId();
|
|
||||||
Local::writeUserSettings();
|
|
||||||
refreshWithCollapsedRows(true);
|
refreshWithCollapsedRows(true);
|
||||||
_collapsedSelected = 0;
|
_collapsedSelected = 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,6 @@ public:
|
||||||
const QVector<MTPPeer> &result);
|
const QVector<MTPPeer> &result);
|
||||||
|
|
||||||
[[nodiscard]] FilterId filterId() const;
|
[[nodiscard]] FilterId filterId() const;
|
||||||
void closeFilter();
|
|
||||||
|
|
||||||
void clearSelection();
|
void clearSelection();
|
||||||
|
|
||||||
|
|
|
@ -1575,7 +1575,7 @@ void Widget::keyPressEvent(QKeyEvent *e) {
|
||||||
if (_openedFolder) {
|
if (_openedFolder) {
|
||||||
controller()->closeFolder();
|
controller()->closeFolder();
|
||||||
} else if (_inner->filterId()) {
|
} else if (_inner->filterId()) {
|
||||||
_inner->closeFilter();
|
controller()->setActiveChatsFilter(0);
|
||||||
} else {
|
} else {
|
||||||
e->ignore();
|
e->ignore();
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,6 +118,8 @@ public:
|
||||||
not_null<PhotoData*> photo);
|
not_null<PhotoData*> photo);
|
||||||
void hideMediaPreview();
|
void hideMediaPreview();
|
||||||
|
|
||||||
|
void updateControlsGeometry() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool eventFilter(QObject *o, QEvent *e) override;
|
bool eventFilter(QObject *o, QEvent *e) override;
|
||||||
void closeEvent(QCloseEvent *e) override;
|
void closeEvent(QCloseEvent *e) override;
|
||||||
|
@ -126,8 +128,6 @@ protected:
|
||||||
void updateIsActiveHook() override;
|
void updateIsActiveHook() override;
|
||||||
void clearWidgetsHook() override;
|
void clearWidgetsHook() override;
|
||||||
|
|
||||||
void updateControlsGeometry() override;
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void showSettings();
|
void showSettings();
|
||||||
void setInnerFocus();
|
void setInnerFocus();
|
||||||
|
|
|
@ -373,6 +373,19 @@ HitTestResult MainWindow::hitTest(const QPoint &p) const {
|
||||||
return Window::HitTestResult::None;
|
return Window::HitTestResult::None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MainWindow::computeMinWidth() const {
|
||||||
|
auto result = st::windowMinWidth;
|
||||||
|
if (const auto session = _controller->sessionController()) {
|
||||||
|
if (const auto add = session->filtersWidth()) {
|
||||||
|
result += add;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (_rightColumn) {
|
||||||
|
result += _rightColumn->width();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
int MainWindow::computeMinHeight() const {
|
int MainWindow::computeMinHeight() const {
|
||||||
const auto title = _title ? _title->height() : 0;
|
const auto title = _title ? _title->height() : 0;
|
||||||
const auto outdated = [&] {
|
const auto outdated = [&] {
|
||||||
|
@ -386,7 +399,7 @@ int MainWindow::computeMinHeight() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::initSize() {
|
void MainWindow::initSize() {
|
||||||
setMinimumWidth(st::windowMinWidth);
|
setMinimumWidth(computeMinWidth());
|
||||||
setMinimumHeight(computeMinHeight());
|
setMinimumHeight(computeMinHeight());
|
||||||
|
|
||||||
auto position = cWindowPos();
|
auto position = cWindowPos();
|
||||||
|
@ -492,6 +505,7 @@ void MainWindow::leaveEventHook(QEvent *e) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateControlsGeometry() {
|
void MainWindow::updateControlsGeometry() {
|
||||||
|
auto bodyLeft = 0;
|
||||||
auto bodyTop = 0;
|
auto bodyTop = 0;
|
||||||
auto bodyWidth = width();
|
auto bodyWidth = width();
|
||||||
if (_title && !_title->isHidden()) {
|
if (_title && !_title->isHidden()) {
|
||||||
|
@ -508,7 +522,13 @@ void MainWindow::updateControlsGeometry() {
|
||||||
bodyWidth -= _rightColumn->width();
|
bodyWidth -= _rightColumn->width();
|
||||||
_rightColumn->setGeometry(bodyWidth, bodyTop, width() - bodyWidth, height() - bodyTop);
|
_rightColumn->setGeometry(bodyWidth, bodyTop, width() - bodyWidth, height() - bodyTop);
|
||||||
}
|
}
|
||||||
_body->setGeometry(0, bodyTop, bodyWidth, height() - bodyTop);
|
if (const auto session = _controller->sessionController()) {
|
||||||
|
if (const auto skip = session->filtersWidth()) {
|
||||||
|
bodyLeft += skip;
|
||||||
|
bodyWidth -= skip;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_body->setGeometry(bodyLeft, bodyTop, bodyWidth, height() - bodyTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MainWindow::updateUnreadCounter() {
|
void MainWindow::updateUnreadCounter() {
|
||||||
|
@ -621,7 +641,7 @@ void MainWindow::showRightColumn(object_ptr<TWidget> widget) {
|
||||||
const auto nowRightWidth = _rightColumn ? _rightColumn->width() : 0;
|
const auto nowRightWidth = _rightColumn ? _rightColumn->width() : 0;
|
||||||
const auto wasMaximized = isMaximized();
|
const auto wasMaximized = isMaximized();
|
||||||
const auto wasMinimumWidth = minimumWidth();
|
const auto wasMinimumWidth = minimumWidth();
|
||||||
const auto nowMinimumWidth = st::windowMinWidth + nowRightWidth;
|
const auto nowMinimumWidth = computeMinWidth();
|
||||||
const auto firstResize = (nowMinimumWidth < wasMinimumWidth);
|
const auto firstResize = (nowMinimumWidth < wasMinimumWidth);
|
||||||
if (firstResize) {
|
if (firstResize) {
|
||||||
setMinimumWidth(nowMinimumWidth);
|
setMinimumWidth(nowMinimumWidth);
|
||||||
|
|
|
@ -80,7 +80,7 @@ public:
|
||||||
|
|
||||||
virtual ~MainWindow();
|
virtual ~MainWindow();
|
||||||
|
|
||||||
TWidget *bodyWidget() {
|
Ui::RpWidget *bodyWidget() {
|
||||||
return _body.data();
|
return _body.data();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +95,11 @@ public:
|
||||||
|
|
||||||
void clearWidgets();
|
void clearWidgets();
|
||||||
|
|
||||||
|
int computeMinWidth() const;
|
||||||
|
int computeMinHeight() const;
|
||||||
|
|
||||||
|
virtual void updateControlsGeometry();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool minimizeToTray();
|
bool minimizeToTray();
|
||||||
void updateGlobalMenu() {
|
void updateGlobalMenu() {
|
||||||
|
@ -148,8 +153,6 @@ protected:
|
||||||
virtual void workmodeUpdated(DBIWorkMode mode) {
|
virtual void workmodeUpdated(DBIWorkMode mode) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void updateControlsGeometry();
|
|
||||||
|
|
||||||
virtual void createGlobalMenu() {
|
virtual void createGlobalMenu() {
|
||||||
}
|
}
|
||||||
virtual void initShadows() {
|
virtual void initShadows() {
|
||||||
|
@ -175,8 +178,6 @@ private:
|
||||||
void showTermsDecline();
|
void showTermsDecline();
|
||||||
void showTermsDelete();
|
void showTermsDelete();
|
||||||
|
|
||||||
int computeMinHeight() const;
|
|
||||||
|
|
||||||
not_null<Window::Controller*> _controller;
|
not_null<Window::Controller*> _controller;
|
||||||
|
|
||||||
base::Timer _positionUpdatedTimer;
|
base::Timer _positionUpdatedTimer;
|
||||||
|
@ -184,7 +185,7 @@ private:
|
||||||
|
|
||||||
object_ptr<TitleWidget> _title = { nullptr };
|
object_ptr<TitleWidget> _title = { nullptr };
|
||||||
object_ptr<Ui::RpWidget> _outdated;
|
object_ptr<Ui::RpWidget> _outdated;
|
||||||
object_ptr<TWidget> _body;
|
object_ptr<Ui::RpWidget> _body;
|
||||||
object_ptr<TWidget> _rightColumn = { nullptr };
|
object_ptr<TWidget> _rightColumn = { nullptr };
|
||||||
QPointer<Ui::BoxContent> _termsBox;
|
QPointer<Ui::BoxContent> _termsBox;
|
||||||
|
|
||||||
|
|
|
@ -245,6 +245,18 @@ createThemeLink: InputField(defaultInputField) {
|
||||||
font: boxTextFont;
|
font: boxTextFont;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
windowFiltersWidth: 72px;
|
||||||
|
windowFiltersIconTop: 8px;
|
||||||
|
windowFiltersAll: icon {{ "filters_all", sideBarIconFg }};
|
||||||
|
windowFiltersAllActive: icon {{ "filters_all_active", sideBarIconFgActive }};
|
||||||
|
windowFiltersUnread: icon {{ "filters_unread", sideBarIconFg }};
|
||||||
|
windowFiltersUnreadActive: icon {{ "filters_unread_active", sideBarIconFgActive }};
|
||||||
|
windowFiltersUnmuted: icon {{ "filters_unmuted", sideBarIconFg }};
|
||||||
|
windowFiltersUnmutedActive: icon {{ "filters_unmuted_active", sideBarIconFgActive }};
|
||||||
|
windowFiltersCustom: icon {{ "filters_custom", sideBarIconFg }};
|
||||||
|
windowFiltersCustomActive: icon {{ "filters_custom_active", sideBarIconFgActive }};
|
||||||
|
windowFiltersSetup: icon {{ "filters_setup", sideBarIconFg }};
|
||||||
|
|
||||||
// Mac specific
|
// Mac specific
|
||||||
|
|
||||||
macAccessoryWidth: 450.;
|
macAccessoryWidth: 450.;
|
||||||
|
|
|
@ -31,6 +31,11 @@ Controller::Controller(not_null<Main::Account*> account)
|
||||||
_sessionController = session
|
_sessionController = session
|
||||||
? std::make_unique<SessionController>(session, this)
|
? std::make_unique<SessionController>(session, this)
|
||||||
: nullptr;
|
: nullptr;
|
||||||
|
if (_sessionController && Global::DialogsFiltersEnabled()) {
|
||||||
|
_sessionController->toggleFiltersMenu(true);
|
||||||
|
} else {
|
||||||
|
sideBarChanged();
|
||||||
|
}
|
||||||
_widget.updateWindowIcon();
|
_widget.updateWindowIcon();
|
||||||
}, _lifetime);
|
}, _lifetime);
|
||||||
|
|
||||||
|
@ -86,6 +91,11 @@ void Controller::showRightColumn(object_ptr<TWidget> widget) {
|
||||||
_widget.showRightColumn(std::move(widget));
|
_widget.showRightColumn(std::move(widget));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Controller::sideBarChanged() {
|
||||||
|
_widget.setMinimumWidth(_widget.computeMinWidth());
|
||||||
|
_widget.updateControlsGeometry();
|
||||||
|
}
|
||||||
|
|
||||||
void Controller::activate() {
|
void Controller::activate() {
|
||||||
_widget.activate();
|
_widget.activate();
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void showRightColumn(object_ptr<TWidget> widget);
|
void showRightColumn(object_ptr<TWidget> widget);
|
||||||
|
void sideBarChanged();
|
||||||
|
|
||||||
void activate();
|
void activate();
|
||||||
void reActivate();
|
void reActivate();
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
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 "window/window_filters_menu.h"
|
||||||
|
|
||||||
|
#include "mainwindow.h"
|
||||||
|
#include "window/window_session_controller.h"
|
||||||
|
#include "main/main_session.h"
|
||||||
|
#include "data/data_session.h"
|
||||||
|
#include "data/data_chat_filters.h"
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
#include "styles/style_window.h"
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
|
||||||
|
FiltersMenu::FiltersMenu(not_null<SessionController*> session)
|
||||||
|
: _session(session)
|
||||||
|
, _widget(session->widget(), st::defaultSideBarMenu) {
|
||||||
|
setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
void FiltersMenu::setup() {
|
||||||
|
const auto body = _session->widget()->bodyWidget();
|
||||||
|
rpl::combine(
|
||||||
|
body->topValue(),
|
||||||
|
body->heightValue()
|
||||||
|
) | rpl::start_with_next([=](int top, int height) {
|
||||||
|
_widget.setGeometry({ 0, top, st::windowFiltersWidth, height });
|
||||||
|
}, _widget.lifetime());
|
||||||
|
|
||||||
|
const auto filters = &_session->session().data().chatsFilters();
|
||||||
|
rpl::single(
|
||||||
|
rpl::empty_value()
|
||||||
|
) | rpl::then(
|
||||||
|
filters->changed()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
refresh();
|
||||||
|
}, _widget.lifetime());
|
||||||
|
|
||||||
|
_session->activeChatsFilter(
|
||||||
|
) | rpl::start_with_next([=](FilterId id) {
|
||||||
|
_widget.setActive(QString::number(id));
|
||||||
|
}, _widget.lifetime());
|
||||||
|
|
||||||
|
_widget.activateRequests(
|
||||||
|
) | rpl::start_with_next([=](const QString &id) {
|
||||||
|
if (id == "setup") {
|
||||||
|
} else if (const auto filterId = id.toInt()) {
|
||||||
|
_session->setActiveChatsFilter(filterId);
|
||||||
|
} else {
|
||||||
|
_session->setActiveChatsFilter(0);
|
||||||
|
}
|
||||||
|
}, _widget.lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
void FiltersMenu::refresh() {
|
||||||
|
auto items = std::vector<Ui::SideBarMenu::Item>();
|
||||||
|
items.push_back({
|
||||||
|
QString::number(0),
|
||||||
|
"All Chats",
|
||||||
|
QString(),
|
||||||
|
&st::windowFiltersCustom,
|
||||||
|
&st::windowFiltersCustomActive,
|
||||||
|
st::windowFiltersIconTop
|
||||||
|
});
|
||||||
|
const auto filters = &_session->session().data().chatsFilters();
|
||||||
|
for (const auto &filter : filters->list()) {
|
||||||
|
items.push_back({
|
||||||
|
QString::number(filter.id()),
|
||||||
|
filter.title(),
|
||||||
|
QString(),
|
||||||
|
&st::windowFiltersCustom,
|
||||||
|
&st::windowFiltersCustomActive,
|
||||||
|
st::windowFiltersIconTop
|
||||||
|
});
|
||||||
|
}
|
||||||
|
items.push_back({
|
||||||
|
"setup",
|
||||||
|
"Setup",
|
||||||
|
QString(),
|
||||||
|
&st::windowFiltersSetup,
|
||||||
|
&st::windowFiltersSetup,
|
||||||
|
st::windowFiltersIconTop
|
||||||
|
});
|
||||||
|
_widget.setItems(items);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace Window
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
|
||||||
|
#include "ui/widgets/side_bar_menu.h"
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
|
||||||
|
class SessionController;
|
||||||
|
|
||||||
|
class FiltersMenu final {
|
||||||
|
public:
|
||||||
|
explicit FiltersMenu(not_null<SessionController*> session);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setup();
|
||||||
|
void refresh();
|
||||||
|
|
||||||
|
const not_null<SessionController*> _session;
|
||||||
|
Ui::SideBarMenu _widget;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Window
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/peers/edit_peer_info_box.h"
|
#include "boxes/peers/edit_peer_info_box.h"
|
||||||
#include "window/window_controller.h"
|
#include "window/window_controller.h"
|
||||||
#include "window/main_window.h"
|
#include "window/main_window.h"
|
||||||
|
#include "window/window_filters_menu.h"
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
#include "info/info_controller.h"
|
#include "info/info_controller.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
|
@ -189,6 +190,17 @@ void SessionController::initSupportMode() {
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SessionController::toggleFiltersMenu(bool enabled) {
|
||||||
|
if (!enabled == !_filters) {
|
||||||
|
return;
|
||||||
|
} else if (enabled) {
|
||||||
|
_filters = std::make_unique<FiltersMenu>(this);
|
||||||
|
} else {
|
||||||
|
_filters = nullptr;
|
||||||
|
}
|
||||||
|
_window->sideBarChanged();
|
||||||
|
}
|
||||||
|
|
||||||
bool SessionController::uniqueChatsInSearchResults() const {
|
bool SessionController::uniqueChatsInSearchResults() const {
|
||||||
return session().supportMode()
|
return session().supportMode()
|
||||||
&& !session().settings().supportAllSearchResults()
|
&& !session().settings().supportAllSearchResults()
|
||||||
|
@ -713,6 +725,22 @@ rpl::producer<FullMsgId> SessionController::floatPlayerClosed() const {
|
||||||
return _floatPlayers->closeEvents();
|
return _floatPlayers->closeEvents();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SessionController::filtersWidth() const {
|
||||||
|
return _filters ? st::windowFiltersWidth : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<FilterId> SessionController::activeChatsFilter() const {
|
||||||
|
return _activeChatsFilter.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterId SessionController::activeChatsFilterCurrent() const {
|
||||||
|
return _activeChatsFilter.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SessionController::setActiveChatsFilter(FilterId id) {
|
||||||
|
_activeChatsFilter = id;
|
||||||
|
}
|
||||||
|
|
||||||
SessionController::~SessionController() = default;
|
SessionController::~SessionController() = default;
|
||||||
|
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
|
@ -56,6 +56,7 @@ namespace Window {
|
||||||
class MainWindow;
|
class MainWindow;
|
||||||
class SectionMemento;
|
class SectionMemento;
|
||||||
class Controller;
|
class Controller;
|
||||||
|
class FiltersMenu;
|
||||||
|
|
||||||
enum class GifPauseReason {
|
enum class GifPauseReason {
|
||||||
Any = 0,
|
Any = 0,
|
||||||
|
@ -292,6 +293,13 @@ public:
|
||||||
not_null<Media::Player::FloatDelegate*> replacement);
|
not_null<Media::Player::FloatDelegate*> replacement);
|
||||||
rpl::producer<FullMsgId> floatPlayerClosed() const;
|
rpl::producer<FullMsgId> floatPlayerClosed() const;
|
||||||
|
|
||||||
|
[[nodiscard]] int filtersWidth() const;
|
||||||
|
[[nodiscard]] rpl::producer<FilterId> activeChatsFilter() const;
|
||||||
|
[[nodiscard]] FilterId activeChatsFilterCurrent() const;
|
||||||
|
void setActiveChatsFilter(FilterId id);
|
||||||
|
|
||||||
|
void toggleFiltersMenu(bool enabled);
|
||||||
|
|
||||||
rpl::lifetime &lifetime() {
|
rpl::lifetime &lifetime() {
|
||||||
return _lifetime;
|
return _lifetime;
|
||||||
}
|
}
|
||||||
|
@ -321,6 +329,7 @@ private:
|
||||||
const not_null<Controller*> _window;
|
const not_null<Controller*> _window;
|
||||||
|
|
||||||
std::unique_ptr<Passport::FormController> _passportForm;
|
std::unique_ptr<Passport::FormController> _passportForm;
|
||||||
|
std::unique_ptr<FiltersMenu> _filters;
|
||||||
|
|
||||||
GifPauseReasons _gifPauseReasons = 0;
|
GifPauseReasons _gifPauseReasons = 0;
|
||||||
base::Observable<void> _gifPauseLevelChanged;
|
base::Observable<void> _gifPauseLevelChanged;
|
||||||
|
@ -335,6 +344,8 @@ private:
|
||||||
std::deque<Dialogs::RowDescriptor> _chatEntryHistory;
|
std::deque<Dialogs::RowDescriptor> _chatEntryHistory;
|
||||||
int _chatEntryHistoryPosition = -1;
|
int _chatEntryHistoryPosition = -1;
|
||||||
|
|
||||||
|
rpl::variable<FilterId> _activeChatsFilter;
|
||||||
|
|
||||||
std::unique_ptr<Media::Player::FloatController> _floatPlayers;
|
std::unique_ptr<Media::Player::FloatController> _floatPlayers;
|
||||||
Media::Player::FloatDelegate *_defaultFloatPlayerDelegate = nullptr;
|
Media::Player::FloatDelegate *_defaultFloatPlayerDelegate = nullptr;
|
||||||
Media::Player::FloatDelegate *_replacementFloatPlayerDelegate = nullptr;
|
Media::Player::FloatDelegate *_replacementFloatPlayerDelegate = nullptr;
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit ccc12ce3da8f9ac30f30228c225585f732f74d5f
|
Subproject commit 81e9a80831555ae7908ee86fb15ea791fadd0891
|