/* 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 #include "storage/storage_facade.h" #include "data/data_feed_messages.h" namespace Storage { struct FeedMessagesAddNew { FeedMessagesAddNew(FeedId feedId, Data::MessagePosition messageId) : feedId(feedId) , messageId(messageId) { } FeedId feedId = 0; Data::MessagePosition messageId; }; struct FeedMessagesAddSlice { FeedMessagesAddSlice( FeedId feedId, std::vector &&messageIds, Data::MessagesRange noSkipRange) : feedId(feedId) , messageIds(std::move(messageIds)) , noSkipRange(noSkipRange) { } FeedId feedId = 0; std::vector messageIds; Data::MessagesRange noSkipRange; }; struct FeedMessagesRemoveOne { FeedMessagesRemoveOne( FeedId feedId, Data::MessagePosition messageId) : feedId(feedId) , messageId(messageId) { } FeedId feedId = 0; Data::MessagePosition messageId; }; struct FeedMessagesRemoveAll { FeedMessagesRemoveAll(FeedId feedId, ChannelId channelId) : feedId(feedId) , channelId(channelId) { } FeedId feedId = 0; ChannelId channelId = 0; }; struct FeedMessagesInvalidate { explicit FeedMessagesInvalidate(FeedId feedId) : feedId(feedId) { } FeedId feedId = 0; }; struct FeedMessagesInvalidateBottom { explicit FeedMessagesInvalidateBottom(FeedId feedId) : feedId(feedId) { } FeedId feedId = 0; }; struct FeedMessagesKey { FeedMessagesKey( FeedId feedId, Data::MessagePosition position) : feedId(feedId) , position(position) { } bool operator==(const FeedMessagesKey &other) const { return (feedId == other.feedId) && (position == other.position); } bool operator!=(const FeedMessagesKey &other) const { return !(*this == other); } FeedId feedId = 0; Data::MessagePosition position; }; struct FeedMessagesQuery { FeedMessagesQuery( FeedMessagesKey key, int limitBefore, int limitAfter) : key(key) , limitBefore(limitBefore) , limitAfter(limitAfter) { } FeedMessagesKey key; int limitBefore = 0; int limitAfter = 0; }; using FeedMessagesResult = Data::MessagesResult; struct FeedMessagesSliceUpdate { FeedMessagesSliceUpdate( FeedId feedId, Data::MessagesSliceUpdate &&data) : feedId(feedId) , data(std::move(data)) { } FeedId feedId = 0; Data::MessagesSliceUpdate data; }; class FeedMessages { public: void add(FeedMessagesAddNew &&query); void add(FeedMessagesAddSlice &&query); void remove(FeedMessagesRemoveOne &&query); void remove(FeedMessagesRemoveAll &&query); void invalidate(FeedMessagesInvalidate &&query); void invalidate(FeedMessagesInvalidateBottom &&query); rpl::producer query( FeedMessagesQuery &&query) const; rpl::producer sliceUpdated() const; rpl::producer oneRemoved() const; rpl::producer allRemoved() const; rpl::producer invalidated() const; rpl::producer bottomInvalidated() const; private: using List = Data::MessagesList; std::map::iterator enforceLists(FeedId feedId); std::map _lists; rpl::event_stream _sliceUpdated; rpl::event_stream _oneRemoved; rpl::event_stream _allRemoved; rpl::event_stream _invalidated; rpl::event_stream _bottomInvalidated; rpl::lifetime _lifetime; }; } // namespace Storage