Request last topic message if it becomes unknown.

This commit is contained in:
John Preston 2022-10-06 20:06:24 +04:00
parent 032e6c57e9
commit f258b054e8
11 changed files with 91 additions and 39 deletions

View File

@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_forum.h"
#include "data/data_channel.h"
#include "data/data_histories.h"
#include "data/data_session.h"
#include "data/data_forum_topic.h"
#include "history/history.h"
@ -32,14 +33,25 @@ constexpr auto kGeneralColorId = 0xA9A9A9;
Forum::Forum(not_null<History*> history)
: _history(history)
, _topicsList(&_history->session(), FilterId(0), rpl::single(1)) {
, _topicsList(&session(), FilterId(0), rpl::single(1)) {
Expects(_history->peer->isChannel());
}
Forum::~Forum() {
if (_requestId) {
_history->session().api().request(_requestId).cancel();
session().api().request(_requestId).cancel();
}
for (const auto &request : _topicRequests) {
owner().histories().cancelRequest(request.second.id);
}
}
Session &Forum::owner() const {
return _history->owner();
}
Main::Session &Forum::session() const {
return _history->session();
}
not_null<History*> Forum::history() const {
@ -60,8 +72,7 @@ void Forum::requestTopics() {
}
const auto firstLoad = !_offsetDate;
const auto loadCount = firstLoad ? kTopicsFirstLoad : kTopicsPerPage;
const auto api = &_history->session().api();
_requestId = api->request(MTPchannels_GetForumTopics(
_requestId = session().api().request(MTPchannels_GetForumTopics(
MTP_flags(0),
channel()->inputChannel,
MTPstring(), // q
@ -90,10 +101,9 @@ void Forum::applyReceivedTopics(
const MTPmessages_ForumTopics &topics,
bool updateOffset) {
const auto &data = topics.data();
const auto owner = &channel()->owner();
owner->processUsers(data.vusers());
owner->processChats(data.vchats());
owner->processMessages(data.vmessages(), NewMessageType::Existing);
owner().processUsers(data.vusers());
owner().processChats(data.vchats());
owner().processMessages(data.vmessages(), NewMessageType::Existing);
channel()->ptsReceived(data.vpts().v);
const auto &list = data.vtopics().v;
for (const auto &topic : list) {
@ -121,6 +131,42 @@ void Forum::applyReceivedTopics(
}
}
void Forum::requestTopic(MsgId rootId, Fn<void()> done) {
auto &request = _topicRequests[rootId];
if (done) {
request.callbacks.push_back(std::move(done));
}
if (request.id) {
return;
}
const auto call = [=] {
if (const auto request = _topicRequests.take(rootId)) {
for (const auto &callback : request->callbacks) {
callback();
}
}
};
const auto type = Histories::RequestType::History;
auto &histories = owner().histories();
request.id = histories.sendRequest(_history, type, [=](
Fn<void()> finish) {
return session().api().request(
MTPchannels_GetForumTopicsByID(
channel()->inputChannel,
MTP_vector<MTPint>(1, MTP_int(rootId.bare)))
).done([=](const MTPmessages_ForumTopics &result) {
if (const auto forum = _history->peer->forum()) {
forum->applyReceivedTopics(result);
call();
finish();
}
}).fail([=] {
call();
finish();
}).send();
});
}
void Forum::applyTopicAdded(
MsgId rootId,
const QString &title,
@ -152,7 +198,7 @@ MsgId Forum::reserveCreatingId(
const QString &title,
int32 colorId,
DocumentId iconId) {
const auto result = _history->owner().nextLocalMessageId();
const auto result = owner().nextLocalMessageId();
_creatingRootIds.emplace(result);
applyTopicAdded(result, title, colorId, iconId);
return result;
@ -189,7 +235,7 @@ void Forum::created(MsgId rootId, MsgId realId) {
std::move(topic)
).first->second->setRealRootId(realId);
}
_history->owner().notifyItemIdChange({ id, rootId });
owner().notifyItemIdChange({ id, rootId });
}
ForumTopic *Forum::topicFor(not_null<HistoryItem*> item) {

View File

@ -12,17 +12,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
class History;
class ChannelData;
namespace Main {
class Session;
} // namespace Main
namespace Window {
class SessionController;
} // namespace Window;
namespace Data {
class Session;
class Forum final {
public:
explicit Forum(not_null<History*> history);
~Forum();
[[nodiscard]] Session &owner() const;
[[nodiscard]] Main::Session &session() const;
[[nodiscard]] not_null<History*> history() const;
[[nodiscard]] not_null<ChannelData*> channel() const;
[[nodiscard]] not_null<Dialogs::MainList*> topicsList();
@ -31,6 +39,7 @@ public:
[[nodiscard]] rpl::producer<> chatsListChanges() const;
[[nodiscard]] rpl::producer<> chatsListLoadedEvents() const;
void requestTopic(MsgId rootId, Fn<void()> done = nullptr);
void applyTopicAdded(
MsgId rootId,
const QString &title,
@ -52,6 +61,11 @@ public:
void created(MsgId rootId, MsgId realId);
private:
struct TopicRequest {
mtpRequestId id = 0;
std::vector<Fn<void()>> callbacks;
};
void applyReceivedTopics(
const MTPmessages_ForumTopics &topics,
bool updateOffset);
@ -61,6 +75,8 @@ private:
base::flat_map<MsgId, std::unique_ptr<ForumTopic>> _topics;
Dialogs::MainList _topicsList;
base::flat_map<MsgId, TopicRequest> _topicRequests;
mtpRequestId _requestId = 0;
TimeId _offsetDate = 0;
MsgId _offsetId = 0;

View File

@ -351,8 +351,8 @@ void ForumTopic::validateDefaultIcon() const {
}
void ForumTopic::requestChatListMessage() {
if (!chatListMessageKnown()) {
// #TODO forum
if (!chatListMessageKnown() && !forum()->creating(_rootId)) {
forum()->requestTopic(_rootId);
}
}
@ -361,7 +361,7 @@ TimeId ForumTopic::adjustedChatListTimeId() const {
return TimeId(1);
}
const auto result = chatListTimeId();
#if 0 // #TODO forum
#if 0 // #TODO forum draft
if (const auto draft = cloudDraft()) {
if (!Data::draftIsNull(draft) && !session().supportMode()) {
return std::max(result, draft->date);
@ -458,6 +458,7 @@ void ForumTopic::applyItemRemoved(MsgId id) {
if (const auto chatListItem = _chatListMessage.value_or(nullptr)) {
if (chatListItem->id == id) {
_chatListMessage = std::nullopt;
requestChatListMessage();
}
}
}

View File

@ -405,7 +405,7 @@ downloadIconSizeDone: 20px;
forumTopicRow: DialogRow(defaultDialogRow) {
height: 54px;
padding: margins(8px, 7px, 8px, 7px);
padding: margins(8px, 7px, 10px, 7px);
photoSize: 20px;
nameLeft: 39px;
nameTop: 7px;

View File

@ -1211,7 +1211,7 @@ void InnerWidget::checkReorderPinnedStart(QPoint localPosition) {
< style::ConvertScale(kStartReorderThreshold)) {
return;
} else if (_openedForum) {
return; // #TODO forum
return; // #TODO forum pinned
}
_dragging = _pressed;
if (updateReorderIndexGetCount() < 2) {
@ -2415,7 +2415,7 @@ void InnerWidget::refreshEmptyLabel() {
: (state == EmptyState::EmptyFolder)
? tr::lng_no_chats_filter()
: (state == EmptyState::EmptyForum)
// #TODO forum
// #TODO lang-forum
? rpl::single(u"No chats currently created in this forum."_q)
: tr::lng_contacts_loading();
auto link = (state == EmptyState::NoContacts)
@ -2423,7 +2423,7 @@ void InnerWidget::refreshEmptyLabel() {
: (state == EmptyState::EmptyFolder)
? tr::lng_filters_context_edit()
: (state == EmptyState::EmptyForum)
// #TODO forum
// #TODO lang-forum
? rpl::single(u"Create topic"_q)
: rpl::single(QString());
auto full = rpl::combine(

View File

@ -346,6 +346,7 @@ void PaintRow(
row->paintRipple(p, 0, 0, context.width, &ripple->c);
const auto history = chat.history();
const auto topic = chat.topic();
if (flags & Flag::SavedMessages) {
EmptyUserpic::PaintSavedMessages(
@ -561,7 +562,7 @@ void PaintRow(
// Empty history
}
} else if (!item->isEmpty()) {
if (history && !promoted) {
if ((history || topic) && !promoted) {
PaintRowDate(p, date, rectForName, context);
}

View File

@ -355,7 +355,6 @@ RepliesWidget::~RepliesWidget() {
if (_readRequestTimer.isActive()) {
sendReadTillRequest();
}
_history->session().api().request(_resolveTopicRequestId).cancel();
base::take(_sendAction);
_history->owner().sendActionManager().repliesPainterRemoved(
_history,
@ -478,7 +477,7 @@ void RepliesWidget::setupTopicViewer() {
void RepliesWidget::setTopic(Data::ForumTopic *topic) {
if ((_topic = topic)) {
refreshTopBarActiveChat();
if (_rootView) {
if (_topic && _rootView) {
_rootView = nullptr;
_rootViewHeight = 0;
updateControlsGeometry();
@ -492,24 +491,15 @@ HistoryItem *RepliesWidget::lookupRoot() const {
Data::ForumTopic *RepliesWidget::lookupTopic() {
if (const auto forum = _history->peer->forum()) {
const auto result = forum->topicFor(_rootId);
if (!result && !_resolveTopicRequestId) {
const auto api = &_history->session().api();
_resolveTopicRequestId = api->request(
MTPchannels_GetForumTopicsByID(
forum->channel()->inputChannel,
MTP_vector<MTPint>(1, MTP_int(_rootId.bare)))
).done([=](const MTPmessages_ForumTopics &result) {
if (const auto result = forum->topicFor(_rootId)) {
return result;
} else {
forum->requestTopic(_rootId, crl::guard(this, [=] {
if (const auto forum = _history->peer->forum()) {
forum->applyReceivedTopics(result);
setTopic(forum->topicFor(_rootId));
}
_resolveTopicRequestId = 0;
}).fail([=] {
_resolveTopicRequestId = 0;
}).send();
}));
}
return result;
}
return nullptr;
}

View File

@ -311,8 +311,6 @@ private:
bool _readRequestPending = false;
mtpRequestId _readRequestId = 0;
mtpRequestId _resolveTopicRequestId = 0;
mtpRequestId _reloadUnreadCountRequestId = 0;
bool _loaded = false;

View File

@ -77,7 +77,7 @@ object_ptr<Ui::RpWidget> InnerWidget::setupContent(
}, _cover->lifetime());
_cover->setOnlineCount(rpl::single(0));
if (_topic) {
// #TODO forum
// #TODO forum shared media
//result->add(setupSharedMedia(result.data()));
return result;
}

View File

@ -1961,7 +1961,7 @@ void MainWidget::windowShown() {
void MainWidget::dialogsToUp() {
if (_dialogs) {
_dialogs->jumpToTop(true);
_dialogs->jumpToTop();
}
}

View File

@ -352,7 +352,7 @@ void Filler::addHidePromotion() {
void Filler::addTogglePin() {
if (!_peer) {
// #TODO forum pin
// #TODO forum pinned
return;
}
const auto controller = _controller;