| 96 | } |
| 97 | |
| 98 | rpl::producer<SparseIdsSlice> SharedMediaViewer( |
| 99 | not_null<Main::Session*> session, |
| 100 | Storage::SharedMediaKey key, |
| 101 | int limitBefore, |
| 102 | int limitAfter) { |
| 103 | Expects(IsServerMsgId(key.messageId) || (key.messageId == 0)); |
| 104 | Expects((key.messageId != 0) || (limitBefore == 0 && limitAfter == 0)); |
| 105 | |
| 106 | return [=](auto consumer) { |
| 107 | auto lifetime = rpl::lifetime(); |
| 108 | auto builder = lifetime.make_state<SparseIdsSliceBuilder>( |
| 109 | key.messageId, |
| 110 | limitBefore, |
| 111 | limitAfter); |
| 112 | auto requestMediaAround = [ |
| 113 | peer = session->data().peer(key.peerId), |
| 114 | topicRootId = key.topicRootId, |
| 115 | monoforumPeerId = key.monoforumPeerId, |
| 116 | type = key.type |
| 117 | ](const SparseIdsSliceBuilder::AroundData &data) { |
| 118 | peer->session().api().requestSharedMedia( |
| 119 | peer, |
| 120 | topicRootId, |
| 121 | monoforumPeerId, |
| 122 | type, |
| 123 | data.aroundId, |
| 124 | data.direction); |
| 125 | }; |
| 126 | builder->insufficientAround( |
| 127 | ) | rpl::on_next(requestMediaAround, lifetime); |
| 128 | |
| 129 | auto pushNextSnapshot = [=] { |
| 130 | consumer.put_next(builder->snapshot()); |
| 131 | }; |
| 132 | |
| 133 | using SliceUpdate = Storage::SharedMediaSliceUpdate; |
| 134 | session->storage().sharedMediaSliceUpdated( |
| 135 | ) | rpl::filter([=](const SliceUpdate &update) { |
| 136 | return (update.peerId == key.peerId) |
| 137 | && (update.topicRootId == key.topicRootId) |
| 138 | && (update.monoforumPeerId == key.monoforumPeerId) |
| 139 | && (update.type == key.type); |
| 140 | }) | rpl::filter([=](const SliceUpdate &update) { |
| 141 | return builder->applyUpdate(update.data); |
| 142 | }) | rpl::on_next(pushNextSnapshot, lifetime); |
| 143 | |
| 144 | using OneRemoved = Storage::SharedMediaRemoveOne; |
| 145 | session->storage().sharedMediaOneRemoved( |
| 146 | ) | rpl::filter([=](const OneRemoved &update) { |
| 147 | return (update.peerId == key.peerId) |
| 148 | && update.types.test(key.type); |
| 149 | }) | rpl::filter([=](const OneRemoved &update) { |
| 150 | return builder->removeOne(update.messageId); |
| 151 | }) | rpl::on_next(pushNextSnapshot, lifetime); |
| 152 | |
| 153 | using AllRemoved = Storage::SharedMediaRemoveAll; |
| 154 | session->storage().sharedMediaAllRemoved( |
| 155 | ) | rpl::filter([=](const AllRemoved &update) { |
no test coverage detected