/* This file is part of Telegram Desktop, the official desktop application for the Telegram messaging service. For license and copyright information please follow this link: https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once #include "data/data_search_controller.h" #include "window/window_session_controller.h" namespace Data { class ForumTopic; } // namespace Data namespace Ui { class SearchFieldController; } // namespace Ui namespace Info::Settings { struct Tag { explicit Tag(not_null self) : self(self) { } not_null self; }; } // namespace Info::Settings namespace Info::Downloads { struct Tag { }; } // namespace Info::Downloads namespace Info::Stories { enum class Tab { Saved, Archive, }; struct Tag { explicit Tag(not_null peer, Tab tab = {}) : peer(peer) , tab(tab) { } not_null peer; Tab tab = {}; }; } // namespace Info::Stories namespace Info::Statistics { struct Tag { explicit Tag(not_null peer, FullMsgId contextId) : peer(peer) , contextId(contextId) { } not_null peer; FullMsgId contextId; }; } // namespace Info::Statistics namespace Info { class Key { public: explicit Key(not_null peer); explicit Key(not_null topic); Key(Settings::Tag settings); Key(Downloads::Tag downloads); Key(Stories::Tag stories); Key(Statistics::Tag statistics); Key(not_null poll, FullMsgId contextId); PeerData *peer() const; Data::ForumTopic *topic() const; UserData *settingsSelf() const; bool isDownloads() const; PeerData *storiesPeer() const; Stories::Tab storiesTab() const; PeerData *statisticsPeer() const; FullMsgId statisticsContextId() const; PollData *poll() const; FullMsgId pollContextId() const; private: struct PollKey { not_null poll; FullMsgId contextId; }; std::variant< not_null, not_null, Settings::Tag, Downloads::Tag, Stories::Tag, Statistics::Tag, PollKey> _value; }; enum class Wrap; class WrapWidget; class Memento; class ContentMemento; class Section final { public: enum class Type { Profile, Media, CommonGroups, Members, Settings, Downloads, Stories, PollResults, Statistics, Boosts, }; using SettingsType = ::Settings::Type; using MediaType = Storage::SharedMediaType; Section(Type type) : _type(type) { Expects(type != Type::Media && type != Type::Settings); } Section(MediaType mediaType) : _type(Type::Media) , _mediaType(mediaType) { } Section(SettingsType settingsType) : _type(Type::Settings) , _settingsType(settingsType) { } Type type() const { return _type; } MediaType mediaType() const { Expects(_type == Type::Media); return _mediaType; } SettingsType settingsType() const { Expects(_type == Type::Settings); return _settingsType; } private: Type _type; MediaType _mediaType = MediaType(); SettingsType _settingsType = SettingsType(); }; class AbstractController : public Window::SessionNavigation { public: AbstractController(not_null parent); [[nodiscard]] virtual Key key() const = 0; [[nodiscard]] virtual PeerData *migrated() const = 0; [[nodiscard]] virtual Section section() const = 0; [[nodiscard]] PeerData *peer() const; [[nodiscard]] PeerId migratedPeerId() const; [[nodiscard]] Data::ForumTopic *topic() const { return key().topic(); } [[nodiscard]] UserData *settingsSelf() const { return key().settingsSelf(); } [[nodiscard]] bool isDownloads() const { return key().isDownloads(); } [[nodiscard]] PeerData *storiesPeer() const { return key().storiesPeer(); } [[nodiscard]] Stories::Tab storiesTab() const { return key().storiesTab(); } [[nodiscard]] PeerData *statisticsPeer() const { return key().statisticsPeer(); } [[nodiscard]] FullMsgId statisticsContextId() const { return key().statisticsContextId(); } [[nodiscard]] PollData *poll() const; [[nodiscard]] FullMsgId pollContextId() const { return key().pollContextId(); } virtual void setSearchEnabledByContent(bool enabled) { } virtual rpl::producer mediaSource( SparseIdsMergedSlice::UniversalMsgId aroundId, int limitBefore, int limitAfter) const; virtual rpl::producer mediaSourceQueryValue() const; virtual rpl::producer searchQueryValue() const; void showSection( std::shared_ptr memento, const Window::SectionShow ¶ms = Window::SectionShow()) override; void showBackFromStack( const Window::SectionShow ¶ms = Window::SectionShow()) override; void showPeerHistory( PeerId peerId, const Window::SectionShow ¶ms = Window::SectionShow::Way::ClearStack, MsgId msgId = ShowAtUnreadMsgId) override; not_null parentController() override { return _parent; } private: not_null _parent; }; class Controller : public AbstractController { public: Controller( not_null widget, not_null window, not_null memento); Key key() const override { return _key; } PeerData *migrated() const override { return _migrated; } Section section() const override { return _section; } bool validateMementoPeer( not_null memento) const; Wrap wrap() const; rpl::producer wrapValue() const; void setSection(not_null memento); Ui::SearchFieldController *searchFieldController() const { return _searchFieldController.get(); } void setSearchEnabledByContent(bool enabled) override { _seachEnabledByContent = enabled; } rpl::producer searchEnabledByContent() const; rpl::producer mediaSource( SparseIdsMergedSlice::UniversalMsgId aroundId, int limitBefore, int limitAfter) const override; rpl::producer mediaSourceQueryValue() const override; rpl::producer searchQueryValue() const override; bool takeSearchStartsFocused() { return base::take(_searchStartsFocused); } void saveSearchState(not_null memento); void showSection( std::shared_ptr memento, const Window::SectionShow ¶ms = Window::SectionShow()) override; void showBackFromStack( const Window::SectionShow ¶ms = Window::SectionShow()) override; void removeFromStack(const std::vector
§ions) const; void takeStepData(not_null another); std::any &stepDataReference(); rpl::lifetime &lifetime() { return _lifetime; } ~Controller(); private: using SearchQuery = Api::DelayedSearchController::Query; void updateSearchControllers(not_null memento); SearchQuery produceSearchQuery(const QString &query) const; void setupMigrationViewer(); void setupTopicViewer(); void replaceWith(std::shared_ptr memento); not_null _widget; Key _key; PeerData *_migrated = nullptr; rpl::variable _wrap; Section _section; std::unique_ptr _searchFieldController; std::unique_ptr _searchController; rpl::variable _seachEnabledByContent = false; bool _searchStartsFocused = false; // Data between sections based on steps. std::any _stepData; rpl::lifetime _lifetime; }; } // namespace Info