mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Support pinned topics in forums.
This commit is contained in:
parent
306179ca7c
commit
adaa1d0c55
7 changed files with 86 additions and 41 deletions
|
@ -34,6 +34,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_drafts.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
#include "data/data_send_action.h"
|
||||
#include "data/data_message_reactions.h"
|
||||
|
@ -2289,6 +2290,23 @@ void Updates::feedUpdate(const MTPUpdate &update) {
|
|||
}
|
||||
} break;
|
||||
|
||||
case mtpc_updateChannelPinnedTopic: {
|
||||
const auto &d = update.c_updateChannelPinnedTopic();
|
||||
const auto peerId = peerFromChannel(d.vchannel_id());
|
||||
if (const auto peer = session().data().peerLoaded(peerId)) {
|
||||
const auto rootId = d.vtopic_id().value_or_empty();
|
||||
if (const auto topic = peer->forumTopicFor(rootId)) {
|
||||
session().data().setChatPinned(topic, 0, true);
|
||||
} else if (const auto forum = peer->forum()) {
|
||||
if (rootId) {
|
||||
forum->requestTopic(rootId);
|
||||
} else {
|
||||
forum->unpinTopic();
|
||||
}
|
||||
}
|
||||
}
|
||||
} break;
|
||||
|
||||
// Pinned message.
|
||||
case mtpc_updatePinnedMessages: {
|
||||
const auto &d = update.c_updatePinnedMessages();
|
||||
|
|
|
@ -70,6 +70,13 @@ not_null<Dialogs::MainList*> Forum::topicsList() {
|
|||
return &_topicsList;
|
||||
}
|
||||
|
||||
void Forum::unpinTopic() {
|
||||
const auto list = _topicsList.pinned();
|
||||
while (!list->order().empty()) {
|
||||
list->setPinned(list->order().front(), false);
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<> Forum::destroyed() const {
|
||||
return channel()->flagsValue(
|
||||
) | rpl::filter([=](const ChannelData::Flags::Change &update) {
|
||||
|
|
|
@ -41,6 +41,7 @@ public:
|
|||
void requestTopics();
|
||||
[[nodiscard]] rpl::producer<> chatsListChanges() const;
|
||||
[[nodiscard]] rpl::producer<> chatsListLoadedEvents() const;
|
||||
void unpinTopic();
|
||||
|
||||
void requestTopic(MsgId rootId, Fn<void()> done = nullptr);
|
||||
ForumTopic *applyTopicAdded(
|
||||
|
|
|
@ -206,6 +206,10 @@ bool ForumTopic::canToggleClosed() const {
|
|||
return !creating() && canEdit();
|
||||
}
|
||||
|
||||
bool ForumTopic::canTogglePinned() const {
|
||||
return !creating() && channel()->canEditTopics();
|
||||
}
|
||||
|
||||
bool ForumTopic::creating() const {
|
||||
return _forum->creating(_rootId);
|
||||
}
|
||||
|
@ -238,11 +242,10 @@ void ForumTopic::applyTopic(const MTPDforumTopic &data) {
|
|||
}
|
||||
applyColorId(data.vicon_color().v);
|
||||
|
||||
const auto pinned = _list->pinned();
|
||||
if (data.is_pinned()) {
|
||||
pinned->addPinned(Dialogs::Key(this));
|
||||
owner().setChatPinned(this, 0, true);
|
||||
} else {
|
||||
pinned->setPinned(Dialogs::Key(this), false);
|
||||
_list->pinned()->setPinned(this, false);
|
||||
}
|
||||
|
||||
owner().notifySettings().apply(this, data.vnotify_settings());
|
||||
|
|
|
@ -63,6 +63,7 @@ public:
|
|||
|
||||
[[nodiscard]] bool canEdit() const;
|
||||
[[nodiscard]] bool canToggleClosed() const;
|
||||
[[nodiscard]] bool canTogglePinned() const;
|
||||
|
||||
[[nodiscard]] bool closed() const;
|
||||
void setClosed(bool closed);
|
||||
|
|
|
@ -1823,10 +1823,13 @@ void Session::setChatPinned(
|
|||
bool pinned) {
|
||||
Expects(key.entry()->folderKnown());
|
||||
|
||||
const auto list = filterId
|
||||
const auto list = (filterId
|
||||
? chatsFilters().chatsList(filterId)
|
||||
: chatsList(key.entry()->folder());
|
||||
list->pinned()->setPinned(key, pinned);
|
||||
: chatsListFor(key.entry()))->pinned();
|
||||
if (const auto topic = key.topic()) {
|
||||
topic->forum()->unpinTopic();
|
||||
}
|
||||
list->setPinned(key, pinned);
|
||||
notifyPinnedDialogsOrderUpdated();
|
||||
}
|
||||
|
||||
|
|
|
@ -300,39 +300,55 @@ bool PinnedLimitReached(
|
|||
return true;
|
||||
}
|
||||
|
||||
void TogglePinnedDialog(
|
||||
void TogglePinnedThread(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<History*> history) {
|
||||
if (!history->folderKnown()) {
|
||||
not_null<Data::Thread*> thread) {
|
||||
if (!thread->folderKnown()) {
|
||||
return;
|
||||
}
|
||||
const auto owner = &history->owner();
|
||||
const auto isPinned = !history->isPinnedDialog(0);
|
||||
if (isPinned && PinnedLimitReached(controller, history, 0)) {
|
||||
return;
|
||||
const auto owner = &thread->owner();
|
||||
const auto isPinned = !thread->isPinnedDialog(0);
|
||||
if (const auto history = thread->asHistory()) {
|
||||
if (isPinned && PinnedLimitReached(controller, history, 0)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
owner->setChatPinned(history, FilterId(), isPinned);
|
||||
const auto flags = isPinned
|
||||
? MTPmessages_ToggleDialogPin::Flag::f_pinned
|
||||
: MTPmessages_ToggleDialogPin::Flag(0);
|
||||
history->session().api().request(MTPmessages_ToggleDialogPin(
|
||||
MTP_flags(flags),
|
||||
MTP_inputDialogPeer(history->peer->input)
|
||||
)).done([=] {
|
||||
owner->notifyPinnedDialogsOrderUpdated();
|
||||
}).send();
|
||||
if (isPinned) {
|
||||
controller->content()->dialogsToUp();
|
||||
owner->setChatPinned(thread, FilterId(), isPinned);
|
||||
if (const auto history = thread->asHistory()) {
|
||||
const auto flags = isPinned
|
||||
? MTPmessages_ToggleDialogPin::Flag::f_pinned
|
||||
: MTPmessages_ToggleDialogPin::Flag(0);
|
||||
owner->session().api().request(MTPmessages_ToggleDialogPin(
|
||||
MTP_flags(flags),
|
||||
MTP_inputDialogPeer(history->peer->input)
|
||||
)).done([=] {
|
||||
owner->notifyPinnedDialogsOrderUpdated();
|
||||
}).send();
|
||||
if (isPinned) {
|
||||
controller->content()->dialogsToUp();
|
||||
}
|
||||
} else if (const auto topic = thread->asTopic()) {
|
||||
owner->session().api().request(MTPchannels_UpdatePinnedForumTopic(
|
||||
topic->channel()->inputChannel,
|
||||
MTP_int(topic->rootId()),
|
||||
MTP_bool(isPinned)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
owner->session().api().applyUpdates(result);
|
||||
}).send();
|
||||
}
|
||||
}
|
||||
|
||||
void TogglePinnedDialog(
|
||||
void TogglePinnedThread(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<History*> history,
|
||||
not_null<Data::Thread*> thread,
|
||||
FilterId filterId) {
|
||||
if (!filterId) {
|
||||
return TogglePinnedDialog(controller, history);
|
||||
return TogglePinnedThread(controller, thread);
|
||||
}
|
||||
const auto history = thread->asHistory();
|
||||
if (!history) {
|
||||
return;
|
||||
}
|
||||
const auto owner = &history->owner();
|
||||
|
||||
|
@ -402,37 +418,33 @@ void Filler::addToggleTopicClosed() {
|
|||
}
|
||||
|
||||
void Filler::addTogglePin() {
|
||||
if (!_peer || _topic) {
|
||||
// #TODO forum pinned
|
||||
if (!_peer || (_topic && !_topic->canTogglePinned())) {
|
||||
return;
|
||||
}
|
||||
const auto controller = _controller;
|
||||
const auto filterId = _request.filterId;
|
||||
const auto peer = _peer;
|
||||
const auto history = _request.key.history();
|
||||
if (!history || history->fixedOnTopIndex()) {
|
||||
const auto thread = _request.key.thread();
|
||||
if (!thread || thread->fixedOnTopIndex()) {
|
||||
return;
|
||||
}
|
||||
const auto pinText = [=] {
|
||||
return history->isPinnedDialog(filterId)
|
||||
return thread->isPinnedDialog(filterId)
|
||||
? tr::lng_context_unpin_from_top(tr::now)
|
||||
: tr::lng_context_pin_to_top(tr::now);
|
||||
};
|
||||
const auto weak = base::make_weak(thread);
|
||||
const auto pinToggle = [=] {
|
||||
TogglePinnedDialog(controller, history, filterId);
|
||||
if (const auto strong = weak.get()) {
|
||||
TogglePinnedThread(controller, strong, filterId);
|
||||
}
|
||||
};
|
||||
const auto pinAction = _addAction(
|
||||
pinText(),
|
||||
pinToggle,
|
||||
(history->isPinnedDialog(filterId)
|
||||
(thread->isPinnedDialog(filterId)
|
||||
? &st::menuIconUnpin
|
||||
: &st::menuIconPin));
|
||||
|
||||
auto actionText = history->session().changes().historyUpdates(
|
||||
history,
|
||||
Data::HistoryUpdate::Flag::IsPinned
|
||||
) | rpl::map(pinText);
|
||||
SetActionText(pinAction, std::move(actionText));
|
||||
}
|
||||
|
||||
void Filler::addToggleMuteSubmenu(bool addSeparator) {
|
||||
|
|
Loading…
Add table
Reference in a new issue