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 "history/history.h"
#include "history/history_item.h"
#include "data/data_document.h"
#include "data/data_media_types.h"
#include "data/data_photo.h"
#include "data/data_scheduled_messages.h"
#include "data/data_sparse_ids.h"
#include "data/data_session.h"
#include "info/info_memento.h"
@ -30,6 +32,42 @@ namespace {
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
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(
not_null<Main::Session*> session,
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(
not_null<Main::Session*> session,
SharedMediaMergedKey key,

View file

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

View file

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