Added ability to sparse id slices of scheduled media.

This commit is contained in:
23rd 2021-06-29 17:40:55 +03:00
parent 118fd187e3
commit 1a93f4fa4c
4 changed files with 154 additions and 26 deletions

View file

@ -16,8 +16,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "storage/storage_shared_media.h" #include "storage/storage_shared_media.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_item.h" #include "history/history_item.h"
#include "data/data_document.h"
#include "data/data_media_types.h" #include "data/data_media_types.h"
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_scheduled_messages.h"
#include "data/data_sparse_ids.h" #include "data/data_sparse_ids.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "info/info_memento.h" #include "info/info_memento.h"
@ -30,6 +32,42 @@ namespace {
using Type = Storage::SharedMediaType; using Type = Storage::SharedMediaType;
bool IsItemGoodForType(const not_null<HistoryItem*> item, Type type) {
const auto media = item->media();
if (!media) {
return false;
}
const auto photo = media->photo();
const auto photoType = (type == Type::Photo);
if (photoType && photo) {
return true;
}
const auto document = media->document();
if (!document) {
return false;
}
const auto voiceType = (type == Type::VoiceFile)
|| (type == Type::RoundVoiceFile);
const auto voiceDoc = (document->isVoiceMessage()
|| document->isVideoMessage());
const auto audioType = (type == Type::MusicFile);
const auto audioDoc = document->isAudioFile();
const auto gifType = (type == Type::GIF);
const auto gifDoc = document->isGifv();
const auto videoType = (type == Type::Video);
const auto videoDoc = document->isVideoFile();
return (audioType && audioDoc)
|| (voiceType && voiceDoc)
|| (gifType && gifDoc)
|| (videoType && videoDoc)
|| (photoType && document->isImage());
}
} // namespace } // namespace
std::optional<Storage::SharedMediaType> SharedMediaOverviewType( std::optional<Storage::SharedMediaType> SharedMediaOverviewType(
@ -153,6 +191,55 @@ rpl::producer<SparseIdsSlice> SharedMediaViewer(
}; };
} }
rpl::producer<SparseIdsMergedSlice> SharedScheduledMediaViewer(
not_null<Main::Session*> session,
SharedMediaMergedKey key,
int limitBefore,
int limitAfter) {
Expects(!IsServerMsgId(key.mergedKey.universalId));
Expects((key.mergedKey.universalId != 0)
|| (limitBefore == 0 && limitAfter == 0));
const auto history = session->data().history(key.mergedKey.peerId);
return rpl::single(
rpl::empty_value()
) | rpl::then(
session->data().scheduledMessages().updates(history)
) | rpl::map([=] {
const auto list = session->data().scheduledMessages().list(history);
auto items = ranges::views::all(
list.ids
) | ranges::views::transform([=](const FullMsgId &fullId) {
return session->data().message(fullId);
}) | ranges::views::filter([=](HistoryItem *item) {
return item
? IsItemGoodForType(item, key.type)
: false;
}) | ranges::to_vector;
ranges::sort(items, ranges::less(), &HistoryItem::position);
auto finishMsgIds = ranges::views::all(
items
) | ranges::views::transform([=](not_null<HistoryItem*> item) {
return item->fullId().msg;
}) | ranges::to_vector;
const auto fullCount = finishMsgIds.size();
auto unsorted = SparseUnsortedIdsSlice(
std::move(finishMsgIds),
fullCount,
list.skippedBefore,
list.skippedAfter);
return SparseIdsMergedSlice(
key.mergedKey,
std::move(unsorted));
});
}
rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer( rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer(
not_null<Main::Session*> session, not_null<Main::Session*> session,
SharedMediaMergedKey key, SharedMediaMergedKey key,

View file

@ -50,6 +50,12 @@ struct SharedMediaMergedKey {
}; };
rpl::producer<SparseIdsMergedSlice> SharedScheduledMediaViewer(
not_null<Main::Session*> session,
SharedMediaMergedKey key,
int limitBefore,
int limitAfter);
rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer( rpl::producer<SparseIdsMergedSlice> SharedMediaMergedViewer(
not_null<Main::Session*> session, not_null<Main::Session*> session,
SharedMediaMergedKey key, SharedMediaMergedKey key,

View file

@ -26,33 +26,48 @@ SparseIdsMergedSlice::SparseIdsMergedSlice(
, _migrated(std::move(migrated)) { , _migrated(std::move(migrated)) {
} }
SparseIdsMergedSlice::SparseIdsMergedSlice(
Key key,
SparseUnsortedIdsSlice scheduled)
: _key(key)
, _scheduled(std::move(scheduled)) {
}
std::optional<int> SparseIdsMergedSlice::fullCount() const { std::optional<int> SparseIdsMergedSlice::fullCount() const {
return Add( return _scheduled
_part.fullCount(), ? _scheduled->fullCount()
_migrated ? _migrated->fullCount() : 0); : Add(
_part.fullCount(),
_migrated ? _migrated->fullCount() : 0);
} }
std::optional<int> SparseIdsMergedSlice::skippedBefore() const { std::optional<int> SparseIdsMergedSlice::skippedBefore() const {
return Add( return _scheduled
isolatedInMigrated() ? 0 : _part.skippedBefore(), ? _scheduled->skippedBefore()
_migrated : Add(
? (isolatedInPart() isolatedInMigrated() ? 0 : _part.skippedBefore(),
? _migrated->fullCount() _migrated
: _migrated->skippedBefore()) ? (isolatedInPart()
: 0 ? _migrated->fullCount()
); : _migrated->skippedBefore())
: 0
);
} }
std::optional<int> SparseIdsMergedSlice::skippedAfter() const { std::optional<int> SparseIdsMergedSlice::skippedAfter() const {
return Add( return _scheduled
isolatedInMigrated() ? _part.fullCount() : _part.skippedAfter(), ? _scheduled->skippedAfter()
isolatedInPart() ? 0 : _migrated->skippedAfter() : Add(
); isolatedInMigrated() ? _part.fullCount() : _part.skippedAfter(),
isolatedInPart() ? 0 : _migrated->skippedAfter()
);
} }
std::optional<int> SparseIdsMergedSlice::indexOf( std::optional<int> SparseIdsMergedSlice::indexOf(
FullMsgId fullId) const { FullMsgId fullId) const {
return isFromPart(fullId) return _scheduled
? _scheduled->indexOf(fullId.msg)
: isFromPart(fullId)
? (_part.indexOf(fullId.msg) | func::add(migratedSize())) ? (_part.indexOf(fullId.msg) | func::add(migratedSize()))
: isolatedInPart() : isolatedInPart()
? std::nullopt ? std::nullopt
@ -62,14 +77,20 @@ std::optional<int> SparseIdsMergedSlice::indexOf(
} }
int SparseIdsMergedSlice::size() const { int SparseIdsMergedSlice::size() const {
return (isolatedInPart() ? 0 : migratedSize()) return _scheduled
+ (isolatedInMigrated() ? 0 : _part.size()); ? _scheduled->size()
: (isolatedInPart() ? 0 : migratedSize())
+ (isolatedInMigrated() ? 0 : _part.size());
} }
FullMsgId SparseIdsMergedSlice::operator[](int index) const { FullMsgId SparseIdsMergedSlice::operator[](int index) const {
Expects(index >= 0 && index < size()); Expects(index >= 0 && index < size());
if (auto size = migratedSize()) { if (_scheduled) {
return ComputeId(_key.peerId, (*_scheduled)[index]);
}
if (const auto size = migratedSize()) {
if (index < size) { if (index < size) {
return ComputeId(_key.migratedPeerId, (*_migrated)[index]); return ComputeId(_key.migratedPeerId, (*_migrated)[index]);
} }
@ -81,8 +102,8 @@ FullMsgId SparseIdsMergedSlice::operator[](int index) const {
std::optional<int> SparseIdsMergedSlice::distance( std::optional<int> SparseIdsMergedSlice::distance(
const Key &a, const Key &a,
const Key &b) const { const Key &b) const {
if (auto i = indexOf(ComputeId(a))) { if (const auto i = indexOf(ComputeId(a))) {
if (auto j = indexOf(ComputeId(b))) { if (const auto j = indexOf(ComputeId(b))) {
return *j - *i; return *j - *i;
} }
} }
@ -91,10 +112,15 @@ std::optional<int> SparseIdsMergedSlice::distance(
auto SparseIdsMergedSlice::nearest( auto SparseIdsMergedSlice::nearest(
UniversalMsgId id) const -> std::optional<FullMsgId> { UniversalMsgId id) const -> std::optional<FullMsgId> {
auto convertFromPartNearest = [&](MsgId result) { if (_scheduled) {
if (const auto nearestId = _scheduled->nearest(id)) {
return ComputeId(_key.peerId, *nearestId);
}
}
const auto convertFromPartNearest = [&](MsgId result) {
return ComputeId(_key.peerId, result); return ComputeId(_key.peerId, result);
}; };
auto convertFromMigratedNearest = [&](MsgId result) { const auto convertFromMigratedNearest = [&](MsgId result) {
return ComputeId(_key.migratedPeerId, result); return ComputeId(_key.migratedPeerId, result);
}; };
if (IsServerMsgId(id)) { if (IsServerMsgId(id)) {
@ -388,4 +414,4 @@ rpl::producer<SparseIdsMergedSlice> SparseIdsMergedSlice::CreateViewer(
std::move(migrated))); std::move(migrated)));
}); });
}; };
} }

View file

@ -22,6 +22,8 @@ public:
}; };
using SparseUnsortedIdsSlice = AbstractSparseIds<std::vector<MsgId>>;
class SparseIdsMergedSlice { class SparseIdsMergedSlice {
public: public:
using UniversalMsgId = MsgId; using UniversalMsgId = MsgId;
@ -29,9 +31,11 @@ public:
Key( Key(
PeerId peerId, PeerId peerId,
PeerId migratedPeerId, PeerId migratedPeerId,
UniversalMsgId universalId) UniversalMsgId universalId,
bool scheduled = false)
: peerId(peerId) : peerId(peerId)
, migratedPeerId(migratedPeerId) , scheduled(scheduled)
, migratedPeerId(scheduled ? 0 : migratedPeerId)
, universalId(universalId) { , universalId(universalId) {
} }
@ -45,6 +49,7 @@ public:
} }
PeerId peerId = 0; PeerId peerId = 0;
bool scheduled = false;
PeerId migratedPeerId = 0; PeerId migratedPeerId = 0;
UniversalMsgId universalId = 0; UniversalMsgId universalId = 0;
@ -55,6 +60,9 @@ public:
Key key, Key key,
SparseIdsSlice part, SparseIdsSlice part,
std::optional<SparseIdsSlice> migrated); std::optional<SparseIdsSlice> migrated);
SparseIdsMergedSlice(
Key key,
SparseUnsortedIdsSlice scheduled);
std::optional<int> fullCount() const; std::optional<int> fullCount() const;
std::optional<int> skippedBefore() const; std::optional<int> skippedBefore() const;
@ -133,6 +141,7 @@ private:
Key _key; Key _key;
SparseIdsSlice _part; SparseIdsSlice _part;
std::optional<SparseIdsSlice> _migrated; std::optional<SparseIdsSlice> _migrated;
std::optional<SparseUnsortedIdsSlice> _scheduled;
}; };