mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 14:45:14 +00:00
Create / move forum topics on new messages.
This commit is contained in:
@@ -13,10 +13,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_chat_participant_status.h"
|
||||
#include "data/data_peer_bot_commands.h"
|
||||
|
||||
namespace Data {
|
||||
class Forum;
|
||||
} // namespace Data
|
||||
|
||||
struct ChannelLocation {
|
||||
QString address;
|
||||
Data::LocationPoint point;
|
||||
|
@@ -69,23 +69,27 @@ void Forum::requestTopics() {
|
||||
const auto &list = data.vtopics().v;
|
||||
for (const auto &topic : list) {
|
||||
const auto rootId = MsgId(topic.data().vid().v);
|
||||
if (const auto i = _topics.find(rootId); i != end(_topics)) {
|
||||
i->second->applyTopic(topic);
|
||||
} else {
|
||||
const auto raw = _topics.emplace(
|
||||
const auto i = _topics.find(rootId);
|
||||
const auto creating = (i == end(_topics));
|
||||
const auto raw = creating
|
||||
? _topics.emplace(
|
||||
rootId,
|
||||
std::make_unique<ForumTopic>(forum, rootId)
|
||||
).first->second.get();
|
||||
raw->applyTopic(topic);
|
||||
).first->second.get()
|
||||
: i->second.get();
|
||||
raw->applyTopic(topic);
|
||||
if (creating) {
|
||||
raw->addToChatList(FilterId(), topicsList());
|
||||
}
|
||||
if (const auto last = raw->lastServerMessage()) {
|
||||
_offsetDate = last->date();
|
||||
_offsetId = last->id;
|
||||
}
|
||||
_offsetTopicId = rootId;
|
||||
}
|
||||
if (list.isEmpty() || list.size() == data.vcount().v) {
|
||||
_allLoaded = true;
|
||||
}
|
||||
if (const auto date = data.vnext_date()) {
|
||||
_offsetDate = date->v;
|
||||
}
|
||||
_requestId = 0;
|
||||
_chatsListChanges.fire({});
|
||||
if (_allLoaded) {
|
||||
@@ -97,21 +101,35 @@ void Forum::requestTopics() {
|
||||
}).send();
|
||||
}
|
||||
|
||||
void Forum::topicAdded(not_null<HistoryItem*> root) {
|
||||
const auto rootId = root->id;
|
||||
void Forum::applyTopicAdded(MsgId rootId, const QString &title) {
|
||||
if (const auto i = _topics.find(rootId); i != end(_topics)) {
|
||||
//i->second->applyTopic(topic);
|
||||
i->second->applyTitle(title);
|
||||
} else {
|
||||
const auto raw = _topics.emplace(
|
||||
rootId,
|
||||
std::make_unique<ForumTopic>(_forum, rootId)
|
||||
).first->second.get();
|
||||
//raw->applyTopic(topic);
|
||||
raw->applyTitle(title);
|
||||
raw->addToChatList(FilterId(), topicsList());
|
||||
_chatsListChanges.fire({});
|
||||
}
|
||||
}
|
||||
|
||||
void Forum::applyTopicRemoved(MsgId rootId) {
|
||||
//if (const auto i = _topics.find(rootId)) {
|
||||
// _topics.erase(i);
|
||||
//}
|
||||
}
|
||||
|
||||
ForumTopic *Forum::topicFor(not_null<HistoryItem*> item) {
|
||||
if (const auto rootId = item->replyToTop()) {
|
||||
if (const auto i = _topics.find(rootId); i != end(_topics)) {
|
||||
return i->second.get();
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
rpl::producer<> Forum::chatsListChanges() const {
|
||||
return _chatsListChanges.events();
|
||||
}
|
||||
|
@@ -29,7 +29,9 @@ public:
|
||||
[[nodiscard]] rpl::producer<> chatsListChanges() const;
|
||||
[[nodiscard]] rpl::producer<> chatsListLoadedEvents() const;
|
||||
|
||||
void topicAdded(not_null<HistoryItem*> root);
|
||||
void applyTopicAdded(MsgId rootId, const QString &title);
|
||||
void applyTopicRemoved(MsgId rootId);
|
||||
[[nodiscard]] ForumTopic *topicFor(not_null<HistoryItem*> item);
|
||||
|
||||
private:
|
||||
const not_null<History*> _forum;
|
||||
|
@@ -37,13 +37,7 @@ void ForumTopic::applyTopic(const MTPForumTopic &topic) {
|
||||
Expects(_rootId == topic.data().vid().v);
|
||||
|
||||
const auto &data = topic.data();
|
||||
const auto title = qs(data.vtitle());
|
||||
if (_title != title) {
|
||||
_title = title;
|
||||
++_titleVersion;
|
||||
indexTitleParts();
|
||||
updateChatListEntry();
|
||||
}
|
||||
applyTitle(qs(data.vtitle()));
|
||||
|
||||
const auto pinned = _list->pinned();
|
||||
if (data.is_pinned()) {
|
||||
@@ -216,7 +210,7 @@ TimeId ForumTopic::adjustedChatListTimeId() const {
|
||||
}
|
||||
|
||||
int ForumTopic::fixedOnTopIndex() const {
|
||||
return kArchiveFixOnTopIndex;
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool ForumTopic::shouldBeInChatList() const {
|
||||
@@ -241,6 +235,38 @@ bool ForumTopic::lastServerMessageKnown() const {
|
||||
return _lastServerMessage.has_value();
|
||||
}
|
||||
|
||||
void ForumTopic::applyTitle(const QString &title) {
|
||||
if (_title == title) {
|
||||
return;
|
||||
}
|
||||
_title = title;
|
||||
++_titleVersion;
|
||||
indexTitleParts();
|
||||
updateChatListEntry();
|
||||
}
|
||||
|
||||
void ForumTopic::applyItemAdded(not_null<HistoryItem*> item) {
|
||||
setLastMessage(item);
|
||||
}
|
||||
|
||||
void ForumTopic::applyItemRemoved(MsgId id) {
|
||||
if (const auto lastItem = lastMessage()) {
|
||||
if (lastItem->id == id) {
|
||||
_lastMessage = std::nullopt;
|
||||
}
|
||||
}
|
||||
if (const auto lastServerItem = lastServerMessage()) {
|
||||
if (lastServerItem->id == id) {
|
||||
_lastServerMessage = std::nullopt;
|
||||
}
|
||||
}
|
||||
if (const auto chatListItem = _chatListMessage.value_or(nullptr)) {
|
||||
if (chatListItem->id == id) {
|
||||
_chatListMessage = std::nullopt;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int ForumTopic::unreadCount() const {
|
||||
return _unreadCount ? *_unreadCount : 0;
|
||||
}
|
||||
|
@@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#pragma once
|
||||
|
||||
#include "dialogs/dialogs_entry.h"
|
||||
#include "dialogs/ui/dialogs_message_view.h"
|
||||
|
||||
class ChannelData;
|
||||
|
||||
@@ -56,6 +57,10 @@ public:
|
||||
[[nodiscard]] bool lastMessageKnown() const;
|
||||
[[nodiscard]] bool lastServerMessageKnown() const;
|
||||
|
||||
void applyTitle(const QString &title);
|
||||
void applyItemAdded(not_null<HistoryItem*> item);
|
||||
void applyItemRemoved(MsgId id);
|
||||
|
||||
void loadUserpic() override;
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
@@ -73,6 +78,9 @@ public:
|
||||
void setUnreadMark(bool unread);
|
||||
[[nodiscard]] bool unreadMark() const;
|
||||
|
||||
Ui::Text::String cloudDraftTextCache;
|
||||
Dialogs::Ui::MessageView lastItemDialogsView;
|
||||
|
||||
private:
|
||||
void indexTitleParts();
|
||||
void applyTopicTopMessage(MsgId topMessageId);
|
||||
|
@@ -12,6 +12,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "dialogs/ui/dialogs_message_view.h"
|
||||
#include "data/data_media_types.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
|
||||
namespace Data {
|
||||
namespace {
|
||||
@@ -145,6 +147,11 @@ void Groups::refreshViews(const HistoryItemsList &items) {
|
||||
for (const auto &item : items) {
|
||||
_data->requestItemViewRefresh(item);
|
||||
history->lastItemDialogsView.itemInvalidated(item);
|
||||
if (const auto forum = history->peer->forum()) {
|
||||
if (const auto topic = forum->topicFor(item)) {
|
||||
topic->lastItemDialogsView.itemInvalidated(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -882,6 +882,13 @@ bool PeerData::isRepliesChat() const {
|
||||
: kTestId) == id;
|
||||
}
|
||||
|
||||
Data::Forum *PeerData::forum() const {
|
||||
if (const auto channel = asChannel()) {
|
||||
return channel->forum();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool PeerData::canWrite() const {
|
||||
if (const auto user = asUser()) {
|
||||
return user->canWrite();
|
||||
|
@@ -32,6 +32,7 @@ class Session;
|
||||
|
||||
namespace Data {
|
||||
|
||||
class Forum;
|
||||
class Session;
|
||||
class GroupCall;
|
||||
class CloudImageView;
|
||||
@@ -195,6 +196,8 @@ public:
|
||||
return isUser() && !(id.value % 1000);
|
||||
}
|
||||
|
||||
[[nodiscard]] Data::Forum *forum() const;
|
||||
|
||||
[[nodiscard]] std::optional<TimeId> notifyMuteUntil() const {
|
||||
return _notify.muteUntil();
|
||||
}
|
||||
|
@@ -67,6 +67,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_premium_limits.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
#include "base/platform/base_platform_info.h"
|
||||
#include "base/unixtime.h"
|
||||
@@ -3793,7 +3795,9 @@ void Session::refreshChatListEntry(Dialogs::Key key) {
|
||||
|
||||
const auto entry = key.entry();
|
||||
const auto history = key.history();
|
||||
const auto mainList = chatsList(entry->folder());
|
||||
const auto mainList = entry->asTopic()
|
||||
? entry->asTopic()->forum()->peer->forum()->topicsList()
|
||||
: chatsList(entry->folder());
|
||||
auto event = ChatListEntryRefresh{ .key = key };
|
||||
const auto creating = event.existenceChanged = !entry->inChatList();
|
||||
if (event.existenceChanged) {
|
||||
@@ -3848,6 +3852,7 @@ void Session::removeChatListEntry(Dialogs::Key key) {
|
||||
return;
|
||||
}
|
||||
Assert(entry->folderKnown());
|
||||
|
||||
for (const auto &filter : _chatsFilters->list()) {
|
||||
const auto id = filter.id();
|
||||
if (id && entry->inChatList(id)) {
|
||||
@@ -3859,7 +3864,9 @@ void Session::removeChatListEntry(Dialogs::Key key) {
|
||||
});
|
||||
}
|
||||
}
|
||||
const auto mainList = chatsList(entry->folder());
|
||||
const auto mainList = entry->asTopic()
|
||||
? entry->asTopic()->forum()->peer->forum()->topicsList()
|
||||
: chatsList(entry->folder());
|
||||
entry->removeFromChatList(0, mainList);
|
||||
_chatListEntryRefreshes.fire(ChatListEntryRefresh{
|
||||
.key = key,
|
||||
|
Reference in New Issue
Block a user