/* 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_messages.h" #include "info/media/info_media_common.h" #include "base/weak_ptr.h" namespace Info { class AbstractController; } // namespace Info namespace Info::GlobalMedia { struct GlobalMediaKey { Data::MessagePosition aroundId; friend inline constexpr bool operator==( const GlobalMediaKey &, const GlobalMediaKey &) = default; }; class GlobalMediaSlice final { public: using Key = GlobalMediaKey; using Value = Data::MessagePosition; explicit GlobalMediaSlice( Key key, std::vector items = {}, std::optional fullCount = std::nullopt, int skippedAfter = 0); [[nodiscard]] std::optional fullCount() const; [[nodiscard]] std::optional skippedBefore() const; [[nodiscard]] std::optional skippedAfter() const; [[nodiscard]] std::optional indexOf(Value fullId) const; [[nodiscard]] int size() const; [[nodiscard]] Value operator[](int index) const; [[nodiscard]] std::optional distance( const Key &a, const Key &b) const; [[nodiscard]] std::optional nearest(Value id) const; private: GlobalMediaKey _key; std::vector _items; std::optional _fullCount; int _skippedAfter = 0; }; class Provider final : public Media::ListProvider , private Media::ListSectionDelegate { public: using Type = Media::Type; using BaseLayout = Media::BaseLayout; explicit Provider(not_null controller); Type type() override; bool hasSelectRestriction() override; rpl::producer hasSelectRestrictionChanges() override; bool isPossiblyMyItem(not_null item) override; std::optional fullCount() override; void restart() override; void checkPreload( QSize viewport, not_null topLayout, not_null bottomLayout, bool preloadTop, bool preloadBottom) override; void refreshViewer() override; rpl::producer<> refreshed() override; std::vector fillSections( not_null delegate) override; rpl::producer> layoutRemoved() override; BaseLayout *lookupLayout(const HistoryItem *item) override; bool isMyItem(not_null item) override; bool isAfter( not_null a, not_null b) override; void setSearchQuery(QString query) override; Media::ListItemSelectionData computeSelectionData( not_null item, TextSelection selection) override; void applyDragSelection( Media::ListSelectedMap &selected, not_null fromItem, bool skipFrom, not_null tillItem, bool skipTill) override; bool allowSaveFileAs( not_null item, not_null document) override; QString showInFolderPath( not_null item, not_null document) override; int64 scrollTopStatePosition(not_null item) override; HistoryItem *scrollTopStateItem( Media::ListScrollTopState state) override; void saveState( not_null memento, Media::ListScrollTopState scrollState) override; void restoreState( not_null memento, Fn restoreScrollState) override; private: static constexpr auto kMinimalIdsLimit = 16; struct FillResult { GlobalMediaSlice slice; bool notEnough = false; }; struct List { std::vector list; Data::MessagePosition offsetPosition; int32 offsetRate = 0; int fullCount = 0; bool loaded = false; }; bool sectionHasFloatingHeader() override; QString sectionTitle(not_null item) override; bool sectionItemBelongsHere( not_null item, not_null previous) override; [[nodiscard]] rpl::producer source( Type type, Data::MessagePosition aroundId, QString query, int limitBefore, int limitAfter); [[nodiscard]] BaseLayout *getLayout( FullMsgId itemId, not_null delegate); [[nodiscard]] std::unique_ptr createLayout( FullMsgId itemId, not_null delegate, Type type); [[nodiscard]] GlobalMediaKey sliceKey( Data::MessagePosition aroundId) const; void itemRemoved(not_null item); void markLayoutsStale(); void clearStaleLayouts(); [[nodiscard]] List *currentList(); [[nodiscard]] FillResult fillRequest( Data::MessagePosition aroundId, int limitBefore, int limitAfter); mtpRequestId requestMore(Fn loaded); const not_null _controller; const Type _type = {}; Data::MessagePosition _aroundId = Data::MaxMessagePosition; int _idsLimit = kMinimalIdsLimit; GlobalMediaSlice _slice; base::flat_set _seenIds; std::unordered_map _layouts; rpl::event_stream> _layoutRemoved; rpl::event_stream<> _refreshed; QString _totalListQuery; base::flat_map _totalLists; rpl::lifetime _lifetime; rpl::lifetime _viewerLifetime; }; } // namespace Info::GlobalMedia