mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-08 08:04:08 +02:00
Implement local pinned bar hiding.
This commit is contained in:
parent
67290eed58
commit
91a0416037
10 changed files with 167 additions and 131 deletions
|
@ -166,6 +166,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
"lng_pinned_quiz" = "Pinned quiz";
|
||||
"lng_pinned_unpin_sure" = "Would you like to unpin this message?";
|
||||
"lng_pinned_pin_sure" = "Would you like to pin this message?";
|
||||
"lng_pinned_pin_old_sure" = "Do you want to pin an older message while leaving a more recent one pinned?";
|
||||
"lng_pinned_pin" = "Pin";
|
||||
"lng_pinned_unpin" = "Unpin";
|
||||
"lng_pinned_notify" = "Notify all members";
|
||||
|
|
|
@ -448,7 +448,7 @@ PinMessageBox::PinMessageBox(
|
|||
, _text(
|
||||
this,
|
||||
(_pinningOld
|
||||
? "Do you want to pin an older message while leaving a more recent one pinned?" // #TODO pinned
|
||||
? tr::lng_pinned_pin_old_sure(tr::now)
|
||||
: tr::lng_pinned_pin_sure(tr::now)),
|
||||
st::boxLabel) {
|
||||
}
|
||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "apiwrap.h"
|
||||
#include "boxes/confirm_box.h"
|
||||
#include "main/main_session.h"
|
||||
#include "main/main_session_settings.h"
|
||||
#include "main/main_account.h"
|
||||
#include "main/main_domain.h"
|
||||
#include "main/main_app_config.h"
|
||||
|
@ -469,14 +470,12 @@ void PeerData::ensurePinnedMessagesCreated() {
|
|||
if (!_pinnedMessages) {
|
||||
_pinnedMessages = std::make_unique<Data::PinnedMessages>(
|
||||
peerToChannel(id));
|
||||
session().changes().peerUpdated(this, UpdateFlag::PinnedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
void PeerData::removeEmptyPinnedMessages() {
|
||||
if (_pinnedMessages && _pinnedMessages->empty()) {
|
||||
_pinnedMessages = nullptr;
|
||||
session().changes().peerUpdated(this, UpdateFlag::PinnedMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -489,18 +488,30 @@ bool PeerData::messageIdTooSmall(MsgId messageId) const {
|
|||
|
||||
void PeerData::setTopPinnedMessageId(MsgId messageId) {
|
||||
if (messageIdTooSmall(messageId)) {
|
||||
clearPinnedMessages();
|
||||
return;
|
||||
}
|
||||
if (session().settings().hiddenPinnedMessageId(id) != messageId) {
|
||||
session().settings().setHiddenPinnedMessageId(id, 0);
|
||||
session().saveSettingsDelayed();
|
||||
}
|
||||
ensurePinnedMessagesCreated();
|
||||
_pinnedMessages->setTopId(messageId);
|
||||
session().changes().peerUpdated(this, UpdateFlag::PinnedMessage);
|
||||
}
|
||||
|
||||
void PeerData::clearPinnedMessages(MsgId lessThanId) {
|
||||
if (lessThanId == ServerMaxMsgId
|
||||
&& session().settings().hiddenPinnedMessageId(id) != 0) {
|
||||
session().settings().setHiddenPinnedMessageId(id, 0);
|
||||
session().saveSettingsDelayed();
|
||||
}
|
||||
if (!_pinnedMessages) {
|
||||
return;
|
||||
}
|
||||
_pinnedMessages->clearLessThanId(lessThanId);
|
||||
removeEmptyPinnedMessages();
|
||||
session().changes().peerUpdated(this, UpdateFlag::PinnedMessage);
|
||||
}
|
||||
|
||||
void PeerData::addPinnedMessage(MsgId messageId) {
|
||||
|
@ -509,6 +520,7 @@ void PeerData::addPinnedMessage(MsgId messageId) {
|
|||
}
|
||||
ensurePinnedMessagesCreated();
|
||||
_pinnedMessages->add(messageId);
|
||||
session().changes().peerUpdated(this, UpdateFlag::PinnedMessage);
|
||||
}
|
||||
|
||||
void PeerData::addPinnedSlice(
|
||||
|
@ -532,6 +544,7 @@ void PeerData::addPinnedSlice(
|
|||
}
|
||||
ensurePinnedMessagesCreated();
|
||||
_pinnedMessages->add(std::move(ids), noSkipRange, std::nullopt);
|
||||
session().changes().peerUpdated(this, UpdateFlag::PinnedMessage);
|
||||
}
|
||||
|
||||
void PeerData::removePinnedMessage(MsgId messageId) {
|
||||
|
@ -540,6 +553,7 @@ void PeerData::removePinnedMessage(MsgId messageId) {
|
|||
}
|
||||
_pinnedMessages->remove(messageId);
|
||||
removeEmptyPinnedMessages();
|
||||
session().changes().peerUpdated(this, UpdateFlag::PinnedMessage);
|
||||
}
|
||||
|
||||
bool PeerData::canExportChatHistory() const {
|
||||
|
|
|
@ -1005,9 +1005,12 @@ void History::applyServiceChanges(
|
|||
case mtpc_messageActionPinMessage: {
|
||||
if (const auto replyTo = data.vreply_to()) {
|
||||
replyTo->match([&](const MTPDmessageReplyHeader &data) {
|
||||
const auto id = data.vreply_to_msg_id().v;
|
||||
if (item) {
|
||||
//item->history()->peer->setTopPinnedMessageId( // #TODO pinned
|
||||
// data.vreply_to_msg_id().v);
|
||||
item->history()->peer->addPinnedSlice(
|
||||
{ id },
|
||||
{ id, ServerMaxMsgId },
|
||||
std::nullopt);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -563,6 +563,7 @@ HistoryWidget::HistoryWidget(
|
|||
| UpdateFlag::ChannelLinkedChat
|
||||
| UpdateFlag::Slowmode
|
||||
| UpdateFlag::BotStartToken
|
||||
| UpdateFlag::PinnedMessage
|
||||
) | rpl::filter([=](const Data::PeerUpdate &update) {
|
||||
return (update.peer.get() == _peer);
|
||||
}) | rpl::map([](const Data::PeerUpdate &update) {
|
||||
|
@ -603,6 +604,9 @@ HistoryWidget::HistoryWidget(
|
|||
| UpdateFlag::ChannelLinkedChat)) {
|
||||
handlePeerUpdate();
|
||||
}
|
||||
if (_pinnedTracker && (flags & UpdateFlag::PinnedMessage)) {
|
||||
checkPinnedBarState();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
rpl::merge(
|
||||
|
@ -5211,12 +5215,50 @@ void HistoryWidget::setupPinnedTracker() {
|
|||
Expects(_history != nullptr);
|
||||
|
||||
_pinnedTracker = std::make_unique<HistoryView::PinnedTracker>(_history);
|
||||
_pinnedBar = nullptr;
|
||||
checkPinnedBarState();
|
||||
}
|
||||
|
||||
void HistoryWidget::checkPinnedBarState() {
|
||||
Expects(_pinnedTracker != nullptr);
|
||||
|
||||
const auto hiddenId = _peer->canPinMessages()
|
||||
? MsgId(0)
|
||||
: session().settings().hiddenPinnedMessageId(_peer->id);
|
||||
const auto currentPinnedId = _peer->topPinnedMessageId();
|
||||
if (currentPinnedId == hiddenId) {
|
||||
if (_pinnedBar) {
|
||||
_pinnedTracker->reset();
|
||||
auto qobject = base::unique_qptr{
|
||||
Ui::WrapAsQObject(this, std::move(_pinnedBar)).get()
|
||||
};
|
||||
auto destroyer = [this, object = std::move(qobject)]() mutable {
|
||||
object = nullptr;
|
||||
updateHistoryGeometry();
|
||||
updateControlsGeometry();
|
||||
};
|
||||
base::call_delayed(
|
||||
st::defaultMessageBar.duration,
|
||||
this,
|
||||
std::move(destroyer));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (_pinnedBar || !currentPinnedId) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto shown = _pinnedTracker->shownMessageId(
|
||||
) | rpl::map([=](HistoryView::PinnedId messageId) {
|
||||
return HistoryView::PinnedBarId{
|
||||
FullMsgId{ peerToChannel(_peer->id), messageId.message },
|
||||
messageId.type
|
||||
};
|
||||
});
|
||||
_pinnedBar = std::make_unique<HistoryView::PinnedBar>(
|
||||
this,
|
||||
&session(),
|
||||
_pinnedTracker->shownMessageId() | rpl::map([=](MsgId messageId) {
|
||||
return FullMsgId{ peerToChannel(_peer->id), messageId };
|
||||
}),
|
||||
std::move(shown),
|
||||
true);
|
||||
|
||||
_pinnedBar->closeClicks(
|
||||
|
@ -5233,68 +5275,13 @@ void HistoryWidget::setupPinnedTracker() {
|
|||
updateControlsGeometry();
|
||||
_topDelta = 0;
|
||||
}, _pinnedBar->lifetime());
|
||||
|
||||
orderWidgets();
|
||||
|
||||
if (_a_show.animating()) {
|
||||
_pinnedBar->hide();
|
||||
}
|
||||
}
|
||||
//
|
||||
//bool HistoryWidget::pinnedMsgVisibilityUpdated() {
|
||||
// auto result = false;
|
||||
// auto pinnedId = _pinnedId;
|
||||
// if (pinnedId && !_peer->canPinMessages()) {
|
||||
// const auto hiddenId = session().settings().hiddenPinnedMessageId(
|
||||
// _peer->id);
|
||||
// if (hiddenId == pinnedId.msg) {
|
||||
// pinnedId = FullMsgId();
|
||||
// } else if (hiddenId) {
|
||||
// session().settings().setHiddenPinnedMessageId(_peer->id, 0);
|
||||
// session().saveSettings();
|
||||
// }
|
||||
// }
|
||||
// if (pinnedId) {
|
||||
// if (!_pinnedBar) {
|
||||
// _pinnedBar = std::make_unique<PinnedBar>(pinnedId.msg, this);
|
||||
// if (_a_show.animating()) {
|
||||
// _pinnedBar->cancel->hide();
|
||||
// _pinnedBar->bar->widget()->hide();
|
||||
// _pinnedBar->shadow->hide();
|
||||
// } else {
|
||||
// _pinnedBar->cancel->show();
|
||||
// _pinnedBar->bar->widget()->show();
|
||||
// _pinnedBar->shadow->show();
|
||||
// }
|
||||
// _pinnedBar->cancel->addClickHandler([=] {
|
||||
// hidePinnedMessage();
|
||||
// });
|
||||
// orderWidgets();
|
||||
//
|
||||
// updatePinnedBar();
|
||||
// result = true;
|
||||
//
|
||||
// const auto barTop = unreadBarTop();
|
||||
// if (!barTop || _scroll->scrollTop() != *barTop) {
|
||||
// synteticScrollToY(_scroll->scrollTop() + st::historyReplyHeight);
|
||||
// }
|
||||
// } else if (_pinnedBar->msgId != pinnedId.msg) {
|
||||
// _pinnedBar->msgId = pinnedId.msg;
|
||||
// _pinnedBar->msg = nullptr;
|
||||
// updatePinnedBar();
|
||||
// }
|
||||
// if (!_pinnedBar->msg) {
|
||||
// requestMessageData(_pinnedBar->msgId);
|
||||
// }
|
||||
// } else if (_pinnedBar) {
|
||||
// destroyPinnedBar();
|
||||
// result = true;
|
||||
// const auto barTop = unreadBarTop();
|
||||
// if (!barTop || _scroll->scrollTop() != *barTop) {
|
||||
// synteticScrollToY(_scroll->scrollTop() - st::historyReplyHeight);
|
||||
// }
|
||||
// updateControlsGeometry();
|
||||
// }
|
||||
// return result;
|
||||
//}
|
||||
|
||||
void HistoryWidget::requestMessageData(MsgId msgId) {
|
||||
const auto callback = [=](ChannelData *channel, MsgId msgId) {
|
||||
|
@ -5574,25 +5561,25 @@ void HistoryWidget::UnpinMessage(not_null<PeerData*> peer, MsgId msgId) {
|
|||
}
|
||||
|
||||
void HistoryWidget::hidePinnedMessage() {
|
||||
//const auto pinnedId = _pinnedId; // #TODO pinned
|
||||
//if (!pinnedId) {
|
||||
// if (pinnedMsgVisibilityUpdated()) {
|
||||
// updateControlsGeometry();
|
||||
// update();
|
||||
// }
|
||||
// return;
|
||||
//}
|
||||
Expects(_pinnedBar != nullptr);
|
||||
|
||||
//if (_peer->canPinMessages()) {
|
||||
// unpinMessage(pinnedId);
|
||||
//} else {
|
||||
// session().settings().setHiddenPinnedMessageId(_peer->id, pinnedId.msg);
|
||||
// session().saveSettings();
|
||||
// if (pinnedMsgVisibilityUpdated()) {
|
||||
// updateControlsGeometry();
|
||||
// update();
|
||||
// }
|
||||
//}
|
||||
const auto id = _pinnedTracker->currentMessageId();
|
||||
if (!id.message) {
|
||||
return;
|
||||
}
|
||||
if (_peer->canPinMessages()) {
|
||||
unpinMessage({ peerToChannel(_peer->id), id.message });
|
||||
} else {
|
||||
const auto top = _peer->topPinnedMessageId();
|
||||
if (top) {
|
||||
session().settings().setHiddenPinnedMessageId(_peer->id, top);
|
||||
session().saveSettingsDelayed();
|
||||
|
||||
checkPinnedBarState();
|
||||
} else {
|
||||
session().api().requestFullPeer(_peer);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryWidget::lastForceReplyReplied(const FullMsgId &replyTo) const {
|
||||
|
@ -6373,16 +6360,6 @@ void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
|
|||
}
|
||||
//
|
||||
//void HistoryWidget::drawPinnedBar(Painter &p) {
|
||||
// Expects(_pinnedBar != nullptr);
|
||||
//
|
||||
// auto top = _topBar->bottomNoMargins();
|
||||
// p.fillRect(myrtlrect(0, top, width(), st::historyReplyHeight), st::historyPinnedBg);
|
||||
//
|
||||
// top += st::msgReplyPadding.top();
|
||||
// QRect rbar(myrtlrect(st::msgReplyBarSkip + st::msgReplyBarPos.x(), top + st::msgReplyBarPos.y(), st::msgReplyBarSize.width(), st::msgReplyBarSize.height()));
|
||||
// p.fillRect(rbar, st::msgInReplyBarColor);
|
||||
//
|
||||
// //int32 left = st::msgReplyBarSkip + st::msgReplyBarSkip;
|
||||
// //if (_pinnedBar->msg) {
|
||||
// // const auto media = _pinnedBar->msg->media();
|
||||
// // if (media && media->hasReplyPreview()) {
|
||||
|
@ -6392,22 +6369,6 @@ void HistoryWidget::drawRecording(Painter &p, float64 recordActive) {
|
|||
// // }
|
||||
// // left += st::msgReplyBarSize.height() + st::msgReplyBarSkip - st::msgReplyBarSize.width() - st::msgReplyBarPos.x();
|
||||
// // }
|
||||
// // p.setPen(st::historyReplyNameFg);
|
||||
// // p.setFont(st::msgServiceNameFont);
|
||||
// // const auto poll = media ? media->poll() : nullptr;
|
||||
// // const auto pinnedHeader = (_pinnedBar->msgId < _peer->topPinnedMessageId())
|
||||
// // ? tr::lng_pinned_previous(tr::now)
|
||||
// // : !poll
|
||||
// // ? tr::lng_pinned_message(tr::now)
|
||||
// // : poll->quiz()
|
||||
// // ? tr::lng_pinned_quiz(tr::now)
|
||||
// // : tr::lng_pinned_poll(tr::now);
|
||||
// // p.drawText(left, top + st::msgServiceNameFont->ascent, pinnedHeader);
|
||||
//
|
||||
// // p.setPen(st::historyComposeAreaFg);
|
||||
// // p.setTextPalette(st::historyComposeAreaPalette);
|
||||
// // _pinnedBar->text.drawElided(p, left, top + st::msgServiceNameFont->height, width() - left - _pinnedBar->cancel->width() - st::msgReplyPadding.right());
|
||||
// // p.restoreTextPalette();
|
||||
// //} else {
|
||||
// // p.setFont(st::msgDateFont);
|
||||
// // p.setPen(st::historyComposeAreaFgService);
|
||||
|
|
|
@ -486,6 +486,7 @@ private:
|
|||
|
||||
void updatePinnedViewer();
|
||||
void setupPinnedTracker();
|
||||
void checkPinnedBarState();
|
||||
|
||||
void sendInlineResult(
|
||||
not_null<InlineBots::Result*> result,
|
||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_poll.h"
|
||||
#include "ui/widgets/shadow.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "history/view/history_view_pinned_tracker.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history.h"
|
||||
#include "apiwrap.h"
|
||||
|
@ -23,7 +24,8 @@ namespace HistoryView {
|
|||
namespace {
|
||||
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItem(
|
||||
not_null<HistoryItem*> item) {
|
||||
not_null<HistoryItem*> item,
|
||||
PinnedIdType type) {
|
||||
return item->history()->session().changes().messageFlagsValue(
|
||||
item,
|
||||
Data::MessageUpdate::Flag::Edited
|
||||
|
@ -32,7 +34,9 @@ namespace {
|
|||
const auto poll = media ? media->poll() : nullptr;
|
||||
return Ui::MessageBarContent{
|
||||
.id = item->id,
|
||||
.title = ((item->id < item->history()->peer->topPinnedMessageId())
|
||||
.title = ((type == PinnedIdType::First)
|
||||
? "First message"
|
||||
: (type == PinnedIdType::Middle)
|
||||
? tr::lng_pinned_previous(tr::now)
|
||||
: !poll
|
||||
? tr::lng_pinned_message(tr::now)
|
||||
|
@ -46,12 +50,12 @@ namespace {
|
|||
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItemId(
|
||||
not_null<Main::Session*> session,
|
||||
FullMsgId id,
|
||||
PinnedBarId id,
|
||||
bool alreadyLoaded = false) {
|
||||
if (!id) {
|
||||
if (!id.message) {
|
||||
return rpl::single(Ui::MessageBarContent());
|
||||
} else if (const auto item = session->data().message(id)) {
|
||||
return ContentByItem(item);
|
||||
} else if (const auto item = session->data().message(id.message)) {
|
||||
return ContentByItem(item, id.type);
|
||||
} else if (alreadyLoaded) {
|
||||
return rpl::single(Ui::MessageBarContent()); // Deleted message?..
|
||||
}
|
||||
|
@ -59,13 +63,13 @@ namespace {
|
|||
consumer.put_next(Ui::MessageBarContent{
|
||||
.text = tr::lng_contacts_loading(tr::now),
|
||||
});
|
||||
const auto channel = id.channel
|
||||
? session->data().channel(id.channel).get()
|
||||
const auto channel = id.message.channel
|
||||
? session->data().channel(id.message.channel).get()
|
||||
: nullptr;
|
||||
const auto callback = [=](ChannelData *channel, MsgId id) {
|
||||
consumer.put_done();
|
||||
};
|
||||
session->api().requestMessageData(channel, id.msg, callback);
|
||||
session->api().requestMessageData(channel, id.message.msg, callback);
|
||||
return rpl::lifetime();
|
||||
});
|
||||
return std::move(
|
||||
|
@ -80,7 +84,7 @@ namespace {
|
|||
PinnedBar::PinnedBar(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<FullMsgId> itemId,
|
||||
rpl::producer<PinnedBarId> itemId,
|
||||
bool withClose)
|
||||
: _wrap(parent, object_ptr<Ui::RpWidget>(parent))
|
||||
, _close(withClose
|
||||
|
@ -101,7 +105,7 @@ PinnedBar::PinnedBar(
|
|||
rpl::duplicate(
|
||||
itemId
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::map([=](FullMsgId id) {
|
||||
) | rpl::map([=](PinnedBarId id) {
|
||||
return ContentByItemId(session, id);
|
||||
}) | rpl::flatten_latest(
|
||||
) | rpl::filter([=](const Ui::MessageBarContent &content) {
|
||||
|
@ -119,15 +123,18 @@ PinnedBar::PinnedBar(
|
|||
|
||||
std::move(
|
||||
itemId
|
||||
) | rpl::map([=](FullMsgId id) {
|
||||
return !id;
|
||||
}) | rpl::start_with_next([=](bool hidden) {
|
||||
) | rpl::map([=](PinnedBarId id) {
|
||||
return !id.message;
|
||||
}) | rpl::start_with_next_done([=](bool hidden) {
|
||||
_shouldBeShown = !hidden;
|
||||
if (!_forceHidden) {
|
||||
_wrap.toggle(_shouldBeShown, anim::type::normal);
|
||||
} else if (!_shouldBeShown) {
|
||||
_bar = nullptr;
|
||||
}
|
||||
}, [=] {
|
||||
_forceHidden = true;
|
||||
_wrap.toggle(false, anim::type::normal);
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
|
|
|
@ -21,12 +21,25 @@ class PlainShadow;
|
|||
|
||||
namespace HistoryView {
|
||||
|
||||
enum class PinnedIdType;
|
||||
struct PinnedBarId {
|
||||
FullMsgId message;
|
||||
PinnedIdType type = PinnedIdType();
|
||||
|
||||
bool operator<(const PinnedBarId &other) const {
|
||||
return std::tie(message, type) < std::tie(other.message, other.type);
|
||||
}
|
||||
bool operator==(const PinnedBarId &other) const {
|
||||
return std::tie(message, type) == std::tie(other.message, other.type);
|
||||
}
|
||||
};
|
||||
|
||||
class PinnedBar final {
|
||||
public:
|
||||
PinnedBar(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<FullMsgId> itemId,
|
||||
rpl::producer<PinnedBarId> itemId,
|
||||
bool withClose = false);
|
||||
|
||||
void show();
|
||||
|
|
|
@ -40,15 +40,23 @@ PinnedTracker::~PinnedTracker() {
|
|||
_history->owner().histories().cancelRequest(_afterRequestId);
|
||||
}
|
||||
|
||||
rpl::producer<MsgId> PinnedTracker::shownMessageId() const {
|
||||
rpl::producer<PinnedId> PinnedTracker::shownMessageId() const {
|
||||
return _current.value();
|
||||
}
|
||||
|
||||
void PinnedTracker::reset() {
|
||||
_current.reset(currentMessageId());
|
||||
}
|
||||
|
||||
PinnedId PinnedTracker::currentMessageId() const {
|
||||
return _current.current();
|
||||
}
|
||||
|
||||
void PinnedTracker::refreshData() {
|
||||
const auto now = _history->peer->currentPinnedMessages();
|
||||
if (!now) {
|
||||
_dataLifetime.destroy();
|
||||
_current = MsgId(0);
|
||||
_current = PinnedId();
|
||||
} else if (_data.get() != now) {
|
||||
_dataLifetime.destroy();
|
||||
_data = now;
|
||||
|
@ -65,7 +73,7 @@ void PinnedTracker::trackAround(MsgId messageId) {
|
|||
_dataLifetime.destroy();
|
||||
_aroundId = messageId;
|
||||
if (!_aroundId) {
|
||||
_current = MsgId(0);
|
||||
_current = PinnedId();
|
||||
} else if (const auto now = _data.get()) {
|
||||
setupViewer(now);
|
||||
}
|
||||
|
@ -90,10 +98,19 @@ void PinnedTracker::setupViewer(not_null<Data::PinnedMessages*> data) {
|
|||
Data::LoadDirection::After,
|
||||
empty ? _aroundId : snapshot.ids.back());
|
||||
}
|
||||
if (snapshot.ids.empty()) {
|
||||
_current = PinnedId();
|
||||
return;
|
||||
}
|
||||
const auto type = (!after && (snapshot.skippedAfter == 0))
|
||||
? PinnedIdType::Last
|
||||
: (before < 2 && (snapshot.skippedBefore == 0))
|
||||
? PinnedIdType::First
|
||||
: PinnedIdType::Middle;
|
||||
if (i != begin(snapshot.ids)) {
|
||||
_current = *(i - 1);
|
||||
_current = PinnedId{ *(i - 1), type };
|
||||
} else if (snapshot.skippedBefore == 0) {
|
||||
_current = 0;
|
||||
_current = PinnedId{ snapshot.ids.front(), type };
|
||||
}
|
||||
}, _dataLifetime);
|
||||
}
|
||||
|
|
|
@ -16,13 +16,32 @@ enum class LoadDirection : char;
|
|||
|
||||
namespace HistoryView {
|
||||
|
||||
enum class PinnedIdType {
|
||||
First,
|
||||
Middle,
|
||||
Last,
|
||||
};
|
||||
struct PinnedId {
|
||||
MsgId message = 0;
|
||||
PinnedIdType type = PinnedIdType::Middle;
|
||||
|
||||
bool operator<(const PinnedId &other) const {
|
||||
return std::tie(message, type) < std::tie(other.message, other.type);
|
||||
}
|
||||
bool operator==(const PinnedId &other) const {
|
||||
return std::tie(message, type) == std::tie(other.message, other.type);
|
||||
}
|
||||
};
|
||||
|
||||
class PinnedTracker final {
|
||||
public:
|
||||
explicit PinnedTracker(not_null<History*> history);
|
||||
~PinnedTracker();
|
||||
|
||||
[[nodiscard]] rpl::producer<MsgId> shownMessageId() const;
|
||||
[[nodiscard]] rpl::producer<PinnedId> shownMessageId() const;
|
||||
[[nodiscard]] PinnedId currentMessageId() const;
|
||||
void trackAround(MsgId messageId);
|
||||
void reset();
|
||||
|
||||
private:
|
||||
void refreshData();
|
||||
|
@ -36,7 +55,7 @@ private:
|
|||
const not_null<History*> _history;
|
||||
|
||||
base::weak_ptr<Data::PinnedMessages> _data;
|
||||
rpl::variable<MsgId> _current = MsgId();
|
||||
rpl::variable<PinnedId> _current;
|
||||
rpl::lifetime _dataLifetime;
|
||||
|
||||
MsgId _aroundId = 0;
|
||||
|
|
Loading…
Add table
Reference in a new issue