mirror of https://github.com/procxx/kepka.git
Use Info::Controller for the whole info section.
This commit is contained in:
parent
c9152b0b3a
commit
86ad15612a
|
@ -40,7 +40,7 @@ public:
|
||||||
unique_qptr &operator=(unique_qptr &&other) {
|
unique_qptr &operator=(unique_qptr &&other) {
|
||||||
if (_object != other._object) {
|
if (_object != other._object) {
|
||||||
destroy();
|
destroy();
|
||||||
_object = std::move(other._object);
|
_object = base::take(other._object);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -58,18 +58,17 @@ public:
|
||||||
unique_qptr &operator=(unique_qptr<U> &&other) {
|
unique_qptr &operator=(unique_qptr<U> &&other) {
|
||||||
if (_object != other._object) {
|
if (_object != other._object) {
|
||||||
destroy();
|
destroy();
|
||||||
_object = std::move(other._object);
|
_object = base::take(other._object);
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
unique_qptr &operator=(std::nullptr_t) {
|
unique_qptr &operator=(std::nullptr_t) {
|
||||||
destroy();
|
destroy();
|
||||||
_object = nullptr;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reset(T *value) {
|
void reset(T *value = nullptr) {
|
||||||
if (_object != value) {
|
if (_object != value) {
|
||||||
destroy();
|
destroy();
|
||||||
_object = value;
|
_object = value;
|
||||||
|
|
|
@ -21,6 +21,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/info_common_groups_inner_widget.h"
|
#include "info/info_common_groups_inner_widget.h"
|
||||||
|
|
||||||
#include "info/info_common_groups_widget.h"
|
#include "info/info_common_groups_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_widgets.h"
|
#include "styles/style_widgets.h"
|
||||||
|
@ -35,13 +36,13 @@ namespace {
|
||||||
|
|
||||||
constexpr int kCommonGroupsPerPage = 40;
|
constexpr int kCommonGroupsPerPage = 40;
|
||||||
|
|
||||||
class Controller
|
class ListController
|
||||||
: public PeerListController
|
: public PeerListController
|
||||||
, private base::Subscriber
|
, private base::Subscriber
|
||||||
, private MTP::Sender {
|
, private MTP::Sender {
|
||||||
public:
|
public:
|
||||||
Controller(
|
ListController(
|
||||||
not_null<Window::Controller*> window,
|
not_null<Controller*> controller,
|
||||||
not_null<UserData*> user);
|
not_null<UserData*> user);
|
||||||
|
|
||||||
void prepare() override;
|
void prepare() override;
|
||||||
|
@ -49,7 +50,7 @@ public:
|
||||||
void loadMoreRows() override;
|
void loadMoreRows() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
not_null<Window::Controller*> _window;
|
const not_null<Controller*> _controller;
|
||||||
not_null<UserData*> _user;
|
not_null<UserData*> _user;
|
||||||
mtpRequestId _preloadRequestId = 0;
|
mtpRequestId _preloadRequestId = 0;
|
||||||
bool _allLoaded = false;
|
bool _allLoaded = false;
|
||||||
|
@ -57,21 +58,21 @@ private:
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Controller::Controller(
|
ListController::ListController(
|
||||||
not_null<Window::Controller*> window,
|
not_null<Controller*> controller,
|
||||||
not_null<UserData*> user)
|
not_null<UserData*> user)
|
||||||
: PeerListController()
|
: PeerListController()
|
||||||
, _window(window)
|
, _controller(controller)
|
||||||
, _user(user) {
|
, _user(user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::prepare() {
|
void ListController::prepare() {
|
||||||
setSearchNoResultsText(lang(lng_blocked_list_not_found));
|
setSearchNoResultsText(lang(lng_blocked_list_not_found));
|
||||||
delegate()->peerListSetSearchMode(PeerListSearchMode::Enabled);
|
delegate()->peerListSetSearchMode(PeerListSearchMode::Enabled);
|
||||||
delegate()->peerListSetTitle(langFactory(lng_profile_common_groups_section));
|
delegate()->peerListSetTitle(langFactory(lng_profile_common_groups_section));
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::loadMoreRows() {
|
void ListController::loadMoreRows() {
|
||||||
if (_preloadRequestId || _allLoaded) {
|
if (_preloadRequestId || _allLoaded) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -103,8 +104,8 @@ void Controller::loadMoreRows() {
|
||||||
}).send();
|
}).send();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Controller::rowClicked(not_null<PeerListRow*> row) {
|
void ListController::rowClicked(not_null<PeerListRow*> row) {
|
||||||
_window->showPeerHistory(
|
_controller->window()->showPeerHistory(
|
||||||
row->peer(),
|
row->peer(),
|
||||||
Window::SectionShow::Way::Forward);
|
Window::SectionShow::Way::Forward);
|
||||||
}
|
}
|
||||||
|
@ -113,11 +114,11 @@ void Controller::rowClicked(not_null<PeerListRow*> row) {
|
||||||
|
|
||||||
InnerWidget::InnerWidget(
|
InnerWidget::InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
not_null<UserData*> user)
|
not_null<UserData*> user)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _user(user)
|
, _user(user)
|
||||||
, _listController(std::make_unique<Controller>(controller, _user))
|
, _listController(std::make_unique<ListController>(controller, _user))
|
||||||
, _list(setupList(this, _listController.get())) {
|
, _list(setupList(this, _listController.get())) {
|
||||||
setContent(_list.data());
|
setContent(_list.data());
|
||||||
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
|
_listController->setDelegate(static_cast<PeerListDelegate*>(this));
|
||||||
|
|
|
@ -25,6 +25,9 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "boxes/peer_list_box.h"
|
#include "boxes/peer_list_box.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
|
class Controller;
|
||||||
|
|
||||||
namespace CommonGroups {
|
namespace CommonGroups {
|
||||||
|
|
||||||
class Memento;
|
class Memento;
|
||||||
|
@ -35,7 +38,7 @@ class InnerWidget final
|
||||||
public:
|
public:
|
||||||
InnerWidget(
|
InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
not_null<UserData*> user);
|
not_null<UserData*> user);
|
||||||
|
|
||||||
not_null<UserData*> user() const {
|
not_null<UserData*> user() const {
|
||||||
|
|
|
@ -21,19 +21,22 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/info_common_groups_widget.h"
|
#include "info/info_common_groups_widget.h"
|
||||||
|
|
||||||
#include "info/info_common_groups_inner_widget.h"
|
#include "info/info_common_groups_inner_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace CommonGroups {
|
namespace CommonGroups {
|
||||||
|
|
||||||
|
Section Memento::section() const {
|
||||||
|
return Section(Section::Type::CommonGroups);
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<ContentWidget> Memento::createWidget(
|
object_ptr<ContentWidget> Memento::createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
const QRect &geometry) {
|
const QRect &geometry) {
|
||||||
auto result = object_ptr<Widget>(
|
auto result = object_ptr<Widget>(
|
||||||
parent,
|
parent,
|
||||||
std::move(wrap),
|
|
||||||
controller,
|
controller,
|
||||||
App::user(userId()));
|
App::user(userId()));
|
||||||
result->setInternalState(geometry, this);
|
result->setInternalState(geometry, this);
|
||||||
|
@ -42,10 +45,9 @@ object_ptr<ContentWidget> Memento::createWidget(
|
||||||
|
|
||||||
Widget::Widget(
|
Widget::Widget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<UserData*> user)
|
not_null<UserData*> user)
|
||||||
: ContentWidget(parent, wrap, controller, user) {
|
: ContentWidget(parent, controller) {
|
||||||
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
||||||
this,
|
this,
|
||||||
controller,
|
controller,
|
||||||
|
@ -56,11 +58,10 @@ not_null<UserData*> Widget::user() const {
|
||||||
return _inner->user();
|
return _inner->user();
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Widget::section() const {
|
|
||||||
return Section(Section::Type::CommonGroups);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||||
|
if (!controller()->validateMementoPeer(memento)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (auto groupsMemento = dynamic_cast<Memento*>(memento.get())) {
|
if (auto groupsMemento = dynamic_cast<Memento*>(memento.get())) {
|
||||||
if (groupsMemento->userId() == user()->bareId()) {
|
if (groupsMemento->userId() == user()->bareId()) {
|
||||||
restoreState(groupsMemento);
|
restoreState(groupsMemento);
|
||||||
|
|
|
@ -30,18 +30,16 @@ class InnerWidget;
|
||||||
|
|
||||||
class Memento final : public ContentMemento {
|
class Memento final : public ContentMemento {
|
||||||
public:
|
public:
|
||||||
Memento(UserId userId) : ContentMemento(peerFromUser(userId)) {
|
Memento(UserId userId)
|
||||||
|
: ContentMemento(peerFromUser(userId), 0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<ContentWidget> createWidget(
|
object_ptr<ContentWidget> createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
const QRect &geometry) override;
|
const QRect &geometry) override;
|
||||||
|
|
||||||
Section section() const override {
|
Section section() const override;
|
||||||
return Section(Section::Type::CommonGroups);
|
|
||||||
}
|
|
||||||
|
|
||||||
UserId userId() const {
|
UserId userId() const {
|
||||||
return peerToUser(peerId());
|
return peerToUser(peerId());
|
||||||
|
@ -55,12 +53,10 @@ class Widget final : public ContentWidget {
|
||||||
public:
|
public:
|
||||||
Widget(
|
Widget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<UserData*> user);
|
not_null<UserData*> user);
|
||||||
|
|
||||||
not_null<UserData*> user() const;
|
not_null<UserData*> user() const;
|
||||||
Section section() const override;
|
|
||||||
|
|
||||||
bool showInternal(
|
bool showInternal(
|
||||||
not_null<ContentMemento*> memento) override;
|
not_null<ContentMemento*> memento) override;
|
||||||
|
|
|
@ -31,6 +31,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/info_common_groups_widget.h"
|
#include "info/info_common_groups_widget.h"
|
||||||
#include "info/info_layer_widget.h"
|
#include "info/info_layer_widget.h"
|
||||||
#include "info/info_section_widget.h"
|
#include "info/info_section_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "styles/style_profile.h"
|
#include "styles/style_profile.h"
|
||||||
|
|
||||||
|
@ -38,22 +39,18 @@ namespace Info {
|
||||||
|
|
||||||
ContentWidget::ContentWidget(
|
ContentWidget::ContentWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller)
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer)
|
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _peer(peer)
|
|
||||||
, _scroll(this, st::infoScroll) {
|
, _scroll(this, st::infoScroll) {
|
||||||
setAttribute(Qt::WA_OpaquePaintEvent);
|
setAttribute(Qt::WA_OpaquePaintEvent);
|
||||||
std::move(wrap) | rpl::start_with_next(
|
_controller->wrapValue()
|
||||||
[this](Wrap value) {
|
| rpl::start_with_next([this](Wrap value) {
|
||||||
_bg = (value == Wrap::Layer)
|
_bg = (value == Wrap::Layer)
|
||||||
? st::boxBg
|
? st::boxBg
|
||||||
: st::profileBg;
|
: st::profileBg;
|
||||||
update();
|
update();
|
||||||
},
|
}, lifetime());
|
||||||
lifetime());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWidget::resizeEvent(QResizeEvent *e) {
|
void ContentWidget::resizeEvent(QResizeEvent *e) {
|
||||||
|
|
|
@ -33,21 +33,16 @@ class ScrollArea;
|
||||||
struct ScrollToRequest;
|
struct ScrollToRequest;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Window {
|
|
||||||
class Controller;
|
|
||||||
} // namespace Window
|
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
class ContentMemento;
|
class ContentMemento;
|
||||||
|
class Controller;
|
||||||
|
|
||||||
class ContentWidget : public Ui::RpWidget {
|
class ContentWidget : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
ContentWidget(
|
ContentWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller);
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer);
|
|
||||||
|
|
||||||
virtual bool showInternal(
|
virtual bool showInternal(
|
||||||
not_null<ContentMemento*> memento) = 0;
|
not_null<ContentMemento*> memento) = 0;
|
||||||
|
@ -57,11 +52,6 @@ public:
|
||||||
virtual void setIsStackBottom(bool isStackBottom) {
|
virtual void setIsStackBottom(bool isStackBottom) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual Section section() const = 0;
|
|
||||||
not_null<PeerData*> peer() const {
|
|
||||||
return _peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<int> desiredHeightValue() const override;
|
rpl::producer<int> desiredHeightValue() const override;
|
||||||
rpl::producer<bool> desiredShadowVisibility() const;
|
rpl::producer<bool> desiredShadowVisibility() const;
|
||||||
bool hasTopBarShadow() const;
|
bool hasTopBarShadow() const;
|
||||||
|
@ -94,7 +84,7 @@ protected:
|
||||||
doSetInnerWidget(std::move(inner), scrollTopSkip));
|
doSetInnerWidget(std::move(inner), scrollTopSkip));
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<Window::Controller*> controller() const {
|
not_null<Controller*> controller() const {
|
||||||
return _controller;
|
return _controller;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -112,8 +102,7 @@ private:
|
||||||
int scrollTopSkip);
|
int scrollTopSkip);
|
||||||
void updateControlsGeometry();
|
void updateControlsGeometry();
|
||||||
|
|
||||||
const not_null<Window::Controller*> _controller;
|
const not_null<Controller*> _controller;
|
||||||
const not_null<PeerData*> _peer;
|
|
||||||
|
|
||||||
style::color _bg;
|
style::color _bg;
|
||||||
int _scrollTopSkip = 0;
|
int _scrollTopSkip = 0;
|
||||||
|
@ -127,18 +116,23 @@ private:
|
||||||
|
|
||||||
class ContentMemento {
|
class ContentMemento {
|
||||||
public:
|
public:
|
||||||
ContentMemento(PeerId peerId) : _peerId(peerId) {
|
ContentMemento(PeerId peerId, PeerId migratedPeerId)
|
||||||
|
: _peerId(peerId)
|
||||||
|
, _migratedPeerId(migratedPeerId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual object_ptr<ContentWidget> createWidget(
|
virtual object_ptr<ContentWidget> createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
const QRect &geometry) = 0;
|
const QRect &geometry) = 0;
|
||||||
|
|
||||||
virtual PeerId peerId() const {
|
PeerId peerId() const {
|
||||||
return _peerId;
|
return _peerId;
|
||||||
}
|
}
|
||||||
|
PeerId migratedPeerId() const {
|
||||||
|
return _migratedPeerId;
|
||||||
|
}
|
||||||
|
|
||||||
virtual Section section() const = 0;
|
virtual Section section() const = 0;
|
||||||
|
|
||||||
virtual ~ContentMemento() = default;
|
virtual ~ContentMemento() = default;
|
||||||
|
@ -151,7 +145,8 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
PeerId _peerId = 0;
|
const PeerId _peerId = 0;
|
||||||
|
const PeerId _migratedPeerId = 0;
|
||||||
int _scrollTop = 0;
|
int _scrollTop = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,139 @@
|
||||||
|
/*
|
||||||
|
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
|
||||||
|
*/
|
||||||
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
|
#include "ui/search_field_controller.h"
|
||||||
|
#include "history/history_shared_media.h"
|
||||||
|
#include "info/info_content_widget.h"
|
||||||
|
#include "info/info_memento.h"
|
||||||
|
|
||||||
|
namespace Info {
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
not_null<PeerData*> CorrectPeer(PeerId peerId) {
|
||||||
|
Expects(peerId != 0);
|
||||||
|
auto result = App::peer(peerId);
|
||||||
|
if (auto to = result->migrateTo()) {
|
||||||
|
return to;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
Controller::Controller(
|
||||||
|
not_null<WrapWidget*> widget,
|
||||||
|
not_null<Window::Controller*> window,
|
||||||
|
not_null<ContentMemento*> memento)
|
||||||
|
: _widget(widget)
|
||||||
|
, _peer(App::peer(memento->peerId()))
|
||||||
|
, _migrated(memento->migratedPeerId()
|
||||||
|
? App::peer(memento->migratedPeerId())
|
||||||
|
: nullptr)
|
||||||
|
, _window(window)
|
||||||
|
, _section(memento->section()) {
|
||||||
|
updateSearchControllers();
|
||||||
|
}
|
||||||
|
|
||||||
|
Wrap Controller::wrap() const {
|
||||||
|
return _widget->wrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<Wrap> Controller::wrapValue() const {
|
||||||
|
return _widget->wrapValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Controller::validateMementoPeer(
|
||||||
|
not_null<ContentMemento*> memento) const {
|
||||||
|
return memento->peerId() == peerId()
|
||||||
|
&& memento->migratedPeerId() == migratedPeerId();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::setSection(const Section §ion) {
|
||||||
|
_section = section;
|
||||||
|
updateSearchControllers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Controller::updateSearchControllers() {
|
||||||
|
auto isMedia = (_section.type() == Section::Type::Media);
|
||||||
|
auto mediaType = isMedia
|
||||||
|
? _section.mediaType()
|
||||||
|
: Section::MediaType::kCount;
|
||||||
|
auto hasMediaSearch = isMedia
|
||||||
|
&& SharedMediaAllowSearch(mediaType);
|
||||||
|
// auto hasCommonGroupsSearch
|
||||||
|
// = (_section.type() == Section::Type::CommonGroups);
|
||||||
|
if (isMedia) {
|
||||||
|
_searchController
|
||||||
|
= std::make_unique<Api::DelayedSearchController>();
|
||||||
|
_searchController->setQueryFast(produceSearchQuery());
|
||||||
|
} else {
|
||||||
|
_searchController = nullptr;
|
||||||
|
}
|
||||||
|
if (hasMediaSearch) {
|
||||||
|
_searchFieldController
|
||||||
|
= std::make_unique<Ui::SearchFieldController>();
|
||||||
|
_searchFieldController->queryValue()
|
||||||
|
| rpl::start_with_next([=](QString &&query) {
|
||||||
|
_searchController->setQuery(
|
||||||
|
produceSearchQuery(std::move(query)));
|
||||||
|
}, _searchFieldController->lifetime());
|
||||||
|
} else {
|
||||||
|
_searchFieldController = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto Controller::produceSearchQuery(
|
||||||
|
QString &&query) const -> SearchQuery {
|
||||||
|
auto result = SearchQuery();
|
||||||
|
result.type = _section.mediaType();
|
||||||
|
result.peerId = _peer->id;
|
||||||
|
result.query = std::move(query);
|
||||||
|
result.migratedPeerId = _migrated ? _migrated->id : PeerId(0);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<SparseIdsMergedSlice> Controller::mediaSource(
|
||||||
|
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
||||||
|
int limitBefore,
|
||||||
|
int limitAfter) const {
|
||||||
|
auto query = _searchController->currentQuery();
|
||||||
|
if (!query.query.isEmpty()) {
|
||||||
|
return _searchController->idsSlice(
|
||||||
|
aroundId,
|
||||||
|
limitBefore,
|
||||||
|
limitAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
return SharedMediaMergedViewer(
|
||||||
|
SharedMediaMergedKey(
|
||||||
|
SparseIdsMergedSlice::Key(
|
||||||
|
query.peerId,
|
||||||
|
query.migratedPeerId,
|
||||||
|
aroundId),
|
||||||
|
query.type),
|
||||||
|
limitBefore,
|
||||||
|
limitAfter);
|
||||||
|
}
|
||||||
|
|
||||||
|
Controller::~Controller() = default;
|
||||||
|
|
||||||
|
} // namespace Info
|
|
@ -0,0 +1,143 @@
|
||||||
|
/*
|
||||||
|
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 <rpl/variable.h>
|
||||||
|
#include "history/history_search_controller.h"
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class SearchFieldController;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
|
namespace Window {
|
||||||
|
class Controller;
|
||||||
|
} // namespace Window
|
||||||
|
|
||||||
|
namespace Info {
|
||||||
|
|
||||||
|
enum class Wrap;
|
||||||
|
class WrapWidget;
|
||||||
|
class Memento;
|
||||||
|
class ContentMemento;
|
||||||
|
|
||||||
|
class Section final {
|
||||||
|
public:
|
||||||
|
enum class Type {
|
||||||
|
Profile,
|
||||||
|
Media,
|
||||||
|
CommonGroups,
|
||||||
|
};
|
||||||
|
using MediaType = Storage::SharedMediaType;
|
||||||
|
|
||||||
|
Section(Type type) : _type(type) {
|
||||||
|
Expects(type != Type::Media);
|
||||||
|
}
|
||||||
|
Section(MediaType mediaType)
|
||||||
|
: _type(Type::Media)
|
||||||
|
, _mediaType(mediaType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Type type() const {
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
MediaType mediaType() const {
|
||||||
|
Expects(_type == Type::Media);
|
||||||
|
return _mediaType;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Type _type;
|
||||||
|
Storage::SharedMediaType _mediaType;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
class Controller {
|
||||||
|
public:
|
||||||
|
Controller(
|
||||||
|
not_null<WrapWidget*> widget,
|
||||||
|
not_null<Window::Controller*> window,
|
||||||
|
not_null<ContentMemento*> memento);
|
||||||
|
|
||||||
|
not_null<PeerData*> peer() const {
|
||||||
|
return _peer;
|
||||||
|
}
|
||||||
|
PeerData *migrated() const {
|
||||||
|
return _migrated;
|
||||||
|
}
|
||||||
|
PeerId peerId() const {
|
||||||
|
return _peer->id;
|
||||||
|
}
|
||||||
|
PeerId migratedPeerId() const {
|
||||||
|
return _migrated ? _migrated->id : PeerId(0);
|
||||||
|
}
|
||||||
|
const Section §ion() const {
|
||||||
|
return _section;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool validateMementoPeer(
|
||||||
|
not_null<ContentMemento*> memento) const;
|
||||||
|
|
||||||
|
Wrap wrap() const;
|
||||||
|
rpl::producer<Wrap> wrapValue() const;
|
||||||
|
void setSection(const Section §ion);
|
||||||
|
|
||||||
|
not_null<Window::Controller*> window() const {
|
||||||
|
return _window;
|
||||||
|
}
|
||||||
|
Ui::SearchFieldController *searchFieldController() const {
|
||||||
|
return _searchFieldController.get();
|
||||||
|
}
|
||||||
|
rpl::producer<SparseIdsMergedSlice> mediaSource(
|
||||||
|
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
||||||
|
int limitBefore,
|
||||||
|
int limitAfter) const;
|
||||||
|
rpl::producer<> mediaSourceChanged() const {
|
||||||
|
return _searchController->sourceChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::lifetime &lifetime() {
|
||||||
|
return _lifetime;
|
||||||
|
}
|
||||||
|
|
||||||
|
~Controller();
|
||||||
|
|
||||||
|
private:
|
||||||
|
using SearchQuery = Api::DelayedSearchController::Query;
|
||||||
|
|
||||||
|
void updateSearchControllers();
|
||||||
|
SearchQuery produceSearchQuery(
|
||||||
|
QString &&query = QString()) const;
|
||||||
|
|
||||||
|
not_null<WrapWidget*> _widget;
|
||||||
|
not_null<PeerData*> _peer;
|
||||||
|
PeerData *_migrated = nullptr;
|
||||||
|
not_null<Window::Controller*> _window;
|
||||||
|
rpl::variable<Wrap> _wrap;
|
||||||
|
Section _section;
|
||||||
|
|
||||||
|
std::unique_ptr<Ui::SearchFieldController> _searchFieldController;
|
||||||
|
std::unique_ptr<Api::DelayedSearchController> _searchController;
|
||||||
|
|
||||||
|
rpl::lifetime _lifetime;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace Info
|
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/info_common_groups_widget.h"
|
#include "info/info_common_groups_widget.h"
|
||||||
#include "info/info_section_widget.h"
|
#include "info/info_section_widget.h"
|
||||||
#include "info/info_layer_widget.h"
|
#include "info/info_layer_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
|
@ -40,23 +41,28 @@ Memento::Memento(std::unique_ptr<ContentMemento> content)
|
||||||
: _content(std::move(content)) {
|
: _content(std::move(content)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerId Memento::peerId() const {
|
|
||||||
return _content->peerId();
|
|
||||||
}
|
|
||||||
|
|
||||||
Section Memento::section() const {
|
|
||||||
return _content->section();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::unique_ptr<ContentMemento> Memento::Default(
|
std::unique_ptr<ContentMemento> Memento::Default(
|
||||||
PeerId peerId,
|
PeerId peerId,
|
||||||
Section section) {
|
Section section) {
|
||||||
|
Expects(peerId != 0);
|
||||||
|
|
||||||
|
auto peer = App::peer(peerId);
|
||||||
|
if (auto to = peer->migrateTo()) {
|
||||||
|
peer = to;
|
||||||
|
}
|
||||||
|
auto migrated = peer->migrateFrom();
|
||||||
|
peerId = peer->id;
|
||||||
|
auto migratedPeerId = migrated ? migrated->id : PeerId(0);
|
||||||
|
|
||||||
switch (section.type()) {
|
switch (section.type()) {
|
||||||
case Section::Type::Profile:
|
case Section::Type::Profile:
|
||||||
return std::make_unique<Profile::Memento>(peerId);
|
return std::make_unique<Profile::Memento>(
|
||||||
|
peerId,
|
||||||
|
migratedPeerId);
|
||||||
case Section::Type::Media:
|
case Section::Type::Media:
|
||||||
return std::make_unique<Media::Memento>(
|
return std::make_unique<Media::Memento>(
|
||||||
peerId,
|
peerId,
|
||||||
|
migratedPeerId,
|
||||||
section.mediaType());
|
section.mediaType());
|
||||||
case Section::Type::CommonGroups:
|
case Section::Type::CommonGroups:
|
||||||
Assert(peerIsUser(peerId));
|
Assert(peerIsUser(peerId));
|
||||||
|
|
|
@ -59,9 +59,6 @@ public:
|
||||||
return _content.get();
|
return _content.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
PeerId peerId() const;
|
|
||||||
Section section() const;
|
|
||||||
|
|
||||||
~Memento();
|
~Memento();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -24,25 +24,26 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/info_wrap_widget.h"
|
#include "info/info_wrap_widget.h"
|
||||||
#include "info/info_layer_widget.h"
|
#include "info/info_layer_widget.h"
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
SectionWidget::SectionWidget(
|
SectionWidget::SectionWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Window::Controller*> window,
|
||||||
Wrap wrap,
|
Wrap wrap,
|
||||||
not_null<Memento*> memento)
|
not_null<Memento*> memento)
|
||||||
: Window::SectionWidget(parent, controller)
|
: Window::SectionWidget(parent, window)
|
||||||
, _content(this, controller, wrap, memento) {
|
, _content(this, window, wrap, memento) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
SectionWidget::SectionWidget(
|
SectionWidget::SectionWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Window::Controller*> window,
|
||||||
Wrap wrap,
|
Wrap wrap,
|
||||||
not_null<MoveMemento*> memento)
|
not_null<MoveMemento*> memento)
|
||||||
: Window::SectionWidget(parent, controller)
|
: Window::SectionWidget(parent, window)
|
||||||
, _content(memento->takeContent(this, wrap)) {
|
, _content(memento->takeContent(this, wrap)) {
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
@ -55,6 +56,11 @@ void SectionWidget::init() {
|
||||||
}, _content->lifetime());
|
}, _content->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
not_null<Controller*> SectionWidget::controller() const {
|
||||||
|
Expects(_content != nullptr);
|
||||||
|
return _content->controller();
|
||||||
|
}
|
||||||
|
|
||||||
PeerData *SectionWidget::peerForDialogs() const {
|
PeerData *SectionWidget::peerForDialogs() const {
|
||||||
return _content->peerForDialogs();
|
return _content->peerForDialogs();
|
||||||
}
|
}
|
||||||
|
@ -83,19 +89,19 @@ bool SectionWidget::showInternal(
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Window::SectionMemento> SectionWidget::createMemento() {
|
std::unique_ptr<Window::SectionMemento> SectionWidget::createMemento() {
|
||||||
auto result = std::make_unique<Memento>(_content->peer()->id);
|
return _content->createMemento();
|
||||||
_content->saveState(result.get());
|
|
||||||
return std::move(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Window::LayerWidget> SectionWidget::moveContentToLayer(
|
object_ptr<Window::LayerWidget> SectionWidget::moveContentToLayer(
|
||||||
QRect bodyGeometry) {
|
QRect bodyGeometry) {
|
||||||
if (_content->wrap() != Wrap::Narrow
|
if (controller()->wrap() != Wrap::Narrow
|
||||||
|| width() < LayerWidget::MinimalSupportedWidth()) {
|
|| width() < LayerWidget::MinimalSupportedWidth()) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
return MoveMemento(
|
return MoveMemento(
|
||||||
std::move(_content)).createLayer(controller(), bodyGeometry);
|
std::move(_content)).createLayer(
|
||||||
|
controller()->window(),
|
||||||
|
bodyGeometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SectionWidget::wheelEventFromFloatPlayer(QEvent *e) {
|
bool SectionWidget::wheelEventFromFloatPlayer(QEvent *e) {
|
||||||
|
|
|
@ -31,6 +31,7 @@ namespace Info {
|
||||||
|
|
||||||
class Memento;
|
class Memento;
|
||||||
class MoveMemento;
|
class MoveMemento;
|
||||||
|
class Controller;
|
||||||
class WrapWidget;
|
class WrapWidget;
|
||||||
enum class Wrap;
|
enum class Wrap;
|
||||||
|
|
||||||
|
@ -38,12 +39,12 @@ class SectionWidget final : public Window::SectionWidget {
|
||||||
public:
|
public:
|
||||||
SectionWidget(
|
SectionWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Window::Controller*> window,
|
||||||
Wrap wrap,
|
Wrap wrap,
|
||||||
not_null<Memento*> memento);
|
not_null<Memento*> memento);
|
||||||
SectionWidget(
|
SectionWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Window::Controller*> window,
|
||||||
Wrap wrap,
|
Wrap wrap,
|
||||||
not_null<MoveMemento*> memento);
|
not_null<MoveMemento*> memento);
|
||||||
|
|
||||||
|
@ -72,6 +73,8 @@ protected:
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
not_null<Controller*> controller() const;
|
||||||
|
|
||||||
object_ptr<WrapWidget> _content;
|
object_ptr<WrapWidget> _content;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -23,6 +23,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "styles/style_info.h"
|
#include "styles/style_info.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "info/info_wrap_widget.h"
|
#include "info/info_wrap_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "storage/storage_shared_media.h"
|
#include "storage/storage_shared_media.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
|
@ -102,19 +103,19 @@ void TopBar::paintEvent(QPaintEvent *e) {
|
||||||
|
|
||||||
rpl::producer<QString> TitleValue(
|
rpl::producer<QString> TitleValue(
|
||||||
const Section §ion,
|
const Section §ion,
|
||||||
PeerId peerId) {
|
not_null<PeerData*> peer) {
|
||||||
return Lang::Viewer([&] {
|
return Lang::Viewer([&] {
|
||||||
switch (section.type()) {
|
switch (section.type()) {
|
||||||
case Section::Type::Profile:
|
case Section::Type::Profile:
|
||||||
if (peerIsUser(peerId)) {
|
if (auto user = peer->asUser()) {
|
||||||
return App::user(peerId)->botInfo
|
return user->botInfo
|
||||||
? lng_info_bot_title
|
? lng_info_bot_title
|
||||||
: lng_info_user_title;
|
: lng_info_user_title;
|
||||||
} else if (peerIsChannel(peerId)) {
|
} else if (auto channel = peer->asChannel()) {
|
||||||
return App::channel(peerId)->isMegagroup()
|
return channel->isMegagroup()
|
||||||
? lng_info_group_title
|
? lng_info_group_title
|
||||||
: lng_info_channel_title;
|
: lng_info_channel_title;
|
||||||
} else if (peerIsChat(peerId)) {
|
} else if (peer->isChat()) {
|
||||||
return lng_info_group_title;
|
return lng_info_group_title;
|
||||||
}
|
}
|
||||||
Unexpected("Bad peer type in Info::TitleValue()");
|
Unexpected("Bad peer type in Info::TitleValue()");
|
||||||
|
|
|
@ -37,7 +37,7 @@ class Section;
|
||||||
|
|
||||||
rpl::producer<QString> TitleValue(
|
rpl::producer<QString> TitleValue(
|
||||||
const Section §ion,
|
const Section §ion,
|
||||||
PeerId peerId);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
class TopBar : public Ui::RpWidget {
|
class TopBar : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/profile/info_profile_widget.h"
|
#include "info/profile/info_profile_widget.h"
|
||||||
#include "info/media/info_media_widget.h"
|
#include "info/media/info_media_widget.h"
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
#include "info/info_top_bar.h"
|
#include "info/info_top_bar.h"
|
||||||
#include "info/info_top_bar_override.h"
|
#include "info/info_top_bar_override.h"
|
||||||
|
@ -57,13 +58,19 @@ struct WrapWidget::StackItem {
|
||||||
|
|
||||||
WrapWidget::WrapWidget(
|
WrapWidget::WrapWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Window::Controller*> window,
|
||||||
Wrap wrap,
|
Wrap wrap,
|
||||||
not_null<Memento*> memento)
|
not_null<Memento*> memento)
|
||||||
: SectionWidget(parent, controller)
|
: SectionWidget(parent, window)
|
||||||
, _wrap(wrap)
|
, _wrap(wrap)
|
||||||
|
, _controller(createController(window, memento->content()))
|
||||||
, _topShadow(this) {
|
, _topShadow(this) {
|
||||||
_topShadow->toggleOn(topShadowToggledValue());
|
_topShadow->toggleOn(topShadowToggledValue());
|
||||||
|
_wrap.changes()
|
||||||
|
| rpl::start_with_next([this] {
|
||||||
|
setupTop();
|
||||||
|
finishShowContent();
|
||||||
|
}, lifetime());
|
||||||
selectedListValue()
|
selectedListValue()
|
||||||
| rpl::start_with_next([this](SelectedItems &&items) {
|
| rpl::start_with_next([this](SelectedItems &&items) {
|
||||||
InvokeQueued(this, [this, items = std::move(items)]() mutable {
|
InvokeQueued(this, [this, items = std::move(items)]() mutable {
|
||||||
|
@ -73,20 +80,18 @@ WrapWidget::WrapWidget(
|
||||||
showNewContent(memento->content());
|
showNewContent(memento->content());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Controller> WrapWidget::createController(
|
||||||
|
not_null<Window::Controller*> window,
|
||||||
|
not_null<ContentMemento*> memento) {
|
||||||
|
auto result = std::make_unique<Controller>(
|
||||||
|
this,
|
||||||
|
window,
|
||||||
|
memento);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
not_null<PeerData*> WrapWidget::peer() const {
|
not_null<PeerData*> WrapWidget::peer() const {
|
||||||
return _content->peer();
|
return _controller->peer();
|
||||||
}
|
|
||||||
|
|
||||||
Wrap WrapWidget::wrap() const {
|
|
||||||
return _wrap.current();
|
|
||||||
}
|
|
||||||
|
|
||||||
void WrapWidget::setWrap(Wrap wrap) {
|
|
||||||
if (_wrap.current() != wrap) {
|
|
||||||
_wrap = wrap;
|
|
||||||
setupTop(_content->section(), _content->peer()->id);
|
|
||||||
finishShowContent();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WrapWidget::createTabs() {
|
void WrapWidget::createTabs() {
|
||||||
|
@ -138,9 +143,15 @@ void WrapWidget::showTab(Tab tab) {
|
||||||
? SlideDirection::FromRight
|
? SlideDirection::FromRight
|
||||||
: SlideDirection::FromLeft;
|
: SlideDirection::FromLeft;
|
||||||
auto newAnotherMemento = _content->createMemento();
|
auto newAnotherMemento = _content->createMemento();
|
||||||
auto newContent = _anotherTabMemento
|
if (!_anotherTabMemento) {
|
||||||
? createContent(_anotherTabMemento.get())
|
_anotherTabMemento = createTabMemento(tab);
|
||||||
: createContent(tab);
|
}
|
||||||
|
auto newController = createController(
|
||||||
|
_controller->window(),
|
||||||
|
_anotherTabMemento.get());
|
||||||
|
auto newContent = createContent(
|
||||||
|
_anotherTabMemento.get(),
|
||||||
|
newController.get());
|
||||||
auto animationParams = SectionSlideParams();
|
auto animationParams = SectionSlideParams();
|
||||||
// animationParams.withFade = (wrap() == Wrap::Layer);
|
// animationParams.withFade = (wrap() == Wrap::Layer);
|
||||||
animationParams.withTabs = true;
|
animationParams.withTabs = true;
|
||||||
|
@ -149,6 +160,7 @@ void WrapWidget::showTab(Tab tab) {
|
||||||
animationParams.oldContentCache = grabForShowAnimation(
|
animationParams.oldContentCache = grabForShowAnimation(
|
||||||
animationParams);
|
animationParams);
|
||||||
|
|
||||||
|
_controller = std::move(newController);
|
||||||
showContent(std::move(newContent));
|
showContent(std::move(newContent));
|
||||||
|
|
||||||
showAnimated(direction, animationParams);
|
showAnimated(direction, animationParams);
|
||||||
|
@ -157,7 +169,8 @@ void WrapWidget::showTab(Tab tab) {
|
||||||
_tab = tab;
|
_tab = tab;
|
||||||
}
|
}
|
||||||
|
|
||||||
void WrapWidget::setupTabbedTop(const Section §ion) {
|
void WrapWidget::setupTabbedTop() {
|
||||||
|
auto section = _controller->section();
|
||||||
switch (section.type()) {
|
switch (section.type()) {
|
||||||
case Section::Type::Profile:
|
case Section::Type::Profile:
|
||||||
setupTabs(Tab::Profile);
|
setupTabs(Tab::Profile);
|
||||||
|
@ -180,30 +193,26 @@ void WrapWidget::setupTabbedTop(const Section §ion) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WrapWidget::setupTop(
|
void WrapWidget::setupTop() {
|
||||||
const Section §ion,
|
|
||||||
PeerId peerId) {
|
|
||||||
if (wrap() == Wrap::Side && _historyStack.empty()) {
|
if (wrap() == Wrap::Side && _historyStack.empty()) {
|
||||||
setupTabbedTop(section);
|
setupTabbedTop();
|
||||||
} else {
|
} else {
|
||||||
setupTabs(Tab::None);
|
setupTabs(Tab::None);
|
||||||
}
|
}
|
||||||
if (_topTabs) {
|
if (_topTabs) {
|
||||||
_topBar.destroy();
|
_topBar.destroy();
|
||||||
} else {
|
} else {
|
||||||
createTopBar(section, peerId);
|
createTopBar();
|
||||||
}
|
}
|
||||||
refreshTopBarOverride();
|
refreshTopBarOverride();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WrapWidget::createTopBar(
|
void WrapWidget::createTopBar() {
|
||||||
const Section §ion,
|
|
||||||
PeerId peerId) {
|
|
||||||
_topBar.create(this, TopBarStyle(wrap()));
|
_topBar.create(this, TopBarStyle(wrap()));
|
||||||
|
|
||||||
_topBar->setTitle(TitleValue(
|
_topBar->setTitle(TitleValue(
|
||||||
section,
|
_controller->section(),
|
||||||
peerId));
|
_controller->peer()));
|
||||||
if (wrap() != Wrap::Layer || !_historyStack.empty()) {
|
if (wrap() != Wrap::Layer || !_historyStack.empty()) {
|
||||||
_topBar->enableBackButton(true);
|
_topBar->enableBackButton(true);
|
||||||
_topBar->backRequest()
|
_topBar->backRequest()
|
||||||
|
@ -216,7 +225,7 @@ void WrapWidget::createTopBar(
|
||||||
_topBar,
|
_topBar,
|
||||||
st::infoLayerTopBarClose));
|
st::infoLayerTopBarClose));
|
||||||
close->addClickHandler([this] {
|
close->addClickHandler([this] {
|
||||||
controller()->hideSpecialLayer();
|
_controller->window()->hideSpecialLayer();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +299,7 @@ void WrapWidget::showBackFromStack() {
|
||||||
params);
|
params);
|
||||||
_anotherTabMemento = std::move(last.anotherTab);
|
_anotherTabMemento = std::move(last.anotherTab);
|
||||||
} else {
|
} else {
|
||||||
controller()->showBackFromStack(params);
|
_controller->window()->showBackFromStack(params);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,7 +333,7 @@ void WrapWidget::finishShowContent() {
|
||||||
rpl::producer<bool> WrapWidget::topShadowToggledValue() const {
|
rpl::producer<bool> WrapWidget::topShadowToggledValue() const {
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
return rpl::combine(
|
return rpl::combine(
|
||||||
_wrap.value(),
|
_controller->wrapValue(),
|
||||||
_desiredShadowVisibilities.events() | rpl::flatten_latest(),
|
_desiredShadowVisibilities.events() | rpl::flatten_latest(),
|
||||||
($1 == Wrap::Side) || $2);
|
($1 == Wrap::Side) || $2);
|
||||||
}
|
}
|
||||||
|
@ -341,39 +350,26 @@ rpl::producer<SelectedItems> WrapWidget::selectedListValue() const {
|
||||||
return _selectedLists.events() | rpl::flatten_latest();
|
return _selectedLists.events() | rpl::flatten_latest();
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<ContentWidget> WrapWidget::createContent(Tab tab) {
|
std::unique_ptr<ContentMemento> WrapWidget::createTabMemento(
|
||||||
|
Tab tab) {
|
||||||
switch (tab) {
|
switch (tab) {
|
||||||
case Tab::Profile: return createProfileWidget();
|
case Tab::Profile: return std::make_unique<Profile::Memento>(
|
||||||
case Tab::Media: return createMediaWidget();
|
_controller->peerId(),
|
||||||
|
_controller->migratedPeerId());
|
||||||
|
case Tab::Media: return std::make_unique<Media::Memento>(
|
||||||
|
_controller->peerId(),
|
||||||
|
_controller->migratedPeerId(),
|
||||||
|
Media::Memento::Type::Photo);
|
||||||
}
|
}
|
||||||
Unexpected("Tab value in Info::WrapWidget::createInner()");
|
Unexpected("Tab value in Info::WrapWidget::createInner()");
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Profile::Widget> WrapWidget::createProfileWidget() {
|
|
||||||
auto result = object_ptr<Profile::Widget>(
|
|
||||||
this,
|
|
||||||
_wrap.value(),
|
|
||||||
controller(),
|
|
||||||
_content->peer());
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
object_ptr<Media::Widget> WrapWidget::createMediaWidget() {
|
|
||||||
auto result = object_ptr<Media::Widget>(
|
|
||||||
this,
|
|
||||||
_wrap.value(),
|
|
||||||
controller(),
|
|
||||||
_content->peer(),
|
|
||||||
Media::Widget::Type::Photo);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
object_ptr<ContentWidget> WrapWidget::createContent(
|
object_ptr<ContentWidget> WrapWidget::createContent(
|
||||||
not_null<ContentMemento*> memento) {
|
not_null<ContentMemento*> memento,
|
||||||
|
not_null<Controller*> controller) {
|
||||||
return memento->createWidget(
|
return memento->createWidget(
|
||||||
this,
|
this,
|
||||||
_wrap.value(),
|
controller,
|
||||||
controller(),
|
|
||||||
contentGeometry());
|
contentGeometry());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -423,20 +419,21 @@ bool WrapWidget::showInternal(
|
||||||
const Window::SectionShow ¶ms) {
|
const Window::SectionShow ¶ms) {
|
||||||
if (auto infoMemento = dynamic_cast<Memento*>(memento.get())) {
|
if (auto infoMemento = dynamic_cast<Memento*>(memento.get())) {
|
||||||
auto content = infoMemento->content();
|
auto content = infoMemento->content();
|
||||||
if (!_content->showInternal(content)) {
|
if (_controller->validateMementoPeer(content)) {
|
||||||
showNewContent(
|
if (_content->showInternal(content)) {
|
||||||
content,
|
return true;
|
||||||
params);
|
}
|
||||||
}
|
}
|
||||||
|
showNewContent(
|
||||||
|
content,
|
||||||
|
params);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Window::SectionMemento> WrapWidget::createMemento() {
|
std::unique_ptr<Window::SectionMemento> WrapWidget::createMemento() {
|
||||||
auto result = std::make_unique<Memento>(_content->peer()->id);
|
return std::make_unique<Memento>(_content->createMemento());
|
||||||
saveState(result.get());
|
|
||||||
return std::move(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rpl::producer<int> WrapWidget::desiredHeightValue() const {
|
rpl::producer<int> WrapWidget::desiredHeightValue() const {
|
||||||
|
@ -446,10 +443,6 @@ rpl::producer<int> WrapWidget::desiredHeightValue() const {
|
||||||
| rpl::flatten_latest();
|
| rpl::flatten_latest();
|
||||||
}
|
}
|
||||||
|
|
||||||
void WrapWidget::saveState(not_null<Memento*> memento) {
|
|
||||||
memento->setInner(_content->createMemento());
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect WrapWidget::contentGeometry() const {
|
QRect WrapWidget::contentGeometry() const {
|
||||||
return rect().marginsRemoved({ 0, topWidget()->height(), 0, 0 });
|
return rect().marginsRemoved({ 0, topWidget()->height(), 0, 0 });
|
||||||
}
|
}
|
||||||
|
@ -462,9 +455,12 @@ void WrapWidget::showNewContent(
|
||||||
auto needAnimation = (_content != nullptr)
|
auto needAnimation = (_content != nullptr)
|
||||||
&& (params.animated != anim::type::instant);
|
&& (params.animated != anim::type::instant);
|
||||||
auto animationParams = SectionSlideParams();
|
auto animationParams = SectionSlideParams();
|
||||||
|
auto newController = createController(
|
||||||
|
_controller->window(),
|
||||||
|
memento);
|
||||||
auto newContent = object_ptr<ContentWidget>(nullptr);
|
auto newContent = object_ptr<ContentWidget>(nullptr);
|
||||||
if (needAnimation) {
|
if (needAnimation) {
|
||||||
newContent = createContent(memento);
|
newContent = createContent(memento, newController.get());
|
||||||
animationParams.withTopBarShadow = hasTopBarShadow()
|
animationParams.withTopBarShadow = hasTopBarShadow()
|
||||||
&& newContent->hasTopBarShadow();
|
&& newContent->hasTopBarShadow();
|
||||||
animationParams.oldContentCache = grabForShowAnimation(
|
animationParams.oldContentCache = grabForShowAnimation(
|
||||||
|
@ -481,8 +477,10 @@ void WrapWidget::showNewContent(
|
||||||
} else if (params.way == Window::SectionShow::Way::ClearStack) {
|
} else if (params.way == Window::SectionShow::Way::ClearStack) {
|
||||||
_historyStack.clear();
|
_historyStack.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_controller = std::move(newController);
|
||||||
if (newContent) {
|
if (newContent) {
|
||||||
setupTop(newContent->section(), newContent->peer()->id);
|
setupTop();
|
||||||
showContent(std::move(newContent));
|
showContent(std::move(newContent));
|
||||||
} else {
|
} else {
|
||||||
showNewContent(memento);
|
showNewContent(memento);
|
||||||
|
@ -498,8 +496,8 @@ void WrapWidget::showNewContent(
|
||||||
|
|
||||||
void WrapWidget::showNewContent(not_null<ContentMemento*> memento) {
|
void WrapWidget::showNewContent(not_null<ContentMemento*> memento) {
|
||||||
// Validates contentGeometry().
|
// Validates contentGeometry().
|
||||||
setupTop(memento->section(), memento->peerId());
|
setupTop();
|
||||||
showContent(createContent(memento));
|
showContent(createContent(memento, _controller.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void WrapWidget::setupTabs(Tab tab) {
|
void WrapWidget::setupTabs(Tab tab) {
|
||||||
|
|
|
@ -43,6 +43,7 @@ namespace Media {
|
||||||
class Widget;
|
class Widget;
|
||||||
} // namespace Media
|
} // namespace Media
|
||||||
|
|
||||||
|
class Controller;
|
||||||
class Section;
|
class Section;
|
||||||
class Memento;
|
class Memento;
|
||||||
class MoveMemento;
|
class MoveMemento;
|
||||||
|
@ -57,37 +58,6 @@ enum class Wrap {
|
||||||
Side,
|
Side,
|
||||||
};
|
};
|
||||||
|
|
||||||
class Section final {
|
|
||||||
public:
|
|
||||||
enum class Type {
|
|
||||||
Profile,
|
|
||||||
Media,
|
|
||||||
CommonGroups,
|
|
||||||
};
|
|
||||||
using MediaType = Storage::SharedMediaType;
|
|
||||||
|
|
||||||
Section(Type type) : _type(type) {
|
|
||||||
Expects(type != Type::Media);
|
|
||||||
}
|
|
||||||
Section(MediaType mediaType)
|
|
||||||
: _type(Type::Media)
|
|
||||||
, _mediaType(mediaType) {
|
|
||||||
}
|
|
||||||
|
|
||||||
Type type() const {
|
|
||||||
return _type;
|
|
||||||
}
|
|
||||||
MediaType mediaType() const {
|
|
||||||
Expects(_type == Type::Media);
|
|
||||||
return _mediaType;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
Type _type;
|
|
||||||
Storage::SharedMediaType _mediaType;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
struct SelectedItem {
|
struct SelectedItem {
|
||||||
explicit SelectedItem(FullMsgId msgId) : msgId(msgId) {
|
explicit SelectedItem(FullMsgId msgId) : msgId(msgId) {
|
||||||
}
|
}
|
||||||
|
@ -111,7 +81,7 @@ class WrapWidget final : public Window::SectionWidget {
|
||||||
public:
|
public:
|
||||||
WrapWidget(
|
WrapWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Window::Controller*> window,
|
||||||
Wrap wrap,
|
Wrap wrap,
|
||||||
not_null<Memento*> memento);
|
not_null<Memento*> memento);
|
||||||
|
|
||||||
|
@ -119,9 +89,19 @@ public:
|
||||||
PeerData *peerForDialogs() const override {
|
PeerData *peerForDialogs() const override {
|
||||||
return peer();
|
return peer();
|
||||||
}
|
}
|
||||||
|
Wrap wrap() const {
|
||||||
|
return _wrap.current();
|
||||||
|
}
|
||||||
|
rpl::producer<Wrap> wrapValue() const {
|
||||||
|
return _wrap.value();
|
||||||
|
}
|
||||||
|
void setWrap(Wrap wrap) {
|
||||||
|
_wrap = wrap;
|
||||||
|
}
|
||||||
|
|
||||||
Wrap wrap() const;
|
not_null<Controller*> controller() {
|
||||||
void setWrap(Wrap wrap);
|
return _controller.get();
|
||||||
|
}
|
||||||
|
|
||||||
bool hasTopBarShadow() const override;
|
bool hasTopBarShadow() const override;
|
||||||
QPixmap grabForShowAnimation(
|
QPixmap grabForShowAnimation(
|
||||||
|
@ -138,7 +118,6 @@ public:
|
||||||
rpl::producer<int> desiredHeightValue() const override;
|
rpl::producer<int> desiredHeightValue() const override;
|
||||||
|
|
||||||
void updateInternalState(not_null<Memento*> memento);
|
void updateInternalState(not_null<Memento*> memento);
|
||||||
void saveState(not_null<Memento*> memento);
|
|
||||||
|
|
||||||
// Float player interface.
|
// Float player interface.
|
||||||
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
bool wheelEventFromFloatPlayer(QEvent *e) override;
|
||||||
|
@ -167,13 +146,11 @@ private:
|
||||||
void showNewContent(
|
void showNewContent(
|
||||||
not_null<ContentMemento*> memento,
|
not_null<ContentMemento*> memento,
|
||||||
const Window::SectionShow ¶ms);
|
const Window::SectionShow ¶ms);
|
||||||
void setupTop(const Section §ion, PeerId peerId);
|
void setupTop();
|
||||||
void setupTabbedTop(const Section §ion);
|
void setupTabbedTop();
|
||||||
void setupTabs(Tab tab);
|
void setupTabs(Tab tab);
|
||||||
void createTabs();
|
void createTabs();
|
||||||
void createTopBar(
|
void createTopBar();
|
||||||
const Section §ion,
|
|
||||||
PeerId peerId);
|
|
||||||
|
|
||||||
not_null<RpWidget*> topWidget() const;
|
not_null<RpWidget*> topWidget() const;
|
||||||
|
|
||||||
|
@ -185,10 +162,12 @@ private:
|
||||||
|
|
||||||
void showTab(Tab tab);
|
void showTab(Tab tab);
|
||||||
void showContent(object_ptr<ContentWidget> content);
|
void showContent(object_ptr<ContentWidget> content);
|
||||||
object_ptr<ContentWidget> createContent(Tab tab);
|
std::unique_ptr<ContentMemento> createTabMemento(Tab tab);
|
||||||
object_ptr<Profile::Widget> createProfileWidget();
|
|
||||||
object_ptr<Media::Widget> createMediaWidget();
|
|
||||||
object_ptr<ContentWidget> createContent(
|
object_ptr<ContentWidget> createContent(
|
||||||
|
not_null<ContentMemento*> memento,
|
||||||
|
not_null<Controller*> controller);
|
||||||
|
std::unique_ptr<Controller> createController(
|
||||||
|
not_null<Window::Controller*> window,
|
||||||
not_null<ContentMemento*> memento);
|
not_null<ContentMemento*> memento);
|
||||||
|
|
||||||
rpl::producer<SelectedItems> selectedListValue() const;
|
rpl::producer<SelectedItems> selectedListValue() const;
|
||||||
|
@ -198,6 +177,7 @@ private:
|
||||||
void destroyTopBarOverride();
|
void destroyTopBarOverride();
|
||||||
|
|
||||||
rpl::variable<Wrap> _wrap;
|
rpl::variable<Wrap> _wrap;
|
||||||
|
std::unique_ptr<Controller> _controller;
|
||||||
object_ptr<ContentWidget> _content = { nullptr };
|
object_ptr<ContentWidget> _content = { nullptr };
|
||||||
object_ptr<Ui::PlainShadow> _topTabsBackground = { nullptr };
|
object_ptr<Ui::PlainShadow> _topTabsBackground = { nullptr };
|
||||||
object_ptr<Ui::SettingsSlider> _topTabs = { nullptr };
|
object_ptr<Ui::SettingsSlider> _topTabs = { nullptr };
|
||||||
|
|
|
@ -25,6 +25,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "storage/storage_shared_media.h"
|
#include "storage/storage_shared_media.h"
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "info/profile/info_profile_button.h"
|
#include "info/profile/info_profile_button.h"
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "ui/wrap/slide_wrap.h"
|
#include "ui/wrap/slide_wrap.h"
|
||||||
|
@ -90,11 +91,12 @@ inline auto AddButton(
|
||||||
Ui::VerticalLayout *parent,
|
Ui::VerticalLayout *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Window::Controller*> controller,
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
PeerData *migrated,
|
||||||
Type type,
|
Type type,
|
||||||
Ui::MultiSlideTracker &tracker) {
|
Ui::MultiSlideTracker &tracker) {
|
||||||
auto result = AddCountedButton(
|
auto result = AddCountedButton(
|
||||||
parent,
|
parent,
|
||||||
Profile::SharedMediaCountValue(peer, type),
|
Profile::SharedMediaCountValue(peer, migrated, type),
|
||||||
MediaText(type),
|
MediaText(type),
|
||||||
tracker)->entity();
|
tracker)->entity();
|
||||||
result->addClickHandler([controller, peer, type] {
|
result->addClickHandler([controller, peer, type] {
|
||||||
|
@ -118,9 +120,7 @@ inline auto AddCommonGroupsButton(
|
||||||
tracker)->entity();
|
tracker)->entity();
|
||||||
result->addClickHandler([controller, user] {
|
result->addClickHandler([controller, user] {
|
||||||
controller->showSection(
|
controller->showSection(
|
||||||
Info::Memento(
|
Info::Memento(user->id, Section::Type::CommonGroups));
|
||||||
user->id,
|
|
||||||
Section::Type::CommonGroups));
|
|
||||||
});
|
});
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
};
|
};
|
||||||
|
|
|
@ -26,6 +26,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/media/info_media_buttons.h"
|
#include "info/media/info_media_buttons.h"
|
||||||
#include "info/profile/info_profile_button.h"
|
#include "info/profile/info_profile_button.h"
|
||||||
#include "info/profile/info_profile_icon.h"
|
#include "info/profile/info_profile_icon.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "ui/widgets/discrete_sliders.h"
|
#include "ui/widgets/discrete_sliders.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
#include "ui/wrap/vertical_layout.h"
|
#include "ui/wrap/vertical_layout.h"
|
||||||
|
@ -61,17 +62,15 @@ Type TabIndexToType(int index) {
|
||||||
|
|
||||||
InnerWidget::InnerWidget(
|
InnerWidget::InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> &&wrap,
|
not_null<Controller*> controller)
|
||||||
not_null<Window::Controller*> controller,
|
: RpWidget(parent)
|
||||||
not_null<PeerData*> peer,
|
, _controller(controller) {
|
||||||
Type type)
|
_list = setupList();
|
||||||
: RpWidget(parent) {
|
setupOtherTypes();
|
||||||
_list = setupList(controller, peer, type);
|
|
||||||
setupOtherTypes(std::move(wrap));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::setupOtherTypes(rpl::producer<Wrap> &&wrap) {
|
void InnerWidget::setupOtherTypes() {
|
||||||
std::move(wrap)
|
_controller->wrapValue()
|
||||||
| rpl::start_with_next([this](Wrap value) {
|
| rpl::start_with_next([this](Wrap value) {
|
||||||
if (value == Wrap::Side
|
if (value == Wrap::Side
|
||||||
&& TypeToTabIndex(type())) {
|
&& TypeToTabIndex(type())) {
|
||||||
|
@ -81,6 +80,7 @@ void InnerWidget::setupOtherTypes(rpl::producer<Wrap> &&wrap) {
|
||||||
_otherTypes.destroy();
|
_otherTypes.destroy();
|
||||||
refreshHeight();
|
refreshHeight();
|
||||||
}
|
}
|
||||||
|
refreshSearchField();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,8 +117,9 @@ void InnerWidget::createTypeButtons() {
|
||||||
const style::icon &icon) {
|
const style::icon &icon) {
|
||||||
auto result = AddButton(
|
auto result = AddButton(
|
||||||
content,
|
content,
|
||||||
controller(),
|
_controller->window(),
|
||||||
peer(),
|
_controller->peer(),
|
||||||
|
_controller->migrated(),
|
||||||
type,
|
type,
|
||||||
tracker);
|
tracker);
|
||||||
object_ptr<Profile::FloatingIcon>(
|
object_ptr<Profile::FloatingIcon>(
|
||||||
|
@ -131,7 +132,7 @@ void InnerWidget::createTypeButtons() {
|
||||||
const style::icon &icon) {
|
const style::icon &icon) {
|
||||||
auto result = AddCommonGroupsButton(
|
auto result = AddCommonGroupsButton(
|
||||||
content,
|
content,
|
||||||
controller(),
|
_controller->window(),
|
||||||
user,
|
user,
|
||||||
tracker);
|
tracker);
|
||||||
object_ptr<Profile::FloatingIcon>(
|
object_ptr<Profile::FloatingIcon>(
|
||||||
|
@ -142,7 +143,7 @@ void InnerWidget::createTypeButtons() {
|
||||||
|
|
||||||
addMediaButton(Type::MusicFile, st::infoIconMediaAudio);
|
addMediaButton(Type::MusicFile, st::infoIconMediaAudio);
|
||||||
addMediaButton(Type::Link, st::infoIconMediaLink);
|
addMediaButton(Type::Link, st::infoIconMediaLink);
|
||||||
if (auto user = peer()->asUser()) {
|
if (auto user = _controller->peer()->asUser()) {
|
||||||
addCommonGroupsButton(user, st::infoIconMediaGroup);
|
addCommonGroupsButton(user, st::infoIconMediaGroup);
|
||||||
}
|
}
|
||||||
addMediaButton(Type::VoiceFile, st::infoIconMediaVoice);
|
addMediaButton(Type::VoiceFile, st::infoIconMediaVoice);
|
||||||
|
@ -170,20 +171,19 @@ void InnerWidget::createTabs() {
|
||||||
_otherTabs->sectionActivated()
|
_otherTabs->sectionActivated()
|
||||||
| rpl::map([](int index) { return TabIndexToType(index); })
|
| rpl::map([](int index) { return TabIndexToType(index); })
|
||||||
| rpl::start_with_next(
|
| rpl::start_with_next(
|
||||||
[this](Type type) {
|
[this](Type newType) {
|
||||||
if (_list->type() != type) {
|
if (type() != newType) {
|
||||||
switchToTab(Memento(peer()->id, type));
|
switchToTab(Memento(
|
||||||
|
_controller->peerId(),
|
||||||
|
_controller->migratedPeerId(),
|
||||||
|
newType));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
_otherTabs->lifetime());
|
_otherTabs->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<PeerData*> InnerWidget::peer() const {
|
|
||||||
return _list->peer();
|
|
||||||
}
|
|
||||||
|
|
||||||
Type InnerWidget::type() const {
|
Type InnerWidget::type() const {
|
||||||
return _list->type();
|
return _controller->section().mediaType();
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::visibleTopBottomUpdated(
|
void InnerWidget::visibleTopBottomUpdated(
|
||||||
|
@ -193,7 +193,7 @@ void InnerWidget::visibleTopBottomUpdated(
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InnerWidget::showInternal(not_null<Memento*> memento) {
|
bool InnerWidget::showInternal(not_null<Memento*> memento) {
|
||||||
if (memento->peerId() != peer()->id) {
|
if (!_controller->validateMementoPeer(memento)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
auto mementoType = memento->section().mediaType();
|
auto mementoType = memento->section().mediaType();
|
||||||
|
@ -210,8 +210,9 @@ bool InnerWidget::showInternal(not_null<Memento*> memento) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void InnerWidget::switchToTab(Memento &&memento) {
|
void InnerWidget::switchToTab(Memento &&memento) {
|
||||||
auto type = memento.section().mediaType();
|
// Save state of the tab before setSection() call.
|
||||||
_list = setupList(controller(), peer(), type);
|
_controller->setSection(memento.section());
|
||||||
|
_list = setupList();
|
||||||
restoreState(&memento);
|
restoreState(&memento);
|
||||||
_list->show();
|
_list->show();
|
||||||
_list->resizeToWidth(width());
|
_list->resizeToWidth(width());
|
||||||
|
@ -219,48 +220,28 @@ void InnerWidget::switchToTab(Memento &&memento) {
|
||||||
if (_otherTypes) {
|
if (_otherTypes) {
|
||||||
_otherTabsShadow->raise();
|
_otherTabsShadow->raise();
|
||||||
_otherTypes->raise();
|
_otherTypes->raise();
|
||||||
_otherTabs->setActiveSection(*TypeToTabIndex(type));
|
_otherTabs->setActiveSection(*TypeToTabIndex(type()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
not_null<Window::Controller*> InnerWidget::controller() const {
|
void InnerWidget::refreshSearchField() {
|
||||||
return _list->controller();
|
auto search = _controller->searchFieldController();
|
||||||
}
|
if (search && _otherTabs) {
|
||||||
|
_searchField = search->createView(
|
||||||
object_ptr<ListWidget> InnerWidget::setupList(
|
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type) {
|
|
||||||
if (SharedMediaAllowSearch(type)) {
|
|
||||||
_searchFieldController
|
|
||||||
= std::make_unique<Ui::SearchFieldController>();
|
|
||||||
_searchFieldController->queryValue()
|
|
||||||
| rpl::start_with_next([=](QString &&query) {
|
|
||||||
_searchController.setQuery(produceSearchQuery(
|
|
||||||
peer,
|
|
||||||
type,
|
|
||||||
std::move(query)));
|
|
||||||
}, _searchFieldController->lifetime());
|
|
||||||
_searchField = _searchFieldController->createView(
|
|
||||||
this,
|
this,
|
||||||
st::infoMediaSearch);
|
st::infoMediaSearch);
|
||||||
_searchField->resizeToWidth(width());
|
_searchField->resizeToWidth(width());
|
||||||
_searchField->show();
|
_searchField->show();
|
||||||
} else {
|
} else {
|
||||||
_searchField = nullptr;
|
_searchField = nullptr;
|
||||||
_searchFieldController = nullptr;
|
|
||||||
}
|
}
|
||||||
_searchController.setQueryFast(produceSearchQuery(peer, type));
|
}
|
||||||
|
|
||||||
|
object_ptr<ListWidget> InnerWidget::setupList() {
|
||||||
|
refreshSearchField();
|
||||||
auto result = object_ptr<ListWidget>(
|
auto result = object_ptr<ListWidget>(
|
||||||
this,
|
this,
|
||||||
controller,
|
_controller);
|
||||||
peer,
|
|
||||||
type,
|
|
||||||
produceListSource());
|
|
||||||
_searchController.sourceChanged()
|
|
||||||
| rpl::start_with_next([widget = result.data()]{
|
|
||||||
widget->restart();
|
|
||||||
}, result->lifetime());
|
|
||||||
result->heightValue()
|
result->heightValue()
|
||||||
| rpl::start_with_next(
|
| rpl::start_with_next(
|
||||||
[this] { refreshHeight(); },
|
[this] { refreshHeight(); },
|
||||||
|
@ -296,47 +277,6 @@ void InnerWidget::cancelSelection() {
|
||||||
|
|
||||||
InnerWidget::~InnerWidget() = default;
|
InnerWidget::~InnerWidget() = default;
|
||||||
|
|
||||||
ListWidget::Source InnerWidget::produceListSource() {
|
|
||||||
return [this](
|
|
||||||
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
|
||||||
int limitBefore,
|
|
||||||
int limitAfter) {
|
|
||||||
auto query = _searchController.currentQuery();
|
|
||||||
if (query.query.isEmpty()) {
|
|
||||||
return SharedMediaMergedViewer(
|
|
||||||
SharedMediaMergedKey(
|
|
||||||
SparseIdsMergedSlice::Key(
|
|
||||||
query.peerId,
|
|
||||||
query.migratedPeerId,
|
|
||||||
aroundId),
|
|
||||||
query.type),
|
|
||||||
limitBefore,
|
|
||||||
limitAfter);
|
|
||||||
}
|
|
||||||
return _searchController.idsSlice(
|
|
||||||
aroundId,
|
|
||||||
limitBefore,
|
|
||||||
limitAfter);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
auto InnerWidget::produceSearchQuery(
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type,
|
|
||||||
QString &&query) const -> SearchQuery {
|
|
||||||
auto result = SearchQuery();
|
|
||||||
result.type = type;
|
|
||||||
result.peerId = peer->id;
|
|
||||||
result.query = std::move(query);
|
|
||||||
result.migratedPeerId = [&] {
|
|
||||||
if (auto migrateFrom = peer->migrateFrom()) {
|
|
||||||
return migrateFrom->id;
|
|
||||||
}
|
|
||||||
return PeerId(0);
|
|
||||||
}();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
int InnerWidget::resizeGetHeight(int newWidth) {
|
int InnerWidget::resizeGetHeight(int newWidth) {
|
||||||
_inResize = true;
|
_inResize = true;
|
||||||
auto guard = gsl::finally([this] { _inResize = false; });
|
auto guard = gsl::finally([this] { _inResize = false; });
|
||||||
|
|
|
@ -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/unique_qptr.h"
|
||||||
#include "info/media/info_media_widget.h"
|
#include "info/media/info_media_widget.h"
|
||||||
#include "info/media/info_media_list_widget.h"
|
#include "info/media/info_media_list_widget.h"
|
||||||
#include "history/history_search_controller.h"
|
#include "history/history_search_controller.h"
|
||||||
|
@ -32,6 +33,9 @@ class SearchFieldController;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
|
class Controller;
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
|
||||||
class Memento;
|
class Memento;
|
||||||
|
@ -42,13 +46,7 @@ public:
|
||||||
using Type = Widget::Type;
|
using Type = Widget::Type;
|
||||||
InnerWidget(
|
InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> &&wrap,
|
not_null<Controller*> controller);
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type);
|
|
||||||
|
|
||||||
not_null<PeerData*> peer() const;
|
|
||||||
Type type() const;
|
|
||||||
|
|
||||||
bool showInternal(not_null<Memento*> memento);
|
bool showInternal(not_null<Memento*> memento);
|
||||||
|
|
||||||
|
@ -72,38 +70,29 @@ protected:
|
||||||
private:
|
private:
|
||||||
int recountHeight();
|
int recountHeight();
|
||||||
void refreshHeight();
|
void refreshHeight();
|
||||||
void setupOtherTypes(rpl::producer<Wrap> &&wrap);
|
void setupOtherTypes();
|
||||||
void createOtherTypes();
|
void createOtherTypes();
|
||||||
void createTypeButtons();
|
void createTypeButtons();
|
||||||
void createTabs();
|
void createTabs();
|
||||||
void switchToTab(Memento &&memento);
|
void switchToTab(Memento &&memento);
|
||||||
|
|
||||||
using SearchQuery = Api::DelayedSearchController::Query;
|
Type type() const;
|
||||||
ListWidget::Source produceListSource();
|
|
||||||
SearchQuery produceSearchQuery(
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type,
|
|
||||||
QString &&query = QString()) const;
|
|
||||||
|
|
||||||
not_null<Window::Controller*> controller() const;
|
void refreshSearchField();
|
||||||
|
object_ptr<ListWidget> setupList();
|
||||||
|
|
||||||
object_ptr<ListWidget> setupList(
|
const not_null<Controller*> _controller;
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type);
|
|
||||||
|
|
||||||
bool _inResize = false;
|
|
||||||
|
|
||||||
Ui::SettingsSlider *_otherTabs = nullptr;
|
Ui::SettingsSlider *_otherTabs = nullptr;
|
||||||
object_ptr<Ui::VerticalLayout> _otherTypes = { nullptr };
|
object_ptr<Ui::VerticalLayout> _otherTypes = { nullptr };
|
||||||
object_ptr<Ui::PlainShadow> _otherTabsShadow = { nullptr };
|
object_ptr<Ui::PlainShadow> _otherTabsShadow = { nullptr };
|
||||||
std::unique_ptr<Ui::SearchFieldController> _searchFieldController;
|
base::unique_qptr<Ui::RpWidget> _searchField = nullptr;
|
||||||
Ui::RpWidget *_searchField = nullptr;
|
|
||||||
object_ptr<ListWidget> _list = { nullptr };
|
object_ptr<ListWidget> _list = { nullptr };
|
||||||
|
|
||||||
|
bool _inResize = false;
|
||||||
|
|
||||||
rpl::event_stream<int> _scrollToRequests;
|
rpl::event_stream<int> _scrollToRequests;
|
||||||
rpl::event_stream<rpl::producer<SelectedItems>> _selectedLists;
|
rpl::event_stream<rpl::producer<SelectedItems>> _selectedLists;
|
||||||
Api::DelayedSearchController _searchController;
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -20,6 +20,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
*/
|
*/
|
||||||
#include "info/media/info_media_list_widget.h"
|
#include "info/media/info_media_list_widget.h"
|
||||||
|
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "overview/overview_layout.h"
|
#include "overview/overview_layout.h"
|
||||||
#include "history/history_media_types.h"
|
#include "history/history_media_types.h"
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
|
@ -538,15 +539,12 @@ void ListWidget::Section::refreshHeight() {
|
||||||
|
|
||||||
ListWidget::ListWidget(
|
ListWidget::ListWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Controller*> controller)
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type,
|
|
||||||
Source source)
|
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _peer(peer)
|
, _peer(_controller->peer())
|
||||||
, _type(type)
|
, _migrated(_controller->migrated())
|
||||||
, _source(std::move(source))
|
, _type(_controller->section().mediaType())
|
||||||
, _slice(sliceKey(_universalAroundId)) {
|
, _slice(sliceKey(_universalAroundId)) {
|
||||||
setAttribute(Qt::WA_MouseTracking);
|
setAttribute(Qt::WA_MouseTracking);
|
||||||
start();
|
start();
|
||||||
|
@ -574,6 +572,10 @@ void ListWidget::start() {
|
||||||
| rpl::start_with_next([this](auto item) {
|
| rpl::start_with_next([this](auto item) {
|
||||||
repaintItem(item);
|
repaintItem(item);
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
_controller->mediaSourceChanged()
|
||||||
|
| rpl::start_with_next([this]{
|
||||||
|
restart();
|
||||||
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ListWidget::restart() {
|
void ListWidget::restart() {
|
||||||
|
@ -733,13 +735,13 @@ void ListWidget::repaintItem(QRect itemGeometry) {
|
||||||
|
|
||||||
bool ListWidget::isMyItem(not_null<const HistoryItem*> item) const {
|
bool ListWidget::isMyItem(not_null<const HistoryItem*> item) const {
|
||||||
auto peer = item->history()->peer;
|
auto peer = item->history()->peer;
|
||||||
return (_peer == peer || _peer == peer->migrateTo());
|
return (_peer == peer) || (_migrated == peer);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::isPossiblyMyId(FullMsgId fullId) const {
|
bool ListWidget::isPossiblyMyId(FullMsgId fullId) const {
|
||||||
return (fullId.channel != 0)
|
return (fullId.channel != 0)
|
||||||
? (_peer->isChannel() && _peer->bareId() == fullId.channel)
|
? (_peer->isChannel() && _peer->bareId() == fullId.channel)
|
||||||
: (!_peer->isChannel() || _peer->migrateFrom());
|
: (!_peer->isChannel() || _migrated);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ListWidget::isItemLayout(
|
bool ListWidget::isItemLayout(
|
||||||
|
@ -757,8 +759,8 @@ void ListWidget::invalidatePaletteCache() {
|
||||||
SparseIdsMergedSlice::Key ListWidget::sliceKey(
|
SparseIdsMergedSlice::Key ListWidget::sliceKey(
|
||||||
UniversalMsgId universalId) const {
|
UniversalMsgId universalId) const {
|
||||||
using Key = SparseIdsMergedSlice::Key;
|
using Key = SparseIdsMergedSlice::Key;
|
||||||
if (auto migrateFrom = _peer->migrateFrom()) {
|
if (_migrated) {
|
||||||
return Key(_peer->id, migrateFrom->id, universalId);
|
return Key(_peer->id, _migrated->id, universalId);
|
||||||
}
|
}
|
||||||
if (universalId < 0) {
|
if (universalId < 0) {
|
||||||
// Convert back to plain id for non-migrated histories.
|
// Convert back to plain id for non-migrated histories.
|
||||||
|
@ -769,7 +771,10 @@ SparseIdsMergedSlice::Key ListWidget::sliceKey(
|
||||||
|
|
||||||
void ListWidget::refreshViewer() {
|
void ListWidget::refreshViewer() {
|
||||||
_viewerLifetime.destroy();
|
_viewerLifetime.destroy();
|
||||||
_source(_universalAroundId, _idsLimit, _idsLimit)
|
_controller->mediaSource(
|
||||||
|
sliceKey(_universalAroundId).universalId,
|
||||||
|
_idsLimit,
|
||||||
|
_idsLimit)
|
||||||
| rpl::start_with_next([this](
|
| rpl::start_with_next([this](
|
||||||
SparseIdsMergedSlice &&slice) {
|
SparseIdsMergedSlice &&slice) {
|
||||||
_slice = std::move(slice);
|
_slice = std::move(slice);
|
||||||
|
@ -1752,8 +1757,8 @@ void ListWidget::mouseActionStart(const QPoint &screenPos, Qt::MouseButton butto
|
||||||
auto pressLayout = _overLayout;
|
auto pressLayout = _overLayout;
|
||||||
|
|
||||||
_mouseAction = MouseAction::None;
|
_mouseAction = MouseAction::None;
|
||||||
_pressWasInactive = _controller->window()->wasInactivePress();
|
_pressWasInactive = _controller->window()->window()->wasInactivePress();
|
||||||
if (_pressWasInactive) _controller->window()->setInactivePress(false);
|
if (_pressWasInactive) _controller->window()->window()->setInactivePress(false);
|
||||||
|
|
||||||
if (ClickHandler::getPressed() && !hasSelected()) {
|
if (ClickHandler::getPressed() && !hasSelected()) {
|
||||||
_mouseAction = MouseAction::PrepareDrag;
|
_mouseAction = MouseAction::PrepareDrag;
|
||||||
|
|
|
@ -39,6 +39,9 @@ class Controller;
|
||||||
} // namespace Window
|
} // namespace Window
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
|
class Controller;
|
||||||
|
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
|
||||||
using BaseLayout = Overview::Layout::ItemBase;
|
using BaseLayout = Overview::Layout::ItemBase;
|
||||||
|
@ -47,27 +50,9 @@ using UniversalMsgId = int32;
|
||||||
class ListWidget : public Ui::RpWidget {
|
class ListWidget : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
using Type = Widget::Type;
|
using Type = Widget::Type;
|
||||||
using Source = base::lambda<
|
|
||||||
rpl::producer<SparseIdsMergedSlice>(
|
|
||||||
SparseIdsMergedSlice::UniversalMsgId aroundId,
|
|
||||||
int limitBefore,
|
|
||||||
int limitAfter)>;
|
|
||||||
ListWidget(
|
ListWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Controller*> controller);
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type,
|
|
||||||
Source source);
|
|
||||||
|
|
||||||
not_null<Window::Controller*> controller() const {
|
|
||||||
return _controller;
|
|
||||||
}
|
|
||||||
not_null<PeerData*> peer() const {
|
|
||||||
return _peer;
|
|
||||||
}
|
|
||||||
Type type() const {
|
|
||||||
return _type;
|
|
||||||
}
|
|
||||||
|
|
||||||
void restart();
|
void restart();
|
||||||
|
|
||||||
|
@ -103,6 +88,7 @@ protected:
|
||||||
void leaveEventHook(QEvent *e) override;
|
void leaveEventHook(QEvent *e) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
using Type = Widget::Type;
|
||||||
enum class MouseAction {
|
enum class MouseAction {
|
||||||
None,
|
None,
|
||||||
PrepareDrag,
|
PrepareDrag,
|
||||||
|
@ -280,10 +266,10 @@ private:
|
||||||
void validateTrippleClickStartTime();
|
void validateTrippleClickStartTime();
|
||||||
void checkMoveToOtherViewer();
|
void checkMoveToOtherViewer();
|
||||||
|
|
||||||
not_null<Window::Controller*> _controller;
|
const not_null<Controller*> _controller;
|
||||||
not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
|
PeerData * const _migrated = nullptr;
|
||||||
Type _type = Type::Photo;
|
Type _type = Type::Photo;
|
||||||
Source _source;
|
|
||||||
|
|
||||||
static constexpr auto kMinimalIdsLimit = 16;
|
static constexpr auto kMinimalIdsLimit = 16;
|
||||||
static constexpr auto kDefaultAroundId = (ServerMaxMsgId - 1);
|
static constexpr auto kDefaultAroundId = (ServerMaxMsgId - 1);
|
||||||
|
|
|
@ -21,39 +21,41 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/media/info_media_widget.h"
|
#include "info/media/info_media_widget.h"
|
||||||
|
|
||||||
#include "info/media/info_media_inner_widget.h"
|
#include "info/media/info_media_inner_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace Media {
|
namespace Media {
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Controller*> controller)
|
||||||
|
: Memento(
|
||||||
|
controller->peerId(),
|
||||||
|
controller->migratedPeerId(),
|
||||||
|
controller->section().mediaType()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Section Memento::section() const {
|
||||||
|
return Section(_type);
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<ContentWidget> Memento::createWidget(
|
object_ptr<ContentWidget> Memento::createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
const QRect &geometry) {
|
const QRect &geometry) {
|
||||||
auto result = object_ptr<Widget>(
|
auto result = object_ptr<Widget>(
|
||||||
parent,
|
parent,
|
||||||
std::move(wrap),
|
controller);
|
||||||
controller,
|
|
||||||
App::peer(peerId()),
|
|
||||||
_type);
|
|
||||||
result->setInternalState(geometry, this);
|
result->setInternalState(geometry, this);
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::Widget(
|
Widget::Widget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller)
|
||||||
not_null<Window::Controller*> controller,
|
: ContentWidget(parent, controller) {
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type)
|
|
||||||
: ContentWidget(parent, rpl::duplicate(wrap), controller, peer) {
|
|
||||||
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
||||||
this,
|
this,
|
||||||
std::move(wrap),
|
controller));
|
||||||
controller,
|
|
||||||
peer,
|
|
||||||
type));
|
|
||||||
_inner->scrollToRequests()
|
_inner->scrollToRequests()
|
||||||
| rpl::start_with_next([this](int skip) {
|
| rpl::start_with_next([this](int skip) {
|
||||||
scrollTo({ skip, -1 });
|
scrollTo({ skip, -1 });
|
||||||
|
@ -68,15 +70,10 @@ void Widget::cancelSelection() {
|
||||||
_inner->cancelSelection();
|
_inner->cancelSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Widget::section() const {
|
|
||||||
return Section(type());
|
|
||||||
}
|
|
||||||
|
|
||||||
Widget::Type Widget::type() const {
|
|
||||||
return _inner->type();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||||
|
if (!controller()->validateMementoPeer(memento)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (auto mediaMemento = dynamic_cast<Memento*>(memento.get())) {
|
if (auto mediaMemento = dynamic_cast<Memento*>(memento.get())) {
|
||||||
if (_inner->showInternal(mediaMemento)) {
|
if (_inner->showInternal(mediaMemento)) {
|
||||||
return true;
|
return true;
|
||||||
|
@ -92,7 +89,7 @@ void Widget::setInternalState(const QRect &geometry, not_null<Memento*> memento)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ContentMemento> Widget::createMemento() {
|
std::unique_ptr<ContentMemento> Widget::createMemento() {
|
||||||
auto result = std::make_unique<Memento>(peer()->id, type());
|
auto result = std::make_unique<Memento>(controller());
|
||||||
saveState(result.get());
|
saveState(result.get());
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,20 +33,19 @@ class Memento final : public ContentMemento {
|
||||||
public:
|
public:
|
||||||
using Type = Storage::SharedMediaType;
|
using Type = Storage::SharedMediaType;
|
||||||
|
|
||||||
Memento(PeerId peerId, Type type)
|
Memento(not_null<Controller*> controller);
|
||||||
: ContentMemento(peerId)
|
|
||||||
|
Memento(PeerId peerId, PeerId migratedPeerId, Type type)
|
||||||
|
: ContentMemento(peerId, migratedPeerId)
|
||||||
, _type(type) {
|
, _type(type) {
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<ContentWidget> createWidget(
|
object_ptr<ContentWidget> createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
const QRect &geometry) override;
|
const QRect &geometry) override;
|
||||||
|
|
||||||
Section section() const override {
|
Section section() const override;
|
||||||
return Section(_type);
|
|
||||||
}
|
|
||||||
|
|
||||||
Type type() const {
|
Type type() const {
|
||||||
return _type;
|
return _type;
|
||||||
|
@ -92,13 +91,7 @@ public:
|
||||||
|
|
||||||
Widget(
|
Widget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller);
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer,
|
|
||||||
Type type);
|
|
||||||
|
|
||||||
Type type() const;
|
|
||||||
Section section() const override;
|
|
||||||
|
|
||||||
bool showInternal(
|
bool showInternal(
|
||||||
not_null<ContentMemento*> memento) override;
|
not_null<ContentMemento*> memento) override;
|
||||||
|
@ -114,7 +107,7 @@ public:
|
||||||
private:
|
private:
|
||||||
void saveState(not_null<Memento*> memento);
|
void saveState(not_null<Memento*> memento);
|
||||||
void restoreState(not_null<Memento*> memento);
|
void restoreState(not_null<Memento*> memento);
|
||||||
|
|
||||||
InnerWidget *_inner = nullptr;
|
InnerWidget *_inner = nullptr;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -24,6 +24,8 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include <rpl/combine_previous.h>
|
#include <rpl/combine_previous.h>
|
||||||
#include <rpl/flatten_latest.h>
|
#include <rpl/flatten_latest.h>
|
||||||
#include "info/info_memento.h"
|
#include "info/info_memento.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
|
#include "info/info_top_bar_override.h"
|
||||||
#include "info/profile/info_profile_button.h"
|
#include "info/profile/info_profile_button.h"
|
||||||
#include "info/profile/info_profile_widget.h"
|
#include "info/profile/info_profile_widget.h"
|
||||||
#include "info/profile/info_profile_text.h"
|
#include "info/profile/info_profile_text.h"
|
||||||
|
@ -32,7 +34,6 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/profile/info_profile_icon.h"
|
#include "info/profile/info_profile_icon.h"
|
||||||
#include "info/profile/info_profile_members.h"
|
#include "info/profile/info_profile_members.h"
|
||||||
#include "info/media/info_media_buttons.h"
|
#include "info/media/info_media_buttons.h"
|
||||||
#include "info/info_top_bar_override.h"
|
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "boxes/add_contact_box.h"
|
#include "boxes/add_contact_box.h"
|
||||||
#include "boxes/confirm_box.h"
|
#include "boxes/confirm_box.h"
|
||||||
|
@ -59,13 +60,12 @@ namespace Profile {
|
||||||
|
|
||||||
InnerWidget::InnerWidget(
|
InnerWidget::InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> &&wrapValue,
|
not_null<Controller*> controller)
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer)
|
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _controller(controller)
|
, _controller(controller)
|
||||||
, _peer(peer)
|
, _peer(_controller->peer())
|
||||||
, _content(setupContent(this, std::move(wrapValue))) {
|
, _migrated(_controller->migrated())
|
||||||
|
, _content(setupContent(this)) {
|
||||||
_content->heightValue()
|
_content->heightValue()
|
||||||
| rpl::start_with_next([this](int height) {
|
| rpl::start_with_next([this](int height) {
|
||||||
resizeToWidth(width());
|
resizeToWidth(width());
|
||||||
|
@ -84,8 +84,7 @@ rpl::producer<bool> InnerWidget::canHideDetails() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
||||||
RpWidget *parent,
|
RpWidget *parent) {
|
||||||
rpl::producer<Wrap> &&wrapValue) {
|
|
||||||
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
||||||
_cover = result->add(object_ptr<Cover>(
|
_cover = result->add(object_ptr<Cover>(
|
||||||
result,
|
result,
|
||||||
|
@ -101,7 +100,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
||||||
} else {
|
} else {
|
||||||
result->add(std::move(details));
|
result->add(std::move(details));
|
||||||
}
|
}
|
||||||
result->add(setupSharedMedia(result, rpl::duplicate(wrapValue)));
|
result->add(setupSharedMedia(result));
|
||||||
result->add(object_ptr<BoxContentDivider>(result));
|
result->add(object_ptr<BoxContentDivider>(result));
|
||||||
if (auto user = _peer->asUser()) {
|
if (auto user = _peer->asUser()) {
|
||||||
result->add(setupUserActions(result, user));
|
result->add(setupUserActions(result, user));
|
||||||
|
@ -114,7 +113,6 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
|
||||||
_members = result->add(object_ptr<Members>(
|
_members = result->add(object_ptr<Members>(
|
||||||
result,
|
result,
|
||||||
_controller,
|
_controller,
|
||||||
std::move(wrapValue),
|
|
||||||
_peer)
|
_peer)
|
||||||
);
|
);
|
||||||
_members->scrollToRequests()
|
_members->scrollToRequests()
|
||||||
|
@ -241,10 +239,10 @@ void InnerWidget::setupUserButtons(
|
||||||
addButton(
|
addButton(
|
||||||
Lang::Viewer(lng_profile_send_message) | ToUpperValue()
|
Lang::Viewer(lng_profile_send_message) | ToUpperValue()
|
||||||
)->toggleOn(
|
)->toggleOn(
|
||||||
_controller->historyPeer.value()
|
_controller->window()->historyPeer.value()
|
||||||
| rpl::map($1 != user)
|
| rpl::map($1 != user)
|
||||||
)->entity()->addClickHandler([this, user] {
|
)->entity()->addClickHandler([this, user] {
|
||||||
_controller->showPeerHistory(
|
_controller->window()->showPeerHistory(
|
||||||
user,
|
user,
|
||||||
Window::SectionShow::Way::Forward);
|
Window::SectionShow::Way::Forward);
|
||||||
});
|
});
|
||||||
|
@ -266,8 +264,7 @@ void InnerWidget::setupUserButtons(
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
||||||
RpWidget *parent,
|
RpWidget *parent) {
|
||||||
rpl::producer<Wrap> &&wrapValue) {
|
|
||||||
using namespace rpl::mappers;
|
using namespace rpl::mappers;
|
||||||
using MediaType = Media::Type;
|
using MediaType = Media::Type;
|
||||||
|
|
||||||
|
@ -278,8 +275,9 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
||||||
const style::icon &icon) {
|
const style::icon &icon) {
|
||||||
auto result = Media::AddButton(
|
auto result = Media::AddButton(
|
||||||
content,
|
content,
|
||||||
_controller,
|
_controller->window(),
|
||||||
peer(),
|
_peer,
|
||||||
|
_migrated,
|
||||||
type,
|
type,
|
||||||
tracker);
|
tracker);
|
||||||
object_ptr<Profile::FloatingIcon>(
|
object_ptr<Profile::FloatingIcon>(
|
||||||
|
@ -292,7 +290,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
||||||
const style::icon &icon) {
|
const style::icon &icon) {
|
||||||
auto result = Media::AddCommonGroupsButton(
|
auto result = Media::AddCommonGroupsButton(
|
||||||
content,
|
content,
|
||||||
_controller,
|
_controller->window(),
|
||||||
user,
|
user,
|
||||||
tracker);
|
tracker);
|
||||||
object_ptr<Profile::FloatingIcon>(
|
object_ptr<Profile::FloatingIcon>(
|
||||||
|
@ -306,7 +304,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
||||||
addMediaButton(MediaType::File, st::infoIconMediaFile);
|
addMediaButton(MediaType::File, st::infoIconMediaFile);
|
||||||
addMediaButton(MediaType::MusicFile, st::infoIconMediaAudio);
|
addMediaButton(MediaType::MusicFile, st::infoIconMediaAudio);
|
||||||
addMediaButton(MediaType::Link, st::infoIconMediaLink);
|
addMediaButton(MediaType::Link, st::infoIconMediaLink);
|
||||||
if (auto user = peer()->asUser()) {
|
if (auto user = _peer->asUser()) {
|
||||||
addCommonGroupsButton(user, st::infoIconMediaGroup);
|
addCommonGroupsButton(user, st::infoIconMediaGroup);
|
||||||
}
|
}
|
||||||
addMediaButton(MediaType::VoiceFile, st::infoIconMediaVoice);
|
addMediaButton(MediaType::VoiceFile, st::infoIconMediaVoice);
|
||||||
|
@ -320,7 +318,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupSharedMedia(
|
||||||
using ToggledData = std::tuple<bool, Wrap, bool>;
|
using ToggledData = std::tuple<bool, Wrap, bool>;
|
||||||
rpl::combine(
|
rpl::combine(
|
||||||
tracker.atLeastOneShownValue(),
|
tracker.atLeastOneShownValue(),
|
||||||
std::move(wrapValue),
|
_controller->wrapValue(),
|
||||||
_isStackBottom.events())
|
_isStackBottom.events())
|
||||||
| rpl::combine_previous(ToggledData())
|
| rpl::combine_previous(ToggledData())
|
||||||
| rpl::start_with_next([wrap = result.data()](
|
| rpl::start_with_next([wrap = result.data()](
|
||||||
|
|
|
@ -37,6 +37,7 @@ struct ScrollToRequest;
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
enum class Wrap;
|
enum class Wrap;
|
||||||
|
class Controller;
|
||||||
|
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
|
||||||
|
@ -48,13 +49,7 @@ class InnerWidget final : public Ui::RpWidget {
|
||||||
public:
|
public:
|
||||||
InnerWidget(
|
InnerWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> &&wrapValue,
|
not_null<Controller*> controller);
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer);
|
|
||||||
|
|
||||||
not_null<PeerData*> peer() const {
|
|
||||||
return _peer;
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveState(not_null<Memento*> memento);
|
void saveState(not_null<Memento*> memento);
|
||||||
void restoreState(not_null<Memento*> memento);
|
void restoreState(not_null<Memento*> memento);
|
||||||
|
@ -77,13 +72,9 @@ protected:
|
||||||
int visibleBottom) override;
|
int visibleBottom) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
object_ptr<RpWidget> setupContent(
|
object_ptr<RpWidget> setupContent(RpWidget *parent);
|
||||||
RpWidget *parent,
|
|
||||||
rpl::producer<Wrap> &&wrapValue);
|
|
||||||
object_ptr<RpWidget> setupDetails(RpWidget *parent) const;
|
object_ptr<RpWidget> setupDetails(RpWidget *parent) const;
|
||||||
object_ptr<RpWidget> setupSharedMedia(
|
object_ptr<RpWidget> setupSharedMedia(RpWidget *parent);
|
||||||
RpWidget *parent,
|
|
||||||
rpl::producer<Wrap> &&wrapValue);
|
|
||||||
object_ptr<RpWidget> setupMuteToggle(RpWidget *parent) const;
|
object_ptr<RpWidget> setupMuteToggle(RpWidget *parent) const;
|
||||||
object_ptr<RpWidget> setupInfo(RpWidget *parent) const;
|
object_ptr<RpWidget> setupInfo(RpWidget *parent) const;
|
||||||
void setupUserButtons(
|
void setupUserButtons(
|
||||||
|
@ -105,8 +96,9 @@ private:
|
||||||
|
|
||||||
rpl::event_stream<bool> _isStackBottom;
|
rpl::event_stream<bool> _isStackBottom;
|
||||||
|
|
||||||
not_null<Window::Controller*> _controller;
|
const not_null<Controller*> _controller;
|
||||||
not_null<PeerData*> _peer;
|
const not_null<PeerData*> _peer;
|
||||||
|
PeerData * const _migrated = nullptr;
|
||||||
|
|
||||||
Members *_members = nullptr;
|
Members *_members = nullptr;
|
||||||
Cover *_cover = nullptr;
|
Cover *_cover = nullptr;
|
||||||
|
|
|
@ -27,6 +27,7 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
#include "info/profile/info_profile_values.h"
|
#include "info/profile/info_profile_values.h"
|
||||||
#include "info/profile/info_profile_members_controllers.h"
|
#include "info/profile/info_profile_members_controllers.h"
|
||||||
#include "info/info_content_widget.h"
|
#include "info/info_content_widget.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
#include "profile/profile_block_group_members.h"
|
#include "profile/profile_block_group_members.h"
|
||||||
#include "ui/widgets/labels.h"
|
#include "ui/widgets/labels.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
|
@ -48,12 +49,11 @@ constexpr auto kEnableSearchMembersAfterCount = 50;
|
||||||
|
|
||||||
Members::Members(
|
Members::Members(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
rpl::producer<Wrap> &&wrapValue,
|
|
||||||
not_null<PeerData*> peer)
|
not_null<PeerData*> peer)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _peer(peer)
|
, _peer(peer)
|
||||||
, _listController(CreateMembersController(controller, _peer))
|
, _listController(CreateMembersController(controller->window(), _peer))
|
||||||
, _labelWrap(this)
|
, _labelWrap(this)
|
||||||
, _label(setupHeader())
|
, _label(setupHeader())
|
||||||
, _addMember(this, st::infoMembersAddMember)
|
, _addMember(this, st::infoMembersAddMember)
|
||||||
|
@ -65,7 +65,7 @@ Members::Members(
|
||||||
, _cancelSearch(this, st::infoMembersCancelSearch)
|
, _cancelSearch(this, st::infoMembersCancelSearch)
|
||||||
, _list(setupList(this, _listController.get())) {
|
, _list(setupList(this, _listController.get())) {
|
||||||
setupButtons();
|
setupButtons();
|
||||||
std::move(wrapValue)
|
controller->wrapValue()
|
||||||
| rpl::start_with_next([this](Wrap wrap) {
|
| rpl::start_with_next([this](Wrap wrap) {
|
||||||
_wrap = wrap;
|
_wrap = wrap;
|
||||||
updateSearchOverrides();
|
updateSearchOverrides();
|
||||||
|
|
|
@ -38,6 +38,7 @@ class ParticipantsBoxController;
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
|
|
||||||
|
class Controller;
|
||||||
enum class Wrap;
|
enum class Wrap;
|
||||||
|
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
@ -50,8 +51,7 @@ class Members
|
||||||
public:
|
public:
|
||||||
Members(
|
Members(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
not_null<Window::Controller*> controller,
|
not_null<Controller*> controller,
|
||||||
rpl::producer<Wrap> &&wrapValue,
|
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
rpl::producer<Ui::ScrollToRequest> scrollToRequests() const {
|
rpl::producer<Ui::ScrollToRequest> scrollToRequests() const {
|
||||||
|
|
|
@ -164,17 +164,14 @@ rpl::producer<int> MembersCountValue(
|
||||||
|
|
||||||
rpl::producer<int> SharedMediaCountValue(
|
rpl::producer<int> SharedMediaCountValue(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
PeerData *migrated,
|
||||||
Storage::SharedMediaType type) {
|
Storage::SharedMediaType type) {
|
||||||
auto real = peer->migrateTo() ? peer->migrateTo() : peer;
|
|
||||||
auto migrated = real->migrateFrom()
|
|
||||||
? real->migrateFrom()
|
|
||||||
: nullptr;
|
|
||||||
auto aroundId = 0;
|
auto aroundId = 0;
|
||||||
auto limit = 0;
|
auto limit = 0;
|
||||||
auto updated = SharedMediaMergedViewer(
|
auto updated = SharedMediaMergedViewer(
|
||||||
SharedMediaMergedKey(
|
SharedMediaMergedKey(
|
||||||
SparseIdsMergedSlice::Key(
|
SparseIdsMergedSlice::Key(
|
||||||
real->id,
|
peer->id,
|
||||||
migrated ? migrated->id : 0,
|
migrated ? migrated->id : 0,
|
||||||
aroundId),
|
aroundId),
|
||||||
type),
|
type),
|
||||||
|
|
|
@ -67,6 +67,7 @@ rpl::producer<int> MembersCountValue(
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
rpl::producer<int> SharedMediaCountValue(
|
rpl::producer<int> SharedMediaCountValue(
|
||||||
not_null<PeerData*> peer,
|
not_null<PeerData*> peer,
|
||||||
|
PeerData *migrated,
|
||||||
Storage::SharedMediaType type);
|
Storage::SharedMediaType type);
|
||||||
rpl::producer<int> CommonGroupsCountValue(
|
rpl::producer<int> CommonGroupsCountValue(
|
||||||
not_null<UserData*> user);
|
not_null<UserData*> user);
|
||||||
|
|
|
@ -22,35 +22,39 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
#include "info/profile/info_profile_inner_widget.h"
|
#include "info/profile/info_profile_inner_widget.h"
|
||||||
#include "ui/widgets/scroll_area.h"
|
#include "ui/widgets/scroll_area.h"
|
||||||
|
#include "info/info_controller.h"
|
||||||
|
|
||||||
namespace Info {
|
namespace Info {
|
||||||
namespace Profile {
|
namespace Profile {
|
||||||
|
|
||||||
|
Memento::Memento(not_null<Controller*> controller)
|
||||||
|
: Memento(
|
||||||
|
controller->peerId(),
|
||||||
|
controller->migratedPeerId()) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Section Memento::section() const {
|
||||||
|
return Section(Section::Type::Profile);
|
||||||
|
}
|
||||||
|
|
||||||
object_ptr<ContentWidget> Memento::createWidget(
|
object_ptr<ContentWidget> Memento::createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
const QRect &geometry) {
|
const QRect &geometry) {
|
||||||
auto result = object_ptr<Widget>(
|
auto result = object_ptr<Widget>(
|
||||||
parent,
|
parent,
|
||||||
std::move(wrap),
|
controller);
|
||||||
controller,
|
|
||||||
App::peer(peerId()));
|
|
||||||
result->setInternalState(geometry, this);
|
result->setInternalState(geometry, this);
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget::Widget(
|
Widget::Widget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller)
|
||||||
not_null<Window::Controller*> controller,
|
: ContentWidget(parent, controller) {
|
||||||
not_null<PeerData*> peer)
|
|
||||||
: ContentWidget(parent, rpl::duplicate(wrap), controller, peer) {
|
|
||||||
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
_inner = setInnerWidget(object_ptr<InnerWidget>(
|
||||||
this,
|
this,
|
||||||
std::move(wrap),
|
controller));
|
||||||
controller,
|
|
||||||
peer));
|
|
||||||
_inner->move(0, 0);
|
_inner->move(0, 0);
|
||||||
_inner->scrollToRequests()
|
_inner->scrollToRequests()
|
||||||
| rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
| rpl::start_with_next([this](Ui::ScrollToRequest request) {
|
||||||
|
@ -67,20 +71,17 @@ void Widget::setIsStackBottom(bool isStackBottom) {
|
||||||
_inner->setIsStackBottom(isStackBottom);
|
_inner->setIsStackBottom(isStackBottom);
|
||||||
}
|
}
|
||||||
|
|
||||||
Section Widget::section() const {
|
|
||||||
return Section(Section::Type::Profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Widget::setInnerFocus() {
|
void Widget::setInnerFocus() {
|
||||||
_inner->setFocus();
|
_inner->setFocus();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
bool Widget::showInternal(not_null<ContentMemento*> memento) {
|
||||||
|
if (!controller()->validateMementoPeer(memento)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
if (auto profileMemento = dynamic_cast<Memento*>(memento.get())) {
|
if (auto profileMemento = dynamic_cast<Memento*>(memento.get())) {
|
||||||
if (profileMemento->peerId() == peer()->id) {
|
restoreState(profileMemento);
|
||||||
restoreState(profileMemento);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -92,7 +93,7 @@ void Widget::setInternalState(const QRect &geometry, not_null<Memento*> memento)
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<ContentMemento> Widget::createMemento() {
|
std::unique_ptr<ContentMemento> Widget::createMemento() {
|
||||||
auto result = std::make_unique<Memento>(peer()->id);
|
auto result = std::make_unique<Memento>(controller());
|
||||||
saveState(result.get());
|
saveState(result.get());
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,18 +31,17 @@ class InnerWidget;
|
||||||
|
|
||||||
class Memento final : public ContentMemento {
|
class Memento final : public ContentMemento {
|
||||||
public:
|
public:
|
||||||
Memento(PeerId peerId) : ContentMemento(peerId) {
|
Memento(not_null<Controller*> controller);
|
||||||
|
Memento(PeerId peerId, PeerId migratedPeerId)
|
||||||
|
: ContentMemento(peerId, migratedPeerId) {
|
||||||
}
|
}
|
||||||
|
|
||||||
object_ptr<ContentWidget> createWidget(
|
object_ptr<ContentWidget> createWidget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller,
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
const QRect &geometry) override;
|
const QRect &geometry) override;
|
||||||
|
|
||||||
Section section() const override {
|
Section section() const override;
|
||||||
return Section(Section::Type::Profile);
|
|
||||||
}
|
|
||||||
|
|
||||||
void setInfoExpanded(bool expanded) {
|
void setInfoExpanded(bool expanded) {
|
||||||
_infoExpanded = expanded;
|
_infoExpanded = expanded;
|
||||||
|
@ -74,12 +73,9 @@ class Widget final : public ContentWidget {
|
||||||
public:
|
public:
|
||||||
Widget(
|
Widget(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
rpl::producer<Wrap> wrap,
|
not_null<Controller*> controller);
|
||||||
not_null<Window::Controller*> controller,
|
|
||||||
not_null<PeerData*> peer);
|
|
||||||
|
|
||||||
void setIsStackBottom(bool isStackBottom) override;
|
void setIsStackBottom(bool isStackBottom) override;
|
||||||
Section section() const override;
|
|
||||||
|
|
||||||
bool showInternal(
|
bool showInternal(
|
||||||
not_null<ContentMemento*> memento) override;
|
not_null<ContentMemento*> memento) override;
|
||||||
|
|
|
@ -50,17 +50,19 @@ public:
|
||||||
}
|
}
|
||||||
auto events() const {
|
auto events() const {
|
||||||
return make_producer<Value>([weak = weak()](
|
return make_producer<Value>([weak = weak()](
|
||||||
const auto &consumer) {
|
const auto &consumer) {
|
||||||
if (auto strong = weak.lock()) {
|
if (auto strong = weak.lock()) {
|
||||||
auto result = [weak, consumer] {
|
auto result = [weak, consumer] {
|
||||||
if (auto strong = weak.lock()) {
|
if (auto strong = weak.lock()) {
|
||||||
auto it = base::find(*strong, consumer);
|
auto it = base::find(
|
||||||
if (it != strong->end()) {
|
strong->consumers,
|
||||||
|
consumer);
|
||||||
|
if (it != strong->consumers.end()) {
|
||||||
it->terminate();
|
it->terminate();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
strong->push_back(std::move(consumer));
|
strong->consumers.push_back(std::move(consumer));
|
||||||
return lifetime(std::move(result));
|
return lifetime(std::move(result));
|
||||||
}
|
}
|
||||||
return lifetime();
|
return lifetime();
|
||||||
|
@ -76,9 +78,13 @@ public:
|
||||||
~event_stream();
|
~event_stream();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::weak_ptr<std::vector<consumer<Value, no_error>>> weak() const;
|
struct Data {
|
||||||
|
std::vector<consumer<Value, no_error>> consumers;
|
||||||
|
int depth = 0;
|
||||||
|
};
|
||||||
|
std::weak_ptr<Data> weak() const;
|
||||||
|
|
||||||
mutable std::shared_ptr<std::vector<consumer<Value, no_error>>> _consumers;
|
mutable std::shared_ptr<Data> _data;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,13 +94,13 @@ inline event_stream<Value>::event_stream() {
|
||||||
|
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
inline event_stream<Value>::event_stream(event_stream &&other)
|
inline event_stream<Value>::event_stream(event_stream &&other)
|
||||||
: _consumers(base::take(other._consumers)) {
|
: _data(base::take(other._data)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
inline event_stream<Value> &event_stream<Value>::operator=(
|
inline event_stream<Value> &event_stream<Value>::operator=(
|
||||||
event_stream &&other) {
|
event_stream &&other) {
|
||||||
_consumers = base::take(other._consumers);
|
_data = base::take(other._data);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,11 +108,13 @@ template <typename Value>
|
||||||
template <typename OtherValue>
|
template <typename OtherValue>
|
||||||
inline void event_stream<Value>::fire_forward(
|
inline void event_stream<Value>::fire_forward(
|
||||||
OtherValue &&value) const {
|
OtherValue &&value) const {
|
||||||
if (!_consumers) {
|
auto copy = _data;
|
||||||
|
if (!copy) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto &consumers = *_consumers;
|
++copy->depth;
|
||||||
|
auto &consumers = copy->consumers;
|
||||||
auto begin = base::index_based_begin(consumers);
|
auto begin = base::index_based_begin(consumers);
|
||||||
auto end = base::index_based_end(consumers);
|
auto end = base::index_based_end(consumers);
|
||||||
if (begin != end) {
|
if (begin != end) {
|
||||||
|
@ -136,24 +144,28 @@ inline void event_stream<Value>::fire_forward(
|
||||||
}
|
}
|
||||||
|
|
||||||
// Erase stale consumers.
|
// Erase stale consumers.
|
||||||
consumers.erase(removeFrom.base(), consumers.end());
|
if (copy->depth == 1) {
|
||||||
|
consumers.erase(removeFrom.base(), consumers.end());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
--copy->depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
inline std::weak_ptr<std::vector<consumer<Value, no_error>>> event_stream<Value>::weak() const {
|
inline auto event_stream<Value>::weak() const
|
||||||
if (!_consumers) {
|
-> std::weak_ptr<Data> {
|
||||||
_consumers = std::make_shared<std::vector<consumer<Value, no_error>>>();
|
if (!_data) {
|
||||||
|
_data = std::make_shared<Data>();
|
||||||
}
|
}
|
||||||
return _consumers;
|
return _data;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
template <typename Value>
|
template <typename Value>
|
||||||
inline event_stream<Value>::~event_stream() {
|
inline event_stream<Value>::~event_stream() {
|
||||||
if (auto consumers = base::take(_consumers)) {
|
if (auto data = base::take(_data)) {
|
||||||
for (auto &consumer : *consumers) {
|
for (auto &consumer : data->consumers) {
|
||||||
consumer.put_done();
|
consumer.put_done();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,6 +81,9 @@ public:
|
||||||
auto value() const {
|
auto value() const {
|
||||||
return _changes.events_starting_with_copy(_data);
|
return _changes.events_starting_with_copy(_data);
|
||||||
}
|
}
|
||||||
|
auto changes() const {
|
||||||
|
return _changes.events();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <typename A, typename B>
|
template <typename A, typename B>
|
||||||
|
|
|
@ -29,20 +29,20 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
|
|
||||||
object_ptr<Ui::RpWidget> SearchFieldController::createView(
|
base::unique_qptr<Ui::RpWidget> SearchFieldController::createView(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const style::SearchFieldRow &st) {
|
const style::SearchFieldRow &st) {
|
||||||
auto result = object_ptr<Ui::FixedHeightWidget>(
|
auto result = base::make_unique_q<Ui::FixedHeightWidget>(
|
||||||
parent,
|
parent,
|
||||||
st.height);
|
st.height);
|
||||||
|
|
||||||
auto cancel = CreateChild<Ui::CrossButton>(
|
auto cancel = CreateChild<Ui::CrossButton>(
|
||||||
result.data(),
|
result.get(),
|
||||||
st.fieldCancel);
|
st.fieldCancel);
|
||||||
cancel->addClickHandler([=] { clearQuery(); });
|
cancel->addClickHandler([=] { clearQuery(); });
|
||||||
|
|
||||||
auto field = CreateChild<Ui::InputField>(
|
auto field = CreateChild<Ui::InputField>(
|
||||||
result.data(),
|
result.get(),
|
||||||
st.field,
|
st.field,
|
||||||
langFactory(lng_dlg_filter),
|
langFactory(lng_dlg_filter),
|
||||||
_query.current());
|
_query.current());
|
||||||
|
@ -54,7 +54,7 @@ object_ptr<Ui::RpWidget> SearchFieldController::createView(
|
||||||
clearQuery();
|
clearQuery();
|
||||||
});
|
});
|
||||||
|
|
||||||
auto shadow = CreateChild<Ui::PlainShadow>(result.data());
|
auto shadow = CreateChild<Ui::PlainShadow>(result.get());
|
||||||
shadow->show();
|
shadow->show();
|
||||||
|
|
||||||
result->widthValue()
|
result->widthValue()
|
||||||
|
@ -84,7 +84,7 @@ object_ptr<Ui::RpWidget> SearchFieldController::createView(
|
||||||
_view.wrap->width());
|
_view.wrap->width());
|
||||||
}, result->lifetime());
|
}, result->lifetime());
|
||||||
|
|
||||||
_view.wrap.reset(result);
|
_view.wrap.reset(result.get());
|
||||||
_view.cancel = cancel;
|
_view.cancel = cancel;
|
||||||
_view.field = field;
|
_view.field = field;
|
||||||
return std::move(result);
|
return std::move(result);
|
||||||
|
|
|
@ -35,7 +35,7 @@ class InputField;
|
||||||
|
|
||||||
class SearchFieldController {
|
class SearchFieldController {
|
||||||
public:
|
public:
|
||||||
object_ptr<Ui::RpWidget> createView(
|
base::unique_qptr<Ui::RpWidget> createView(
|
||||||
QWidget *parent,
|
QWidget *parent,
|
||||||
const style::SearchFieldRow &st);
|
const style::SearchFieldRow &st);
|
||||||
|
|
||||||
|
|
|
@ -219,6 +219,8 @@
|
||||||
<(src_loc)/info/info_common_groups_widget.h
|
<(src_loc)/info/info_common_groups_widget.h
|
||||||
<(src_loc)/info/info_content_widget.cpp
|
<(src_loc)/info/info_content_widget.cpp
|
||||||
<(src_loc)/info/info_content_widget.h
|
<(src_loc)/info/info_content_widget.h
|
||||||
|
<(src_loc)/info/info_controller.cpp
|
||||||
|
<(src_loc)/info/info_controller.h
|
||||||
<(src_loc)/info/info_layer_widget.cpp
|
<(src_loc)/info/info_layer_widget.cpp
|
||||||
<(src_loc)/info/info_layer_widget.h
|
<(src_loc)/info/info_layer_widget.h
|
||||||
<(src_loc)/info/info_memento.cpp
|
<(src_loc)/info/info_memento.cpp
|
||||||
|
|
Loading…
Reference in New Issue