mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +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 "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,
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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)));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue