mirror of https://github.com/procxx/kepka.git
				
				
				
			Remove old shared media overview section.
Also move window/top_bar_widget to history/history_top_bar_widget.
This commit is contained in:
		
							parent
							
								
									534b578598
								
							
						
					
					
						commit
						3deea14559
					
				| 
						 | 
					@ -854,8 +854,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
"lng_attach_file" = "File";
 | 
					"lng_attach_file" = "File";
 | 
				
			||||||
"lng_attach_photo" = "Photo";
 | 
					"lng_attach_photo" = "Photo";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
"lng_media_type" = "Media type";
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
"lng_media_open_with" = "Open With";
 | 
					"lng_media_open_with" = "Open With";
 | 
				
			||||||
"lng_media_download" = "Download";
 | 
					"lng_media_download" = "Download";
 | 
				
			||||||
"lng_media_cancel" = "Cancel";
 | 
					"lng_media_cancel" = "Cancel";
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -27,6 +27,10 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "storage/storage_shared_media.h"
 | 
					#include "storage/storage_shared_media.h"
 | 
				
			||||||
#include "history/history_media_types.h"
 | 
					#include "history/history_media_types.h"
 | 
				
			||||||
#include "data/data_sparse_ids.h"
 | 
					#include "data/data_sparse_ids.h"
 | 
				
			||||||
 | 
					#include "info/info_memento.h"
 | 
				
			||||||
 | 
					#include "info/info_controller.h"
 | 
				
			||||||
 | 
					#include "window/window_controller.h"
 | 
				
			||||||
 | 
					#include "mainwindow.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace {
 | 
					namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,7 +63,9 @@ void SharedMediaShowOverview(
 | 
				
			||||||
		Storage::SharedMediaType type,
 | 
							Storage::SharedMediaType type,
 | 
				
			||||||
		not_null<History*> history) {
 | 
							not_null<History*> history) {
 | 
				
			||||||
	if (SharedMediaOverviewType(type)) {
 | 
						if (SharedMediaOverviewType(type)) {
 | 
				
			||||||
		Ui::showPeerOverview(history, SharedMediaTypeToOverview(type));
 | 
							App::wnd()->controller()->showSection(Info::Memento(
 | 
				
			||||||
 | 
								history->peer->id,
 | 
				
			||||||
 | 
								Info::Section(type)));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -272,12 +272,6 @@ void showPeerProfile(const PeerId &peer) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void showPeerOverview(const PeerId &peer, MediaOverviewType type) {
 | 
					 | 
				
			||||||
	if (auto m = App::main()) {
 | 
					 | 
				
			||||||
		m->showMediaOverview(App::peer(peer), type);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void showPeerHistory(
 | 
					void showPeerHistory(
 | 
				
			||||||
		const PeerId &peer,
 | 
							const PeerId &peer,
 | 
				
			||||||
		MsgId msgId) {
 | 
							MsgId msgId) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -192,14 +192,6 @@ inline void showPeerProfile(const History *history) {
 | 
				
			||||||
	showPeerProfile(history->peer->id);
 | 
						showPeerProfile(history->peer->id);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void showPeerOverview(const PeerId &peer, MediaOverviewType type);
 | 
					 | 
				
			||||||
inline void showPeerOverview(const PeerData *peer, MediaOverviewType type) {
 | 
					 | 
				
			||||||
	showPeerOverview(peer->id, type);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
inline void showPeerOverview(const History *history, MediaOverviewType type) {
 | 
					 | 
				
			||||||
	showPeerOverview(history->peer->id, type);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void showPeerHistory(const PeerId &peer, MsgId msgId);
 | 
					void showPeerHistory(const PeerId &peer, MsgId msgId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
inline void showPeerHistory(const PeerData *peer, MsgId msgId) {
 | 
					inline void showPeerHistory(const PeerData *peer, MsgId msgId) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,7 +31,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "mainwidget.h"
 | 
					#include "mainwidget.h"
 | 
				
			||||||
#include "mainwindow.h"
 | 
					#include "mainwindow.h"
 | 
				
			||||||
#include "storage/localstorage.h"
 | 
					#include "storage/localstorage.h"
 | 
				
			||||||
#include "window/top_bar_widget.h"
 | 
					 | 
				
			||||||
#include "observer_peer.h"
 | 
					#include "observer_peer.h"
 | 
				
			||||||
#include "auth_session.h"
 | 
					#include "auth_session.h"
 | 
				
			||||||
#include "window/notifications_manager.h"
 | 
					#include "window/notifications_manager.h"
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1953,8 +1953,8 @@ bool HistoryInner::canDeleteSelected() const {
 | 
				
			||||||
	return (selectedState.count > 0) && (selectedState.count == selectedState.canDeleteCount);
 | 
						return (selectedState.count > 0) && (selectedState.count == selectedState.canDeleteCount);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Window::TopBarWidget::SelectedState HistoryInner::getSelectionState() const {
 | 
					HistoryTopBarWidget::SelectedState HistoryInner::getSelectionState() const {
 | 
				
			||||||
	auto result = Window::TopBarWidget::SelectedState {};
 | 
						auto result = HistoryTopBarWidget::SelectedState {};
 | 
				
			||||||
	for (auto &selected : _selected) {
 | 
						for (auto &selected : _selected) {
 | 
				
			||||||
		if (selected.second == FullSelection) {
 | 
							if (selected.second == FullSelection) {
 | 
				
			||||||
			++result.count;
 | 
								++result.count;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "ui/rp_widget.h"
 | 
					#include "ui/rp_widget.h"
 | 
				
			||||||
#include "ui/widgets/tooltip.h"
 | 
					#include "ui/widgets/tooltip.h"
 | 
				
			||||||
#include "ui/widgets/scroll_area.h"
 | 
					#include "ui/widgets/scroll_area.h"
 | 
				
			||||||
#include "window/top_bar_widget.h"
 | 
					#include "history/history_top_bar_widget.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Window {
 | 
					namespace Window {
 | 
				
			||||||
class Controller;
 | 
					class Controller;
 | 
				
			||||||
| 
						 | 
					@ -63,7 +63,7 @@ public:
 | 
				
			||||||
	bool canCopySelected() const;
 | 
						bool canCopySelected() const;
 | 
				
			||||||
	bool canDeleteSelected() const;
 | 
						bool canDeleteSelected() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Window::TopBarWidget::SelectedState getSelectionState() const;
 | 
						HistoryTopBarWidget::SelectedState getSelectionState() const;
 | 
				
			||||||
	void clearSelectedItems(bool onlyTextSelection = false);
 | 
						void clearSelectedItems(bool onlyTextSelection = false);
 | 
				
			||||||
	SelectedItemSet getSelectedItems() const;
 | 
						SelectedItemSet getSelectedItems() const;
 | 
				
			||||||
	void selectItem(HistoryItem *item);
 | 
						void selectItem(HistoryItem *item);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,11 +18,13 @@ to link the code of portions of this program with the OpenSSL library.
 | 
				
			||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
 | 
					Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
 | 
				
			||||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
					Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "window/top_bar_widget.h"
 | 
					#include "history/history_top_bar_widget.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <rpl/combine.h>
 | 
					#include <rpl/combine.h>
 | 
				
			||||||
#include <rpl/combine_previous.h>
 | 
					#include <rpl/combine_previous.h>
 | 
				
			||||||
#include "styles/style_window.h"
 | 
					#include "styles/style_window.h"
 | 
				
			||||||
 | 
					#include "styles/style_dialogs.h"
 | 
				
			||||||
 | 
					#include "styles/style_history.h"
 | 
				
			||||||
#include "boxes/add_contact_box.h"
 | 
					#include "boxes/add_contact_box.h"
 | 
				
			||||||
#include "boxes/confirm_box.h"
 | 
					#include "boxes/confirm_box.h"
 | 
				
			||||||
#include "info/info_memento.h"
 | 
					#include "info/info_memento.h"
 | 
				
			||||||
| 
						 | 
					@ -39,10 +41,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "window/window_peer_menu.h"
 | 
					#include "window/window_peer_menu.h"
 | 
				
			||||||
#include "calls/calls_instance.h"
 | 
					#include "calls/calls_instance.h"
 | 
				
			||||||
#include "observer_peer.h"
 | 
					#include "observer_peer.h"
 | 
				
			||||||
 | 
					#include "apiwrap.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Window {
 | 
					HistoryTopBarWidget::HistoryTopBarWidget(
 | 
				
			||||||
 | 
					 | 
				
			||||||
TopBarWidget::TopBarWidget(
 | 
					 | 
				
			||||||
	QWidget *parent,
 | 
						QWidget *parent,
 | 
				
			||||||
	not_null<Window::Controller*> controller)
 | 
						not_null<Window::Controller*> controller)
 | 
				
			||||||
: RpWidget(parent)
 | 
					: RpWidget(parent)
 | 
				
			||||||
| 
						 | 
					@ -51,11 +52,11 @@ TopBarWidget::TopBarWidget(
 | 
				
			||||||
, _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton)
 | 
					, _forward(this, langFactory(lng_selected_forward), st::defaultActiveButton)
 | 
				
			||||||
, _delete(this, langFactory(lng_selected_delete), st::defaultActiveButton)
 | 
					, _delete(this, langFactory(lng_selected_delete), st::defaultActiveButton)
 | 
				
			||||||
, _info(this, nullptr, st::topBarInfoButton)
 | 
					, _info(this, nullptr, st::topBarInfoButton)
 | 
				
			||||||
, _mediaType(this, langFactory(lng_media_type), st::topBarButton)
 | 
					 | 
				
			||||||
, _call(this, st::topBarCall)
 | 
					, _call(this, st::topBarCall)
 | 
				
			||||||
, _search(this, st::topBarSearch)
 | 
					, _search(this, st::topBarSearch)
 | 
				
			||||||
, _infoToggle(this, st::topBarInfo)
 | 
					, _infoToggle(this, st::topBarInfo)
 | 
				
			||||||
, _menuToggle(this, st::topBarMenuToggle) {
 | 
					, _menuToggle(this, st::topBarMenuToggle)
 | 
				
			||||||
 | 
					, _onlineUpdater([this] { updateOnlineDisplay(); }) {
 | 
				
			||||||
	subscribe(Lang::Current().updated(), [this] { refreshLang(); });
 | 
						subscribe(Lang::Current().updated(), [this] { refreshLang(); });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_forward->setClickedCallback([this] { onForwardSelection(); });
 | 
						_forward->setClickedCallback([this] { onForwardSelection(); });
 | 
				
			||||||
| 
						 | 
					@ -99,14 +100,22 @@ TopBarWidget::TopBarWidget(
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	subscribe(App::histories().sendActionAnimationUpdated(), [this](const Histories::SendActionAnimationUpdate &update) {
 | 
						subscribe(App::histories().sendActionAnimationUpdated(), [this](const Histories::SendActionAnimationUpdate &update) {
 | 
				
			||||||
		if (update.history->peer == _controller->historyPeer.current()) {
 | 
							if (update.history->peer == _historyPeer) {
 | 
				
			||||||
			rtlupdate(0, 0, width(), height());
 | 
								rtlupdate(0, 0, width(), height());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
	subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(Notify::PeerUpdate::Flag::UserHasCalls, [this](const Notify::PeerUpdate &update) {
 | 
						using UpdateFlag = Notify::PeerUpdate::Flag;
 | 
				
			||||||
 | 
						auto flags = UpdateFlag::UserHasCalls
 | 
				
			||||||
 | 
							| UpdateFlag::UserOnlineChanged
 | 
				
			||||||
 | 
							| UpdateFlag::MembersChanged;
 | 
				
			||||||
 | 
						subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(flags, [this](const Notify::PeerUpdate &update) {
 | 
				
			||||||
 | 
							if (update.flags & UpdateFlag::UserHasCalls) {
 | 
				
			||||||
			if (update.peer->isUser()) {
 | 
								if (update.peer->isUser()) {
 | 
				
			||||||
				updateControlsVisibility();
 | 
									updateControlsVisibility();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								updateOnlineDisplay();
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}));
 | 
						}));
 | 
				
			||||||
	subscribe(Global::RefPhoneCallsEnabledChanged(), [this] {
 | 
						subscribe(Global::RefPhoneCallsEnabledChanged(), [this] {
 | 
				
			||||||
		updateControlsVisibility(); });
 | 
							updateControlsVisibility(); });
 | 
				
			||||||
| 
						 | 
					@ -122,50 +131,44 @@ TopBarWidget::TopBarWidget(
 | 
				
			||||||
	updateControlsVisibility();
 | 
						updateControlsVisibility();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::refreshLang() {
 | 
					void HistoryTopBarWidget::refreshLang() {
 | 
				
			||||||
	InvokeQueued(this, [this] { updateControlsGeometry(); });
 | 
						InvokeQueued(this, [this] { updateControlsGeometry(); });
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::onForwardSelection() {
 | 
					void HistoryTopBarWidget::onForwardSelection() {
 | 
				
			||||||
	if (App::main()) App::main()->forwardSelectedItems();
 | 
						if (App::main()) App::main()->forwardSelectedItems();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::onDeleteSelection() {
 | 
					void HistoryTopBarWidget::onDeleteSelection() {
 | 
				
			||||||
	if (App::main()) App::main()->confirmDeleteSelectedItems();
 | 
						if (App::main()) App::main()->confirmDeleteSelectedItems();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::onClearSelection() {
 | 
					void HistoryTopBarWidget::onClearSelection() {
 | 
				
			||||||
	if (App::main()) App::main()->clearSelectedItems();
 | 
						if (App::main()) App::main()->clearSelectedItems();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::onInfoClicked() {
 | 
					void HistoryTopBarWidget::onInfoClicked() {
 | 
				
			||||||
	if (auto peer = _controller->historyPeer.current()) {
 | 
						if (_historyPeer) {
 | 
				
			||||||
		_controller->showPeerInfo(peer);
 | 
							_controller->showPeerInfo(_historyPeer);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::onSearch() {
 | 
					void HistoryTopBarWidget::onSearch() {
 | 
				
			||||||
	if (auto main = App::main()) {
 | 
						if (_historyPeer) {
 | 
				
			||||||
		if (auto peer = main->peer()) {
 | 
							App::main()->searchInPeer(_historyPeer);
 | 
				
			||||||
			main->searchInPeer(peer);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::onCall() {
 | 
					void HistoryTopBarWidget::onCall() {
 | 
				
			||||||
	if (auto main = App::main()) {
 | 
						if (auto user = _historyPeer->asUser()) {
 | 
				
			||||||
		if (auto peer = main->peer()) {
 | 
					 | 
				
			||||||
			if (auto user = peer->asUser()) {
 | 
					 | 
				
			||||||
		Calls::Current().startOutgoingCall(user);
 | 
							Calls::Current().startOutgoingCall(user);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::showMenu() {
 | 
					void HistoryTopBarWidget::showMenu() {
 | 
				
			||||||
	if (auto main = App::main()) {
 | 
						if (!_historyPeer || _menu) {
 | 
				
			||||||
		if (auto peer = main->peer()) {
 | 
							return;
 | 
				
			||||||
			if (!_menu) {
 | 
						}
 | 
				
			||||||
	_menu.create(parentWidget());
 | 
						_menu.create(parentWidget());
 | 
				
			||||||
	_menu->setHiddenCallback([that = weak(this), menu = _menu.data()] {
 | 
						_menu->setHiddenCallback([that = weak(this), menu = _menu.data()] {
 | 
				
			||||||
		menu->deleteLater();
 | 
							menu->deleteLater();
 | 
				
			||||||
| 
						 | 
					@ -187,42 +190,39 @@ void TopBarWidget::showMenu() {
 | 
				
			||||||
	_menuToggle->installEventFilter(_menu);
 | 
						_menuToggle->installEventFilter(_menu);
 | 
				
			||||||
	Window::FillPeerMenu(
 | 
						Window::FillPeerMenu(
 | 
				
			||||||
		_controller,
 | 
							_controller,
 | 
				
			||||||
					peer,
 | 
							_historyPeer,
 | 
				
			||||||
		[this](const QString &text, base::lambda<void()> callback) {
 | 
							[this](const QString &text, base::lambda<void()> callback) {
 | 
				
			||||||
			return _menu->addAction(text, std::move(callback));
 | 
								return _menu->addAction(text, std::move(callback));
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Window::PeerMenuSource::History);
 | 
							Window::PeerMenuSource::History);
 | 
				
			||||||
	_menu->moveToRight((parentWidget()->width() - width()) + st::topBarMenuPosition.x(), st::topBarMenuPosition.y());
 | 
						_menu->moveToRight((parentWidget()->width() - width()) + st::topBarMenuPosition.x(), st::topBarMenuPosition.y());
 | 
				
			||||||
	_menu->showAnimated(Ui::PanelAnimation::Origin::TopRight);
 | 
						_menu->showAnimated(Ui::PanelAnimation::Origin::TopRight);
 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::toggleInfoSection() {
 | 
					void HistoryTopBarWidget::toggleInfoSection() {
 | 
				
			||||||
	if (Adaptive::ThreeColumn()
 | 
						if (Adaptive::ThreeColumn()
 | 
				
			||||||
		&& (Auth().data().thirdSectionInfoEnabled()
 | 
							&& (Auth().data().thirdSectionInfoEnabled()
 | 
				
			||||||
			|| Auth().data().tabbedReplacedWithInfo())) {
 | 
								|| Auth().data().tabbedReplacedWithInfo())) {
 | 
				
			||||||
		_controller->closeThirdSection();
 | 
							_controller->closeThirdSection();
 | 
				
			||||||
	} else if (auto peer = _controller->historyPeer.current()) {
 | 
						} else if (_historyPeer) {
 | 
				
			||||||
		if (_controller->canShowThirdSection()) {
 | 
							if (_controller->canShowThirdSection()) {
 | 
				
			||||||
			Auth().data().setThirdSectionInfoEnabled(true);
 | 
								Auth().data().setThirdSectionInfoEnabled(true);
 | 
				
			||||||
			Auth().saveDataDelayed();
 | 
								Auth().saveDataDelayed();
 | 
				
			||||||
			if (Adaptive::ThreeColumn()) {
 | 
								if (Adaptive::ThreeColumn()) {
 | 
				
			||||||
				_controller->showSection(Info::Memento(peer->id));
 | 
									_controller->showSection(Info::Memento(_historyPeer->id));
 | 
				
			||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				_controller->resizeForThirdSection();
 | 
									_controller->resizeForThirdSection();
 | 
				
			||||||
				_controller->updateColumnLayout();
 | 
									_controller->updateColumnLayout();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			_controller->showSection(Info::Memento(peer->id));
 | 
								_controller->showSection(Info::Memento(_historyPeer->id));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		updateControlsVisibility();
 | 
							updateControlsVisibility();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) {
 | 
					bool HistoryTopBarWidget::eventFilter(QObject *obj, QEvent *e) {
 | 
				
			||||||
	if (obj == _membersShowArea) {
 | 
						if (obj == _membersShowArea) {
 | 
				
			||||||
		switch (e->type()) {
 | 
							switch (e->type()) {
 | 
				
			||||||
		case QEvent::MouseButtonPress:
 | 
							case QEvent::MouseButtonPress:
 | 
				
			||||||
| 
						 | 
					@ -230,18 +230,18 @@ bool TopBarWidget::eventFilter(QObject *obj, QEvent *e) {
 | 
				
			||||||
			return true;
 | 
								return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case QEvent::Enter:
 | 
							case QEvent::Enter:
 | 
				
			||||||
			App::main()->setMembersShowAreaActive(true);
 | 
								_membersShowAreaActive.fire(true);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		case QEvent::Leave:
 | 
							case QEvent::Leave:
 | 
				
			||||||
			App::main()->setMembersShowAreaActive(false);
 | 
								_membersShowAreaActive.fire(false);
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return TWidget::eventFilter(obj, e);
 | 
						return TWidget::eventFilter(obj, e);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::paintEvent(QPaintEvent *e) {
 | 
					void HistoryTopBarWidget::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
	Painter p(this);
 | 
						Painter p(this);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto ms = getms();
 | 
						auto ms = getms();
 | 
				
			||||||
| 
						 | 
					@ -271,16 +271,61 @@ void TopBarWidget::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
		if (!_call->isHidden()) {
 | 
							if (!_call->isHidden()) {
 | 
				
			||||||
			decreaseWidth += st::topBarCallSkip + _call->width();
 | 
								decreaseWidth += st::topBarCallSkip + _call->width();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		auto paintCounter = App::main()->paintTopBar(p, decreaseWidth, ms);
 | 
							paintTopBar(p, decreaseWidth, ms);
 | 
				
			||||||
		p.restore();
 | 
							p.restore();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (paintCounter) {
 | 
							paintUnreadCounter(p, width(), _historyPeer);
 | 
				
			||||||
			paintUnreadCounter(p, width());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::paintUnreadCounter(Painter &p, int outerWidth) {
 | 
					void HistoryTopBarWidget::paintTopBar(
 | 
				
			||||||
 | 
							Painter &p,
 | 
				
			||||||
 | 
							int decreaseWidth,
 | 
				
			||||||
 | 
							TimeMs ms) {
 | 
				
			||||||
 | 
						auto history = App::historyLoaded(_historyPeer);
 | 
				
			||||||
 | 
						if (!history) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						auto increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty())
 | 
				
			||||||
 | 
							? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right())
 | 
				
			||||||
 | 
							: 0;
 | 
				
			||||||
 | 
						auto nameleft = st::topBarArrowPadding.right() + increaseLeft;
 | 
				
			||||||
 | 
						auto nametop = st::topBarArrowPadding.top();
 | 
				
			||||||
 | 
						auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
 | 
				
			||||||
 | 
						auto namewidth = width() - decreaseWidth - nameleft - st::topBarArrowPadding.right();
 | 
				
			||||||
 | 
						p.setFont(st::dialogsTextFont);
 | 
				
			||||||
 | 
						if (!history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) {
 | 
				
			||||||
 | 
							p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg);
 | 
				
			||||||
 | 
							p.drawText(nameleft, statustop + st::dialogsTextFont->ascent, _titlePeerText);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						p.setPen(st::dialogsNameFg);
 | 
				
			||||||
 | 
						_historyPeer->dialogName().drawElided(p, nameleft, nametop, namewidth);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
 | 
				
			||||||
 | 
							st::topBarBackward.paint(
 | 
				
			||||||
 | 
								p,
 | 
				
			||||||
 | 
								(st::topBarArrowPadding.left() - st::topBarBackward.width()) / 2,
 | 
				
			||||||
 | 
								(st::topBarHeight - st::topBarBackward.height()) / 2,
 | 
				
			||||||
 | 
								width());
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					QRect HistoryTopBarWidget::getMembersShowAreaGeometry() const {
 | 
				
			||||||
 | 
						int increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty())
 | 
				
			||||||
 | 
							? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right())
 | 
				
			||||||
 | 
							: 0;
 | 
				
			||||||
 | 
						int membersTextLeft = st::topBarArrowPadding.right() + increaseLeft;
 | 
				
			||||||
 | 
						int membersTextTop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
 | 
				
			||||||
 | 
						int membersTextWidth = _titlePeerTextWidth;
 | 
				
			||||||
 | 
						int membersTextHeight = st::topBarHeight - membersTextTop;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return myrtlrect(membersTextLeft, membersTextTop, membersTextWidth, membersTextHeight);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HistoryTopBarWidget::paintUnreadCounter(
 | 
				
			||||||
 | 
							Painter &p,
 | 
				
			||||||
 | 
							int outerWidth,
 | 
				
			||||||
 | 
							PeerData *substractPeer) {
 | 
				
			||||||
	if (!Adaptive::OneColumn()) {
 | 
						if (!Adaptive::OneColumn()) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -288,7 +333,7 @@ void TopBarWidget::paintUnreadCounter(Painter &p, int outerWidth) {
 | 
				
			||||||
	auto fullCounter = App::histories().unreadBadge() + (Global::IncludeMuted() ? 0 : mutedCount);
 | 
						auto fullCounter = App::histories().unreadBadge() + (Global::IncludeMuted() ? 0 : mutedCount);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Do not include currently shown chat in the top bar unread counter.
 | 
						// Do not include currently shown chat in the top bar unread counter.
 | 
				
			||||||
	if (auto historyShown = App::historyLoaded(App::wnd()->controller()->historyPeer.current())) {
 | 
						if (auto historyShown = App::historyLoaded(substractPeer)) {
 | 
				
			||||||
		auto shownUnreadCount = historyShown->unreadCount();
 | 
							auto shownUnreadCount = historyShown->unreadCount();
 | 
				
			||||||
		if (!historyShown->mute() || Global::IncludeMuted()) {
 | 
							if (!historyShown->mute() || Global::IncludeMuted()) {
 | 
				
			||||||
			fullCounter -= shownUnreadCount;
 | 
								fullCounter -= shownUnreadCount;
 | 
				
			||||||
| 
						 | 
					@ -309,21 +354,31 @@ void TopBarWidget::paintUnreadCounter(Painter &p, int outerWidth) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::mousePressEvent(QMouseEvent *e) {
 | 
					void HistoryTopBarWidget::mousePressEvent(QMouseEvent *e) {
 | 
				
			||||||
	if (e->button() == Qt::LeftButton && e->pos().y() < st::topBarHeight && !_selectedCount) {
 | 
						if (e->button() == Qt::LeftButton
 | 
				
			||||||
		emit clicked();
 | 
							&& e->pos().y() < st::topBarHeight
 | 
				
			||||||
 | 
							&& !_selectedCount) {
 | 
				
			||||||
 | 
							clicked();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::resizeEvent(QResizeEvent *e) {
 | 
					void HistoryTopBarWidget::clicked() {
 | 
				
			||||||
 | 
						if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
 | 
				
			||||||
 | 
							_controller->showBackFromStack();
 | 
				
			||||||
 | 
						} else if (_historyPeer) {
 | 
				
			||||||
 | 
							_controller->showPeerInfo(_historyPeer);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HistoryTopBarWidget::resizeEvent(QResizeEvent *e) {
 | 
				
			||||||
	updateControlsGeometry();
 | 
						updateControlsGeometry();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int TopBarWidget::countSelectedButtonsTop(float64 selectedShown) {
 | 
					int HistoryTopBarWidget::countSelectedButtonsTop(float64 selectedShown) {
 | 
				
			||||||
	return (1. - selectedShown) * (-st::topBarHeight);
 | 
						return (1. - selectedShown) * (-st::topBarHeight);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::updateControlsGeometry() {
 | 
					void HistoryTopBarWidget::updateControlsGeometry() {
 | 
				
			||||||
	auto hasSelected = (_selectedCount > 0);
 | 
						auto hasSelected = (_selectedCount > 0);
 | 
				
			||||||
	auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.current(hasSelected ? 1. : 0.));
 | 
						auto selectedButtonsTop = countSelectedButtonsTop(_selectedShown.current(hasSelected ? 1. : 0.));
 | 
				
			||||||
	auto otherButtonsTop = selectedButtonsTop + st::topBarHeight;
 | 
						auto otherButtonsTop = selectedButtonsTop + st::topBarHeight;
 | 
				
			||||||
| 
						 | 
					@ -348,7 +403,6 @@ void TopBarWidget::updateControlsGeometry() {
 | 
				
			||||||
	auto right = 0;
 | 
						auto right = 0;
 | 
				
			||||||
	_info->moveToRight(right, otherButtonsTop);
 | 
						_info->moveToRight(right, otherButtonsTop);
 | 
				
			||||||
	_menuToggle->moveToRight(right, otherButtonsTop);
 | 
						_menuToggle->moveToRight(right, otherButtonsTop);
 | 
				
			||||||
	_mediaType->moveToRight(right, otherButtonsTop);
 | 
					 | 
				
			||||||
	if (_info->isHidden()) {
 | 
						if (_info->isHidden()) {
 | 
				
			||||||
		right += _menuToggle->width() + st::topBarSkip;
 | 
							right += _menuToggle->width() + st::topBarSkip;
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
| 
						 | 
					@ -363,20 +417,17 @@ void TopBarWidget::updateControlsGeometry() {
 | 
				
			||||||
	_call->moveToRight(right, otherButtonsTop);
 | 
						_call->moveToRight(right, otherButtonsTop);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::animationFinished() {
 | 
					void HistoryTopBarWidget::animationFinished() {
 | 
				
			||||||
	updateMembersShowArea();
 | 
						updateMembersShowArea();
 | 
				
			||||||
	updateControlsVisibility();
 | 
						updateControlsVisibility();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::updateControlsVisibility() {
 | 
					void HistoryTopBarWidget::updateControlsVisibility() {
 | 
				
			||||||
	auto overviewPeer = App::main() ? App::main()->overviewPeer() : nullptr;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_clearSelection->show();
 | 
						_clearSelection->show();
 | 
				
			||||||
	_delete->setVisible(_canDelete);
 | 
						_delete->setVisible(_canDelete);
 | 
				
			||||||
	_forward->setVisible(_canForward);
 | 
						_forward->setVisible(_canForward);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_mediaType->setVisible(App::main() ? App::main()->showMediaTypeSwitch() : false);
 | 
						if (_historyPeer) {
 | 
				
			||||||
	if (_historyPeer && !overviewPeer) {
 | 
					 | 
				
			||||||
		if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
 | 
							if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
 | 
				
			||||||
			_info->setPeer(_historyPeer);
 | 
								_info->setPeer(_historyPeer);
 | 
				
			||||||
			_info->show();
 | 
								_info->show();
 | 
				
			||||||
| 
						 | 
					@ -408,10 +459,10 @@ void TopBarWidget::updateControlsVisibility() {
 | 
				
			||||||
	updateControlsGeometry();
 | 
						updateControlsGeometry();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::updateMembersShowArea() {
 | 
					void HistoryTopBarWidget::updateMembersShowArea() {
 | 
				
			||||||
	auto membersShowAreaNeeded = [this]() {
 | 
						auto membersShowAreaNeeded = [this]() {
 | 
				
			||||||
		auto peer = App::main()->peer();
 | 
							auto peer = App::main()->peer();
 | 
				
			||||||
		if ((_selectedCount > 0) || !peer || App::main()->overviewPeer()) {
 | 
							if ((_selectedCount > 0) || !peer) {
 | 
				
			||||||
			return false;
 | 
								return false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (auto chat = peer->asChat()) {
 | 
							if (auto chat = peer->asChat()) {
 | 
				
			||||||
| 
						 | 
					@ -424,7 +475,7 @@ void TopBarWidget::updateMembersShowArea() {
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
	if (!membersShowAreaNeeded()) {
 | 
						if (!membersShowAreaNeeded()) {
 | 
				
			||||||
		if (_membersShowArea) {
 | 
							if (_membersShowArea) {
 | 
				
			||||||
			App::main()->setMembersShowAreaActive(false);
 | 
								_membersShowAreaActive.fire(false);
 | 
				
			||||||
			_membersShowArea.destroy();
 | 
								_membersShowArea.destroy();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -433,10 +484,10 @@ void TopBarWidget::updateMembersShowArea() {
 | 
				
			||||||
		_membersShowArea->show();
 | 
							_membersShowArea->show();
 | 
				
			||||||
		_membersShowArea->installEventFilter(this);
 | 
							_membersShowArea->installEventFilter(this);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_membersShowArea->setGeometry(App::main()->getMembersShowAreaGeometry());
 | 
						_membersShowArea->setGeometry(getMembersShowAreaGeometry());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::showSelected(SelectedState state) {
 | 
					void HistoryTopBarWidget::showSelected(SelectedState state) {
 | 
				
			||||||
	auto canDelete = (state.count > 0 && state.count == state.canDeleteCount);
 | 
						auto canDelete = (state.count > 0 && state.count == state.canDeleteCount);
 | 
				
			||||||
	auto canForward = (state.count > 0 && state.count == state.canForwardCount);
 | 
						auto canForward = (state.count > 0 && state.count == state.canForwardCount);
 | 
				
			||||||
	if (_selectedCount == state.count && _canDelete == canDelete && _canForward == canForward) {
 | 
						if (_selectedCount == state.count && _canDelete == canDelete && _canForward == canForward) {
 | 
				
			||||||
| 
						 | 
					@ -474,12 +525,12 @@ void TopBarWidget::showSelected(SelectedState state) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::selectedShowCallback() {
 | 
					void HistoryTopBarWidget::selectedShowCallback() {
 | 
				
			||||||
	updateControlsGeometry();
 | 
						updateControlsGeometry();
 | 
				
			||||||
	update();
 | 
						update();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::updateAdaptiveLayout() {
 | 
					void HistoryTopBarWidget::updateAdaptiveLayout() {
 | 
				
			||||||
	updateMembersShowArea();
 | 
						updateMembersShowArea();
 | 
				
			||||||
	updateControlsVisibility();
 | 
						updateControlsVisibility();
 | 
				
			||||||
	if (!Adaptive::OneColumn()) {
 | 
						if (!Adaptive::OneColumn()) {
 | 
				
			||||||
| 
						 | 
					@ -492,7 +543,7 @@ void TopBarWidget::updateAdaptiveLayout() {
 | 
				
			||||||
	updateInfoToggleActive();
 | 
						updateInfoToggleActive();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void TopBarWidget::updateInfoToggleActive() {
 | 
					void HistoryTopBarWidget::updateInfoToggleActive() {
 | 
				
			||||||
	auto infoThirdActive = Adaptive::ThreeColumn()
 | 
						auto infoThirdActive = Adaptive::ThreeColumn()
 | 
				
			||||||
		&& (Auth().data().thirdSectionInfoEnabled()
 | 
							&& (Auth().data().thirdSectionInfoEnabled()
 | 
				
			||||||
			|| Auth().data().tabbedReplacedWithInfo());
 | 
								|| Auth().data().tabbedReplacedWithInfo());
 | 
				
			||||||
| 
						 | 
					@ -506,8 +557,105 @@ void TopBarWidget::updateInfoToggleActive() {
 | 
				
			||||||
	_infoToggle->setRippleColorOverride(rippleOverride);
 | 
						_infoToggle->setRippleColorOverride(rippleOverride);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Ui::RoundButton *TopBarWidget::mediaTypeButton() {
 | 
					void HistoryTopBarWidget::updateOnlineDisplay() {
 | 
				
			||||||
	return _mediaType;
 | 
						if (!_historyPeer) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QString text;
 | 
				
			||||||
 | 
						int32 t = unixtime();
 | 
				
			||||||
 | 
						bool titlePeerTextOnline = false;
 | 
				
			||||||
 | 
						if (auto user = _historyPeer->asUser()) {
 | 
				
			||||||
 | 
							text = App::onlineText(user, t);
 | 
				
			||||||
 | 
							titlePeerTextOnline = App::onlineColorUse(user, t);
 | 
				
			||||||
 | 
						} else if (auto chat = _historyPeer->asChat()) {
 | 
				
			||||||
 | 
							if (!chat->amIn()) {
 | 
				
			||||||
 | 
								text = lang(lng_chat_status_unaccessible);
 | 
				
			||||||
 | 
							} else if (chat->participants.isEmpty()) {
 | 
				
			||||||
 | 
								if (!_titlePeerText.isEmpty()) {
 | 
				
			||||||
 | 
									text = _titlePeerText;
 | 
				
			||||||
 | 
								} else if (chat->count <= 0) {
 | 
				
			||||||
 | 
									text = lang(lng_group_status);
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									text = lng_chat_status_members(lt_count, chat->count);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								auto online = 0;
 | 
				
			||||||
 | 
								auto onlyMe = true;
 | 
				
			||||||
 | 
								for (auto i = chat->participants.cbegin(), e = chat->participants.cend(); i != e; ++i) {
 | 
				
			||||||
 | 
									if (i.key()->onlineTill > t) {
 | 
				
			||||||
 | 
										++online;
 | 
				
			||||||
 | 
										if (onlyMe && i.key() != App::self()) onlyMe = false;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (online > 0 && !onlyMe) {
 | 
				
			||||||
 | 
									auto membersCount = lng_chat_status_members(lt_count, chat->participants.size());
 | 
				
			||||||
 | 
									auto onlineCount = lng_chat_status_online(lt_count, online);
 | 
				
			||||||
 | 
									text = lng_chat_status_members_online(lt_members_count, membersCount, lt_online_count, onlineCount);
 | 
				
			||||||
 | 
								} else if (chat->participants.size() > 0) {
 | 
				
			||||||
 | 
									text = lng_chat_status_members(lt_count, chat->participants.size());
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									text = lang(lng_group_status);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (auto channel = _historyPeer->asChannel()) {
 | 
				
			||||||
 | 
							if (channel->isMegagroup() && channel->membersCount() > 0 && channel->membersCount() <= Global::ChatSizeMax()) {
 | 
				
			||||||
 | 
								if (channel->mgInfo->lastParticipants.size() < channel->membersCount() || channel->lastParticipantsCountOutdated()) {
 | 
				
			||||||
 | 
									Auth().api().requestLastParticipants(channel);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								auto online = 0;
 | 
				
			||||||
 | 
								bool onlyMe = true;
 | 
				
			||||||
 | 
								for (auto &participant : std::as_const(channel->mgInfo->lastParticipants)) {
 | 
				
			||||||
 | 
									if (participant->onlineTill > t) {
 | 
				
			||||||
 | 
										++online;
 | 
				
			||||||
 | 
										if (onlyMe && participant != App::self()) {
 | 
				
			||||||
 | 
											onlyMe = false;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if (online && !onlyMe) {
 | 
				
			||||||
 | 
									auto membersCount = lng_chat_status_members(lt_count, channel->membersCount());
 | 
				
			||||||
 | 
									auto onlineCount = lng_chat_status_online(lt_count, online);
 | 
				
			||||||
 | 
									text = lng_chat_status_members_online(lt_members_count, membersCount, lt_online_count, onlineCount);
 | 
				
			||||||
 | 
								} else if (channel->membersCount() > 0) {
 | 
				
			||||||
 | 
									text = lng_chat_status_members(lt_count, channel->membersCount());
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									text = lang(lng_group_status);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else if (channel->membersCount() > 0) {
 | 
				
			||||||
 | 
								text = lng_chat_status_members(lt_count, channel->membersCount());
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								text = lang(channel->isMegagroup() ? lng_group_status : lng_channel_status);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						if (_titlePeerText != text) {
 | 
				
			||||||
 | 
							_titlePeerText = text;
 | 
				
			||||||
 | 
							_titlePeerTextOnline = titlePeerTextOnline;
 | 
				
			||||||
 | 
							_titlePeerTextWidth = st::dialogsTextFont->width(_titlePeerText);
 | 
				
			||||||
 | 
							updateMembersShowArea();
 | 
				
			||||||
 | 
							update();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						updateOnlineDisplayTimer();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace Window
 | 
					void HistoryTopBarWidget::updateOnlineDisplayTimer() {
 | 
				
			||||||
 | 
						if (!_historyPeer) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						int32 t = unixtime(), minIn = 86400;
 | 
				
			||||||
 | 
						if (auto user = _historyPeer->asUser()) {
 | 
				
			||||||
 | 
							minIn = App::onlineWillChangeIn(user, t);
 | 
				
			||||||
 | 
						} else if (auto chat = _historyPeer->asChat()) {
 | 
				
			||||||
 | 
							if (chat->participants.isEmpty()) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							for (auto i = chat->participants.cbegin(), e = chat->participants.cend(); i != e; ++i) {
 | 
				
			||||||
 | 
								int32 onlineWillChangeIn = App::onlineWillChangeIn(i.key(), t);
 | 
				
			||||||
 | 
								if (onlineWillChangeIn < minIn) {
 | 
				
			||||||
 | 
									minIn = onlineWillChangeIn;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						} else if (_historyPeer->isChannel()) {
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						updateOnlineDisplayIn(minIn * 1000);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void HistoryTopBarWidget::updateOnlineDisplayIn(TimeMs timeout) {
 | 
				
			||||||
 | 
						_onlineUpdater.callOnce(timeout);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#pragma once
 | 
					#pragma once
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "ui/rp_widget.h"
 | 
					#include "ui/rp_widget.h"
 | 
				
			||||||
 | 
					#include "base/timer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Ui {
 | 
					namespace Ui {
 | 
				
			||||||
class PeerAvatarButton;
 | 
					class PeerAvatarButton;
 | 
				
			||||||
| 
						 | 
					@ -30,14 +31,14 @@ class DropdownMenu;
 | 
				
			||||||
} // namespace Ui
 | 
					} // namespace Ui
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Window {
 | 
					namespace Window {
 | 
				
			||||||
 | 
					 | 
				
			||||||
class Controller;
 | 
					class Controller;
 | 
				
			||||||
 | 
					} // namespace Window
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TopBarWidget : public Ui::RpWidget, private base::Subscriber {
 | 
					class HistoryTopBarWidget : public Ui::RpWidget, private base::Subscriber {
 | 
				
			||||||
	Q_OBJECT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					public:
 | 
				
			||||||
	TopBarWidget(QWidget *parent, not_null<Window::Controller*> controller);
 | 
						HistoryTopBarWidget(
 | 
				
			||||||
 | 
							QWidget *parent,
 | 
				
			||||||
 | 
							not_null<Window::Controller*> controller);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct SelectedState {
 | 
						struct SelectedState {
 | 
				
			||||||
		bool textSelected = false;
 | 
							bool textSelected = false;
 | 
				
			||||||
| 
						 | 
					@ -49,14 +50,19 @@ public:
 | 
				
			||||||
	void updateControlsVisibility();
 | 
						void updateControlsVisibility();
 | 
				
			||||||
	void showSelected(SelectedState state);
 | 
						void showSelected(SelectedState state);
 | 
				
			||||||
	void animationFinished();
 | 
						void animationFinished();
 | 
				
			||||||
	void updateMembersShowArea();
 | 
						rpl::producer<bool> membersShowAreaActive() const {
 | 
				
			||||||
 | 
							return _membersShowAreaActive.events();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Ui::RoundButton *mediaTypeButton();
 | 
					 | 
				
			||||||
	void setHistoryPeer(not_null<PeerData*> historyPeer) {
 | 
						void setHistoryPeer(not_null<PeerData*> historyPeer) {
 | 
				
			||||||
		_historyPeer = historyPeer;
 | 
							_historyPeer = historyPeer;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static void paintUnreadCounter(Painter &p, int outerWidth);
 | 
						void clicked();
 | 
				
			||||||
 | 
						static void paintUnreadCounter(
 | 
				
			||||||
 | 
							Painter &p,
 | 
				
			||||||
 | 
							int outerWidth,
 | 
				
			||||||
 | 
							PeerData *substractPeer = nullptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
protected:
 | 
					protected:
 | 
				
			||||||
	void paintEvent(QPaintEvent *e) override;
 | 
						void paintEvent(QPaintEvent *e) override;
 | 
				
			||||||
| 
						 | 
					@ -64,9 +70,6 @@ protected:
 | 
				
			||||||
	void resizeEvent(QResizeEvent *e) override;
 | 
						void resizeEvent(QResizeEvent *e) override;
 | 
				
			||||||
	bool eventFilter(QObject *obj, QEvent *e) override;
 | 
						bool eventFilter(QObject *obj, QEvent *e) override;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
signals:
 | 
					 | 
				
			||||||
	void clicked();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					private:
 | 
				
			||||||
	void refreshLang();
 | 
						void refreshLang();
 | 
				
			||||||
	void updateControlsGeometry();
 | 
						void updateControlsGeometry();
 | 
				
			||||||
| 
						 | 
					@ -85,6 +88,13 @@ private:
 | 
				
			||||||
	void updateAdaptiveLayout();
 | 
						void updateAdaptiveLayout();
 | 
				
			||||||
	int countSelectedButtonsTop(float64 selectedShown);
 | 
						int countSelectedButtonsTop(float64 selectedShown);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						void paintTopBar(Painter &p, int decreaseWidth, TimeMs ms);
 | 
				
			||||||
 | 
						QRect getMembersShowAreaGeometry() const;
 | 
				
			||||||
 | 
						void updateMembersShowArea();
 | 
				
			||||||
 | 
						void updateOnlineDisplay();
 | 
				
			||||||
 | 
						void updateOnlineDisplayTimer();
 | 
				
			||||||
 | 
						void updateOnlineDisplayIn(TimeMs timeout);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	not_null<Window::Controller*> _controller;
 | 
						not_null<Window::Controller*> _controller;
 | 
				
			||||||
	PeerData *_historyPeer = nullptr;
 | 
						PeerData *_historyPeer = nullptr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,7 +108,6 @@ private:
 | 
				
			||||||
	object_ptr<Ui::RoundButton> _forward, _delete;
 | 
						object_ptr<Ui::RoundButton> _forward, _delete;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	object_ptr<Ui::PeerAvatarButton> _info;
 | 
						object_ptr<Ui::PeerAvatarButton> _info;
 | 
				
			||||||
	object_ptr<Ui::RoundButton> _mediaType;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	object_ptr<Ui::IconButton> _call;
 | 
						object_ptr<Ui::IconButton> _call;
 | 
				
			||||||
	object_ptr<Ui::IconButton> _search;
 | 
						object_ptr<Ui::IconButton> _search;
 | 
				
			||||||
| 
						 | 
					@ -107,9 +116,13 @@ private:
 | 
				
			||||||
	object_ptr<Ui::DropdownMenu> _menu = { nullptr };
 | 
						object_ptr<Ui::DropdownMenu> _menu = { nullptr };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	object_ptr<TWidget> _membersShowArea = { nullptr };
 | 
						object_ptr<TWidget> _membersShowArea = { nullptr };
 | 
				
			||||||
 | 
						rpl::event_stream<bool> _membersShowAreaActive;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						QString _titlePeerText;
 | 
				
			||||||
 | 
						bool _titlePeerTextOnline = false;
 | 
				
			||||||
 | 
						int _titlePeerTextWidth = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int _unreadCounterSubscription = 0;
 | 
						int _unreadCounterSubscription = 0;
 | 
				
			||||||
 | 
						base::Timer _onlineUpdater;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					 | 
				
			||||||
} // namespace Window
 | 
					 | 
				
			||||||
| 
						 | 
					@ -64,7 +64,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "media/player/media_player_instance.h"
 | 
					#include "media/player/media_player_instance.h"
 | 
				
			||||||
#include "storage/localstorage.h"
 | 
					#include "storage/localstorage.h"
 | 
				
			||||||
#include "apiwrap.h"
 | 
					#include "apiwrap.h"
 | 
				
			||||||
#include "window/top_bar_widget.h"
 | 
					#include "history/history_top_bar_widget.h"
 | 
				
			||||||
#include "window/themes/window_theme.h"
 | 
					#include "window/themes/window_theme.h"
 | 
				
			||||||
#include "observer_peer.h"
 | 
					#include "observer_peer.h"
 | 
				
			||||||
#include "base/qthelp_regex.h"
 | 
					#include "base/qthelp_regex.h"
 | 
				
			||||||
| 
						 | 
					@ -547,7 +547,6 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
 | 
				
			||||||
	setAcceptDrops(true);
 | 
						setAcceptDrops(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
 | 
						subscribe(Auth().downloaderTaskFinished(), [this] { update(); });
 | 
				
			||||||
	connect(_topBar, &Window::TopBarWidget::clicked, this, [this] { topBarClick(); });
 | 
					 | 
				
			||||||
	connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
 | 
						connect(_scroll, SIGNAL(scrolled()), this, SLOT(onScroll()));
 | 
				
			||||||
	_historyDown->setClickedCallback([this] { historyDownClicked(); });
 | 
						_historyDown->setClickedCallback([this] { historyDownClicked(); });
 | 
				
			||||||
	_unreadMentions->setClickedCallback([this] { showNextUnreadMention(); });
 | 
						_unreadMentions->setClickedCallback([this] { showNextUnreadMention(); });
 | 
				
			||||||
| 
						 | 
					@ -760,6 +759,10 @@ HistoryWidget::HistoryWidget(QWidget *parent, not_null<Window::Controller*> cont
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}, lifetime());
 | 
							}, lifetime());
 | 
				
			||||||
 | 
						_topBar->membersShowAreaActive()
 | 
				
			||||||
 | 
							| rpl::start_with_next([this](bool active) {
 | 
				
			||||||
 | 
								setMembersShowAreaActive(active);
 | 
				
			||||||
 | 
							}, _topBar->lifetime());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	orderWidgets();
 | 
						orderWidgets();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1753,12 +1756,9 @@ void HistoryWidget::showHistory(const PeerId &peerId, MsgId showAtMsgId, bool re
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	_reportSpamSettingRequestId = ReportSpamRequestNeeded;
 | 
						_reportSpamSettingRequestId = ReportSpamRequestNeeded;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_titlePeerText = QString();
 | 
					 | 
				
			||||||
	_titlePeerTextWidth = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	noSelectingScroll();
 | 
						noSelectingScroll();
 | 
				
			||||||
	_nonEmptySelection = false;
 | 
						_nonEmptySelection = false;
 | 
				
			||||||
	_topBar->showSelected(Window::TopBarWidget::SelectedState {});
 | 
						_topBar->showSelected(HistoryTopBarWidget::SelectedState {});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	App::hoveredItem(nullptr);
 | 
						App::hoveredItem(nullptr);
 | 
				
			||||||
	App::pressedItem(nullptr);
 | 
						App::pressedItem(nullptr);
 | 
				
			||||||
| 
						 | 
					@ -2975,7 +2975,9 @@ MsgId HistoryWidget::msgId() const {
 | 
				
			||||||
	return _showAtMsgId;
 | 
						return _showAtMsgId;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms) {
 | 
					void HistoryWidget::showAnimated(
 | 
				
			||||||
 | 
							Window::SlideDirection direction,
 | 
				
			||||||
 | 
							const Window::SectionSlideParams ¶ms) {
 | 
				
			||||||
	_showDirection = direction;
 | 
						_showDirection = direction;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_a_show.finish();
 | 
						_a_show.finish();
 | 
				
			||||||
| 
						 | 
					@ -2997,7 +2999,7 @@ void HistoryWidget::showAnimated(Window::SlideDirection direction, const Window:
 | 
				
			||||||
	_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
 | 
						_a_show.start([this] { animationCallback(); }, 0., 1., st::slideDuration, Window::SlideAnimation::transition());
 | 
				
			||||||
	if (_history) {
 | 
						if (_history) {
 | 
				
			||||||
		_backAnimationButton.create(this);
 | 
							_backAnimationButton.create(this);
 | 
				
			||||||
		_backAnimationButton->setClickedCallback([this] { topBarClick(); });
 | 
							_backAnimationButton->setClickedCallback([this] { _topBar->clicked(); });
 | 
				
			||||||
		_backAnimationButton->setGeometry(_topBar->geometry());
 | 
							_backAnimationButton->setGeometry(_topBar->geometry());
 | 
				
			||||||
		_backAnimationButton->show();
 | 
							_backAnimationButton->show();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -3716,39 +3718,6 @@ void HistoryWidget::selectMessage() {
 | 
				
			||||||
	if (_list) _list->selectItem(item);
 | 
						if (_list) _list->selectItem(item);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool HistoryWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
 | 
					 | 
				
			||||||
	if (!_history) return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right()) : 0;
 | 
					 | 
				
			||||||
	auto nameleft = st::topBarArrowPadding.right() + increaseLeft;
 | 
					 | 
				
			||||||
	auto nametop = st::topBarArrowPadding.top();
 | 
					 | 
				
			||||||
	auto statustop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
 | 
					 | 
				
			||||||
	auto namewidth = width() - decreaseWidth - nameleft - st::topBarArrowPadding.right();
 | 
					 | 
				
			||||||
	p.setFont(st::dialogsTextFont);
 | 
					 | 
				
			||||||
	if (!_history->paintSendAction(p, nameleft, statustop, namewidth, width(), st::historyStatusFgTyping, ms)) {
 | 
					 | 
				
			||||||
		p.setPen(_titlePeerTextOnline ? st::historyStatusFgActive : st::historyStatusFg);
 | 
					 | 
				
			||||||
		p.drawText(nameleft, statustop + st::dialogsTextFont->ascent, _titlePeerText);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	p.setPen(st::dialogsNameFg);
 | 
					 | 
				
			||||||
	_peer->dialogName().drawElided(p, nameleft, nametop, namewidth);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
 | 
					 | 
				
			||||||
		st::topBarBackward.paint(p, (st::topBarArrowPadding.left() - st::topBarBackward.width()) / 2, (st::topBarHeight - st::topBarBackward.height()) / 2, width());
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return true;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QRect HistoryWidget::getMembersShowAreaGeometry() const {
 | 
					 | 
				
			||||||
	int increaseLeft = (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) ? (st::topBarArrowPadding.left() - st::topBarArrowPadding.right()) : 0;
 | 
					 | 
				
			||||||
	int membersTextLeft = st::topBarArrowPadding.right() + increaseLeft;
 | 
					 | 
				
			||||||
	int membersTextTop = st::topBarHeight - st::topBarArrowPadding.bottom() - st::dialogsTextFont->height;
 | 
					 | 
				
			||||||
	int membersTextWidth = _titlePeerTextWidth;
 | 
					 | 
				
			||||||
	int membersTextHeight = st::topBarHeight - membersTextTop;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return myrtlrect(membersTextLeft, membersTextTop, membersTextWidth, membersTextHeight);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void HistoryWidget::setMembersShowAreaActive(bool active) {
 | 
					void HistoryWidget::setMembersShowAreaActive(bool active) {
 | 
				
			||||||
	if (!active) {
 | 
						if (!active) {
 | 
				
			||||||
		_membersDropdownShowTimer.stop();
 | 
							_membersDropdownShowTimer.stop();
 | 
				
			||||||
| 
						 | 
					@ -3781,14 +3750,6 @@ void HistoryWidget::onModerateKeyActivate(int index, bool *outHandled) {
 | 
				
			||||||
	*outHandled = _keyboard->isHidden() ? false : _keyboard->moderateKeyActivate(index);
 | 
						*outHandled = _keyboard->isHidden() ? false : _keyboard->moderateKeyActivate(index);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HistoryWidget::topBarClick() {
 | 
					 | 
				
			||||||
	if (Adaptive::OneColumn() || !App::main()->stackIsEmpty()) {
 | 
					 | 
				
			||||||
		controller()->showBackFromStack();
 | 
					 | 
				
			||||||
	} else if (_peer) {
 | 
					 | 
				
			||||||
		controller()->showPeerInfo(_peer);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void HistoryWidget::pushTabbedSelectorToThirdSection(
 | 
					void HistoryWidget::pushTabbedSelectorToThirdSection(
 | 
				
			||||||
		const Window::SectionShow ¶ms) {
 | 
							const Window::SectionShow ¶ms) {
 | 
				
			||||||
	if (!_history || !_tabbedPanel) {
 | 
						if (!_history || !_tabbedPanel) {
 | 
				
			||||||
| 
						 | 
					@ -3862,107 +3823,6 @@ void HistoryWidget::recountChatWidth() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HistoryWidget::updateOnlineDisplay() {
 | 
					 | 
				
			||||||
	if (!_history) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QString text;
 | 
					 | 
				
			||||||
	int32 t = unixtime();
 | 
					 | 
				
			||||||
	bool titlePeerTextOnline = false;
 | 
					 | 
				
			||||||
	if (auto user = _peer->asUser()) {
 | 
					 | 
				
			||||||
		text = App::onlineText(user, t);
 | 
					 | 
				
			||||||
		titlePeerTextOnline = App::onlineColorUse(user, t);
 | 
					 | 
				
			||||||
	} else if (_peer->isChat()) {
 | 
					 | 
				
			||||||
		auto chat = _peer->asChat();
 | 
					 | 
				
			||||||
		if (!chat->amIn()) {
 | 
					 | 
				
			||||||
			text = lang(lng_chat_status_unaccessible);
 | 
					 | 
				
			||||||
		} else if (chat->participants.isEmpty()) {
 | 
					 | 
				
			||||||
			if (!_titlePeerText.isEmpty()) {
 | 
					 | 
				
			||||||
				text = _titlePeerText;
 | 
					 | 
				
			||||||
			} else if (chat->count <= 0) {
 | 
					 | 
				
			||||||
				text = lang(lng_group_status);
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				text = lng_chat_status_members(lt_count, chat->count);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			auto online = 0;
 | 
					 | 
				
			||||||
			auto onlyMe = true;
 | 
					 | 
				
			||||||
			for (auto i = chat->participants.cbegin(), e = chat->participants.cend(); i != e; ++i) {
 | 
					 | 
				
			||||||
				if (i.key()->onlineTill > t) {
 | 
					 | 
				
			||||||
					++online;
 | 
					 | 
				
			||||||
					if (onlyMe && i.key() != App::self()) onlyMe = false;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (online > 0 && !onlyMe) {
 | 
					 | 
				
			||||||
				auto membersCount = lng_chat_status_members(lt_count, chat->participants.size());
 | 
					 | 
				
			||||||
				auto onlineCount = lng_chat_status_online(lt_count, online);
 | 
					 | 
				
			||||||
				text = lng_chat_status_members_online(lt_members_count, membersCount, lt_online_count, onlineCount);
 | 
					 | 
				
			||||||
			} else if (chat->participants.size() > 0) {
 | 
					 | 
				
			||||||
				text = lng_chat_status_members(lt_count, chat->participants.size());
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				text = lang(lng_group_status);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else if (_peer->isChannel()) {
 | 
					 | 
				
			||||||
		if (_peer->isMegagroup() && _peer->asChannel()->membersCount() > 0 && _peer->asChannel()->membersCount() <= Global::ChatSizeMax()) {
 | 
					 | 
				
			||||||
			if (_peer->asChannel()->mgInfo->lastParticipants.size() < _peer->asChannel()->membersCount() || _peer->asChannel()->lastParticipantsCountOutdated()) {
 | 
					 | 
				
			||||||
				Auth().api().requestLastParticipants(_peer->asChannel());
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			auto online = 0;
 | 
					 | 
				
			||||||
			bool onlyMe = true;
 | 
					 | 
				
			||||||
			for (auto i = _peer->asChannel()->mgInfo->lastParticipants.cbegin(), e = _peer->asChannel()->mgInfo->lastParticipants.cend(); i != e; ++i) {
 | 
					 | 
				
			||||||
				if ((*i)->onlineTill > t) {
 | 
					 | 
				
			||||||
					++online;
 | 
					 | 
				
			||||||
					if (onlyMe && (*i) != App::self()) onlyMe = false;
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if (online && !onlyMe) {
 | 
					 | 
				
			||||||
				auto membersCount = lng_chat_status_members(lt_count, _peer->asChannel()->membersCount());
 | 
					 | 
				
			||||||
				auto onlineCount = lng_chat_status_online(lt_count, online);
 | 
					 | 
				
			||||||
				text = lng_chat_status_members_online(lt_members_count, membersCount, lt_online_count, onlineCount);
 | 
					 | 
				
			||||||
			} else if (_peer->asChannel()->membersCount() > 0) {
 | 
					 | 
				
			||||||
				text = lng_chat_status_members(lt_count, _peer->asChannel()->membersCount());
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				text = lang(lng_group_status);
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		} else if (_peer->asChannel()->membersCount() > 0) {
 | 
					 | 
				
			||||||
			text = lng_chat_status_members(lt_count, _peer->asChannel()->membersCount());
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			text = lang(_peer->isMegagroup() ? lng_group_status : lng_channel_status);
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (_titlePeerText != text) {
 | 
					 | 
				
			||||||
		_titlePeerText = text;
 | 
					 | 
				
			||||||
		_titlePeerTextOnline = titlePeerTextOnline;
 | 
					 | 
				
			||||||
		_titlePeerTextWidth = st::dialogsTextFont->width(_titlePeerText);
 | 
					 | 
				
			||||||
		if (App::main()) {
 | 
					 | 
				
			||||||
			_topBar->updateMembersShowArea();
 | 
					 | 
				
			||||||
			_topBar->update();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	updateOnlineDisplayTimer();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void HistoryWidget::updateOnlineDisplayTimer() {
 | 
					 | 
				
			||||||
	if (!_history) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int32 t = unixtime(), minIn = 86400;
 | 
					 | 
				
			||||||
	if (_peer->isUser()) {
 | 
					 | 
				
			||||||
		minIn = App::onlineWillChangeIn(_peer->asUser(), t);
 | 
					 | 
				
			||||||
	} else if (_peer->isChat()) {
 | 
					 | 
				
			||||||
		ChatData *chat = _peer->asChat();
 | 
					 | 
				
			||||||
		if (chat->participants.isEmpty()) return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		for (auto i = chat->participants.cbegin(), e = chat->participants.cend(); i != e; ++i) {
 | 
					 | 
				
			||||||
			int32 onlineWillChangeIn = App::onlineWillChangeIn(i.key(), t);
 | 
					 | 
				
			||||||
			if (onlineWillChangeIn < minIn) {
 | 
					 | 
				
			||||||
				minIn = onlineWillChangeIn;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	} else if (_peer->isChannel()) {
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	App::main()->updateOnlineDisplayIn(minIn * 1000);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void HistoryWidget::moveFieldControls() {
 | 
					void HistoryWidget::moveFieldControls() {
 | 
				
			||||||
	auto keyboardHeight = 0;
 | 
						auto keyboardHeight = 0;
 | 
				
			||||||
	auto bottom = height();
 | 
						auto bottom = height();
 | 
				
			||||||
| 
						 | 
					@ -6005,7 +5865,6 @@ void HistoryWidget::handlePeerUpdate() {
 | 
				
			||||||
			updateControlsGeometry();
 | 
								updateControlsGeometry();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	App::main()->updateOnlineDisplay();
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HistoryWidget::onForwardSelected() {
 | 
					void HistoryWidget::onForwardSelected() {
 | 
				
			||||||
| 
						 | 
					@ -6113,7 +5972,7 @@ SelectedItemSet HistoryWidget::getSelectedItems() const {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void HistoryWidget::updateTopBarSelection() {
 | 
					void HistoryWidget::updateTopBarSelection() {
 | 
				
			||||||
	if (!_list) {
 | 
						if (!_list) {
 | 
				
			||||||
		_topBar->showSelected(Window::TopBarWidget::SelectedState {});
 | 
							_topBar->showSelected(HistoryTopBarWidget::SelectedState {});
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,7 +58,6 @@ class SuggestionsController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace Window {
 | 
					namespace Window {
 | 
				
			||||||
class Controller;
 | 
					class Controller;
 | 
				
			||||||
class TopBarWidget;
 | 
					 | 
				
			||||||
} // namespace Window
 | 
					} // namespace Window
 | 
				
			||||||
 | 
					
 | 
				
			||||||
namespace ChatHelpers {
 | 
					namespace ChatHelpers {
 | 
				
			||||||
| 
						 | 
					@ -73,6 +72,7 @@ class SendFilesBox;
 | 
				
			||||||
class BotKeyboard;
 | 
					class BotKeyboard;
 | 
				
			||||||
class MessageField;
 | 
					class MessageField;
 | 
				
			||||||
class HistoryInner;
 | 
					class HistoryInner;
 | 
				
			||||||
 | 
					class HistoryTopBarWidget;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class ReportSpamPanel : public TWidget {
 | 
					class ReportSpamPanel : public TWidget {
 | 
				
			||||||
	Q_OBJECT
 | 
						Q_OBJECT
 | 
				
			||||||
| 
						 | 
					@ -191,10 +191,6 @@ public:
 | 
				
			||||||
	bool isItemCompletelyHidden(HistoryItem *item) const;
 | 
						bool isItemCompletelyHidden(HistoryItem *item) const;
 | 
				
			||||||
	void updateTopBarSelection();
 | 
						void updateTopBarSelection();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bool paintTopBar(Painter &p, int decreaseWidth, TimeMs ms);
 | 
					 | 
				
			||||||
	QRect getMembersShowAreaGeometry() const;
 | 
					 | 
				
			||||||
	void setMembersShowAreaActive(bool active);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void loadMessages();
 | 
						void loadMessages();
 | 
				
			||||||
	void loadMessagesDown();
 | 
						void loadMessagesDown();
 | 
				
			||||||
	void firstLoadMessages();
 | 
						void firstLoadMessages();
 | 
				
			||||||
| 
						 | 
					@ -237,8 +233,6 @@ public:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void updateControlsVisibility();
 | 
						void updateControlsVisibility();
 | 
				
			||||||
	void updateControlsGeometry();
 | 
						void updateControlsGeometry();
 | 
				
			||||||
	void updateOnlineDisplay();
 | 
					 | 
				
			||||||
	void updateOnlineDisplayTimer();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void onShareContact(const PeerId &peer, UserData *contact);
 | 
						void onShareContact(const PeerId &peer, UserData *contact);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -483,7 +477,6 @@ private:
 | 
				
			||||||
	void repaintHistoryItem(not_null<const HistoryItem*> item);
 | 
						void repaintHistoryItem(not_null<const HistoryItem*> item);
 | 
				
			||||||
	void handlePendingHistoryUpdate();
 | 
						void handlePendingHistoryUpdate();
 | 
				
			||||||
	void fullPeerUpdated(PeerData *peer);
 | 
						void fullPeerUpdated(PeerData *peer);
 | 
				
			||||||
	void topBarClick();
 | 
					 | 
				
			||||||
	void toggleTabbedSelectorMode();
 | 
						void toggleTabbedSelectorMode();
 | 
				
			||||||
	void returnTabbedSelector(object_ptr<TabbedSelector> selector);
 | 
						void returnTabbedSelector(object_ptr<TabbedSelector> selector);
 | 
				
			||||||
	void recountChatWidth();
 | 
						void recountChatWidth();
 | 
				
			||||||
| 
						 | 
					@ -491,6 +484,7 @@ private:
 | 
				
			||||||
	void historyDownClicked();
 | 
						void historyDownClicked();
 | 
				
			||||||
	void showNextUnreadMention();
 | 
						void showNextUnreadMention();
 | 
				
			||||||
	void handlePeerUpdate();
 | 
						void handlePeerUpdate();
 | 
				
			||||||
 | 
						void setMembersShowAreaActive(bool active);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void highlightMessage(MsgId universalMessageId);
 | 
						void highlightMessage(MsgId universalMessageId);
 | 
				
			||||||
	void adjustHighlightedMessageToMigrated();
 | 
						void adjustHighlightedMessageToMigrated();
 | 
				
			||||||
| 
						 | 
					@ -735,7 +729,7 @@ private:
 | 
				
			||||||
	mtpRequestId _delayedShowAtRequest = 0;
 | 
						mtpRequestId _delayedShowAtRequest = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	object_ptr<Ui::AbstractButton> _backAnimationButton = { nullptr };
 | 
						object_ptr<Ui::AbstractButton> _backAnimationButton = { nullptr };
 | 
				
			||||||
	object_ptr<Window::TopBarWidget> _topBar;
 | 
						object_ptr<HistoryTopBarWidget> _topBar;
 | 
				
			||||||
	object_ptr<Ui::ScrollArea> _scroll;
 | 
						object_ptr<Ui::ScrollArea> _scroll;
 | 
				
			||||||
	QPointer<HistoryInner> _list;
 | 
						QPointer<HistoryInner> _list;
 | 
				
			||||||
	History *_migrated = nullptr;
 | 
						History *_migrated = nullptr;
 | 
				
			||||||
| 
						 | 
					@ -836,10 +830,6 @@ private:
 | 
				
			||||||
	int64 _serviceImageCacheSize = 0;
 | 
						int64 _serviceImageCacheSize = 0;
 | 
				
			||||||
	QString _confirmSource;
 | 
						QString _confirmSource;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	QString _titlePeerText;
 | 
					 | 
				
			||||||
	bool _titlePeerTextOnline = false;
 | 
					 | 
				
			||||||
	int _titlePeerTextWidth = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Animation _a_show;
 | 
						Animation _a_show;
 | 
				
			||||||
	Window::SlideDirection _showDirection;
 | 
						Window::SlideDirection _showDirection;
 | 
				
			||||||
	QPixmap _cacheUnder, _cacheOver;
 | 
						QPixmap _cacheUnder, _cacheOver;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "ui/widgets/shadow.h"
 | 
					#include "ui/widgets/shadow.h"
 | 
				
			||||||
#include "window/section_memento.h"
 | 
					#include "window/section_memento.h"
 | 
				
			||||||
#include "window/section_widget.h"
 | 
					#include "window/section_widget.h"
 | 
				
			||||||
#include "window/top_bar_widget.h"
 | 
					 | 
				
			||||||
#include "data/data_drafts.h"
 | 
					#include "data/data_drafts.h"
 | 
				
			||||||
#include "ui/widgets/dropdown_menu.h"
 | 
					#include "ui/widgets/dropdown_menu.h"
 | 
				
			||||||
#include "ui/focus_persister.h"
 | 
					#include "ui/focus_persister.h"
 | 
				
			||||||
| 
						 | 
					@ -49,7 +48,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
#include "history/history_message.h"
 | 
					#include "history/history_message.h"
 | 
				
			||||||
#include "history/history_media.h"
 | 
					#include "history/history_media.h"
 | 
				
			||||||
#include "history/history_service_layout.h"
 | 
					#include "history/history_service_layout.h"
 | 
				
			||||||
#include "overviewwidget.h"
 | 
					 | 
				
			||||||
#include "lang/lang_keys.h"
 | 
					#include "lang/lang_keys.h"
 | 
				
			||||||
#include "lang/lang_cloud_manager.h"
 | 
					#include "lang/lang_cloud_manager.h"
 | 
				
			||||||
#include "boxes/add_contact_box.h"
 | 
					#include "boxes/add_contact_box.h"
 | 
				
			||||||
| 
						 | 
					@ -112,7 +110,6 @@ MTPMessagesFilter TypeToMediaFilter(MediaOverviewType &type) {
 | 
				
			||||||
enum StackItemType {
 | 
					enum StackItemType {
 | 
				
			||||||
	HistoryStackItem,
 | 
						HistoryStackItem,
 | 
				
			||||||
	SectionStackItem,
 | 
						SectionStackItem,
 | 
				
			||||||
	OverviewStackItem,
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StackItem {
 | 
					class StackItem {
 | 
				
			||||||
| 
						 | 
					@ -176,28 +173,6 @@ private:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StackItemOverview : public StackItem {
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	StackItemOverview(
 | 
					 | 
				
			||||||
		PeerData *peer,
 | 
					 | 
				
			||||||
		MediaOverviewType mediaType,
 | 
					 | 
				
			||||||
		int32 lastWidth,
 | 
					 | 
				
			||||||
		int32 lastScrollTop)
 | 
					 | 
				
			||||||
	: StackItem(peer)
 | 
					 | 
				
			||||||
	, mediaType(mediaType)
 | 
					 | 
				
			||||||
	, lastWidth(lastWidth)
 | 
					 | 
				
			||||||
	, lastScrollTop(lastScrollTop) {
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	StackItemType type() const {
 | 
					 | 
				
			||||||
		return OverviewStackItem;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	MediaOverviewType mediaType;
 | 
					 | 
				
			||||||
	int32 lastWidth, lastScrollTop;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void StackItem::setThirdSectionMemento(
 | 
					void StackItem::setThirdSectionMemento(
 | 
				
			||||||
		std::unique_ptr<Window::SectionMemento> &&memento) {
 | 
							std::unique_ptr<Window::SectionMemento> &&memento) {
 | 
				
			||||||
	_thirdSectionMemento = std::move(memento);
 | 
						_thirdSectionMemento = std::move(memento);
 | 
				
			||||||
| 
						 | 
					@ -244,7 +219,6 @@ MainWidget::MainWidget(
 | 
				
			||||||
	connect(_history, SIGNAL(cancelled()), _dialogs, SLOT(activate()));
 | 
						connect(_history, SIGNAL(cancelled()), _dialogs, SLOT(activate()));
 | 
				
			||||||
	connect(&noUpdatesTimer, SIGNAL(timeout()), this, SLOT(mtpPing()));
 | 
						connect(&noUpdatesTimer, SIGNAL(timeout()), this, SLOT(mtpPing()));
 | 
				
			||||||
	connect(&_onlineTimer, SIGNAL(timeout()), this, SLOT(updateOnline()));
 | 
						connect(&_onlineTimer, SIGNAL(timeout()), this, SLOT(updateOnline()));
 | 
				
			||||||
	connect(&_onlineUpdater, SIGNAL(timeout()), this, SLOT(updateOnlineDisplay()));
 | 
					 | 
				
			||||||
	connect(&_idleFinishTimer, SIGNAL(timeout()), this, SLOT(checkIdleFinish()));
 | 
						connect(&_idleFinishTimer, SIGNAL(timeout()), this, SLOT(checkIdleFinish()));
 | 
				
			||||||
	connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
 | 
						connect(&_bySeqTimer, SIGNAL(timeout()), this, SLOT(getDifference()));
 | 
				
			||||||
	connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeByPts()));
 | 
						connect(&_byPtsTimer, SIGNAL(timeout()), this, SLOT(onGetDifferenceTimeByPts()));
 | 
				
			||||||
| 
						 | 
					@ -344,11 +318,6 @@ MainWidget::MainWidget(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subscribe(Adaptive::Changed(), [this]() { handleAdaptiveLayoutUpdate(); });
 | 
						subscribe(Adaptive::Changed(), [this]() { handleAdaptiveLayoutUpdate(); });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto observeEvents = Notify::PeerUpdate::Flag::SharedMediaChanged;
 | 
					 | 
				
			||||||
	subscribe(Notify::PeerUpdated(), Notify::PeerUpdatedHandler(observeEvents, [this](const Notify::PeerUpdate &update) {
 | 
					 | 
				
			||||||
		mediaOverviewUpdated(update);
 | 
					 | 
				
			||||||
	}));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_dialogs->show();
 | 
						_dialogs->show();
 | 
				
			||||||
	if (Adaptive::OneColumn()) {
 | 
						if (Adaptive::OneColumn()) {
 | 
				
			||||||
		_history->hide();
 | 
							_history->hide();
 | 
				
			||||||
| 
						 | 
					@ -529,9 +498,6 @@ Window::AbstractSectionWidget *MainWidget::getFloatPlayerSection(Window::Column
 | 
				
			||||||
	} else if (Adaptive::Normal()) {
 | 
						} else if (Adaptive::Normal()) {
 | 
				
			||||||
		if (column == Window::Column::First) {
 | 
							if (column == Window::Column::First) {
 | 
				
			||||||
			return _dialogs;
 | 
								return _dialogs;
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (_overview) {
 | 
					 | 
				
			||||||
			return _overview;
 | 
					 | 
				
			||||||
		} else if (_mainSection) {
 | 
							} else if (_mainSection) {
 | 
				
			||||||
			return _mainSection;
 | 
								return _mainSection;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -539,8 +505,6 @@ Window::AbstractSectionWidget *MainWidget::getFloatPlayerSection(Window::Column
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (Adaptive::OneColumn() && selectingPeer()) {
 | 
						if (Adaptive::OneColumn() && selectingPeer()) {
 | 
				
			||||||
		return _dialogs;
 | 
							return _dialogs;
 | 
				
			||||||
	} else if (_overview) {
 | 
					 | 
				
			||||||
		return _overview;
 | 
					 | 
				
			||||||
	} else if (_mainSection) {
 | 
						} else if (_mainSection) {
 | 
				
			||||||
		return _mainSection;
 | 
							return _mainSection;
 | 
				
			||||||
	} else if (!Adaptive::OneColumn() || _history->peer()) {
 | 
						} else if (!Adaptive::OneColumn() || _history->peer()) {
 | 
				
			||||||
| 
						 | 
					@ -589,9 +553,7 @@ void MainWidget::updateFloatPlayerColumnCorner(QPoint center) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (Adaptive::Normal()) {
 | 
						} else if (Adaptive::Normal()) {
 | 
				
			||||||
		checkSection(_dialogs, Window::Column::First);
 | 
							checkSection(_dialogs, Window::Column::First);
 | 
				
			||||||
		if (_overview) {
 | 
							if (_mainSection) {
 | 
				
			||||||
			checkSection(_overview, Window::Column::Second);
 | 
					 | 
				
			||||||
		} else if (_mainSection) {
 | 
					 | 
				
			||||||
			checkSection(_mainSection, Window::Column::Second);
 | 
								checkSection(_mainSection, Window::Column::Second);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			checkSection(_history, Window::Column::Second);
 | 
								checkSection(_history, Window::Column::Second);
 | 
				
			||||||
| 
						 | 
					@ -599,8 +561,6 @@ void MainWidget::updateFloatPlayerColumnCorner(QPoint center) {
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (Adaptive::OneColumn() && selectingPeer()) {
 | 
							if (Adaptive::OneColumn() && selectingPeer()) {
 | 
				
			||||||
			checkSection(_dialogs, Window::Column::First);
 | 
								checkSection(_dialogs, Window::Column::First);
 | 
				
			||||||
		} else if (_overview) {
 | 
					 | 
				
			||||||
			checkSection(_overview, Window::Column::Second);
 | 
					 | 
				
			||||||
		} else if (_mainSection) {
 | 
							} else if (_mainSection) {
 | 
				
			||||||
			checkSection(_mainSection, Window::Column::Second);
 | 
								checkSection(_mainSection, Window::Column::Second);
 | 
				
			||||||
		} else if (!Adaptive::OneColumn() || _history->peer()) {
 | 
							} else if (!Adaptive::OneColumn() || _history->peer()) {
 | 
				
			||||||
| 
						 | 
					@ -648,7 +608,7 @@ void MainWidget::finishFloatPlayerDrag(not_null<Float*> instance, bool closed) {
 | 
				
			||||||
bool MainWidget::setForwardDraft(PeerId peerId, ForwardWhatMessages what) {
 | 
					bool MainWidget::setForwardDraft(PeerId peerId, ForwardWhatMessages what) {
 | 
				
			||||||
	auto toForward = SelectedItemSet();
 | 
						auto toForward = SelectedItemSet();
 | 
				
			||||||
	if (what == ForwardSelectedMessages) {
 | 
						if (what == ForwardSelectedMessages) {
 | 
				
			||||||
		toForward = _overview ? _overview->getSelectedItems() : _history->getSelectedItems();
 | 
							toForward = _history->getSelectedItems();
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		auto item = (HistoryItem*)nullptr;
 | 
							auto item = (HistoryItem*)nullptr;
 | 
				
			||||||
		if (what == ForwardContextMessage) {
 | 
							if (what == ForwardContextMessage) {
 | 
				
			||||||
| 
						 | 
					@ -969,19 +929,15 @@ void MainWidget::noHider(HistoryHider *destroyed) {
 | 
				
			||||||
				_forwardConfirm = nullptr;
 | 
									_forwardConfirm = nullptr;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			onHistoryShown(_history->history(), _history->msgId());
 | 
								onHistoryShown(_history->history(), _history->msgId());
 | 
				
			||||||
			if (_mainSection || _overview || (_history->peer() && _history->peer()->id)) {
 | 
								if (_mainSection || (_history->peer() && _history->peer()->id)) {
 | 
				
			||||||
				auto animationParams = ([this] {
 | 
									auto animationParams = ([this] {
 | 
				
			||||||
					if (_overview) {
 | 
										if (_mainSection) {
 | 
				
			||||||
						return prepareOverviewAnimation();
 | 
					 | 
				
			||||||
					} else if (_mainSection) {
 | 
					 | 
				
			||||||
						return prepareMainSectionAnimation(_mainSection);
 | 
											return prepareMainSectionAnimation(_mainSection);
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
					return prepareHistoryAnimation(_history->peer() ? _history->peer()->id : 0);
 | 
										return prepareHistoryAnimation(_history->peer() ? _history->peer()->id : 0);
 | 
				
			||||||
				})();
 | 
									})();
 | 
				
			||||||
				_dialogs->hide();
 | 
									_dialogs->hide();
 | 
				
			||||||
				if (_overview) {
 | 
									if (_mainSection) {
 | 
				
			||||||
					_overview->showAnimated(Window::SlideDirection::FromRight, animationParams);
 | 
					 | 
				
			||||||
				} else if (_mainSection) {
 | 
					 | 
				
			||||||
					_mainSection->showAnimated(Window::SlideDirection::FromRight, animationParams);
 | 
										_mainSection->showAnimated(Window::SlideDirection::FromRight, animationParams);
 | 
				
			||||||
				} else {
 | 
									} else {
 | 
				
			||||||
					_history->showAnimated(Window::SlideDirection::FromRight, animationParams);
 | 
										_history->showAnimated(Window::SlideDirection::FromRight, animationParams);
 | 
				
			||||||
| 
						 | 
					@ -1011,9 +967,7 @@ void MainWidget::hiderLayer(object_ptr<HistoryHider> h) {
 | 
				
			||||||
		auto animationParams = prepareDialogsAnimation();
 | 
							auto animationParams = prepareDialogsAnimation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		onHistoryShown(0, 0);
 | 
							onHistoryShown(0, 0);
 | 
				
			||||||
		if (_overview) {
 | 
							if (_mainSection) {
 | 
				
			||||||
			_overview->hide();
 | 
					 | 
				
			||||||
		} else if (_mainSection) {
 | 
					 | 
				
			||||||
			_mainSection->hide();
 | 
								_mainSection->hide();
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			_history->hide();
 | 
								_history->hide();
 | 
				
			||||||
| 
						 | 
					@ -1042,12 +996,12 @@ void MainWidget::showSendPathsLayer() {
 | 
				
			||||||
void MainWidget::deleteLayer(int selectedCount) {
 | 
					void MainWidget::deleteLayer(int selectedCount) {
 | 
				
			||||||
	if (selectedCount) {
 | 
						if (selectedCount) {
 | 
				
			||||||
		auto forDelete = true;
 | 
							auto forDelete = true;
 | 
				
			||||||
		auto selected = _overview ? _overview->getSelectedItems() : _history->getSelectedItems();
 | 
							auto selected = _history->getSelectedItems();
 | 
				
			||||||
		if (!selected.isEmpty()) {
 | 
							if (!selected.isEmpty()) {
 | 
				
			||||||
			Ui::show(Box<DeleteMessagesBox>(selected));
 | 
								Ui::show(Box<DeleteMessagesBox>(selected));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (auto item = App::contextItem()) {
 | 
						} else if (auto item = App::contextItem()) {
 | 
				
			||||||
		auto suggestModerateActions = !_overview;
 | 
							auto suggestModerateActions = true;
 | 
				
			||||||
		Ui::show(Box<DeleteMessagesBox>(item, suggestModerateActions));
 | 
							Ui::show(Box<DeleteMessagesBox>(item, suggestModerateActions));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1060,11 +1014,7 @@ void MainWidget::cancelUploadLayer() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Auth().uploader().pause(item->fullId());
 | 
						Auth().uploader().pause(item->fullId());
 | 
				
			||||||
	Ui::show(Box<ConfirmBox>(lang(lng_selected_cancel_sure_this), lang(lng_selected_upload_stop), lang(lng_continue), base::lambda_guarded(this, [this] {
 | 
						Ui::show(Box<ConfirmBox>(lang(lng_selected_cancel_sure_this), lang(lng_selected_upload_stop), lang(lng_continue), base::lambda_guarded(this, [this] {
 | 
				
			||||||
		if (_overview) {
 | 
					 | 
				
			||||||
			_overview->deleteContextItem(false);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
		_history->deleteContextItem(false);
 | 
							_history->deleteContextItem(false);
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		Auth().uploader().unpause();
 | 
							Auth().uploader().unpause();
 | 
				
			||||||
	}), base::lambda_guarded(this, [] {
 | 
						}), base::lambda_guarded(this, [] {
 | 
				
			||||||
		Auth().uploader().unpause();
 | 
							Auth().uploader().unpause();
 | 
				
			||||||
| 
						 | 
					@ -1473,27 +1423,15 @@ void MainWidget::onCacheBackground() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::forwardSelectedItems() {
 | 
					void MainWidget::forwardSelectedItems() {
 | 
				
			||||||
	if (_overview) {
 | 
					 | 
				
			||||||
		_overview->onForwardSelected();
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
	_history->onForwardSelected();
 | 
						_history->onForwardSelected();
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::confirmDeleteSelectedItems() {
 | 
					void MainWidget::confirmDeleteSelectedItems() {
 | 
				
			||||||
	if (_overview) {
 | 
					 | 
				
			||||||
		_overview->confirmDeleteSelectedItems();
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
	_history->confirmDeleteSelectedItems();
 | 
						_history->confirmDeleteSelectedItems();
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::clearSelectedItems() {
 | 
					void MainWidget::clearSelectedItems() {
 | 
				
			||||||
	if (_overview) {
 | 
					 | 
				
			||||||
		_overview->onClearSelected();
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
	_history->onClearSelected();
 | 
						_history->onClearSelected();
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Dialogs::IndexedList *MainWidget::contactsList() {
 | 
					Dialogs::IndexedList *MainWidget::contactsList() {
 | 
				
			||||||
| 
						 | 
					@ -1682,11 +1620,32 @@ bool MainWidget::preloadOverview(PeerData *peer, MediaOverviewType type) {
 | 
				
			||||||
		return false;
 | 
							return false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_overviewPreload[type].insert(peer, MTP::send(MTPmessages_Search(MTP_flags(0), peer->input, MTP_string(""), MTP_inputUserEmpty(), filter, MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0), MTP_int(0)), rpcDone(&MainWidget::overviewPreloaded, peer), rpcFail(&MainWidget::overviewFailed, peer), 0, 10));
 | 
						auto request = MTPmessages_Search(
 | 
				
			||||||
 | 
							MTP_flags(0),
 | 
				
			||||||
 | 
							peer->input,
 | 
				
			||||||
 | 
							MTP_string(""),
 | 
				
			||||||
 | 
							MTP_inputUserEmpty(),
 | 
				
			||||||
 | 
							filter,
 | 
				
			||||||
 | 
							MTP_int(0),
 | 
				
			||||||
 | 
							MTP_int(0),
 | 
				
			||||||
 | 
							MTP_int(0),
 | 
				
			||||||
 | 
							MTP_int(0),
 | 
				
			||||||
 | 
							MTP_int(0),
 | 
				
			||||||
 | 
							MTP_int(0),
 | 
				
			||||||
 | 
							MTP_int(0));
 | 
				
			||||||
 | 
						_overviewPreload[type].insert(peer, MTP::send(
 | 
				
			||||||
 | 
							request,
 | 
				
			||||||
 | 
							rpcDone(&MainWidget::overviewPreloaded, peer),
 | 
				
			||||||
 | 
							rpcFail(&MainWidget::overviewFailed, peer),
 | 
				
			||||||
 | 
							0,
 | 
				
			||||||
 | 
							10));
 | 
				
			||||||
	return true;
 | 
						return true;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &result, mtpRequestId req) {
 | 
					void MainWidget::overviewPreloaded(
 | 
				
			||||||
 | 
							PeerData *peer,
 | 
				
			||||||
 | 
							const MTPmessages_Messages &result,
 | 
				
			||||||
 | 
							mtpRequestId req) {
 | 
				
			||||||
	MediaOverviewType type = OverviewCount;
 | 
						MediaOverviewType type = OverviewCount;
 | 
				
			||||||
	for (int32 i = 0; i < OverviewCount; ++i) {
 | 
						for (int32 i = 0; i < OverviewCount; ++i) {
 | 
				
			||||||
		OverviewsPreload::iterator j = _overviewPreload[i].find(peer);
 | 
							OverviewsPreload::iterator j = _overviewPreload[i].find(peer);
 | 
				
			||||||
| 
						 | 
					@ -1705,13 +1664,6 @@ void MainWidget::overviewPreloaded(PeerData *peer, const MTPmessages_Messages &r
 | 
				
			||||||
	Notify::mediaOverviewUpdated(peer, type);
 | 
						Notify::mediaOverviewUpdated(peer, type);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::mediaOverviewUpdated(const Notify::PeerUpdate &update) {
 | 
					 | 
				
			||||||
	auto peer = update.peer;
 | 
					 | 
				
			||||||
	if (_overview && (_overview->peer() == peer || _overview->peer()->migrateFrom() == peer)) {
 | 
					 | 
				
			||||||
		_overview->mediaOverviewUpdated(update);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MainWidget::itemEdited(HistoryItem *item) {
 | 
					void MainWidget::itemEdited(HistoryItem *item) {
 | 
				
			||||||
	if (_history->peer() == item->history()->peer || (_history->peer() && _history->peer() == item->history()->peer->migrateTo())) {
 | 
						if (_history->peer() == item->history()->peer || (_history->peer() && _history->peer() == item->history()->peer->migrateTo())) {
 | 
				
			||||||
		_history->itemEdited(item);
 | 
							_history->itemEdited(item);
 | 
				
			||||||
| 
						 | 
					@ -2123,11 +2075,6 @@ void MainWidget::mediaMarkRead(not_null<HistoryItem*> item) {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::updateOnlineDisplay() {
 | 
					 | 
				
			||||||
	if (this != App::main()) return;
 | 
					 | 
				
			||||||
	_history->updateOnlineDisplay();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MainWidget::onSendFileConfirm(const FileLoadResultPtr &file) {
 | 
					void MainWidget::onSendFileConfirm(const FileLoadResultPtr &file) {
 | 
				
			||||||
	_history->sendFileConfirmed(file);
 | 
						_history->sendFileConfirmed(file);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2274,8 +2221,6 @@ void MainWidget::setInnerFocus() {
 | 
				
			||||||
	if (_hider || !_history->peer()) {
 | 
						if (_hider || !_history->peer()) {
 | 
				
			||||||
		if (_hider && _hider->wasOffered()) {
 | 
							if (_hider && _hider->wasOffered()) {
 | 
				
			||||||
			_hider->setFocus();
 | 
								_hider->setFocus();
 | 
				
			||||||
		} else if (!_hider && _overview) {
 | 
					 | 
				
			||||||
			_overview->activate();
 | 
					 | 
				
			||||||
		} else if (!_hider && _mainSection) {
 | 
							} else if (!_hider && _mainSection) {
 | 
				
			||||||
			_mainSection->setInnerFocus();
 | 
								_mainSection->setInnerFocus();
 | 
				
			||||||
		} else if (!_hider && _thirdSection) {
 | 
							} else if (!_hider && _thirdSection) {
 | 
				
			||||||
| 
						 | 
					@ -2283,8 +2228,6 @@ void MainWidget::setInnerFocus() {
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			dialogsActivate();
 | 
								dialogsActivate();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (_overview) {
 | 
					 | 
				
			||||||
		_overview->activate();
 | 
					 | 
				
			||||||
	} else if (_mainSection) {
 | 
						} else if (_mainSection) {
 | 
				
			||||||
		_mainSection->setInnerFocus();
 | 
							_mainSection->setInnerFocus();
 | 
				
			||||||
	} else if (_history->peer() || !_thirdSection) {
 | 
						} else if (_history->peer() || !_thirdSection) {
 | 
				
			||||||
| 
						 | 
					@ -2465,7 +2408,6 @@ void MainWidget::ui_showPeerHistory(
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (_history->isHidden()) {
 | 
							if (_history->isHidden()) {
 | 
				
			||||||
			return (_mainSection != nullptr)
 | 
								return (_mainSection != nullptr)
 | 
				
			||||||
				|| (_overview != nullptr)
 | 
					 | 
				
			||||||
				|| (Adaptive::OneColumn() && !_dialogs->isHidden());
 | 
									|| (Adaptive::OneColumn() && !_dialogs->isHidden());
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (back || way == Way::Forward) {
 | 
							if (back || way == Way::Forward) {
 | 
				
			||||||
| 
						 | 
					@ -2493,20 +2435,11 @@ void MainWidget::ui_showPeerHistory(
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	auto noPeer = !_history->peer();
 | 
						auto noPeer = !_history->peer();
 | 
				
			||||||
	auto onlyDialogs = noPeer && Adaptive::OneColumn();
 | 
						auto onlyDialogs = noPeer && Adaptive::OneColumn();
 | 
				
			||||||
	if (_mainSection || _overview) {
 | 
					 | 
				
			||||||
	if (_mainSection) {
 | 
						if (_mainSection) {
 | 
				
			||||||
		_mainSection->hide();
 | 
							_mainSection->hide();
 | 
				
			||||||
		_mainSection->deleteLater();
 | 
							_mainSection->deleteLater();
 | 
				
			||||||
		_mainSection = nullptr;
 | 
							_mainSection = nullptr;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
		if (_overview) {
 | 
					 | 
				
			||||||
			_overview->hide();
 | 
					 | 
				
			||||||
			_overview->clear();
 | 
					 | 
				
			||||||
			_overview->deleteLater();
 | 
					 | 
				
			||||||
			_overview->rpcClear();
 | 
					 | 
				
			||||||
			_overview = nullptr;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	updateControlsGeometry();
 | 
						updateControlsGeometry();
 | 
				
			||||||
	if (onlyDialogs) {
 | 
						if (onlyDialogs) {
 | 
				
			||||||
| 
						 | 
					@ -2584,7 +2517,7 @@ void MainWidget::peerAfter(const PeerData *inPeer, MsgId inMsg, PeerData *&outPe
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PeerData *MainWidget::peer() {
 | 
					PeerData *MainWidget::peer() {
 | 
				
			||||||
	return _overview ? _overview->peer() : _history->peer();
 | 
						return _history->peer();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PeerData *MainWidget::activePeer() {
 | 
					PeerData *MainWidget::activePeer() {
 | 
				
			||||||
| 
						 | 
					@ -2595,22 +2528,8 @@ MsgId MainWidget::activeMsgId() {
 | 
				
			||||||
	return _history->peer() ? _history->msgId() : _msgIdInStack;
 | 
						return _history->peer() ? _history->msgId() : _msgIdInStack;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
PeerData *MainWidget::overviewPeer() {
 | 
					 | 
				
			||||||
	return _overview ? _overview->peer() : 0;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool MainWidget::showMediaTypeSwitch() const {
 | 
					 | 
				
			||||||
	return _overview ? _overview->showMediaTypeSwitch() : false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MainWidget::saveSectionInStack() {
 | 
					void MainWidget::saveSectionInStack() {
 | 
				
			||||||
	if (_overview) {
 | 
						if (_mainSection) {
 | 
				
			||||||
		_stack.push_back(std::make_unique<StackItemOverview>(
 | 
					 | 
				
			||||||
			_overview->peer(),
 | 
					 | 
				
			||||||
			_overview->type(),
 | 
					 | 
				
			||||||
			_overview->lastWidth(),
 | 
					 | 
				
			||||||
			_overview->lastScrollTop()));
 | 
					 | 
				
			||||||
	} else if (_mainSection) {
 | 
					 | 
				
			||||||
		if (auto memento = _mainSection->createMemento()) {
 | 
							if (auto memento = _mainSection->createMemento()) {
 | 
				
			||||||
			_stack.push_back(std::make_unique<StackItemSection>(
 | 
								_stack.push_back(std::make_unique<StackItemSection>(
 | 
				
			||||||
				std::move(memento)));
 | 
									std::move(memento)));
 | 
				
			||||||
| 
						 | 
					@ -2625,77 +2544,6 @@ void MainWidget::saveSectionInStack() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::showMediaOverview(PeerData *peer, MediaOverviewType type, bool back, int32 lastScrollTop) {
 | 
					 | 
				
			||||||
	if (peer->migrateTo()) {
 | 
					 | 
				
			||||||
		peer = peer->migrateTo();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Ui::hideSettingsAndLayer();
 | 
					 | 
				
			||||||
	if (_overview && _overview->peer() == peer) {
 | 
					 | 
				
			||||||
		if (_overview->type() != type) {
 | 
					 | 
				
			||||||
			_overview->switchType(type);
 | 
					 | 
				
			||||||
		} else if (type == OverviewMusicFiles) { // hack for player
 | 
					 | 
				
			||||||
			_controller->showBackFromStack();
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_controller->dialogsListFocused().set(false, true);
 | 
					 | 
				
			||||||
	_a_dialogsWidth.finish();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	auto animatedShow = [this] {
 | 
					 | 
				
			||||||
		if (_a_show.animating() || App::passcoded()) {
 | 
					 | 
				
			||||||
			return false;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		if (Adaptive::OneColumn() || isMainSectionShown()) {
 | 
					 | 
				
			||||||
			return true;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return false;
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	auto animationParams = animatedShow() ? prepareOverviewAnimation() : Window::SectionSlideParams();
 | 
					 | 
				
			||||||
	setFocus(); // otherwise dialogs widget could be focused.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (!back) {
 | 
					 | 
				
			||||||
		saveSectionInStack();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (_overview) {
 | 
					 | 
				
			||||||
		_overview->hide();
 | 
					 | 
				
			||||||
		_overview->clear();
 | 
					 | 
				
			||||||
		_overview->deleteLater();
 | 
					 | 
				
			||||||
		_overview->rpcClear();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	if (_mainSection) {
 | 
					 | 
				
			||||||
		_mainSection->hide();
 | 
					 | 
				
			||||||
		_mainSection->deleteLater();
 | 
					 | 
				
			||||||
		_mainSection = nullptr;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_overview.create(this, _controller, peer, type);
 | 
					 | 
				
			||||||
	updateControlsGeometry();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Send a fake update.
 | 
					 | 
				
			||||||
	Notify::PeerUpdate update(peer);
 | 
					 | 
				
			||||||
	update.flags |= Notify::PeerUpdate::Flag::SharedMediaChanged;
 | 
					 | 
				
			||||||
	update.mediaTypesMask |= (1 << type);
 | 
					 | 
				
			||||||
	mediaOverviewUpdated(update);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	_overview->setLastScrollTop(lastScrollTop);
 | 
					 | 
				
			||||||
	if (!animationParams.oldContentCache.isNull()) {
 | 
					 | 
				
			||||||
		_overview->showAnimated(back ? Window::SlideDirection::FromLeft : Window::SlideDirection::FromRight, animationParams);
 | 
					 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		_overview->fastShow();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_history->finishAnimating();
 | 
					 | 
				
			||||||
	if (back) {
 | 
					 | 
				
			||||||
		clearBotStartToken(_history->peer());
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_history->showHistory(0, 0);
 | 
					 | 
				
			||||||
	_history->hide();
 | 
					 | 
				
			||||||
	if (Adaptive::OneColumn()) _dialogs->hide();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	checkFloatPlayerVisibility();
 | 
					 | 
				
			||||||
	orderWidgets();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MainWidget::showSection(
 | 
					void MainWidget::showSection(
 | 
				
			||||||
		Window::SectionMemento &&memento,
 | 
							Window::SectionMemento &&memento,
 | 
				
			||||||
		const SectionShow ¶ms) {
 | 
							const SectionShow ¶ms) {
 | 
				
			||||||
| 
						 | 
					@ -2754,7 +2602,7 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(
 | 
				
			||||||
		if (!_mainSection->hasTopBarShadow()) {
 | 
							if (!_mainSection->hasTopBarShadow()) {
 | 
				
			||||||
			result.withTopBarShadow = false;
 | 
								result.withTopBarShadow = false;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	} else if (!_overview && !_history->peer()) {
 | 
						} else if (!_history->peer()) {
 | 
				
			||||||
		result.withTopBarShadow = false;
 | 
							result.withTopBarShadow = false;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2788,10 +2636,8 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(
 | 
				
			||||||
		result.oldContentCache = _mainSection->grabForShowAnimation(result);
 | 
							result.oldContentCache = _mainSection->grabForShowAnimation(result);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (result.withTopBarShadow) {
 | 
							if (result.withTopBarShadow) {
 | 
				
			||||||
			if (_overview) _overview->grapWithoutTopBarShadow();
 | 
					 | 
				
			||||||
			_history->grapWithoutTopBarShadow();
 | 
								_history->grapWithoutTopBarShadow();
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			if (_overview) _overview->grabStart();
 | 
					 | 
				
			||||||
			_history->grabStart();
 | 
								_history->grabStart();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (Adaptive::OneColumn()) {
 | 
							if (Adaptive::OneColumn()) {
 | 
				
			||||||
| 
						 | 
					@ -2815,7 +2661,6 @@ Window::SectionSlideParams MainWidget::prepareShowAnimation(
 | 
				
			||||||
				_thirdShadow->show();
 | 
									_thirdShadow->show();
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if (_overview) _overview->grabFinish();
 | 
					 | 
				
			||||||
		_history->grabFinish();
 | 
							_history->grabFinish();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2848,10 +2693,6 @@ Window::SectionSlideParams MainWidget::prepareHistoryAnimation(PeerId historyPee
 | 
				
			||||||
	return prepareShowAnimation(historyPeerId != 0);
 | 
						return prepareShowAnimation(historyPeerId != 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Window::SectionSlideParams MainWidget::prepareOverviewAnimation() {
 | 
					 | 
				
			||||||
	return prepareShowAnimation(true);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Window::SectionSlideParams MainWidget::prepareDialogsAnimation() {
 | 
					Window::SectionSlideParams MainWidget::prepareDialogsAnimation() {
 | 
				
			||||||
	return prepareShowAnimation(false);
 | 
						return prepareShowAnimation(false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2934,13 +2775,6 @@ void MainWidget::showNewSection(
 | 
				
			||||||
		// This may modify the current section, for example remove its contents.
 | 
							// This may modify the current section, for example remove its contents.
 | 
				
			||||||
		saveSectionInStack();
 | 
							saveSectionInStack();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (_overview) {
 | 
					 | 
				
			||||||
		_overview->hide();
 | 
					 | 
				
			||||||
		_overview->clear();
 | 
					 | 
				
			||||||
		_overview->deleteLater();
 | 
					 | 
				
			||||||
		_overview->rpcClear();
 | 
					 | 
				
			||||||
		_overview = nullptr;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	auto &settingSection = newThirdSection
 | 
						auto &settingSection = newThirdSection
 | 
				
			||||||
		? _thirdSection
 | 
							? _thirdSection
 | 
				
			||||||
		: _mainSection;
 | 
							: _mainSection;
 | 
				
			||||||
| 
						 | 
					@ -3009,7 +2843,7 @@ void MainWidget::dropMainSection(Window::SectionWidget *widget) {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MainWidget::isMainSectionShown() const {
 | 
					bool MainWidget::isMainSectionShown() const {
 | 
				
			||||||
	return _mainSection || _overview || _history->peer();
 | 
						return _mainSection || _history->peer();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MainWidget::isThirdSectionShown() const {
 | 
					bool MainWidget::isThirdSectionShown() const {
 | 
				
			||||||
| 
						 | 
					@ -3057,13 +2891,6 @@ void MainWidget::showBackFromStack(
 | 
				
			||||||
		showNewSection(
 | 
							showNewSection(
 | 
				
			||||||
			std::move(*sectionItem->memento()),
 | 
								std::move(*sectionItem->memento()),
 | 
				
			||||||
			params.withWay(SectionShow::Way::Backward));
 | 
								params.withWay(SectionShow::Way::Backward));
 | 
				
			||||||
	} else if (item->type() == OverviewStackItem) {
 | 
					 | 
				
			||||||
		auto overviewItem = static_cast<StackItemOverview*>(item.get());
 | 
					 | 
				
			||||||
		showMediaOverview(
 | 
					 | 
				
			||||||
			overviewItem->peer(),
 | 
					 | 
				
			||||||
			overviewItem->mediaType,
 | 
					 | 
				
			||||||
			true,
 | 
					 | 
				
			||||||
			overviewItem->lastScrollTop);
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (auto memento = item->thirdSectionMemento()) {
 | 
						if (auto memento = item->thirdSectionMemento()) {
 | 
				
			||||||
		if (_thirdSection) {
 | 
							if (_thirdSection) {
 | 
				
			||||||
| 
						 | 
					@ -3299,9 +3126,6 @@ void MainWidget::hideAll() {
 | 
				
			||||||
	if (_thirdSection) {
 | 
						if (_thirdSection) {
 | 
				
			||||||
		_thirdSection->hide();
 | 
							_thirdSection->hide();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (_overview) {
 | 
					 | 
				
			||||||
		_overview->hide();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	_sideShadow->hide();
 | 
						_sideShadow->hide();
 | 
				
			||||||
	if (_thirdShadow) {
 | 
						if (_thirdShadow) {
 | 
				
			||||||
		_thirdShadow->hide();
 | 
							_thirdShadow->hide();
 | 
				
			||||||
| 
						 | 
					@ -3337,10 +3161,7 @@ void MainWidget::showAll() {
 | 
				
			||||||
		if (selectingPeer()) {
 | 
							if (selectingPeer()) {
 | 
				
			||||||
			_dialogs->showFast();
 | 
								_dialogs->showFast();
 | 
				
			||||||
			_history->hide();
 | 
								_history->hide();
 | 
				
			||||||
			if (_overview) _overview->hide();
 | 
					 | 
				
			||||||
			if (_mainSection) _mainSection->hide();
 | 
								if (_mainSection) _mainSection->hide();
 | 
				
			||||||
		} else if (_overview) {
 | 
					 | 
				
			||||||
			_overview->show();
 | 
					 | 
				
			||||||
		} else if (_mainSection) {
 | 
							} else if (_mainSection) {
 | 
				
			||||||
			_mainSection->show();
 | 
								_mainSection->show();
 | 
				
			||||||
		} else if (_history->peer()) {
 | 
							} else if (_history->peer()) {
 | 
				
			||||||
| 
						 | 
					@ -3370,9 +3191,7 @@ void MainWidget::showAll() {
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		_dialogs->showFast();
 | 
							_dialogs->showFast();
 | 
				
			||||||
		if (_overview) {
 | 
							if (_mainSection) {
 | 
				
			||||||
			_overview->show();
 | 
					 | 
				
			||||||
		} else if (_mainSection) {
 | 
					 | 
				
			||||||
			_mainSection->show();
 | 
								_mainSection->show();
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			_history->show();
 | 
								_history->show();
 | 
				
			||||||
| 
						 | 
					@ -3487,7 +3306,6 @@ void MainWidget::updateControlsGeometry() {
 | 
				
			||||||
		auto mainSectionGeometry = QRect(_history->x(), mainSectionTop, _history->width(), height() - mainSectionTop);
 | 
							auto mainSectionGeometry = QRect(_history->x(), mainSectionTop, _history->width(), height() - mainSectionTop);
 | 
				
			||||||
		_mainSection->setGeometryWithTopMoved(mainSectionGeometry, _contentScrollAddToY);
 | 
							_mainSection->setGeometryWithTopMoved(mainSectionGeometry, _contentScrollAddToY);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if (_overview) _overview->setGeometry(_history->geometry());
 | 
					 | 
				
			||||||
	refreshResizeAreas();
 | 
						refreshResizeAreas();
 | 
				
			||||||
	updateMediaPlayerPosition();
 | 
						updateMediaPlayerPosition();
 | 
				
			||||||
	updateMediaPlaylistPosition(_playerPlaylist->x());
 | 
						updateMediaPlaylistPosition(_playerPlaylist->x());
 | 
				
			||||||
| 
						 | 
					@ -3689,7 +3507,6 @@ bool MainWidget::eventFilter(QObject *o, QEvent *e) {
 | 
				
			||||||
	if (e->type() == QEvent::FocusIn) {
 | 
						if (e->type() == QEvent::FocusIn) {
 | 
				
			||||||
		if (auto widget = qobject_cast<QWidget*>(o)) {
 | 
							if (auto widget = qobject_cast<QWidget*>(o)) {
 | 
				
			||||||
			if (_history == widget || _history->isAncestorOf(widget)
 | 
								if (_history == widget || _history->isAncestorOf(widget)
 | 
				
			||||||
				|| (_overview && (_overview == widget || _overview->isAncestorOf(widget)))
 | 
					 | 
				
			||||||
				|| (_mainSection && (_mainSection == widget || _mainSection->isAncestorOf(widget)))
 | 
									|| (_mainSection && (_mainSection == widget || _mainSection->isAncestorOf(widget)))
 | 
				
			||||||
				|| (_thirdSection && (_thirdSection == widget || _thirdSection->isAncestorOf(widget)))) {
 | 
									|| (_thirdSection && (_thirdSection == widget || _thirdSection->isAncestorOf(widget)))) {
 | 
				
			||||||
				_controller->dialogsListFocused().set(false);
 | 
									_controller->dialogsListFocused().set(false);
 | 
				
			||||||
| 
						 | 
					@ -3782,28 +3599,6 @@ void MainWidget::updateWindowAdaptiveLayout() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MainWidget::paintTopBar(Painter &p, int decreaseWidth, TimeMs ms) {
 | 
					 | 
				
			||||||
	if (_overview) {
 | 
					 | 
				
			||||||
		return _overview->paintTopBar(p, decreaseWidth);
 | 
					 | 
				
			||||||
	} else if (!_mainSection) {
 | 
					 | 
				
			||||||
		return _history->paintTopBar(p, decreaseWidth, ms);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return false;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
QRect MainWidget::getMembersShowAreaGeometry() const {
 | 
					 | 
				
			||||||
	if (!_overview && !_mainSection) {
 | 
					 | 
				
			||||||
		return _history->getMembersShowAreaGeometry();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return QRect();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void MainWidget::setMembersShowAreaActive(bool active) {
 | 
					 | 
				
			||||||
	if (!active || (!_overview && !_mainSection)) {
 | 
					 | 
				
			||||||
		_history->setMembersShowAreaActive(active);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
int MainWidget::backgroundFromY() const {
 | 
					int MainWidget::backgroundFromY() const {
 | 
				
			||||||
	return -getMainSectionTop();
 | 
						return -getMainSectionTop();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -4406,7 +4201,6 @@ void MainWidget::onSelfParticipantUpdated(ChannelData *channel) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MainWidget::contentOverlapped(const QRect &globalRect) {
 | 
					bool MainWidget::contentOverlapped(const QRect &globalRect) {
 | 
				
			||||||
	return (_history->contentOverlapped(globalRect)
 | 
						return (_history->contentOverlapped(globalRect)
 | 
				
			||||||
			|| (_overview && _overview->contentOverlapped(globalRect))
 | 
					 | 
				
			||||||
			|| _playerPanel->overlaps(globalRect)
 | 
								|| _playerPanel->overlaps(globalRect)
 | 
				
			||||||
			|| _playerPlaylist->overlaps(globalRect)
 | 
								|| _playerPlaylist->overlaps(globalRect)
 | 
				
			||||||
			|| (_playerVolume && _playerVolume->overlaps(globalRect)));
 | 
								|| (_playerVolume && _playerVolume->overlaps(globalRect)));
 | 
				
			||||||
| 
						 | 
					@ -4745,7 +4539,7 @@ void MainWidget::incrementSticker(DocumentData *sticker) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::activate() {
 | 
					void MainWidget::activate() {
 | 
				
			||||||
	if (_a_show.animating()) return;
 | 
						if (_a_show.animating()) return;
 | 
				
			||||||
	if (!_mainSection && !_overview) {
 | 
						if (!_mainSection) {
 | 
				
			||||||
		if (_hider) {
 | 
							if (_hider) {
 | 
				
			||||||
			if (_hider->wasOffered()) {
 | 
								if (_hider->wasOffered()) {
 | 
				
			||||||
				_hider->setFocus();
 | 
									_hider->setFocus();
 | 
				
			||||||
| 
						 | 
					@ -4770,20 +4564,16 @@ void MainWidget::destroyData() {
 | 
				
			||||||
	_dialogs->destroyData();
 | 
						_dialogs->destroyData();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void MainWidget::updateOnlineDisplayIn(int32 msecs) {
 | 
					 | 
				
			||||||
	_onlineUpdater.start(msecs);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
bool MainWidget::isActive() const {
 | 
					bool MainWidget::isActive() const {
 | 
				
			||||||
	return !_isIdle && isVisible() && !_a_show.animating();
 | 
						return !_isIdle && isVisible() && !_a_show.animating();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MainWidget::doWeReadServerHistory() const {
 | 
					bool MainWidget::doWeReadServerHistory() const {
 | 
				
			||||||
	return isActive() && !_mainSection && !_overview && _history->doWeReadServerHistory();
 | 
						return isActive() && !_mainSection && _history->doWeReadServerHistory();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MainWidget::doWeReadMentions() const {
 | 
					bool MainWidget::doWeReadMentions() const {
 | 
				
			||||||
	return isActive() && !_mainSection && !_overview && _history->doWeReadMentions();
 | 
						return isActive() && !_mainSection && _history->doWeReadMentions();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool MainWidget::lastWasOnline() const {
 | 
					bool MainWidget::lastWasOnline() const {
 | 
				
			||||||
| 
						 | 
					@ -4827,7 +4617,9 @@ void MainWidget::updateOnline(bool gotOtherOffline) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	auto ms = getms(true);
 | 
						auto ms = getms(true);
 | 
				
			||||||
	if (isOnline != _lastWasOnline || (isOnline && _lastSetOnline + Global::OnlineUpdatePeriod() <= ms) || (isOnline && gotOtherOffline)) {
 | 
						if (isOnline != _lastWasOnline
 | 
				
			||||||
 | 
							|| (isOnline && _lastSetOnline + Global::OnlineUpdatePeriod() <= ms)
 | 
				
			||||||
 | 
							|| (isOnline && gotOtherOffline)) {
 | 
				
			||||||
		if (_onlineRequest) {
 | 
							if (_onlineRequest) {
 | 
				
			||||||
			MTP::cancel(_onlineRequest);
 | 
								MTP::cancel(_onlineRequest);
 | 
				
			||||||
			_onlineRequest = 0;
 | 
								_onlineRequest = 0;
 | 
				
			||||||
| 
						 | 
					@ -4846,8 +4638,6 @@ void MainWidget::updateOnline(bool gotOtherOffline) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		_lastSetOnline = ms;
 | 
							_lastSetOnline = ms;
 | 
				
			||||||
 | 
					 | 
				
			||||||
		updateOnlineDisplay();
 | 
					 | 
				
			||||||
	} else if (isOnline) {
 | 
						} else if (isOnline) {
 | 
				
			||||||
		updateIn = qMin(updateIn, int(_lastSetOnline + Global::OnlineUpdatePeriod() - ms));
 | 
							updateIn = qMin(updateIn, int(_lastSetOnline + Global::OnlineUpdatePeriod() - ms));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,6 @@ class SlideWrap;
 | 
				
			||||||
namespace Window {
 | 
					namespace Window {
 | 
				
			||||||
class Controller;
 | 
					class Controller;
 | 
				
			||||||
class PlayerWrapWidget;
 | 
					class PlayerWrapWidget;
 | 
				
			||||||
class TopBarWidget;
 | 
					 | 
				
			||||||
class SectionMemento;
 | 
					class SectionMemento;
 | 
				
			||||||
class SectionWidget;
 | 
					class SectionWidget;
 | 
				
			||||||
class AbstractSectionWidget;
 | 
					class AbstractSectionWidget;
 | 
				
			||||||
| 
						 | 
					@ -72,7 +71,6 @@ class MainWindow;
 | 
				
			||||||
class ConfirmBox;
 | 
					class ConfirmBox;
 | 
				
			||||||
class DialogsWidget;
 | 
					class DialogsWidget;
 | 
				
			||||||
class HistoryWidget;
 | 
					class HistoryWidget;
 | 
				
			||||||
class OverviewWidget;
 | 
					 | 
				
			||||||
class HistoryHider;
 | 
					class HistoryHider;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StackItem;
 | 
					class StackItem;
 | 
				
			||||||
| 
						 | 
					@ -105,11 +103,6 @@ public:
 | 
				
			||||||
	bool isMainSectionShown() const;
 | 
						bool isMainSectionShown() const;
 | 
				
			||||||
	bool isThirdSectionShown() const;
 | 
						bool isThirdSectionShown() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Temporary methods, while top bar was not done inside HistoryWidget / OverviewWidget.
 | 
					 | 
				
			||||||
	bool paintTopBar(Painter &, int decreaseWidth, TimeMs ms);
 | 
					 | 
				
			||||||
	QRect getMembersShowAreaGeometry() const;
 | 
					 | 
				
			||||||
	void setMembersShowAreaActive(bool active);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int contentScrollAddToY() const;
 | 
						int contentScrollAddToY() const;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void showAnimated(const QPixmap &bgAnimCache, bool back = false);
 | 
						void showAnimated(const QPixmap &bgAnimCache, bool back = false);
 | 
				
			||||||
| 
						 | 
					@ -156,17 +149,10 @@ public:
 | 
				
			||||||
	MsgId activeMsgId();
 | 
						MsgId activeMsgId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int backgroundFromY() const;
 | 
						int backgroundFromY() const;
 | 
				
			||||||
	PeerData *overviewPeer();
 | 
					 | 
				
			||||||
	bool showMediaTypeSwitch() const;
 | 
					 | 
				
			||||||
	void showSection(
 | 
						void showSection(
 | 
				
			||||||
		Window::SectionMemento &&memento,
 | 
							Window::SectionMemento &&memento,
 | 
				
			||||||
		const SectionShow ¶ms);
 | 
							const SectionShow ¶ms);
 | 
				
			||||||
	void updateColumnLayout();
 | 
						void updateColumnLayout();
 | 
				
			||||||
	void showMediaOverview(
 | 
					 | 
				
			||||||
		PeerData *peer,
 | 
					 | 
				
			||||||
		MediaOverviewType type,
 | 
					 | 
				
			||||||
		bool back = false,
 | 
					 | 
				
			||||||
		int32 lastScrollTop = -1);
 | 
					 | 
				
			||||||
	bool stackIsEmpty() const;
 | 
						bool stackIsEmpty() const;
 | 
				
			||||||
	void showBackFromStack(
 | 
						void showBackFromStack(
 | 
				
			||||||
		const SectionShow ¶ms);
 | 
							const SectionShow ¶ms);
 | 
				
			||||||
| 
						 | 
					@ -381,7 +367,6 @@ public slots:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void updateOnline(bool gotOtherOffline = false);
 | 
						void updateOnline(bool gotOtherOffline = false);
 | 
				
			||||||
	void checkIdleFinish();
 | 
						void checkIdleFinish();
 | 
				
			||||||
	void updateOnlineDisplay();
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void onHistoryShown(History *history, MsgId atMsgId);
 | 
						void onHistoryShown(History *history, MsgId atMsgId);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -472,7 +457,6 @@ private:
 | 
				
			||||||
		std::pair<not_null<History*>, MsgId> historyAndStartMsgId,
 | 
							std::pair<not_null<History*>, MsgId> historyAndStartMsgId,
 | 
				
			||||||
		const MTPmessages_Messages &result,
 | 
							const MTPmessages_Messages &result,
 | 
				
			||||||
		mtpRequestId req);
 | 
							mtpRequestId req);
 | 
				
			||||||
	void mediaOverviewUpdated(const Notify::PeerUpdate &update);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Window::SectionSlideParams prepareShowAnimation(
 | 
						Window::SectionSlideParams prepareShowAnimation(
 | 
				
			||||||
		bool willHaveTopBarShadow);
 | 
							bool willHaveTopBarShadow);
 | 
				
			||||||
| 
						 | 
					@ -486,7 +470,6 @@ private:
 | 
				
			||||||
	// All this methods use the prepareShowAnimation().
 | 
						// All this methods use the prepareShowAnimation().
 | 
				
			||||||
	Window::SectionSlideParams prepareMainSectionAnimation(Window::SectionWidget *section);
 | 
						Window::SectionSlideParams prepareMainSectionAnimation(Window::SectionWidget *section);
 | 
				
			||||||
	Window::SectionSlideParams prepareHistoryAnimation(PeerId historyPeerId);
 | 
						Window::SectionSlideParams prepareHistoryAnimation(PeerId historyPeerId);
 | 
				
			||||||
	Window::SectionSlideParams prepareOverviewAnimation();
 | 
					 | 
				
			||||||
	Window::SectionSlideParams prepareDialogsAnimation();
 | 
						Window::SectionSlideParams prepareDialogsAnimation();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void startWithSelf(const MTPUserFull &user);
 | 
						void startWithSelf(const MTPUserFull &user);
 | 
				
			||||||
| 
						 | 
					@ -595,7 +578,6 @@ private:
 | 
				
			||||||
	object_ptr<HistoryWidget> _history;
 | 
						object_ptr<HistoryWidget> _history;
 | 
				
			||||||
	object_ptr<Window::SectionWidget> _mainSection = { nullptr };
 | 
						object_ptr<Window::SectionWidget> _mainSection = { nullptr };
 | 
				
			||||||
	object_ptr<Window::SectionWidget> _thirdSection = { nullptr };
 | 
						object_ptr<Window::SectionWidget> _thirdSection = { nullptr };
 | 
				
			||||||
	object_ptr<OverviewWidget> _overview = { nullptr };
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	base::weak_unique_ptr<Calls::Call> _currentCall;
 | 
						base::weak_unique_ptr<Calls::Call> _currentCall;
 | 
				
			||||||
	object_ptr<Ui::SlideWrap<Calls::TopBar>> _callTopBar = { nullptr };
 | 
						object_ptr<Ui::SlideWrap<Calls::TopBar>> _callTopBar = { nullptr };
 | 
				
			||||||
| 
						 | 
					@ -636,7 +618,7 @@ private:
 | 
				
			||||||
	SingleTimer _byMinChannelTimer;
 | 
						SingleTimer _byMinChannelTimer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mtpRequestId _onlineRequest = 0;
 | 
						mtpRequestId _onlineRequest = 0;
 | 
				
			||||||
	SingleTimer _onlineTimer, _onlineUpdater, _idleFinishTimer;
 | 
						SingleTimer _onlineTimer, _idleFinishTimer;
 | 
				
			||||||
	bool _lastWasOnline = false;
 | 
						bool _lastWasOnline = false;
 | 
				
			||||||
	TimeMs _lastSetOnline = 0;
 | 
						TimeMs _lastSetOnline = 0;
 | 
				
			||||||
	bool _isIdle = false;
 | 
						bool _isIdle = false;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -69,8 +69,6 @@ public:
 | 
				
			||||||
		updateOver(mapFromGlobal(QCursor::pos()));
 | 
							updateOver(mapFromGlobal(QCursor::pos()));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void mediaOverviewUpdated(const Notify::PeerUpdate &update);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void close();
 | 
						void close();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void activateControls();
 | 
						void activateControls();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| 
						 | 
					@ -1,399 +0,0 @@
 | 
				
			||||||
/*
 | 
					 | 
				
			||||||
This file is part of Telegram Desktop,
 | 
					 | 
				
			||||||
the official desktop version of Telegram messaging app, see https://telegram.org
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Telegram Desktop is free software: you can redistribute it and/or modify
 | 
					 | 
				
			||||||
it under the terms of the GNU General Public License as published by
 | 
					 | 
				
			||||||
the Free Software Foundation, either version 3 of the License, or
 | 
					 | 
				
			||||||
(at your option) any later version.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
It is distributed in the hope that it will be useful,
 | 
					 | 
				
			||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					 | 
				
			||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 | 
					 | 
				
			||||||
GNU General Public License for more details.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
In addition, as a special exception, the copyright holders give permission
 | 
					 | 
				
			||||||
to link the code of portions of this program with the OpenSSL library.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
 | 
					 | 
				
			||||||
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
					 | 
				
			||||||
*/
 | 
					 | 
				
			||||||
#pragma once
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#include "window/section_widget.h"
 | 
					 | 
				
			||||||
#include "window/top_bar_widget.h"
 | 
					 | 
				
			||||||
#include "ui/widgets/tooltip.h"
 | 
					 | 
				
			||||||
#include "ui/widgets/scroll_area.h"
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Overview {
 | 
					 | 
				
			||||||
namespace Layout {
 | 
					 | 
				
			||||||
class AbstractItem;
 | 
					 | 
				
			||||||
class ItemBase;
 | 
					 | 
				
			||||||
class Date;
 | 
					 | 
				
			||||||
} // namespace Layout
 | 
					 | 
				
			||||||
} // namespace Overview
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Ui {
 | 
					 | 
				
			||||||
class AbstractButton;
 | 
					 | 
				
			||||||
class PlainShadow;
 | 
					 | 
				
			||||||
class PopupMenu;
 | 
					 | 
				
			||||||
class IconButton;
 | 
					 | 
				
			||||||
class FlatInput;
 | 
					 | 
				
			||||||
class CrossButton;
 | 
					 | 
				
			||||||
class DropdownMenu;
 | 
					 | 
				
			||||||
} // namespace Ui
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Notify {
 | 
					 | 
				
			||||||
struct PeerUpdate;
 | 
					 | 
				
			||||||
} // namespace Notify
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Window {
 | 
					 | 
				
			||||||
class Controller;
 | 
					 | 
				
			||||||
class TopBarWidget;
 | 
					 | 
				
			||||||
} // namespace Window
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class OverviewWidget;
 | 
					 | 
				
			||||||
class OverviewInner : public TWidget, public Ui::AbstractTooltipShower, public RPCSender, private base::Subscriber {
 | 
					 | 
				
			||||||
	Q_OBJECT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	OverviewInner(OverviewWidget *overview, Ui::ScrollArea *scroll, PeerData *peer, MediaOverviewType type);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void activate();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void clear();
 | 
					 | 
				
			||||||
	int32 itemTop(const FullMsgId &msgId) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool preloadLocal();
 | 
					 | 
				
			||||||
	void preloadMore();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void showContextMenu(QContextMenuEvent *e, bool showFromTouch = false);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void dragActionStart(const QPoint &screenPos, Qt::MouseButton button = Qt::LeftButton);
 | 
					 | 
				
			||||||
	void dragActionUpdate(const QPoint &screenPos);
 | 
					 | 
				
			||||||
	void dragActionFinish(const QPoint &screenPos, Qt::MouseButton button = Qt::LeftButton);
 | 
					 | 
				
			||||||
	void dragActionCancel();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void touchScrollUpdated(const QPoint &screenPos);
 | 
					 | 
				
			||||||
	QPoint mapMouseToItem(QPoint p, MsgId itemId, int32 itemIndex);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int32 resizeToWidth(int32 nwidth, int32 scrollTop, int32 minHeight, bool force = false); // returns new scroll top
 | 
					 | 
				
			||||||
	void dropResizeIndex();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PeerData *peer() const;
 | 
					 | 
				
			||||||
	PeerData *migratePeer() const;
 | 
					 | 
				
			||||||
	MediaOverviewType type() const;
 | 
					 | 
				
			||||||
	void switchType(MediaOverviewType type);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void setSelectMode(bool enabled);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void mediaOverviewUpdated();
 | 
					 | 
				
			||||||
	void repaintItem(const HistoryItem *msg);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Window::TopBarWidget::SelectedState getSelectionState() const;
 | 
					 | 
				
			||||||
	void clearSelectedItems(bool onlyTextSelection = false);
 | 
					 | 
				
			||||||
	SelectedItemSet getSelectedItems() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// AbstractTooltipShower interface
 | 
					 | 
				
			||||||
	QString tooltipText() const override;
 | 
					 | 
				
			||||||
	QPoint tooltipPos() const override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	~OverviewInner();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
protected:
 | 
					 | 
				
			||||||
	bool event(QEvent *e) override;
 | 
					 | 
				
			||||||
	void touchEvent(QTouchEvent *e);
 | 
					 | 
				
			||||||
	void paintEvent(QPaintEvent *e) override;
 | 
					 | 
				
			||||||
	void mouseMoveEvent(QMouseEvent *e) override;
 | 
					 | 
				
			||||||
	void mousePressEvent(QMouseEvent *e) override;
 | 
					 | 
				
			||||||
	void mouseReleaseEvent(QMouseEvent *e) override;
 | 
					 | 
				
			||||||
	void keyPressEvent(QKeyEvent *e) override;
 | 
					 | 
				
			||||||
	void enterEventHook(QEvent *e) override;
 | 
					 | 
				
			||||||
	void leaveEventHook(QEvent *e) override;
 | 
					 | 
				
			||||||
	void resizeEvent(QResizeEvent *e) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public slots:
 | 
					 | 
				
			||||||
	void onUpdateSelected();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void copyContextUrl();
 | 
					 | 
				
			||||||
	void cancelContextDownload();
 | 
					 | 
				
			||||||
	void showContextInFolder();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void goToMessage();
 | 
					 | 
				
			||||||
	void forwardMessage();
 | 
					 | 
				
			||||||
	void selectMessage();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void onSearchUpdate();
 | 
					 | 
				
			||||||
	void onCancel();
 | 
					 | 
				
			||||||
	bool onCancelSearch();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void onMenuDestroy(QObject *obj);
 | 
					 | 
				
			||||||
	void onTouchSelect();
 | 
					 | 
				
			||||||
	void onTouchScrollTimer();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool onSearchMessages(bool searchCache = false);
 | 
					 | 
				
			||||||
	void onNeedSearchMessages();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	void saveDocumentToFile(DocumentData *document);
 | 
					 | 
				
			||||||
	void invalidateCache();
 | 
					 | 
				
			||||||
	void resizeItems();
 | 
					 | 
				
			||||||
	void resizeAndRepositionItems();
 | 
					 | 
				
			||||||
	void performDrag();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void itemRemoved(HistoryItem *item);
 | 
					 | 
				
			||||||
	MsgId complexMsgId(const HistoryItem *item) const;
 | 
					 | 
				
			||||||
	void changingMsgId(HistoryItem *row, MsgId newId);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool itemMigrated(MsgId msgId) const;
 | 
					 | 
				
			||||||
	ChannelId itemChannel(MsgId msgId) const;
 | 
					 | 
				
			||||||
	MsgId itemMsgId(MsgId msgId) const;
 | 
					 | 
				
			||||||
	int32 migratedIndexSkip() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void fixItemIndex(int32 ¤t, MsgId msgId) const;
 | 
					 | 
				
			||||||
	bool itemHasPoint(MsgId msgId, int32 index, int32 x, int32 y) const;
 | 
					 | 
				
			||||||
	int32 itemHeight(MsgId msgId, int32 index) const;
 | 
					 | 
				
			||||||
	void moveToNextItem(MsgId &msgId, int32 &index, MsgId upTo, int32 delta) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void updateDragSelection(MsgId dragSelFrom, int32 dragSelFromIndex, MsgId dragSelTo, int32 dragSelToIndex, bool dragSelecting);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void repaintItem(MsgId itemId, int32 itemIndex);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void touchResetSpeed();
 | 
					 | 
				
			||||||
	void touchUpdateSpeed();
 | 
					 | 
				
			||||||
	void touchDeaccelerate(int32 elapsed);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void applyDragSelection();
 | 
					 | 
				
			||||||
	void addSelectionRange(int32 selFrom, int32 selTo, History *history);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void recountMargins();
 | 
					 | 
				
			||||||
	int countHeight();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	OverviewWidget *_overview;
 | 
					 | 
				
			||||||
	Ui::ScrollArea *_scroll;
 | 
					 | 
				
			||||||
	int _resizeIndex = -1;
 | 
					 | 
				
			||||||
	int _resizeSkip = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PeerData *_peer;
 | 
					 | 
				
			||||||
	MediaOverviewType _type;
 | 
					 | 
				
			||||||
	bool _reversed;
 | 
					 | 
				
			||||||
	History *_history;
 | 
					 | 
				
			||||||
	History *_migrated;
 | 
					 | 
				
			||||||
	ChannelId _channel;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool _selMode = false;
 | 
					 | 
				
			||||||
	TextSelection itemSelectedValue(int32 index) const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int _rowsLeft = 0;
 | 
					 | 
				
			||||||
	int _rowWidth = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	typedef QVector<Overview::Layout::AbstractItem*> Items;
 | 
					 | 
				
			||||||
	Items _items;
 | 
					 | 
				
			||||||
	typedef QMap<HistoryItem*, Overview::Layout::ItemBase*> LayoutItems;
 | 
					 | 
				
			||||||
	LayoutItems _layoutItems;
 | 
					 | 
				
			||||||
	typedef QMap<int32, Overview::Layout::Date*> LayoutDates;
 | 
					 | 
				
			||||||
	LayoutDates _layoutDates;
 | 
					 | 
				
			||||||
	Overview::Layout::ItemBase *layoutPrepare(HistoryItem *item);
 | 
					 | 
				
			||||||
	Overview::Layout::AbstractItem *layoutPrepare(const QDate &date, bool month);
 | 
					 | 
				
			||||||
	int32 setLayoutItem(int32 index, Overview::Layout::AbstractItem *item, int32 top);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	object_ptr<Ui::FlatInput> _search;
 | 
					 | 
				
			||||||
	object_ptr<Ui::CrossButton> _cancelSearch;
 | 
					 | 
				
			||||||
	QVector<MsgId> _results;
 | 
					 | 
				
			||||||
	int32 _itemsToBeLoaded;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// photos
 | 
					 | 
				
			||||||
	int32 _photosInRow = 1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QTimer _searchTimer;
 | 
					 | 
				
			||||||
	QString _searchQuery;
 | 
					 | 
				
			||||||
	bool _inSearch = false;
 | 
					 | 
				
			||||||
	bool _searchFull = false;
 | 
					 | 
				
			||||||
	bool _searchFullMigrated = false;
 | 
					 | 
				
			||||||
	mtpRequestId _searchRequest = 0;
 | 
					 | 
				
			||||||
	QList<MsgId> _searchResults;
 | 
					 | 
				
			||||||
	MsgId _lastSearchId = 0;
 | 
					 | 
				
			||||||
	MsgId _lastSearchMigratedId = 0;
 | 
					 | 
				
			||||||
	int _searchedCount = 0;
 | 
					 | 
				
			||||||
	enum SearchRequestType {
 | 
					 | 
				
			||||||
		SearchFromStart,
 | 
					 | 
				
			||||||
		SearchFromOffset,
 | 
					 | 
				
			||||||
		SearchMigratedFromStart,
 | 
					 | 
				
			||||||
		SearchMigratedFromOffset
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	void searchReceived(SearchRequestType type, const MTPmessages_Messages &result, mtpRequestId req);
 | 
					 | 
				
			||||||
	bool searchFailed(SearchRequestType type, const RPCError &error, mtpRequestId req);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	typedef QMap<QString, MTPmessages_Messages> SearchCache;
 | 
					 | 
				
			||||||
	SearchCache _searchCache;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	typedef QMap<mtpRequestId, QString> SearchQueries;
 | 
					 | 
				
			||||||
	SearchQueries _searchQueries;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int _width = 0;
 | 
					 | 
				
			||||||
	int _height = 0;
 | 
					 | 
				
			||||||
	int _minHeight = 0;
 | 
					 | 
				
			||||||
	int _marginTop = 0;
 | 
					 | 
				
			||||||
	int _marginBottom = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QTimer _linkTipTimer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// selection support, like in HistoryWidget
 | 
					 | 
				
			||||||
	style::cursor _cursor = style::cur_default;
 | 
					 | 
				
			||||||
	HistoryCursorState _cursorState = HistoryDefaultCursorState;
 | 
					 | 
				
			||||||
	using SelectedItems = QMap<MsgId, TextSelection>;
 | 
					 | 
				
			||||||
	SelectedItems _selected;
 | 
					 | 
				
			||||||
	enum DragAction {
 | 
					 | 
				
			||||||
		NoDrag = 0x00,
 | 
					 | 
				
			||||||
		PrepareDrag = 0x01,
 | 
					 | 
				
			||||||
		Dragging = 0x02,
 | 
					 | 
				
			||||||
		PrepareSelect = 0x03,
 | 
					 | 
				
			||||||
		Selecting = 0x04,
 | 
					 | 
				
			||||||
	};
 | 
					 | 
				
			||||||
	DragAction _dragAction = NoDrag;
 | 
					 | 
				
			||||||
	QPoint _dragStartPos, _dragPos;
 | 
					 | 
				
			||||||
	MsgId _dragItem = 0;
 | 
					 | 
				
			||||||
	MsgId _selectedMsgId = 0;
 | 
					 | 
				
			||||||
	int _dragItemIndex = -1;
 | 
					 | 
				
			||||||
	MsgId _mousedItem = 0;
 | 
					 | 
				
			||||||
	int _mousedItemIndex = -1;
 | 
					 | 
				
			||||||
	uint16 _dragSymbol;
 | 
					 | 
				
			||||||
	bool _dragWasInactive = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ClickHandlerPtr _contextMenuLnk;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	MsgId _dragSelFrom = 0;
 | 
					 | 
				
			||||||
	MsgId _dragSelTo = 0;
 | 
					 | 
				
			||||||
	int _dragSelFromIndex = -1;
 | 
					 | 
				
			||||||
	int _dragSelToIndex = -1;
 | 
					 | 
				
			||||||
	bool _dragSelecting = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool _touchScroll = false;
 | 
					 | 
				
			||||||
	bool _touchSelect = false;
 | 
					 | 
				
			||||||
	bool _touchInProgress = false;
 | 
					 | 
				
			||||||
	QPoint _touchStart, _touchPrevPos, _touchPos;
 | 
					 | 
				
			||||||
	QTimer _touchSelectTimer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Ui::TouchScrollState _touchScrollState = Ui::TouchScrollState::Manual;
 | 
					 | 
				
			||||||
	bool _touchPrevPosValid = false;
 | 
					 | 
				
			||||||
	bool _touchWaitingAcceleration = false;
 | 
					 | 
				
			||||||
	QPoint _touchSpeed;
 | 
					 | 
				
			||||||
	TimeMs _touchSpeedTime = 0;
 | 
					 | 
				
			||||||
	TimeMs _touchAccelerationTime = 0;
 | 
					 | 
				
			||||||
	TimeMs _touchTime = 0;
 | 
					 | 
				
			||||||
	QTimer _touchScrollTimer;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Ui::PopupMenu *_menu = nullptr;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
class OverviewWidget : public Window::AbstractSectionWidget, public RPCSender {
 | 
					 | 
				
			||||||
	Q_OBJECT
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public:
 | 
					 | 
				
			||||||
	OverviewWidget(QWidget *parent, not_null<Window::Controller*> controller, PeerData *peer, MediaOverviewType type);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void clear();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void scrollBy(int32 add);
 | 
					 | 
				
			||||||
	void scrollReset();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool paintTopBar(Painter &p, int decreaseWidth);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	PeerData *peer() const;
 | 
					 | 
				
			||||||
	PeerData *migratePeer() const;
 | 
					 | 
				
			||||||
	MediaOverviewType type() const;
 | 
					 | 
				
			||||||
	void switchType(MediaOverviewType type);
 | 
					 | 
				
			||||||
	bool showMediaTypeSwitch() const;
 | 
					 | 
				
			||||||
	void updateTopBarSelection();
 | 
					 | 
				
			||||||
	bool contentOverlapped(const QRect &globalRect);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int32 lastWidth() const;
 | 
					 | 
				
			||||||
	int32 lastScrollTop() const;
 | 
					 | 
				
			||||||
	int32 countBestScroll() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void fastShow(bool back = false, int32 lastScrollTop = -1);
 | 
					 | 
				
			||||||
	bool hasTopBarShadow() const {
 | 
					 | 
				
			||||||
		return true;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	void setLastScrollTop(int lastScrollTop);
 | 
					 | 
				
			||||||
	void showAnimated(Window::SlideDirection direction, const Window::SectionSlideParams ¶ms);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void doneShow();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void mediaOverviewUpdated(const Notify::PeerUpdate &update);
 | 
					 | 
				
			||||||
	void itemRemoved(HistoryItem *item);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QPoint clampMousePosition(QPoint point);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void checkSelectingScroll(QPoint point);
 | 
					 | 
				
			||||||
	void noSelectingScroll();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	bool touchScroll(const QPoint &delta);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	SelectedItemSet getSelectedItems() const;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void grabStart() override {
 | 
					 | 
				
			||||||
		_inGrab = true;
 | 
					 | 
				
			||||||
		resizeEvent(0);
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	void grapWithoutTopBarShadow();
 | 
					 | 
				
			||||||
	void grabFinish() override;
 | 
					 | 
				
			||||||
	void rpcClear() override {
 | 
					 | 
				
			||||||
		_inner->rpcClear();
 | 
					 | 
				
			||||||
		RPCSender::rpcClear();
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void confirmDeleteContextItem();
 | 
					 | 
				
			||||||
	void confirmDeleteSelectedItems();
 | 
					 | 
				
			||||||
	void deleteContextItem(bool forEveryone);
 | 
					 | 
				
			||||||
	void deleteSelectedItems(bool forEveryone);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Float player interface.
 | 
					 | 
				
			||||||
	bool wheelEventFromFloatPlayer(QEvent *e) override;
 | 
					 | 
				
			||||||
	QRect rectForFloatPlayer() const override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	~OverviewWidget();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
protected:
 | 
					 | 
				
			||||||
	void resizeEvent(QResizeEvent *e) override;
 | 
					 | 
				
			||||||
	void paintEvent(QPaintEvent *e) override;
 | 
					 | 
				
			||||||
	void contextMenuEvent(QContextMenuEvent *e) override;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
public slots:
 | 
					 | 
				
			||||||
	void activate();
 | 
					 | 
				
			||||||
	void onScroll();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void onScrollTimer();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	void onForwardSelected();
 | 
					 | 
				
			||||||
	void onClearSelected();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
private:
 | 
					 | 
				
			||||||
	void topBarClick();
 | 
					 | 
				
			||||||
	void animationCallback();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	object_ptr<Ui::AbstractButton> _backAnimationButton = { nullptr };
 | 
					 | 
				
			||||||
	object_ptr<Window::TopBarWidget> _topBar;
 | 
					 | 
				
			||||||
	object_ptr<Ui::ScrollArea> _scroll;
 | 
					 | 
				
			||||||
	QPointer<OverviewInner> _inner;
 | 
					 | 
				
			||||||
	bool _noDropResizeIndex = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	object_ptr<Ui::DropdownMenu> _mediaType;
 | 
					 | 
				
			||||||
	int32 _mediaTypeMask = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QString _header;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	Animation _a_show;
 | 
					 | 
				
			||||||
	Window::SlideDirection _showDirection;
 | 
					 | 
				
			||||||
	QPixmap _cacheUnder, _cacheOver;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	int32 _scrollSetAfterShow = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	QTimer _scrollTimer;
 | 
					 | 
				
			||||||
	int32 _scrollDelta = 0;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	object_ptr<Ui::PlainShadow> _topShadow;
 | 
					 | 
				
			||||||
	bool _inGrab = false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
| 
						 | 
					@ -20,7 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
#include "profile/profile_back_button.h"
 | 
					#include "profile/profile_back_button.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "window/top_bar_widget.h"
 | 
					#include "history/history_top_bar_widget.h"
 | 
				
			||||||
#include "styles/style_widgets.h"
 | 
					#include "styles/style_widgets.h"
 | 
				
			||||||
#include "styles/style_window.h"
 | 
					#include "styles/style_window.h"
 | 
				
			||||||
#include "styles/style_profile.h"
 | 
					#include "styles/style_profile.h"
 | 
				
			||||||
| 
						 | 
					@ -54,7 +54,7 @@ void BackButton::paintEvent(QPaintEvent *e) {
 | 
				
			||||||
	p.setPen(st::topBarButton.textFg);
 | 
						p.setPen(st::topBarButton.textFg);
 | 
				
			||||||
	p.drawTextLeft(st::topBarArrowPadding.left(), st::topBarButton.padding.top() + st::topBarButton.textTop, width(), _text);
 | 
						p.drawTextLeft(st::topBarArrowPadding.left(), st::topBarButton.padding.top() + st::topBarButton.textTop, width(), _text);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Window::TopBarWidget::paintUnreadCounter(p, width());
 | 
						HistoryTopBarWidget::paintUnreadCounter(p, width());
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void BackButton::onStateChanged(State was, StateChangeSource source) {
 | 
					void BackButton::onStateChanged(State was, StateChangeSource source) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -145,7 +145,7 @@ void SharedMediaWidget::onMediaChosen() {
 | 
				
			||||||
	for (int i = 0; i < OverviewCount; ++i) {
 | 
						for (int i = 0; i < OverviewCount; ++i) {
 | 
				
			||||||
		auto button = _mediaButtons[i];
 | 
							auto button = _mediaButtons[i];
 | 
				
			||||||
		if (button && button == sender()) {
 | 
							if (button && button == sender()) {
 | 
				
			||||||
			App::main()->showMediaOverview(peer(), static_cast<MediaOverviewType>(i));
 | 
								// SharedMediaShowOverview();
 | 
				
			||||||
			return;
 | 
								return;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -215,6 +215,8 @@
 | 
				
			||||||
<(src_loc)/history/history_service.h
 | 
					<(src_loc)/history/history_service.h
 | 
				
			||||||
<(src_loc)/history/history_service_layout.cpp
 | 
					<(src_loc)/history/history_service_layout.cpp
 | 
				
			||||||
<(src_loc)/history/history_service_layout.h
 | 
					<(src_loc)/history/history_service_layout.h
 | 
				
			||||||
 | 
					<(src_loc)/history/history_top_bar_widget.cpp
 | 
				
			||||||
 | 
					<(src_loc)/history/history_top_bar_widget.h
 | 
				
			||||||
<(src_loc)/history/history_widget.cpp
 | 
					<(src_loc)/history/history_widget.cpp
 | 
				
			||||||
<(src_loc)/history/history_widget.h
 | 
					<(src_loc)/history/history_widget.h
 | 
				
			||||||
<(src_loc)/info/info_content_widget.cpp
 | 
					<(src_loc)/info/info_content_widget.cpp
 | 
				
			||||||
| 
						 | 
					@ -632,8 +634,6 @@
 | 
				
			||||||
<(src_loc)/window/section_memento.h
 | 
					<(src_loc)/window/section_memento.h
 | 
				
			||||||
<(src_loc)/window/section_widget.cpp
 | 
					<(src_loc)/window/section_widget.cpp
 | 
				
			||||||
<(src_loc)/window/section_widget.h
 | 
					<(src_loc)/window/section_widget.h
 | 
				
			||||||
<(src_loc)/window/top_bar_widget.cpp
 | 
					 | 
				
			||||||
<(src_loc)/window/top_bar_widget.h
 | 
					 | 
				
			||||||
<(src_loc)/window/window_controller.cpp
 | 
					<(src_loc)/window/window_controller.cpp
 | 
				
			||||||
<(src_loc)/window/window_controller.h
 | 
					<(src_loc)/window/window_controller.h
 | 
				
			||||||
<(src_loc)/window/window_main_menu.cpp
 | 
					<(src_loc)/window/window_main_menu.cpp
 | 
				
			||||||
| 
						 | 
					@ -682,8 +682,6 @@
 | 
				
			||||||
<(src_loc)/messenger.h
 | 
					<(src_loc)/messenger.h
 | 
				
			||||||
<(src_loc)/observer_peer.cpp
 | 
					<(src_loc)/observer_peer.cpp
 | 
				
			||||||
<(src_loc)/observer_peer.h
 | 
					<(src_loc)/observer_peer.h
 | 
				
			||||||
<(src_loc)/overviewwidget.cpp
 | 
					 | 
				
			||||||
<(src_loc)/overviewwidget.h
 | 
					 | 
				
			||||||
<(src_loc)/passcodewidget.cpp
 | 
					<(src_loc)/passcodewidget.cpp
 | 
				
			||||||
<(src_loc)/passcodewidget.h
 | 
					<(src_loc)/passcodewidget.h
 | 
				
			||||||
<(src_loc)/qt_static_plugins.cpp
 | 
					<(src_loc)/qt_static_plugins.cpp
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue