tdesktop/Telegram/SourceFiles/window/window_session_controller.h

690 lines
19 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
2017-08-31 16:28:58 +00:00
#include "base/flags.h"
2019-09-13 12:22:54 +00:00
#include "base/object_ptr.h"
2020-06-10 18:08:17 +00:00
#include "base/weak_ptr.h"
2020-07-01 14:19:25 +00:00
#include "base/timer.h"
2022-07-03 14:56:12 +00:00
#include "boxes/gift_premium_box.h" // GiftPremiumValidator.
#include "data/data_chat_participant_status.h"
#include "dialogs/dialogs_key.h"
#include "ui/layers/layer_widget.h"
#include "ui/layers/show.h"
#include "settings/settings_type.h"
#include "window/window_adaptive.h"
#include "mtproto/sender.h"
2017-08-31 16:28:58 +00:00
class PhotoData;
class MainWidget;
class MainWindow;
namespace Adaptive {
enum class WindowLayout;
} // namespace Adaptive
namespace ChatHelpers {
class TabbedSelector;
class EmojiInteractions;
2022-09-14 10:45:23 +00:00
struct FileChosen;
} // namespace ChatHelpers
2019-07-24 11:45:24 +00:00
namespace Main {
class Session;
} // namespace Main
namespace InlineBots {
class AttachWebView;
2022-06-02 20:26:41 +00:00
enum class PeerType : uint8;
using PeerTypes = base::flags<PeerType>;
} // namespace InlineBots
namespace Calls {
struct StartGroupCallArgs;
} // namespace Calls
namespace Passport {
struct FormRequest;
class FormController;
} // namespace Passport
2019-09-18 11:19:05 +00:00
namespace Ui {
class LayerWidget;
enum class ReportReason;
class ChatStyle;
2021-08-26 13:25:48 +00:00
class ChatTheme;
struct ChatThemeKey;
2021-08-26 15:02:21 +00:00
struct ChatPaintContext;
struct ChatThemeBackground;
struct ChatThemeBackgroundData;
class MessageSendingAnimationController;
2021-08-26 15:02:21 +00:00
} // namespace Ui
2021-08-26 13:25:48 +00:00
namespace Data {
struct CloudTheme;
enum class CloudThemeType;
class Thread;
class Forum;
class ForumTopic;
2021-08-26 13:25:48 +00:00
} // namespace Data
namespace HistoryView::Reactions {
class CachedIconFactory;
} // namespace HistoryView::Reactions
namespace Window {
class MainWindow;
class SectionMemento;
2019-09-03 15:24:51 +00:00
class Controller;
2020-03-03 12:07:22 +00:00
class FiltersMenu;
2017-10-13 17:35:29 +00:00
enum class GifPauseReason {
Any = 0,
InlineResults = (1 << 0),
TabbedPanel = (1 << 1),
Layer = (1 << 2),
RoundPlaying = (1 << 3),
MediaPreview = (1 << 4),
};
2017-08-31 16:28:58 +00:00
using GifPauseReasons = base::flags<GifPauseReason>;
inline constexpr bool is_flag_type(GifPauseReason) { return true; };
enum class ResolveType {
Default,
BotStart,
AddToGroup,
AddToChannel,
ShareGame,
Mention,
};
2021-09-24 15:10:25 +00:00
struct PeerThemeOverride {
PeerData *peer = nullptr;
std::shared_ptr<Ui::ChatTheme> theme;
};
bool operator==(const PeerThemeOverride &a, const PeerThemeOverride &b);
bool operator!=(const PeerThemeOverride &a, const PeerThemeOverride &b);
2018-02-21 21:17:36 +00:00
class DateClickHandler : public ClickHandler {
public:
DateClickHandler(Dialogs::Key chat, QDate date);
void setDate(QDate date);
void onClick(ClickContext context) const override;
2018-02-21 21:17:36 +00:00
private:
Dialogs::Key _chat;
base::weak_ptr<Data::ForumTopic> _weak;
2018-02-21 21:17:36 +00:00
QDate _date;
};
struct SectionShow {
enum class Way {
Forward,
Backward,
ClearStack,
};
struct OriginMessage {
FullMsgId id;
};
using Origin = std::variant<v::null_t, OriginMessage>;
SectionShow(
Way way = Way::Forward,
anim::type animated = anim::type::normal,
anim::activation activation = anim::activation::normal)
: way(way)
, animated(animated)
, activation(activation) {
}
SectionShow(
anim::type animated,
anim::activation activation = anim::activation::normal)
: animated(animated)
, activation(activation) {
}
[[nodiscard]] SectionShow withWay(Way newWay) const {
return SectionShow(newWay, animated, activation);
}
[[nodiscard]] SectionShow withThirdColumn() const {
auto copy = *this;
copy.thirdColumn = true;
return copy;
}
[[nodiscard]] SectionShow withChildColumn() const {
auto copy = *this;
copy.childColumn = true;
return copy;
}
Way way = Way::Forward;
anim::type animated = anim::type::normal;
anim::activation activation = anim::activation::normal;
bool thirdColumn = false;
bool childColumn = false;
Origin origin;
};
class SessionController;
2020-06-30 14:26:44 +00:00
class SessionNavigation : public base::has_weak_ptr {
public:
2019-07-24 11:45:24 +00:00
explicit SessionNavigation(not_null<Main::Session*> session);
2020-09-03 08:21:31 +00:00
virtual ~SessionNavigation();
2019-01-18 12:27:37 +00:00
2019-07-24 11:45:24 +00:00
Main::Session &session() const;
2019-01-18 12:27:37 +00:00
virtual void showSection(
2020-12-14 14:48:10 +00:00
std::shared_ptr<SectionMemento> memento,
const SectionShow &params = SectionShow()) = 0;
virtual void showBackFromStack(
const SectionShow &params = SectionShow()) = 0;
virtual not_null<SessionController*> parentController() = 0;
2020-09-22 15:05:07 +00:00
struct CommentId {
MsgId id = 0;
};
struct ThreadId {
MsgId id = 0;
};
using RepliesByLinkInfo = std::variant<v::null_t, CommentId, ThreadId>;
struct PeerByLinkInfo {
std::variant<QString, ChannelId> usernameOrId;
2022-03-01 11:44:29 +00:00
QString phone;
2020-09-22 15:05:07 +00:00
MsgId messageId = ShowAtUnreadMsgId;
RepliesByLinkInfo repliesInfo;
ResolveType resolveType = ResolveType::Default;
2020-09-22 15:05:07 +00:00
QString startToken;
ChatAdminRights startAdminRights;
bool startAutoSubmit = false;
QString attachBotUsername;
2022-03-31 09:24:13 +00:00
std::optional<QString> attachBotToggleCommand;
2022-06-02 20:26:41 +00:00
InlineBots::PeerTypes attachBotChooseTypes;
2021-03-10 20:03:20 +00:00
std::optional<QString> voicechatHash;
2020-09-22 15:05:07 +00:00
FullMsgId clickFromMessageId;
};
void showPeerByLink(const PeerByLinkInfo &info);
2020-09-03 08:21:31 +00:00
void showRepliesForMessage(
not_null<History*> history,
MsgId rootId,
MsgId commentId = 0,
2020-09-03 08:21:31 +00:00
const SectionShow &params = SectionShow());
2022-10-27 07:35:35 +00:00
void showTopic(
not_null<Data::ForumTopic*> topic,
2022-11-01 04:46:31 +00:00
MsgId itemId = 0,
const SectionShow &params = SectionShow());
void showThread(
not_null<Data::Thread*> thread,
MsgId itemId = 0,
2022-10-27 07:35:35 +00:00
const SectionShow &params = SectionShow());
2020-09-03 08:21:31 +00:00
void showPeerInfo(
PeerId peerId,
const SectionShow &params = SectionShow());
void showPeerInfo(
not_null<PeerData*> peer,
const SectionShow &params = SectionShow());
void showPeerInfo(
not_null<Data::Thread*> thread,
const SectionShow &params = SectionShow());
2020-09-22 15:05:07 +00:00
virtual void showPeerHistory(
PeerId peerId,
const SectionShow &params = SectionShow::Way::ClearStack,
MsgId msgId = ShowAtUnreadMsgId) = 0;
void showPeerHistory(
not_null<PeerData*> peer,
const SectionShow &params = SectionShow::Way::ClearStack,
MsgId msgId = ShowAtUnreadMsgId);
void showPeerHistory(
not_null<History*> history,
const SectionShow &params = SectionShow::Way::ClearStack,
MsgId msgId = ShowAtUnreadMsgId);
void clearSectionStack(
const SectionShow &params = SectionShow::Way::ClearStack) {
showPeerHistory(
PeerId(0),
params,
ShowAtUnreadMsgId);
}
2018-09-05 19:05:49 +00:00
void showSettings(
Settings::Type type,
const SectionShow &params = SectionShow());
void showSettings(const SectionShow &params = SectionShow());
void showPollResults(
not_null<PollData*> poll,
FullMsgId contextId,
const SectionShow &params = SectionShow());
2019-01-18 12:27:37 +00:00
private:
2022-03-01 11:44:29 +00:00
void resolvePhone(
const QString &phone,
Fn<void(not_null<PeerData*>)> done);
2020-09-22 15:05:07 +00:00
void resolveUsername(
const QString &username,
Fn<void(not_null<PeerData*>)> done);
void resolveChannelById(
ChannelId channelId,
Fn<void(not_null<ChannelData*>)> done);
2022-03-01 11:44:29 +00:00
void resolveDone(
const MTPcontacts_ResolvedPeer &result,
Fn<void(not_null<PeerData*>)> done);
void showMessageByLinkResolved(
not_null<HistoryItem*> item,
const PeerByLinkInfo &info);
2020-09-22 15:05:07 +00:00
void showPeerByLinkResolved(
not_null<PeerData*> peer,
const PeerByLinkInfo &info);
2022-03-31 09:24:13 +00:00
void joinVoiceChatFromLink(
not_null<PeerData*> peer,
const PeerByLinkInfo &info);
2020-09-22 15:05:07 +00:00
2019-07-24 11:45:24 +00:00
const not_null<Main::Session*> _session;
2019-01-18 12:27:37 +00:00
MTP::Sender _api;
2020-09-22 15:05:07 +00:00
mtpRequestId _resolveRequestId = 0;
2020-09-03 08:21:31 +00:00
History *_showingRepliesHistory = nullptr;
MsgId _showingRepliesRootId = 0;
mtpRequestId _showingRepliesRequestId = 0;
};
class SessionController : public SessionNavigation {
public:
SessionController(
2019-07-24 11:45:24 +00:00
not_null<Main::Session*> session,
2019-09-03 15:24:51 +00:00
not_null<Controller*> window);
~SessionController();
2019-09-03 15:24:51 +00:00
[[nodiscard]] Controller &window() const {
return *_window;
}
[[nodiscard]] PeerData *singlePeer() const;
[[nodiscard]] bool isPrimary() const;
2019-09-03 15:24:51 +00:00
[[nodiscard]] not_null<::MainWindow*> widget() const;
2020-06-10 18:08:17 +00:00
[[nodiscard]] not_null<MainWidget*> content() const;
[[nodiscard]] Adaptive &adaptive() const;
[[nodiscard]] ChatHelpers::EmojiInteractions &emojiInteractions() const {
return *_emojiInteractions;
}
void setConnectingBottomSkip(int skip);
rpl::producer<int> connectingBottomSkipValue() const;
2022-09-14 10:45:23 +00:00
using FileChosen = ChatHelpers::FileChosen;
void stickerOrEmojiChosen(FileChosen chosen);
[[nodiscard]] rpl::producer<FileChosen> stickerOrEmojiChosen() const;
QPointer<Ui::BoxContent> show(
object_ptr<Ui::BoxContent> content,
Ui::LayerOptions options = Ui::LayerOption::KeepOther,
anim::type animated = anim::type::normal);
void hideLayer(anim::type animated = anim::type::normal);
[[nodiscard]] auto sendingAnimation() const
-> Ui::MessageSendingAnimationController &;
[[nodiscard]] auto tabbedSelector() const
-> not_null<ChatHelpers::TabbedSelector*>;
void takeTabbedSelectorOwnershipFrom(not_null<QWidget*> parent);
[[nodiscard]] bool hasTabbedSelectorOwnership() const;
// This is needed for History TopBar updating when searchInChat
2019-04-24 10:15:10 +00:00
// is changed in the Dialogs::Widget of the current window.
rpl::variable<Dialogs::Key> searchInChat;
2019-04-24 10:15:10 +00:00
bool uniqueChatsInSearchResults() const;
2019-04-24 10:15:10 +00:00
void openFolder(not_null<Data::Folder*> folder);
void closeFolder();
const rpl::variable<Data::Folder*> &openedFolder() const;
void showForum(
not_null<Data::Forum*> forum,
const SectionShow &params = SectionShow::Way::ClearStack);
void closeForum();
const rpl::variable<Data::Forum*> &shownForum() const;
void setActiveChatEntry(Dialogs::RowDescriptor row);
void setActiveChatEntry(Dialogs::Key key);
Dialogs::RowDescriptor activeChatEntryCurrent() const;
Dialogs::Key activeChatCurrent() const;
rpl::producer<Dialogs::RowDescriptor> activeChatEntryChanges() const;
rpl::producer<Dialogs::Key> activeChatChanges() const;
rpl::producer<Dialogs::RowDescriptor> activeChatEntryValue() const;
rpl::producer<Dialogs::Key> activeChatValue() const;
bool jumpToChatListEntry(Dialogs::RowDescriptor row);
2022-02-05 15:15:24 +00:00
[[nodiscard]] Dialogs::RowDescriptor resolveChatNext(
Dialogs::RowDescriptor from = {}) const;
[[nodiscard]] Dialogs::RowDescriptor resolveChatPrevious(
Dialogs::RowDescriptor from = {}) const;
void showEditPeerBox(PeerData *peer);
2022-07-03 14:56:12 +00:00
void showGiftPremiumBox(UserData *user);
2017-11-08 16:45:30 +00:00
void enableGifPauseReason(GifPauseReason reason);
void disableGifPauseReason(GifPauseReason reason);
rpl::producer<> gifPauseLevelChanged() const {
return _gifPauseLevelChanged.events();
}
bool isGifPausedAtLeastFor(GifPauseReason reason) const;
void floatPlayerAreaUpdated();
void materializeLocalDrafts();
[[nodiscard]] rpl::producer<> materializeLocalDraftsRequests() const;
struct ColumnLayout {
int bodyWidth = 0;
int dialogsWidth = 0;
int chatWidth = 0;
int thirdWidth = 0;
Adaptive::WindowLayout windowLayout = Adaptive::WindowLayout();
};
[[nodiscard]] ColumnLayout computeColumnLayout() const;
int dialogsSmallColumnWidth() const;
bool forceWideDialogs() const;
void updateColumnLayout();
bool canShowThirdSection() const;
2017-09-19 10:32:34 +00:00
bool canShowThirdSectionWithoutResize() const;
bool takeThirdSectionFromLayer();
void resizeForThirdSection();
void closeThirdSection();
[[nodiscard]] bool canShowSeparateWindow(not_null<PeerData*> peer) const;
void showPeer(not_null<PeerData*> peer, MsgId msgId = ShowAtUnreadMsgId);
void startOrJoinGroupCall(not_null<PeerData*> peer);
2020-12-08 15:09:13 +00:00
void startOrJoinGroupCall(
not_null<PeerData*> peer,
Calls::StartGroupCallArgs args);
2020-12-08 15:09:13 +00:00
void showSection(
2020-12-14 14:48:10 +00:00
std::shared_ptr<SectionMemento> memento,
const SectionShow &params = SectionShow()) override;
void showBackFromStack(
const SectionShow &params = SectionShow()) override;
2020-09-22 15:05:07 +00:00
using SessionNavigation::showPeerHistory;
void showPeerHistory(
PeerId peerId,
const SectionShow &params = SectionShow::Way::ClearStack,
2020-09-22 15:05:07 +00:00
MsgId msgId = ShowAtUnreadMsgId) override;
2022-11-01 07:18:56 +00:00
void showMessage(
not_null<const HistoryItem*> item,
const SectionShow &params = SectionShow::Way::ClearStack);
void cancelUploadLayer(not_null<HistoryItem*> item);
void showLayer(
std::unique_ptr<Ui::LayerWidget> &&layer,
Ui::LayerOptions options,
anim::type animated = anim::type::normal);
void showSpecialLayer(
2019-09-18 11:19:05 +00:00
object_ptr<Ui::LayerWidget> &&layer,
anim::type animated = anim::type::normal);
void hideSpecialLayer(
anim::type animated = anim::type::normal) {
showSpecialLayer(nullptr, animated);
}
void removeLayerBlackout();
void showCalendar(
2018-02-21 21:17:36 +00:00
Dialogs::Key chat,
QDate requestedDate);
void showAddContact();
void showNewGroup();
void showNewChannel();
void showPassportForm(const Passport::FormRequest &request);
void clearPassportForm();
2022-10-11 15:08:19 +00:00
void openPhoto(
not_null<PhotoData*> photo,
FullMsgId contextId,
MsgId topicRootId);
void openPhoto(not_null<PhotoData*> photo, not_null<PeerData*> peer);
void openDocument(
not_null<DocumentData*> document,
FullMsgId contextId,
2022-10-11 15:08:19 +00:00
MsgId topicRootId,
bool showInMediaView = false);
void showChooseReportMessages(
not_null<PeerData*> peer,
Ui::ReportReason reason,
Fn<void(MessageIdsList)> done);
void clearChooseReportMessages();
2021-09-24 15:10:25 +00:00
void toggleChooseChatTheme(not_null<PeerData*> peer);
[[nodiscard]] bool dialogsListFocused() const {
return _dialogsListFocused.current();
}
[[nodiscard]] rpl::producer<bool> dialogsListFocusedChanges() const {
return _dialogsListFocused.changes();
}
void setDialogsListFocused(bool value) {
_dialogsListFocused = value;
}
[[nodiscard]] bool dialogsListDisplayForced() const {
return _dialogsListDisplayForced.current();
}
[[nodiscard]] auto dialogsListDisplayForcedChanges() const
-> rpl::producer<bool> {
return _dialogsListDisplayForced.changes();
}
void setDialogsListDisplayForced(bool value) {
_dialogsListDisplayForced = value;
}
not_null<SessionController*> parentController() override {
return this;
}
2020-03-03 12:07:22 +00:00
[[nodiscard]] int filtersWidth() const;
[[nodiscard]] rpl::producer<FilterId> activeChatsFilter() const;
[[nodiscard]] FilterId activeChatsFilterCurrent() const;
void setActiveChatsFilter(
FilterId id,
const SectionShow &params = SectionShow::Way::ClearStack);
2020-03-03 12:07:22 +00:00
void toggleFiltersMenu(bool enabled);
[[nodiscard]] rpl::producer<> filtersMenuChanged() const;
2020-03-03 12:07:22 +00:00
2021-08-26 13:25:48 +00:00
[[nodiscard]] auto defaultChatTheme() const
2021-08-26 15:02:21 +00:00
-> const std::shared_ptr<Ui::ChatTheme> & {
2021-08-26 13:25:48 +00:00
return _defaultChatTheme;
}
2021-08-26 13:25:48 +00:00
[[nodiscard]] auto cachedChatThemeValue(
const Data::CloudTheme &data,
Data::CloudThemeType type)
2021-08-26 15:02:21 +00:00
-> rpl::producer<std::shared_ptr<Ui::ChatTheme>>;
void setChatStyleTheme(const std::shared_ptr<Ui::ChatTheme> &theme);
void clearCachedChatThemes();
2021-09-24 15:10:25 +00:00
void pushLastUsedChatTheme(const std::shared_ptr<Ui::ChatTheme> &theme);
[[nodiscard]] not_null<Ui::ChatTheme*> currentChatTheme() const;
2021-09-24 15:10:25 +00:00
void overridePeerTheme(
not_null<PeerData*> peer,
std::shared_ptr<Ui::ChatTheme> theme);
void clearPeerThemeOverride(not_null<PeerData*> peer);
[[nodiscard]] auto peerThemeOverrideValue() const
-> rpl::producer<PeerThemeOverride> {
return _peerThemeOverride.value();
}
2021-08-26 13:25:48 +00:00
struct PaintContextArgs {
2021-08-26 15:02:21 +00:00
not_null<Ui::ChatTheme*> theme;
int visibleAreaTop = 0;
int visibleAreaTopGlobal = 0;
int visibleAreaWidth = 0;
QRect clip;
};
2021-08-26 15:02:21 +00:00
[[nodiscard]] Ui::ChatPaintContext preparePaintContext(
2021-08-26 13:25:48 +00:00
PaintContextArgs &&args);
[[nodiscard]] not_null<const Ui::ChatStyle*> chatStyle() const {
return _chatStyle.get();
}
[[nodiscard]] auto cachedReactionIconFactory() const
-> HistoryView::Reactions::CachedIconFactory & {
return *_cachedReactionIconFactory;
}
void setPremiumRef(const QString &ref);
[[nodiscard]] QString premiumRef() const;
2022-11-30 12:55:51 +00:00
[[nodiscard]] bool contentOverlapped(QWidget *w, QPaintEvent *e);
[[nodiscard]] rpl::lifetime &lifetime() {
return _lifetime;
}
private:
struct CachedTheme;
2019-01-18 12:27:37 +00:00
void init();
void initSupportMode();
void refreshFiltersMenu();
void checkOpenedFilter();
void suggestArchiveAndMute();
void activateFirstChatsFilter();
int minimalThreeColumnWidth() const;
2017-11-12 16:50:58 +00:00
int countDialogsWidthFromRatio(int bodyWidth) const;
int countThirdColumnWidthFromRatio(int bodyWidth) const;
struct ShrinkResult {
int dialogsWidth;
int thirdWidth;
};
ShrinkResult shrinkDialogsAndThirdColumns(
int dialogsWidth,
int thirdWidth,
int bodyWidth) const;
void pushToChatEntryHistory(Dialogs::RowDescriptor row);
bool chatEntryHistoryMove(int steps);
void resetFakeUnreadWhileOpened();
2020-07-01 14:19:25 +00:00
void checkInvitePeek();
2022-06-07 08:41:10 +00:00
void setupPremiumToast();
2020-07-01 14:19:25 +00:00
2021-08-26 15:02:21 +00:00
void pushDefaultChatBackground();
void cacheChatTheme(
const Data::CloudTheme &data,
Data::CloudThemeType type);
void cacheChatThemeDone(std::shared_ptr<Ui::ChatTheme> result);
void updateCustomThemeBackground(CachedTheme &theme);
[[nodiscard]] Ui::ChatThemeBackgroundData backgroundData(
CachedTheme &theme,
bool generateGradient = true) const;
2019-09-03 15:24:51 +00:00
const not_null<Controller*> _window;
const std::unique_ptr<ChatHelpers::EmojiInteractions> _emojiInteractions;
const bool _isPrimary = false;
using SendingAnimation = Ui::MessageSendingAnimationController;
const std::unique_ptr<SendingAnimation> _sendingAnimation;
std::unique_ptr<Passport::FormController> _passportForm;
2020-03-03 12:07:22 +00:00
std::unique_ptr<FiltersMenu> _filters;
2017-08-31 16:28:58 +00:00
GifPauseReasons _gifPauseReasons = 0;
rpl::event_stream<> _gifPauseLevelChanged;
// Depends on _gifPause*.
const std::unique_ptr<ChatHelpers::TabbedSelector> _tabbedSelector;
rpl::variable<Dialogs::RowDescriptor> _activeChatEntry;
rpl::lifetime _activeHistoryLifetime;
rpl::variable<bool> _dialogsListFocused = false;
rpl::variable<bool> _dialogsListDisplayForced = false;
std::deque<Dialogs::RowDescriptor> _chatEntryHistory;
int _chatEntryHistoryPosition = -1;
bool _filtersActivated = false;
2020-07-01 14:19:25 +00:00
base::Timer _invitePeekTimer;
2020-03-03 12:07:22 +00:00
rpl::variable<FilterId> _activeChatsFilter;
rpl::variable<int> _connectingBottomSkip;
2022-09-14 10:45:23 +00:00
rpl::event_stream<ChatHelpers::FileChosen> _stickerOrEmojiChosen;
PeerData *_showEditPeer = nullptr;
2019-04-24 10:15:10 +00:00
rpl::variable<Data::Folder*> _openedFolder;
rpl::variable<Data::Forum*> _shownForum;
rpl::lifetime _shownForumLifetime;
rpl::event_stream<> _filtersMenuChanged;
2021-08-26 15:02:21 +00:00
std::shared_ptr<Ui::ChatTheme> _defaultChatTheme;
base::flat_map<Ui::ChatThemeKey, CachedTheme> _customChatThemes;
2021-08-26 15:02:21 +00:00
rpl::event_stream<std::shared_ptr<Ui::ChatTheme>> _cachedThemesStream;
const std::unique_ptr<Ui::ChatStyle> _chatStyle;
std::weak_ptr<Ui::ChatTheme> _chatStyleTheme;
std::deque<std::shared_ptr<Ui::ChatTheme>> _lastUsedCustomChatThemes;
2021-09-24 15:10:25 +00:00
rpl::variable<PeerThemeOverride> _peerThemeOverride;
using ReactionIconFactory = HistoryView::Reactions::CachedIconFactory;
std::unique_ptr<ReactionIconFactory> _cachedReactionIconFactory;
2022-07-03 14:56:12 +00:00
GiftPremiumValidator _giftPremiumValidator;
QString _premiumRef;
rpl::event_stream<> _materializeLocalDraftsRequests;
rpl::lifetime _lifetime;
};
void ActivateWindow(not_null<SessionController*> controller);
[[nodiscard]] bool IsPaused(
not_null<SessionController*> controller,
GifPauseReason level);
[[nodiscard]] Fn<bool()> PausedIn(
not_null<SessionController*> controller,
GifPauseReason level);
class Show : public Ui::Show {
public:
explicit Show(not_null<SessionNavigation*> navigation);
explicit Show(Controller *window);
~Show();
void showBox(
object_ptr<Ui::BoxContent> content,
Ui::LayerOptions options = Ui::LayerOption::KeepOther) const override;
void hideLayer() const override;
[[nodiscard]] not_null<QWidget*> toastParent() const override;
[[nodiscard]] bool valid() const override;
operator bool() const override;
2022-06-07 08:41:10 +00:00
private:
const base::weak_ptr<Controller> _window;
2022-06-07 08:41:10 +00:00
};
} // namespace Window