mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 23:27:09 +02:00
Added ability to sparse id slices of scheduled media.
This commit is contained in:
parent
118fd187e3
commit
1a93f4fa4c
4 changed files with 154 additions and 26 deletions
|
@ -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,
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)));
|
||||
});
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue