/* 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 <rpl/event_stream.h> #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<Data::MessagePosition> &&messageIds, Data::MessagesRange noSkipRange) : feedId(feedId) , messageIds(std::move(messageIds)) , noSkipRange(noSkipRange) { } FeedId feedId = 0; std::vector<Data::MessagePosition> 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<FeedMessagesResult> query( FeedMessagesQuery &&query) const; rpl::producer<FeedMessagesSliceUpdate> sliceUpdated() const; rpl::producer<FeedMessagesRemoveOne> oneRemoved() const; rpl::producer<FeedMessagesRemoveAll> allRemoved() const; rpl::producer<FeedMessagesInvalidate> invalidated() const; rpl::producer<FeedMessagesInvalidateBottom> bottomInvalidated() const; private: using List = Data::MessagesList; std::map<FeedId, List>::iterator enforceLists(FeedId feedId); std::map<FeedId, List> _lists; rpl::event_stream<FeedMessagesSliceUpdate> _sliceUpdated; rpl::event_stream<FeedMessagesRemoveOne> _oneRemoved; rpl::event_stream<FeedMessagesRemoveAll> _allRemoved; rpl::event_stream<FeedMessagesInvalidate> _invalidated; rpl::event_stream<FeedMessagesInvalidateBottom> _bottomInvalidated; rpl::lifetime _lifetime; }; } // namespace Storage