Loop pinned messages in the top bar.

This commit is contained in:
John Preston 2020-10-26 14:46:08 +03:00
parent 08f7069370
commit 53c308c24b
6 changed files with 72 additions and 9 deletions

View file

@ -1051,6 +1051,40 @@ FullMsgId ResolveTopPinnedId(
}
}
FullMsgId ResolveMinPinnedId(
not_null<PeerData*> peer,
PeerData *migrated) {
const auto slice = peer->session().storage().snapshot(
Storage::SharedMediaQuery(
Storage::SharedMediaKey(
peer->id,
Storage::SharedMediaType::Pinned,
1),
1,
1));
const auto old = migrated
? migrated->session().storage().snapshot(
Storage::SharedMediaQuery(
Storage::SharedMediaKey(
migrated->id,
Storage::SharedMediaType::Pinned,
1),
1,
1))
: Storage::SharedMediaResult{
.count = 0,
.skippedBefore = 0,
.skippedAfter = 0,
};
if (!old.messageIds.empty()) {
return FullMsgId(0, old.messageIds.front());
} else if (old.count == 0 && !slice.messageIds.empty()) {
return FullMsgId(peerToChannel(peer->id), slice.messageIds.front());
} else {
return FullMsgId();
}
}
std::optional<int> ResolvePinnedCount(
not_null<PeerData*> peer,
PeerData *migrated) {

View file

@ -446,6 +446,9 @@ void SetTopPinnedMessageId(not_null<PeerData*> peer, MsgId messageId);
[[nodiscard]] FullMsgId ResolveTopPinnedId(
not_null<PeerData*> peer,
PeerData *migrated);
[[nodiscard]] FullMsgId ResolveMinPinnedId(
not_null<PeerData*> peer,
PeerData *migrated);
[[nodiscard]] std::optional<int> ResolvePinnedCount(
not_null<PeerData*> peer,
PeerData *migrated);

View file

@ -1609,6 +1609,7 @@ void HistoryWidget::showHistory(
MsgId showAtMsgId,
bool reload) {
_pinnedClickedId = FullMsgId();
_minPinnedId = std::nullopt;
MsgId wasMsgId = _showAtMsgId;
History *wasHistory = _history;
@ -5195,7 +5196,17 @@ void HistoryWidget::updatePinnedViewer() {
if (_pinnedClickedId && lessThanId <= lastClickedId) {
_pinnedClickedId = FullMsgId();
}
_pinnedTracker->trackAround(std::min(lessThanId, lastClickedId));
if (_pinnedClickedId && !_minPinnedId) {
_minPinnedId = Data::ResolveMinPinnedId(
_peer,
_migrated ? _migrated->peer.get() : nullptr);
}
if (_pinnedClickedId && _minPinnedId == _pinnedClickedId) {
// After click on the last pinned message we should the top one.
_pinnedTracker->trackAround(ServerMaxMsgId - 1);
} else {
_pinnedTracker->trackAround(std::min(lessThanId, lastClickedId));
}
}
void HistoryWidget::checkLastPinnedClickedIdReset(
@ -5211,6 +5222,7 @@ void HistoryWidget::checkLastPinnedClickedIdReset(
if (wasScrollTop < nowScrollTop && _pinnedClickedId) {
// User scrolled down.
_pinnedClickedId = FullMsgId();
_minPinnedId = std::nullopt;
updatePinnedViewer();
}
}
@ -5269,7 +5281,13 @@ void HistoryWidget::checkPinnedBarState() {
_peer,
nullptr,
Storage::SharedMediaType::Pinned
) | rpl::distinct_until_changed(
) | rpl::map([=](int count) {
if (_pinnedClickedId) {
_pinnedClickedId = FullMsgId();
_minPinnedId = std::nullopt;
updatePinnedViewer();
}
return (count > 1);
}) | rpl::distinct_until_changed(
) | rpl::start_with_next([=](bool many) {
@ -5297,6 +5315,7 @@ void HistoryWidget::checkPinnedBarState() {
if (const auto item = session().data().message(id.message)) {
Ui::showPeerHistory(item->history()->peer, item->id);
_pinnedClickedId = id.message;
_minPinnedId = std::nullopt;
updatePinnedViewer();
}
}, _pinnedBar->lifetime());

View file

@ -600,6 +600,7 @@ private:
std::unique_ptr<Ui::PinnedBar> _pinnedBar;
int _pinnedBarHeight = 0;
FullMsgId _pinnedClickedId;
std::optional<FullMsgId> _minPinnedId;
mtpRequestId _saveEditMsgRequestId = 0;

View file

@ -54,8 +54,7 @@ SparseIdsList::AddResult SparseIdsList::uniteAndAdd(
}
update.messages = &uniteFrom->messages;
update.range = uniteFrom->range;
const auto count = int(uniteFrom->messages.size());
return { count, count - was };
return { int(uniteFrom->messages.size()) - was };
}
template <typename Range>
@ -65,6 +64,10 @@ SparseIdsList::AddResult SparseIdsList::addRangeItemsAndCountNew(
MsgRange noSkipRange) {
Expects(noSkipRange.from <= noSkipRange.till);
if (noSkipRange.from == noSkipRange.till
&& std::begin(messages) == std::end(messages)) {
return { 0 };
}
auto uniteFrom = ranges::lower_bound(
_slices,
noSkipRange.from,
@ -88,8 +91,7 @@ SparseIdsList::AddResult SparseIdsList::addRangeItemsAndCountNew(
).first;
update.messages = &slice->messages;
update.range = slice->range;
const auto count = int(slice->messages.size());
return { count, count };
return { int(slice->messages.size()) };
}
template <typename Range>
@ -111,12 +113,17 @@ void SparseIdsList::addRange(
*_count += result.added;
}
if (_slices.size() == 1) {
if (_slices.front().range == MsgRange { 0, ServerMaxMsgId }) {
if (_count && _slices.front().messages.size() >= *_count) {
_slices.modify(_slices.begin(), [&](Slice &slice) {
slice.range = { 0, ServerMaxMsgId };
});
}
if (_slices.front().range == MsgRange{ 0, ServerMaxMsgId }) {
_count = _slices.front().messages.size();
}
}
if (_count) {
accumulate_max(*_count, result.inslice);
if (_count && update.messages) {
accumulate_max(*_count, int(update.messages->size()));
}
update.count = _count;
_sliceUpdated.fire(std::move(update));

View file

@ -71,7 +71,6 @@ private:
};
struct AddResult {
int inslice = 0;
int added = 0;
};
template <typename Range>