2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-23 02:37:11 +00:00
tdesktop/Telegram/SourceFiles/info/info_controller.h

379 lines
8.7 KiB
C
Raw Normal View History

/*
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
2024-11-17 12:22:12 +04:00
#include "data/data_message_reaction_id.h"
#include "data/data_search_controller.h"
#include "info/statistics/info_statistics_tag.h"
#include "window/window_session_controller.h"
2024-11-17 12:22:12 +04:00
namespace Api {
struct WhoReadList;
} // namespace Api
2022-09-27 16:05:47 +04:00
namespace Data {
class ForumTopic;
} // namespace Data
namespace Ui {
class SearchFieldController;
} // namespace Ui
2022-09-27 16:05:47 +04:00
namespace Info::Settings {
2018-09-05 22:05:49 +03:00
struct Tag {
explicit Tag(not_null<UserData*> self) : self(self) {
}
not_null<UserData*> self;
};
2022-09-27 16:05:47 +04:00
} // namespace Info::Settings
2022-09-27 16:05:47 +04:00
namespace Info::Downloads {
struct Tag {
};
2022-09-27 16:05:47 +04:00
} // namespace Info::Downloads
2024-12-17 21:16:38 +04:00
namespace Info::GlobalMedia {
struct Tag {
explicit Tag(not_null<UserData*> self) : self(self) {
}
not_null<UserData*> self;
};
} // namespace Info::GlobalMedia
namespace Info::Stories {
enum class Tab {
Saved,
Archive,
};
struct Tag {
explicit Tag(not_null<PeerData*> peer, Tab tab = {})
: peer(peer)
, tab(tab) {
}
not_null<PeerData*> peer;
Tab tab = {};
};
} // namespace Info::Stories
namespace Info::BotStarRef {
enum class Type : uchar {
Setup,
Join,
};
struct Tag {
Tag(not_null<PeerData*> peer, Type type) : peer(peer), type(type) {
}
not_null<PeerData*> peer;
Type type = {};
};
} // namespace Info::BotStarRef
2022-09-27 16:05:47 +04:00
namespace Info {
2018-01-22 22:51:38 +03:00
class Key {
public:
2022-09-27 16:05:47 +04:00
explicit Key(not_null<PeerData*> peer);
explicit Key(not_null<Data::ForumTopic*> topic);
2018-09-05 22:05:49 +03:00
Key(Settings::Tag settings);
Key(Downloads::Tag downloads);
Key(Stories::Tag stories);
Key(Statistics::Tag statistics);
Key(BotStarRef::Tag starref);
2024-12-17 21:16:38 +04:00
Key(GlobalMedia::Tag global);
Key(not_null<PollData*> poll, FullMsgId contextId);
2024-11-17 12:22:12 +04:00
Key(
std::shared_ptr<Api::WhoReadList> whoReadIds,
Data::ReactionId selected,
FullMsgId contextId);
2018-01-22 22:51:38 +03:00
PeerData *peer() const;
2022-09-27 16:05:47 +04:00
Data::ForumTopic *topic() const;
2018-09-05 22:05:49 +03:00
UserData *settingsSelf() const;
bool isDownloads() const;
2024-12-17 21:16:38 +04:00
bool isGlobalMedia() const;
PeerData *storiesPeer() const;
Stories::Tab storiesTab() const;
Statistics::Tag statisticsTag() const;
PeerData *starrefPeer() const;
BotStarRef::Type starrefType() const;
PollData *poll() const;
FullMsgId pollContextId() const;
2024-11-17 12:22:12 +04:00
std::shared_ptr<Api::WhoReadList> reactionsWhoReadIds() const;
Data::ReactionId reactionsSelected() const;
FullMsgId reactionsContextId() const;
2018-01-22 22:51:38 +03:00
private:
struct PollKey {
not_null<PollData*> poll;
FullMsgId contextId;
};
2024-11-17 12:22:12 +04:00
struct ReactionsKey {
std::shared_ptr<Api::WhoReadList> whoReadIds;
Data::ReactionId selected;
FullMsgId contextId;
};
std::variant<
2018-09-05 22:05:49 +03:00
not_null<PeerData*>,
2022-09-27 16:05:47 +04:00
not_null<Data::ForumTopic*>,
Settings::Tag,
Downloads::Tag,
Stories::Tag,
Statistics::Tag,
BotStarRef::Tag,
2024-12-17 21:16:38 +04:00
GlobalMedia::Tag,
2024-11-17 12:22:12 +04:00
PollKey,
ReactionsKey> _value;
2018-01-22 22:51:38 +03:00
};
enum class Wrap;
class WrapWidget;
class Memento;
class ContentMemento;
class Section final {
public:
enum class Type {
Profile,
Media,
2024-12-17 21:16:38 +04:00
GlobalMedia,
CommonGroups,
SimilarChannels,
2024-11-16 20:46:30 +04:00
RequestsList,
2024-11-17 12:22:12 +04:00
ReactionsList,
SavedSublists,
2024-09-20 15:07:01 +04:00
PeerGifts,
Members,
2018-09-05 22:05:49 +03:00
Settings,
Downloads,
Stories,
PollResults,
Statistics,
BotStarRef,
2023-10-11 23:13:10 +03:00
Boosts,
ChannelEarn,
2024-06-19 04:53:33 +03:00
BotEarn,
};
2018-09-05 22:05:49 +03:00
using SettingsType = ::Settings::Type;
using MediaType = Storage::SharedMediaType;
Section(Type type) : _type(type) {
2024-12-17 21:16:38 +04:00
Expects(type != Type::Media
&& type != Type::GlobalMedia
&& type != Type::Settings);
}
2024-12-17 21:16:38 +04:00
Section(MediaType mediaType, Type type = Type::Media)
: _type(type)
, _mediaType(mediaType) {
}
2018-09-05 22:05:49 +03:00
Section(SettingsType settingsType)
: _type(Type::Settings)
, _settingsType(settingsType) {
}
2024-12-17 21:16:38 +04:00
[[nodiscard]] Type type() const {
return _type;
}
2024-12-17 21:16:38 +04:00
[[nodiscard]] MediaType mediaType() const {
Expects(_type == Type::Media || _type == Type::GlobalMedia);
2018-09-05 22:05:49 +03:00
return _mediaType;
}
2024-12-17 21:16:38 +04:00
[[nodiscard]] SettingsType settingsType() const {
2018-09-05 22:05:49 +03:00
Expects(_type == Type::Settings);
return _settingsType;
}
private:
Type _type;
2018-09-05 22:05:49 +03:00
MediaType _mediaType = MediaType();
SettingsType _settingsType = SettingsType();
};
class AbstractController : public Window::SessionNavigation {
public:
AbstractController(not_null<Window::SessionController*> 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 {
2022-10-11 19:08:19 +04:00
return key().topic();
}
[[nodiscard]] UserData *settingsSelf() const {
2018-09-05 22:05:49 +03:00
return key().settingsSelf();
}
[[nodiscard]] bool isDownloads() const {
return key().isDownloads();
}
2024-12-17 21:16:38 +04:00
[[nodiscard]] bool isGlobalMedia() const {
return key().isGlobalMedia();
}
[[nodiscard]] PeerData *storiesPeer() const {
return key().storiesPeer();
}
[[nodiscard]] Stories::Tab storiesTab() const {
return key().storiesTab();
}
[[nodiscard]] Statistics::Tag statisticsTag() const {
return key().statisticsTag();
}
[[nodiscard]] PeerData *starrefPeer() const {
return key().starrefPeer();
}
[[nodiscard]] BotStarRef::Type starrefType() const {
return key().starrefType();
}
[[nodiscard]] PollData *poll() const;
[[nodiscard]] FullMsgId pollContextId() const {
return key().pollContextId();
}
2024-11-17 12:22:12 +04:00
[[nodiscard]] auto reactionsWhoReadIds() const
-> std::shared_ptr<Api::WhoReadList>;
[[nodiscard]] Data::ReactionId reactionsSelected() const;
[[nodiscard]] FullMsgId reactionsContextId() const;
virtual void setSearchEnabledByContent(bool enabled) {
}
virtual rpl::producer<SparseIdsMergedSlice> mediaSource(
SparseIdsMergedSlice::UniversalMsgId aroundId,
int limitBefore,
int limitAfter) const;
virtual rpl::producer<QString> mediaSourceQueryValue() const;
2022-03-11 15:14:07 +04:00
virtual rpl::producer<QString> searchQueryValue() const;
void showSection(
2020-12-14 18:48:10 +04:00
std::shared_ptr<Window::SectionMemento> memento,
const Window::SectionShow &params = Window::SectionShow()) override;
void showBackFromStack(
const Window::SectionShow &params = Window::SectionShow()) override;
2020-09-22 18:05:07 +03:00
void showPeerHistory(
PeerId peerId,
const Window::SectionShow &params = Window::SectionShow::Way::ClearStack,
MsgId msgId = ShowAtUnreadMsgId) override;
not_null<Window::SessionController*> parentController() override {
return _parent;
}
private:
not_null<Window::SessionController*> _parent;
};
class Controller : public AbstractController {
public:
Controller(
not_null<WrapWidget*> widget,
not_null<Window::SessionController*> window,
not_null<ContentMemento*> memento);
2018-01-22 22:51:38 +03:00
Key key() const override {
return _key;
}
PeerData *migrated() const override {
return _migrated;
}
Section section() const override {
return _section;
}
bool validateMementoPeer(
not_null<ContentMemento*> memento) const;
Wrap wrap() const;
rpl::producer<Wrap> wrapValue() const;
2017-11-03 19:47:08 +04:00
void setSection(not_null<ContentMemento*> memento);
Ui::SearchFieldController *searchFieldController() const {
return _searchFieldController.get();
}
void setSearchEnabledByContent(bool enabled) override {
_seachEnabledByContent = enabled;
}
2017-11-21 13:20:56 +04:00
rpl::producer<bool> searchEnabledByContent() const;
rpl::producer<SparseIdsMergedSlice> mediaSource(
SparseIdsMergedSlice::UniversalMsgId aroundId,
int limitBefore,
int limitAfter) const override;
rpl::producer<QString> mediaSourceQueryValue() const override;
2022-03-11 15:14:07 +04:00
rpl::producer<QString> searchQueryValue() const override;
bool takeSearchStartsFocused() {
return base::take(_searchStartsFocused);
}
2017-11-03 19:47:08 +04:00
void saveSearchState(not_null<ContentMemento*> memento);
void showSection(
2020-12-14 18:48:10 +04:00
std::shared_ptr<Window::SectionMemento> memento,
const Window::SectionShow &params = Window::SectionShow()) override;
void showBackFromStack(
const Window::SectionShow &params = Window::SectionShow()) override;
void removeFromStack(const std::vector<Section> &sections) const;
void takeStepData(not_null<Controller*> another);
std::any &stepDataReference();
rpl::lifetime &lifetime() {
return _lifetime;
}
~Controller();
private:
using SearchQuery = Api::DelayedSearchController::Query;
2017-11-03 19:47:08 +04:00
void updateSearchControllers(not_null<ContentMemento*> memento);
SearchQuery produceSearchQuery(const QString &query) const;
void setupMigrationViewer();
2022-10-04 19:34:45 +04:00
void setupTopicViewer();
void replaceWith(std::shared_ptr<Memento> memento);
not_null<WrapWidget*> _widget;
2018-01-22 22:51:38 +03:00
Key _key;
PeerData *_migrated = nullptr;
rpl::variable<Wrap> _wrap;
Section _section;
std::unique_ptr<Ui::SearchFieldController> _searchFieldController;
std::unique_ptr<Api::DelayedSearchController> _searchController;
rpl::variable<bool> _seachEnabledByContent = false;
bool _searchStartsFocused = false;
// Data between sections based on steps.
std::any _stepData;
rpl::lifetime _lifetime;
};
} // namespace Info