tdesktop/Telegram/SourceFiles/data/data_session.h

532 lines
16 KiB
C++

/*
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 "chat_helpers/stickers.h"
#include "dialogs/dialogs_key.h"
#include "data/data_groups.h"
class HistoryItem;
namespace HistoryView {
struct Group;
class Element;
} // namespace HistoryView
class AuthSession;
namespace Media {
namespace Clip {
class Reader;
} // namespace Clip
} // namespace Media
namespace Data {
class Feed;
enum class FeedUpdateFlag;
struct FeedUpdate;
class Session final {
public:
using ViewElement = HistoryView::Element;
explicit Session(not_null<AuthSession*> session);
~Session();
AuthSession &session() const {
return *_session;
}
base::Variable<bool> &contactsLoaded() {
return _contactsLoaded;
}
base::Variable<bool> &allChatsLoaded() {
return _allChatsLoaded;
}
base::Observable<void> &moreChatsLoaded() {
return _moreChatsLoaded;
}
struct ItemVisibilityQuery {
not_null<HistoryItem*> item;
not_null<bool*> isVisible;
};
base::Observable<ItemVisibilityQuery> &queryItemVisibility() {
return _queryItemVisibility;
}
struct IdChange {
not_null<HistoryItem*> item;
MsgId oldId = 0;
};
void notifyItemIdChange(IdChange event);
rpl::producer<IdChange> itemIdChanged() const;
void notifyItemLayoutChange(not_null<const HistoryItem*> item);
rpl::producer<not_null<const HistoryItem*>> itemLayoutChanged() const;
void notifyViewLayoutChange(not_null<const ViewElement*> view);
rpl::producer<not_null<const ViewElement*>> viewLayoutChanged() const;
void requestItemRepaint(not_null<const HistoryItem*> item);
rpl::producer<not_null<const HistoryItem*>> itemRepaintRequest() const;
void requestViewRepaint(not_null<const ViewElement*> view);
rpl::producer<not_null<const ViewElement*>> viewRepaintRequest() const;
void requestItemResize(not_null<const HistoryItem*> item);
rpl::producer<not_null<const HistoryItem*>> itemResizeRequest() const;
void requestViewResize(not_null<ViewElement*> view);
rpl::producer<not_null<ViewElement*>> viewResizeRequest() const;
void requestItemViewRefresh(not_null<HistoryItem*> item);
rpl::producer<not_null<HistoryItem*>> itemViewRefreshRequest() const;
void requestAnimationPlayInline(not_null<HistoryItem*> item);
rpl::producer<not_null<HistoryItem*>> animationPlayInlineRequest() const;
void notifyHistoryUnloaded(not_null<const History*> history);
rpl::producer<not_null<const History*>> historyUnloaded() const;
void notifyItemRemoved(not_null<const HistoryItem*> item);
rpl::producer<not_null<const HistoryItem*>> itemRemoved() const;
void notifyHistoryCleared(not_null<const History*> history);
rpl::producer<not_null<const History*>> historyCleared() const;
void notifyHistoryChangeDelayed(not_null<History*> history);
rpl::producer<not_null<History*>> historyChanged() const;
void sendHistoryChangeNotifications();
using MegagroupParticipant = std::tuple<
not_null<ChannelData*>,
not_null<UserData*>>;
void removeMegagroupParticipant(
not_null<ChannelData*> channel,
not_null<UserData*> user);
rpl::producer<MegagroupParticipant> megagroupParticipantRemoved() const;
rpl::producer<not_null<UserData*>> megagroupParticipantRemoved(
not_null<ChannelData*> channel) const;
void addNewMegagroupParticipant(
not_null<ChannelData*> channel,
not_null<UserData*> user);
rpl::producer<MegagroupParticipant> megagroupParticipantAdded() const;
rpl::producer<not_null<UserData*>> megagroupParticipantAdded(
not_null<ChannelData*> channel) const;
void notifyFeedUpdated(not_null<Feed*> feed, FeedUpdateFlag update);
rpl::producer<FeedUpdate> feedUpdated() const;
void notifyStickersUpdated();
rpl::producer<> stickersUpdated() const;
void notifySavedGifsUpdated();
rpl::producer<> savedGifsUpdated() const;
bool stickersUpdateNeeded(TimeMs now) const {
return stickersUpdateNeeded(_lastStickersUpdate, now);
}
void setLastStickersUpdate(TimeMs update) {
_lastStickersUpdate = update;
}
bool recentStickersUpdateNeeded(TimeMs now) const {
return stickersUpdateNeeded(_lastRecentStickersUpdate, now);
}
void setLastRecentStickersUpdate(TimeMs update) {
_lastRecentStickersUpdate = update;
}
bool favedStickersUpdateNeeded(TimeMs now) const {
return stickersUpdateNeeded(_lastFavedStickersUpdate, now);
}
void setLastFavedStickersUpdate(TimeMs update) {
_lastFavedStickersUpdate = update;
}
bool featuredStickersUpdateNeeded(TimeMs now) const {
return stickersUpdateNeeded(_lastFeaturedStickersUpdate, now);
}
void setLastFeaturedStickersUpdate(TimeMs update) {
_lastFeaturedStickersUpdate = update;
}
bool savedGifsUpdateNeeded(TimeMs now) const {
return stickersUpdateNeeded(_lastSavedGifsUpdate, now);
}
void setLastSavedGifsUpdate(TimeMs update) {
_lastSavedGifsUpdate = update;
}
int featuredStickerSetsUnreadCount() const {
return _featuredStickerSetsUnreadCount.current();
}
void setFeaturedStickerSetsUnreadCount(int count) {
_featuredStickerSetsUnreadCount = count;
}
rpl::producer<int> featuredStickerSetsUnreadCountValue() const {
return _featuredStickerSetsUnreadCount.value();
}
const Stickers::Sets &stickerSets() const {
return _stickerSets;
}
Stickers::Sets &stickerSetsRef() {
return _stickerSets;
}
const Stickers::Order &stickerSetsOrder() const {
return _stickerSetsOrder;
}
Stickers::Order &stickerSetsOrderRef() {
return _stickerSetsOrder;
}
const Stickers::Order &featuredStickerSetsOrder() const {
return _featuredStickerSetsOrder;
}
Stickers::Order &featuredStickerSetsOrderRef() {
return _featuredStickerSetsOrder;
}
const Stickers::Order &archivedStickerSetsOrder() const {
return _archivedStickerSetsOrder;
}
Stickers::Order &archivedStickerSetsOrderRef() {
return _archivedStickerSetsOrder;
}
const Stickers::SavedGifs &savedGifs() const {
return _savedGifs;
}
Stickers::SavedGifs &savedGifsRef() {
return _savedGifs;
}
HistoryItemsList idsToItems(const MessageIdsList &ids) const;
MessageIdsList itemsToIds(const HistoryItemsList &items) const;
MessageIdsList itemOrItsGroup(not_null<HistoryItem*> item) const;
int pinnedDialogsCount() const;
const std::deque<Dialogs::Key> &pinnedDialogsOrder() const;
void setPinnedDialog(const Dialogs::Key &key, bool pinned);
void applyPinnedDialogs(const QVector<MTPDialog> &list);
void applyPinnedDialogs(const QVector<MTPDialogPeer> &list);
void reorderTwoPinnedDialogs(
const Dialogs::Key &key1,
const Dialogs::Key &key2);
void photoLoadSettingsChanged();
void voiceLoadSettingsChanged();
void animationLoadSettingsChanged();
void notifyPhotoLayoutChanged(not_null<const PhotoData*> photo);
void notifyDocumentLayoutChanged(
not_null<const DocumentData*> document);
void requestDocumentViewRepaint(not_null<const DocumentData*> document);
void markMediaRead(not_null<const DocumentData*> document);
not_null<PhotoData*> photo(PhotoId id);
not_null<PhotoData*> photo(const MTPPhoto &data);
not_null<PhotoData*> photo(const MTPDphoto &data);
not_null<PhotoData*> photo(
const MTPPhoto &data,
const PreparedPhotoThumbs &thumbs);
not_null<PhotoData*> photo(
PhotoId id,
const uint64 &access,
TimeId date,
const ImagePtr &thumb,
const ImagePtr &medium,
const ImagePtr &full);
void photoConvert(
not_null<PhotoData*> original,
const MTPPhoto &data);
not_null<DocumentData*> document(DocumentId id);
not_null<DocumentData*> document(const MTPDocument &data);
not_null<DocumentData*> document(const MTPDdocument &data);
not_null<DocumentData*> document(
const MTPdocument &data,
const QPixmap &thumb);
not_null<DocumentData*> document(
DocumentId id,
const uint64 &access,
int32 version,
TimeId date,
const QVector<MTPDocumentAttribute> &attributes,
const QString &mime,
const ImagePtr &thumb,
int32 dc,
int32 size,
const StorageImageLocation &thumbLocation);
void documentConvert(
not_null<DocumentData*> original,
const MTPDocument &data);
not_null<WebPageData*> webpage(WebPageId id);
not_null<WebPageData*> webpage(const MTPWebPage &data);
not_null<WebPageData*> webpage(const MTPDwebPage &data);
not_null<WebPageData*> webpage(const MTPDwebPagePending &data);
not_null<WebPageData*> webpage(
WebPageId id,
const QString &siteName,
const TextWithEntities &content);
not_null<WebPageData*> webpage(
WebPageId id,
const QString &type,
const QString &url,
const QString &displayUrl,
const QString &siteName,
const QString &title,
const TextWithEntities &description,
PhotoData *photo,
DocumentData *document,
int duration,
const QString &author,
TimeId pendingTill);
not_null<GameData*> game(GameId id);
not_null<GameData*> game(const MTPDgame &data);
not_null<GameData*> game(
GameId id,
const uint64 &accessHash,
const QString &shortName,
const QString &title,
const QString &description,
PhotoData *photo,
DocumentData *document);
void gameConvert(
not_null<GameData*> original,
const MTPGame &data);
void registerPhotoItem(
not_null<const PhotoData*> photo,
not_null<HistoryItem*> item);
void unregisterPhotoItem(
not_null<const PhotoData*> photo,
not_null<HistoryItem*> item);
void registerDocumentItem(
not_null<const DocumentData*> document,
not_null<HistoryItem*> item);
void unregisterDocumentItem(
not_null<const DocumentData*> document,
not_null<HistoryItem*> item);
void registerWebPageView(
not_null<const WebPageData*> page,
not_null<ViewElement*> view);
void unregisterWebPageView(
not_null<const WebPageData*> page,
not_null<ViewElement*> view);
void registerWebPageItem(
not_null<const WebPageData*> page,
not_null<HistoryItem*> item);
void unregisterWebPageItem(
not_null<const WebPageData*> page,
not_null<HistoryItem*> item);
void registerGameView(
not_null<const GameData*> game,
not_null<ViewElement*> view);
void unregisterGameView(
not_null<const GameData*> game,
not_null<ViewElement*> view);
void registerContactView(
UserId contactId,
not_null<ViewElement*> view);
void unregisterContactView(
UserId contactId,
not_null<ViewElement*> view);
void registerContactItem(
UserId contactId,
not_null<HistoryItem*> item);
void unregisterContactItem(
UserId contactId,
not_null<HistoryItem*> item);
void registerAutoplayAnimation(
not_null<::Media::Clip::Reader*> reader,
not_null<ViewElement*> view);
void unregisterAutoplayAnimation(
not_null<::Media::Clip::Reader*> reader);
HistoryItem *findWebPageItem(not_null<WebPageData*> page) const;
QString findContactPhone(not_null<UserData*> contact) const;
QString findContactPhone(UserId contactId) const;
void notifyWebPageUpdateDelayed(not_null<WebPageData*> page);
void notifyGameUpdateDelayed(not_null<GameData*> game);
void sendWebPageGameNotifications();
void stopAutoplayAnimations();
void registerItemView(not_null<ViewElement*> view);
void unregisterItemView(not_null<ViewElement*> view);
not_null<Feed*> feed(FeedId id);
Feed *feedLoaded(FeedId id);
void forgetMedia();
void setMimeForwardIds(MessageIdsList &&list);
MessageIdsList takeMimeForwardIds();
Groups &groups() {
return _groups;
}
const Groups &groups() const {
return _groups;
}
private:
void photoApplyFields(
not_null<PhotoData*> photo,
const MTPPhoto &data);
void photoApplyFields(
not_null<PhotoData*> photo,
const MTPDphoto &data);
void photoApplyFields(
not_null<PhotoData*> photo,
const uint64 &access,
TimeId date,
const ImagePtr &thumb,
const ImagePtr &medium,
const ImagePtr &full);
void documentApplyFields(
not_null<DocumentData*> document,
const MTPDocument &data);
void documentApplyFields(
not_null<DocumentData*> document,
const MTPDdocument &data);
void documentApplyFields(
not_null<DocumentData*> document,
const uint64 &access,
int32 version,
TimeId date,
const QVector<MTPDocumentAttribute> &attributes,
const QString &mime,
const ImagePtr &thumb,
int32 dc,
int32 size,
const StorageImageLocation &thumbLocation);
void webpageApplyFields(
not_null<WebPageData*> page,
const MTPDwebPage &data);
void webpageApplyFields(
not_null<WebPageData*> page,
const QString &type,
const QString &url,
const QString &displayUrl,
const QString &siteName,
const QString &title,
const TextWithEntities &description,
PhotoData *photo,
DocumentData *document,
int duration,
const QString &author,
TimeId pendingTill);
void gameApplyFields(
not_null<GameData*> game,
const MTPDgame &data);
void gameApplyFields(
not_null<GameData*> game,
const uint64 &accessHash,
const QString &shortName,
const QString &title,
const QString &description,
PhotoData *photo,
DocumentData *document);
bool stickersUpdateNeeded(TimeMs lastUpdate, TimeMs now) const {
constexpr auto kStickersUpdateTimeout = TimeMs(3600'000);
return (lastUpdate == 0)
|| (now >= lastUpdate + kStickersUpdateTimeout);
}
void userIsContactUpdated(not_null<UserData*> user);
void clearPinnedDialogs();
void setIsPinned(const Dialogs::Key &key, bool pinned);
template <typename Method>
void enumerateItemViews(
not_null<const HistoryItem*> item,
Method method);
not_null<AuthSession*> _session;
base::Variable<bool> _contactsLoaded = { false };
base::Variable<bool> _allChatsLoaded = { false };
base::Observable<void> _moreChatsLoaded;
base::Observable<ItemVisibilityQuery> _queryItemVisibility;
rpl::event_stream<IdChange> _itemIdChanges;
rpl::event_stream<not_null<const HistoryItem*>> _itemLayoutChanges;
rpl::event_stream<not_null<const ViewElement*>> _viewLayoutChanges;
rpl::event_stream<not_null<const HistoryItem*>> _itemRepaintRequest;
rpl::event_stream<not_null<const ViewElement*>> _viewRepaintRequest;
rpl::event_stream<not_null<const HistoryItem*>> _itemResizeRequest;
rpl::event_stream<not_null<ViewElement*>> _viewResizeRequest;
rpl::event_stream<not_null<HistoryItem*>> _itemViewRefreshRequest;
rpl::event_stream<not_null<HistoryItem*>> _animationPlayInlineRequest;
rpl::event_stream<not_null<const HistoryItem*>> _itemRemoved;
rpl::event_stream<not_null<const History*>> _historyUnloaded;
rpl::event_stream<not_null<const History*>> _historyCleared;
base::flat_set<not_null<History*>> _historiesChanged;
rpl::event_stream<not_null<History*>> _historyChanged;
rpl::event_stream<MegagroupParticipant> _megagroupParticipantRemoved;
rpl::event_stream<MegagroupParticipant> _megagroupParticipantAdded;
rpl::event_stream<FeedUpdate> _feedUpdates;
rpl::event_stream<> _stickersUpdated;
rpl::event_stream<> _savedGifsUpdated;
TimeMs _lastStickersUpdate = 0;
TimeMs _lastRecentStickersUpdate = 0;
TimeMs _lastFavedStickersUpdate = 0;
TimeMs _lastFeaturedStickersUpdate = 0;
TimeMs _lastSavedGifsUpdate = 0;
rpl::variable<int> _featuredStickerSetsUnreadCount = 0;
Stickers::Sets _stickerSets;
Stickers::Order _stickerSetsOrder;
Stickers::Order _featuredStickerSetsOrder;
Stickers::Order _archivedStickerSetsOrder;
Stickers::SavedGifs _savedGifs;
std::unordered_map<
PhotoId,
std::unique_ptr<PhotoData>> _photos;
std::map<
not_null<const PhotoData*>,
base::flat_set<not_null<HistoryItem*>>> _photoItems;
std::unordered_map<
DocumentId,
std::unique_ptr<DocumentData>> _documents;
std::map<
not_null<const DocumentData*>,
base::flat_set<not_null<HistoryItem*>>> _documentItems;
std::unordered_map<
WebPageId,
std::unique_ptr<WebPageData>> _webpages;
std::map<
not_null<const WebPageData*>,
base::flat_set<not_null<HistoryItem*>>> _webpageItems;
std::map<
not_null<const WebPageData*>,
base::flat_set<not_null<ViewElement*>>> _webpageViews;
std::unordered_map<
GameId,
std::unique_ptr<GameData>> _games;
std::map<
not_null<const GameData*>,
base::flat_set<not_null<ViewElement*>>> _gameViews;
std::map<
UserId,
base::flat_set<not_null<HistoryItem*>>> _contactItems;
std::map<
UserId,
base::flat_set<not_null<ViewElement*>>> _contactViews;
base::flat_map<
not_null<::Media::Clip::Reader*>,
not_null<ViewElement*>> _autoplayAnimations;
base::flat_set<not_null<WebPageData*>> _webpagesUpdated;
base::flat_set<not_null<GameData*>> _gamesUpdated;
std::deque<Dialogs::Key> _pinnedDialogs;
base::flat_map<FeedId, std::unique_ptr<Feed>> _feeds;
Groups _groups;
std::map<
not_null<const HistoryItem*>,
std::vector<not_null<ViewElement*>>> _views;
MessageIdsList _mimeForwardIds;
rpl::lifetime _lifetime;
};
} // namespace Data