mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-29 16:58:07 +00:00
Switch between pinned messages in chat.
This commit is contained in:
@@ -469,12 +469,14 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -511,8 +513,8 @@ void PeerData::addPinnedMessage(MsgId messageId) {
|
||||
|
||||
void PeerData::addPinnedSlice(
|
||||
std::vector<MsgId> &&ids,
|
||||
MsgId from,
|
||||
MsgId till) {
|
||||
MsgRange noSkipRange,
|
||||
std::optional<int> count) {
|
||||
const auto min = [&] {
|
||||
if (const auto channel = asChannel()) {
|
||||
return channel->availableMinId();
|
||||
@@ -522,14 +524,14 @@ void PeerData::addPinnedSlice(
|
||||
ids.erase(
|
||||
ranges::remove_if(ids, [&](MsgId id) { return id <= min; }),
|
||||
end(ids));
|
||||
if (from <= min) {
|
||||
from = 0;
|
||||
if (noSkipRange.from <= min) {
|
||||
noSkipRange.from = 0;
|
||||
}
|
||||
if (ids.empty() && !_pinnedMessages) {
|
||||
return;
|
||||
}
|
||||
ensurePinnedMessagesCreated();
|
||||
_pinnedMessages->add(std::move(ids), from, till, std::nullopt);
|
||||
_pinnedMessages->add(std::move(ids), noSkipRange, std::nullopt);
|
||||
}
|
||||
|
||||
void PeerData::removePinnedMessage(MsgId messageId) {
|
||||
|
||||
@@ -30,6 +30,7 @@ namespace Data {
|
||||
|
||||
class Session;
|
||||
class PinnedMessages;
|
||||
struct PinnedAroundId;
|
||||
|
||||
int PeerColorIndex(PeerId peerId);
|
||||
int PeerColorIndex(int32 bareId);
|
||||
@@ -331,8 +332,14 @@ public:
|
||||
void setTopPinnedMessageId(MsgId messageId);
|
||||
void clearPinnedMessages(MsgId lessThanId = ServerMaxMsgId);
|
||||
void addPinnedMessage(MsgId messageId);
|
||||
void addPinnedSlice(std::vector<MsgId> &&ids, MsgId from, MsgId till);
|
||||
void addPinnedSlice(
|
||||
std::vector<MsgId> &&ids,
|
||||
MsgRange noSkipRange,
|
||||
std::optional<int> count);
|
||||
void removePinnedMessage(MsgId messageId);
|
||||
Data::PinnedMessages *currentPinnedMessages() const {
|
||||
return _pinnedMessages.get();
|
||||
}
|
||||
|
||||
[[nodiscard]] bool canExportChatHistory() const;
|
||||
|
||||
|
||||
@@ -25,6 +25,25 @@ MsgId PinnedMessages::topId() const {
|
||||
return slice.messageIds.empty() ? 0 : slice.messageIds.back().fullId.msg;
|
||||
}
|
||||
|
||||
rpl::producer<PinnedAroundId> PinnedMessages::viewer(
|
||||
MsgId aroundId,
|
||||
int limit) const {
|
||||
return _list.viewer(MessagesQuery{
|
||||
.aroundId = position(aroundId),
|
||||
.limitBefore = limit,
|
||||
.limitAfter = limit
|
||||
}) | rpl::map([](const MessagesResult &result) {
|
||||
auto data = PinnedAroundId();
|
||||
data.fullCount = result.count;
|
||||
data.skippedBefore = result.skippedBefore;
|
||||
data.skippedAfter = result.skippedAfter;
|
||||
data.ids = result.messageIds | ranges::view::transform(
|
||||
[](MessagePosition position) { return position.fullId.msg; }
|
||||
) | ranges::to_vector;
|
||||
return data;
|
||||
});
|
||||
}
|
||||
|
||||
MessagePosition PinnedMessages::position(MsgId id) const {
|
||||
return MessagePosition{
|
||||
.fullId = FullMsgId(_channelId, id),
|
||||
@@ -37,8 +56,7 @@ void PinnedMessages::add(MsgId messageId) {
|
||||
|
||||
void PinnedMessages::add(
|
||||
std::vector<MsgId> &&ids,
|
||||
MsgId from,
|
||||
MsgId till,
|
||||
MsgRange range,
|
||||
std::optional<int> count) {
|
||||
auto positions = ids | ranges::view::transform([&](MsgId id) {
|
||||
return position(id);
|
||||
@@ -47,16 +65,14 @@ void PinnedMessages::add(
|
||||
_list.addSlice(
|
||||
std::move(positions),
|
||||
MessagesRange{
|
||||
.from = from ? position(from) : MinMessagePosition,
|
||||
.till = position(till)
|
||||
.from = range.from ? position(range.from) : MinMessagePosition,
|
||||
.till = position(range.till)
|
||||
},
|
||||
count);
|
||||
}
|
||||
|
||||
void PinnedMessages::remove(MsgId messageId) {
|
||||
_list.removeOne(MessagePosition{
|
||||
.fullId = FullMsgId(0, messageId),
|
||||
});
|
||||
_list.removeOne(position(messageId));
|
||||
}
|
||||
|
||||
void PinnedMessages::setTopId(MsgId messageId) {
|
||||
@@ -70,19 +86,15 @@ void PinnedMessages::setTopId(MsgId messageId) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
const auto position = MessagePosition{
|
||||
.fullId = FullMsgId(0, messageId),
|
||||
};
|
||||
const auto wrapped = position(messageId);
|
||||
_list.addSlice(
|
||||
{ position },
|
||||
{ .from = position, .till = MaxMessagePosition },
|
||||
{ wrapped },
|
||||
{ .from = wrapped, .till = MaxMessagePosition },
|
||||
std::nullopt);
|
||||
}
|
||||
|
||||
void PinnedMessages::clearLessThanId(MsgId messageId) {
|
||||
_list.removeLessThan(MessagePosition{
|
||||
.fullId = FullMsgId(0, messageId),
|
||||
});
|
||||
_list.removeLessThan(position(messageId));
|
||||
}
|
||||
|
||||
} // namespace Data
|
||||
|
||||
@@ -8,21 +8,31 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
#include "data/data_messages.h"
|
||||
#include "base/weak_ptr.h"
|
||||
|
||||
namespace Data {
|
||||
|
||||
class PinnedMessages final {
|
||||
struct PinnedAroundId {
|
||||
std::vector<MsgId> ids;
|
||||
std::optional<int> skippedBefore;
|
||||
std::optional<int> skippedAfter;
|
||||
std::optional<int> fullCount;
|
||||
};
|
||||
|
||||
class PinnedMessages final : public base::has_weak_ptr {
|
||||
public:
|
||||
explicit PinnedMessages(ChannelId channelId);
|
||||
|
||||
[[nodiscard]] bool empty() const;
|
||||
[[nodiscard]] MsgId topId() const;
|
||||
[[nodiscard]] rpl::producer<PinnedAroundId> viewer(
|
||||
MsgId aroundId,
|
||||
int limit) const;
|
||||
|
||||
void add(MsgId messageId);
|
||||
void add(
|
||||
std::vector<MsgId> &&ids,
|
||||
MsgId from,
|
||||
MsgId till,
|
||||
MsgRange range,
|
||||
std::optional<int> count);
|
||||
void remove(MsgId messageId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user