/* 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 { class Key { public: explicit Key(not_null peer); explicit Key(not_null topic); Key(Settings::Tag settings); Key(Downloads::Tag downloads); Key(not_null poll, FullMsgId contextId); PeerData *peer() const; Data::ForumTopic *topic() const; UserData *settingsSelf() const; bool isDownloads() 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, PollKey> _value; }; enum class Wrap; class WrapWidget; class Memento; class ContentMemento; class Section final { public: enum class Type { Profile, Media, CommonGroups, Members, Settings, Downloads, PollResults, }; 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); virtual Key key() const = 0; virtual PeerData *migrated() const = 0; virtual Section section() const = 0; PeerData *peer() const; PeerId migratedPeerId() const; UserData *settingsSelf() const { return key().settingsSelf(); } bool isDownloads() const { return key().isDownloads(); } PollData *poll() const; 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(); 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