mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-07-27 07:52:57 +02:00
Support forwarding to monoforums.
This commit is contained in:
parent
e17bf18350
commit
76db55ff19
36 changed files with 516 additions and 78 deletions
|
@ -388,7 +388,7 @@ void ApiWrap::savePinnedOrder(not_null<Data::SavedMessages*> saved) {
|
|||
const auto &order = _session->data().pinnedChatsOrder(saved);
|
||||
const auto input = [](Dialogs::Key key) {
|
||||
if (const auto sublist = key.sublist()) {
|
||||
return MTP_inputDialogPeer(sublist->peer()->input);
|
||||
return MTP_inputDialogPeer(sublist->sublistPeer()->input);
|
||||
}
|
||||
Unexpected("Key type in pinnedDialogsOrder().");
|
||||
};
|
||||
|
@ -3303,6 +3303,13 @@ void ApiWrap::forwardMessages(
|
|||
if (topMsgId) {
|
||||
sendFlags |= SendFlag::f_top_msg_id;
|
||||
}
|
||||
const auto monoforumPeerId = action.replyTo.monoforumPeerId;
|
||||
const auto monoforumPeer = monoforumPeerId
|
||||
? session().data().peer(monoforumPeerId).get()
|
||||
: nullptr;
|
||||
if (monoforumPeer) {
|
||||
sendFlags |= SendFlag::f_reply_to;
|
||||
}
|
||||
|
||||
auto forwardFrom = draft.items.front()->history()->peer;
|
||||
auto ids = QVector<MTPint>();
|
||||
|
@ -3332,7 +3339,9 @@ void ApiWrap::forwardMessages(
|
|||
MTP_vector<MTPlong>(randomIds),
|
||||
peer->input,
|
||||
MTP_int(topMsgId),
|
||||
MTPInputReplyTo(),
|
||||
(monoforumPeer
|
||||
? MTP_inputReplyToMonoForum(monoforumPeer->input)
|
||||
: MTPInputReplyTo()),
|
||||
MTP_int(action.options.scheduled),
|
||||
(sendAs ? sendAs->input : MTP_inputPeerEmpty()),
|
||||
Data::ShortcutIdToMTP(_session, action.options.shortcutId),
|
||||
|
@ -3379,7 +3388,10 @@ void ApiWrap::forwardMessages(
|
|||
.id = newId.msg,
|
||||
.flags = flags,
|
||||
.from = NewMessageFromId(action),
|
||||
.replyTo = { .topicRootId = topMsgId },
|
||||
.replyTo = {
|
||||
.topicRootId = topMsgId,
|
||||
.monoforumPeerId = monoforumPeerId,
|
||||
},
|
||||
.date = NewMessageDate(action.options),
|
||||
.shortcutId = action.options.shortcutId,
|
||||
.starsPaid = action.options.starsApproved,
|
||||
|
|
|
@ -23,6 +23,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/ui_utility.h"
|
||||
#include "main/main_session.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_saved_messages.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_stories.h"
|
||||
#include "data/data_channel.h"
|
||||
|
@ -867,6 +869,45 @@ void ChooseRecipientBoxController::rowClicked(not_null<PeerListRow*> row) {
|
|||
*weak = owned.data();
|
||||
delegate()->peerListUiShow()->showBox(std::move(owned));
|
||||
return;
|
||||
} else if (const auto monoforum = peer->monoforum()) {
|
||||
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||
auto callback = [=](not_null<Data::SavedSublist*> sublist) {
|
||||
const auto exists = guard.get();
|
||||
if (!exists) {
|
||||
if (*weak) {
|
||||
(*weak)->closeBox();
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto onstack = std::move(_callback);
|
||||
onstack(sublist);
|
||||
if (guard) {
|
||||
_callback = std::move(onstack);
|
||||
} else if (*weak) {
|
||||
(*weak)->closeBox();
|
||||
}
|
||||
};
|
||||
const auto filter = [=](not_null<Data::SavedSublist*> sublist) {
|
||||
return guard && (!_filter || _filter(sublist));
|
||||
};
|
||||
auto owned = Box<PeerListBox>(
|
||||
std::make_unique<ChooseSublistBoxController>(
|
||||
monoforum,
|
||||
std::move(callback),
|
||||
filter),
|
||||
[=](not_null<PeerListBox*> box) {
|
||||
box->addButton(tr::lng_cancel(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
|
||||
monoforum->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
box->closeBox();
|
||||
}, box->lifetime());
|
||||
});
|
||||
*weak = owned.data();
|
||||
delegate()->peerListUiShow()->showBox(std::move(owned));
|
||||
return;
|
||||
}
|
||||
const auto history = peer->owner().history(peer);
|
||||
auto callback = std::move(_callback);
|
||||
|
@ -1137,6 +1178,111 @@ auto ChooseTopicBoxController::createRow(not_null<Data::ForumTopic*> topic)
|
|||
return skip ? nullptr : std::make_unique<Row>(topic);
|
||||
};
|
||||
|
||||
ChooseSublistBoxController::ChooseSublistBoxController(
|
||||
not_null<Data::SavedMessages*> monoforum,
|
||||
FnMut<void(not_null<Data::SavedSublist*>)> callback,
|
||||
Fn<bool(not_null<Data::SavedSublist*>)> filter)
|
||||
: _monoforum(monoforum)
|
||||
, _callback(std::move(callback))
|
||||
, _filter(std::move(filter)) {
|
||||
setStyleOverrides(&st::chooseTopicList);
|
||||
|
||||
_monoforum->chatsListChanges(
|
||||
) | rpl::start_with_next([=] {
|
||||
refreshRows();
|
||||
}, lifetime());
|
||||
|
||||
_monoforum->sublistDestroyed(
|
||||
) | rpl::start_with_next([=](not_null<Data::SavedSublist*> sublist) {
|
||||
const auto id = sublist->sublistPeer()->id.value;
|
||||
if (const auto row = delegate()->peerListFindRow(id)) {
|
||||
delegate()->peerListRemoveRow(row);
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
Main::Session &ChooseSublistBoxController::session() const {
|
||||
return _monoforum->session();
|
||||
}
|
||||
|
||||
void ChooseSublistBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||
const auto weak = base::make_weak(this);
|
||||
auto onstack = base::take(_callback);
|
||||
onstack(_monoforum->sublist(row->peer()));
|
||||
if (weak) {
|
||||
_callback = std::move(onstack);
|
||||
}
|
||||
}
|
||||
|
||||
void ChooseSublistBoxController::prepare() {
|
||||
delegate()->peerListSetTitle(tr::lng_forward_choose());
|
||||
setSearchNoResultsText(tr::lng_topics_not_found(tr::now));
|
||||
delegate()->peerListSetSearchMode(PeerListSearchMode::Enabled);
|
||||
refreshRows(true);
|
||||
|
||||
session().changes().entryUpdates(
|
||||
Data::EntryUpdate::Flag::Repaint
|
||||
) | rpl::start_with_next([=](const Data::EntryUpdate &update) {
|
||||
if (const auto sublist = update.entry->asSublist()) {
|
||||
if (sublist->parent() == _monoforum) {
|
||||
const auto id = sublist->sublistPeer()->id.value;
|
||||
if (const auto row = delegate()->peerListFindRow(id)) {
|
||||
delegate()->peerListUpdateRow(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void ChooseSublistBoxController::refreshRows(bool initial) {
|
||||
auto added = false;
|
||||
for (const auto &row : _monoforum->chatsList()->indexed()->all()) {
|
||||
if (const auto sublist = row->sublist()) {
|
||||
const auto id = sublist->sublistPeer()->id.value;
|
||||
auto already = delegate()->peerListFindRow(id);
|
||||
if (initial || !already) {
|
||||
if (auto created = createRow(sublist)) {
|
||||
delegate()->peerListAppendRow(std::move(created));
|
||||
added = true;
|
||||
}
|
||||
} else if (already->isSearchResult()) {
|
||||
delegate()->peerListAppendFoundRow(already);
|
||||
added = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (added) {
|
||||
delegate()->peerListRefreshRows();
|
||||
}
|
||||
}
|
||||
|
||||
void ChooseSublistBoxController::loadMoreRows() {
|
||||
_monoforum->loadMore();
|
||||
}
|
||||
|
||||
std::unique_ptr<PeerListRow> ChooseSublistBoxController::createSearchRow(
|
||||
PeerListRowId id) {
|
||||
const auto peer = session().data().peer(PeerId(id));
|
||||
if (const auto sublist = _monoforum->sublistLoaded(peer)) {
|
||||
auto result = std::make_unique<PeerListRow>(sublist->sublistPeer());
|
||||
result->setCustomStatus(QString());
|
||||
return result;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto ChooseSublistBoxController::createRow(
|
||||
not_null<Data::SavedSublist*> sublist)
|
||||
-> std::unique_ptr<PeerListRow> {
|
||||
if (const auto skip = _filter && !_filter(sublist)) {
|
||||
return nullptr;
|
||||
}
|
||||
auto result = std::make_unique<PeerListRow>(sublist->sublistPeer());
|
||||
result->setCustomStatus(QString());
|
||||
return result;
|
||||
};
|
||||
|
||||
void PaintRestrictionBadge(
|
||||
Painter &p,
|
||||
not_null<const style::PeerListItem*> st,
|
||||
|
|
|
@ -27,6 +27,8 @@ namespace Data {
|
|||
class Thread;
|
||||
class Forum;
|
||||
class ForumTopic;
|
||||
class SavedSublist;
|
||||
class SavedMessages;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
|
@ -393,3 +395,30 @@ private:
|
|||
Fn<bool(not_null<Data::ForumTopic*>)> _filter;
|
||||
|
||||
};
|
||||
|
||||
class ChooseSublistBoxController final
|
||||
: public PeerListController
|
||||
, public base::has_weak_ptr {
|
||||
public:
|
||||
ChooseSublistBoxController(
|
||||
not_null<Data::SavedMessages*> monoforum,
|
||||
FnMut<void(not_null<Data::SavedSublist*>)> callback,
|
||||
Fn<bool(not_null<Data::SavedSublist*>)> filter = nullptr);
|
||||
|
||||
Main::Session &session() const override;
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
|
||||
void prepare() override;
|
||||
void loadMoreRows() override;
|
||||
std::unique_ptr<PeerListRow> createSearchRow(PeerListRowId id) override;
|
||||
|
||||
private:
|
||||
void refreshRows(bool initial = false);
|
||||
[[nodiscard]] std::unique_ptr<PeerListRow> createRow(
|
||||
not_null<Data::SavedSublist*> sublist);
|
||||
|
||||
const not_null<Data::SavedMessages*> _monoforum;
|
||||
FnMut<void(not_null<Data::SavedSublist*>)> _callback;
|
||||
Fn<bool(not_null<Data::SavedSublist*>)> _filter;
|
||||
|
||||
};
|
||||
|
|
|
@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/stickers/data_custom_emoji.h"
|
||||
|
@ -1163,8 +1164,11 @@ void SingleRowController::prepare() {
|
|||
return;
|
||||
}
|
||||
const auto topic = strong->asTopic();
|
||||
const auto sublist = strong->asSublist();
|
||||
auto row = topic
|
||||
? ChooseTopicBoxController::MakeRow(topic)
|
||||
: sublist
|
||||
? std::make_unique<PeerListRow>(sublist->sublistPeer())
|
||||
: std::make_unique<PeerListRow>(strong->peer());
|
||||
const auto raw = row.get();
|
||||
if (_status) {
|
||||
|
|
|
@ -45,6 +45,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_histories.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_saved_messages.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_folder.h"
|
||||
#include "data/data_forum.h"
|
||||
|
@ -114,7 +116,9 @@ private:
|
|||
not_null<History*> history;
|
||||
not_null<PeerData*> peer;
|
||||
Data::ForumTopic *topic = nullptr;
|
||||
Data::SavedSublist *sublist = nullptr;
|
||||
rpl::lifetime topicLifetime;
|
||||
rpl::lifetime sublistLifetime;
|
||||
Ui::RoundImageCheckbox checkbox;
|
||||
Ui::Text::String name;
|
||||
Ui::Animations::Simple nameActive;
|
||||
|
@ -143,6 +147,7 @@ private:
|
|||
void preloadUserpic(not_null<Dialogs::Entry*> entry);
|
||||
void changeCheckState(Chat *chat);
|
||||
void chooseForumTopic(not_null<Data::Forum*> forum);
|
||||
void chooseMonoforumSublist(not_null<Data::SavedMessages*> monoforum);
|
||||
enum class ChangeStateWay {
|
||||
Default,
|
||||
SkipCallback,
|
||||
|
@ -638,15 +643,18 @@ void ShareBox::addPeerToMultiSelect(not_null<Data::Thread*> thread) {
|
|||
auto addItemWay = Ui::MultiSelect::AddItemWay::Default;
|
||||
const auto peer = thread->peer();
|
||||
const auto topic = thread->asTopic();
|
||||
const auto sublist = thread->asSublist();
|
||||
_select->addItem(
|
||||
peer->id.value,
|
||||
(topic
|
||||
? topic->title()
|
||||
: sublist
|
||||
? sublist->sublistPeer()->shortName()
|
||||
: peer->isSelf()
|
||||
? tr::lng_saved_short(tr::now)
|
||||
: peer->shortName()),
|
||||
st::activeButtonBg,
|
||||
(topic
|
||||
((topic || sublist)
|
||||
? ForceRoundUserpicCallback(peer)
|
||||
: PaintUserpicCallback(peer, true)),
|
||||
addItemWay);
|
||||
|
@ -970,6 +978,8 @@ void ShareBox::Inner::updateChatName(not_null<Chat*> chat) {
|
|||
const auto peer = chat->peer;
|
||||
const auto text = chat->topic
|
||||
? chat->topic->title()
|
||||
: chat->sublist
|
||||
? chat->sublist->sublistPeer()->name()
|
||||
: peer->isSelf()
|
||||
? tr::lng_saved_messages(tr::now)
|
||||
: peer->isRepliesChat()
|
||||
|
@ -1209,7 +1219,7 @@ ShareBox::Inner::Chat::Chat(
|
|||
st.checkbox,
|
||||
updateCallback,
|
||||
PaintUserpicCallback(peer, true),
|
||||
[=](int size) { return peer->isForum()
|
||||
[=](int size) { return (peer->isForum() || peer->isMonoforum())
|
||||
? int(size * Ui::ForumUserpicRadiusMultiplier())
|
||||
: std::optional<int>(); })
|
||||
, name(st.checkbox.imageRadius * 2) {
|
||||
|
@ -1350,10 +1360,13 @@ void ShareBox::Inner::changeCheckState(Chat *chat) {
|
|||
|
||||
const auto checked = chat->checkbox.checked();
|
||||
const auto forum = chat->peer->forum();
|
||||
if (checked || !forum) {
|
||||
const auto monoforum = chat->peer->monoforum();
|
||||
if (checked || (!forum && !monoforum)) {
|
||||
changePeerCheckState(chat, !checked);
|
||||
} else {
|
||||
chooseForumTopic(chat->peer->forum());
|
||||
} else if (forum) {
|
||||
chooseForumTopic(forum);
|
||||
} else if (monoforum) {
|
||||
chooseMonoforumSublist(monoforum);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1404,6 +1417,54 @@ void ShareBox::Inner::chooseForumTopic(not_null<Data::Forum*> forum) {
|
|||
_show->showBox(std::move(box));
|
||||
}
|
||||
|
||||
void ShareBox::Inner::chooseMonoforumSublist(
|
||||
not_null<Data::SavedMessages*> monoforum) {
|
||||
const auto guard = Ui::MakeWeak(this);
|
||||
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||
auto chosen = [=](not_null<Data::SavedSublist*> sublist) {
|
||||
if (const auto strong = *weak) {
|
||||
strong->closeBox();
|
||||
}
|
||||
if (!guard) {
|
||||
return;
|
||||
}
|
||||
const auto row = _chatsIndexed->getRow(sublist->owningHistory());
|
||||
if (!row) {
|
||||
return;
|
||||
}
|
||||
const auto chat = getChat(row);
|
||||
Assert(!chat->sublist);
|
||||
chat->sublist = sublist;
|
||||
chat->sublist->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
changePeerCheckState(chat, false);
|
||||
}, chat->sublistLifetime);
|
||||
updateChatName(chat);
|
||||
changePeerCheckState(chat, true);
|
||||
};
|
||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||
box->addButton(tr::lng_cancel(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
|
||||
monoforum->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
box->closeBox();
|
||||
}, box->lifetime());
|
||||
};
|
||||
auto filter = [=](not_null<Data::SavedSublist*> sublist) {
|
||||
return guard && _descriptor.filterCallback(sublist);
|
||||
};
|
||||
auto box = Box<PeerListBox>(
|
||||
std::make_unique<ChooseSublistBoxController>(
|
||||
monoforum,
|
||||
std::move(chosen),
|
||||
std::move(filter)),
|
||||
std::move(initBox));
|
||||
*weak = box.data();
|
||||
_show->showBox(std::move(box));
|
||||
}
|
||||
|
||||
void ShareBox::Inner::peerUnselected(not_null<PeerData*> peer) {
|
||||
if (const auto i = _dataMap.find(peer); i != end(_dataMap)) {
|
||||
changePeerCheckState(
|
||||
|
@ -1434,6 +1495,11 @@ void ShareBox::Inner::changePeerCheckState(
|
|||
chat->topic = nullptr;
|
||||
updateChatName(chat);
|
||||
}
|
||||
if (chat->sublist) {
|
||||
chat->sublistLifetime.destroy();
|
||||
chat->sublist = nullptr;
|
||||
updateChatName(chat);
|
||||
}
|
||||
}
|
||||
if (useCallback != ChangeStateWay::SkipCallback
|
||||
&& _peerSelectedChangedCallback) {
|
||||
|
@ -1565,6 +1631,8 @@ not_null<Data::Thread*> ShareBox::Inner::chatThread(
|
|||
not_null<Chat*> chat) const {
|
||||
return chat->topic
|
||||
? (Data::Thread*)chat->topic
|
||||
: chat->sublist
|
||||
? (Data::Thread*)chat->sublist
|
||||
: chat->peer->owner().history(chat->peer).get();
|
||||
}
|
||||
|
||||
|
@ -1675,6 +1743,7 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
|
|||
api.sendMessage(std::move(message));
|
||||
}
|
||||
const auto topicRootId = thread->topicRootId();
|
||||
const auto sublistPeer = thread->maybeSublistPeer();
|
||||
const auto kGeneralId = Data::ForumTopic::kGeneralId;
|
||||
const auto topMsgId = (topicRootId == kGeneralId)
|
||||
? MsgId(0)
|
||||
|
@ -1699,7 +1768,8 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
|
|||
| (options.shortcutId
|
||||
? Flag::f_quick_reply_shortcut
|
||||
: Flag(0))
|
||||
| (starsPaid ? Flag::f_allow_paid_stars : Flag());
|
||||
| (starsPaid ? Flag::f_allow_paid_stars : Flag())
|
||||
| (sublistPeer ? Flag::f_reply_to : Flag());
|
||||
threadHistory->sendRequestId = api.request(
|
||||
MTPmessages_ForwardMessages(
|
||||
MTP_flags(sendFlags),
|
||||
|
@ -1708,7 +1778,9 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
|
|||
MTP_vector<MTPlong>(generateRandom()),
|
||||
peer->input,
|
||||
MTP_int(topMsgId),
|
||||
MTPInputReplyTo(),
|
||||
(sublistPeer
|
||||
? MTP_inputReplyToMonoForum(sublistPeer->input)
|
||||
: MTPInputReplyTo()),
|
||||
MTP_int(options.scheduled),
|
||||
MTP_inputPeerEmpty(), // send_as
|
||||
Data::ShortcutIdToMTP(session, options.shortcutId),
|
||||
|
|
|
@ -228,6 +228,7 @@ void ChannelData::setFlags(ChannelDataFlags which) {
|
|||
}
|
||||
}
|
||||
if (diff & (Flag::Forum
|
||||
| Flag::Monoforum
|
||||
| Flag::CallNotEmpty
|
||||
| Flag::SimilarExpanded
|
||||
| Flag::Signatures
|
||||
|
@ -236,12 +237,14 @@ void ChannelData::setFlags(ChannelDataFlags which) {
|
|||
if (diff & Flag::CallNotEmpty) {
|
||||
history->updateChatListEntry();
|
||||
}
|
||||
if (diff & Flag::Forum) {
|
||||
if (diff & (Flag::Forum | Flag::Monoforum)) {
|
||||
Core::App().notifications().clearFromHistory(history);
|
||||
history->updateChatListEntryHeight();
|
||||
if (history->inChatList()) {
|
||||
if (const auto forum = this->forum()) {
|
||||
forum->preloadTopics();
|
||||
} else if (const auto monoforum = this->monoforum()) {
|
||||
monoforum->loadMore();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -48,7 +48,6 @@ Forum::Forum(not_null<History*> history)
|
|||
, _topicsList(&session(), {}, owner().maxPinnedChatsLimitValue(this)) {
|
||||
Expects(_history->peer->isChannel());
|
||||
|
||||
|
||||
if (_history->inChatList()) {
|
||||
preloadTopics();
|
||||
}
|
||||
|
|
|
@ -867,7 +867,7 @@ void ForumTopic::setMuted(bool muted) {
|
|||
session().changes().topicUpdated(this, UpdateFlag::Notifications);
|
||||
}
|
||||
|
||||
not_null<HistoryView::SendActionPainter*> ForumTopic::sendActionPainter() {
|
||||
HistoryView::SendActionPainter *ForumTopic::sendActionPainter() {
|
||||
return _sendActionPainter.get();
|
||||
}
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ public:
|
|||
void setMuted(bool muted) override;
|
||||
|
||||
[[nodiscard]] auto sendActionPainter()
|
||||
->not_null<HistoryView::SendActionPainter*> override;
|
||||
-> HistoryView::SendActionPainter* override;
|
||||
|
||||
private:
|
||||
enum class Flag : uchar {
|
||||
|
|
|
@ -1028,7 +1028,7 @@ void Reactions::requestMyTags(SavedSublist *sublist) {
|
|||
using Flag = MTPmessages_GetSavedReactionTags::Flag;
|
||||
my.requestId = api.request(MTPmessages_GetSavedReactionTags(
|
||||
MTP_flags(sublist ? Flag::f_peer : Flag()),
|
||||
(sublist ? sublist->peer()->input : MTP_inputPeerEmpty()),
|
||||
(sublist ? sublist->sublistPeer()->input : MTP_inputPeerEmpty()),
|
||||
MTP_long(my.hash)
|
||||
)).done([=](const MTPmessages_SavedReactionTags &result) {
|
||||
auto &my = _myTags[sublist];
|
||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_unread_things.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Data {
|
||||
|
@ -23,6 +24,7 @@ constexpr auto kPerPage = 50;
|
|||
constexpr auto kFirstPerPage = 10;
|
||||
constexpr auto kListPerPage = 100;
|
||||
constexpr auto kListFirstPerPage = 20;
|
||||
constexpr auto kLoadedSublistsMinCount = 20;
|
||||
|
||||
} // namespace
|
||||
|
||||
|
@ -36,6 +38,10 @@ SavedMessages::SavedMessages(
|
|||
FilterId(),
|
||||
_owner->maxPinnedChatsLimitValue(this))
|
||||
, _loadMore([=] { sendLoadMoreRequests(); }) {
|
||||
if (_parentChat
|
||||
&& _parentChat->owner().history(_parentChat)->inChatList()) {
|
||||
preloadSublists();
|
||||
}
|
||||
}
|
||||
|
||||
SavedMessages::~SavedMessages() = default;
|
||||
|
@ -61,15 +67,19 @@ not_null<Dialogs::MainList*> SavedMessages::chatsList() {
|
|||
}
|
||||
|
||||
not_null<SavedSublist*> SavedMessages::sublist(not_null<PeerData*> peer) {
|
||||
const auto i = _sublists.find(peer);
|
||||
if (i != end(_sublists)) {
|
||||
return i->second.get();
|
||||
if (const auto loaded = sublistLoaded(peer)) {
|
||||
return loaded;
|
||||
}
|
||||
return _sublists.emplace(
|
||||
peer,
|
||||
std::make_unique<SavedSublist>(this, peer)).first->second.get();
|
||||
}
|
||||
|
||||
SavedSublist *SavedMessages::sublistLoaded(not_null<PeerData*> peer) {
|
||||
const auto i = _sublists.find(peer);
|
||||
return (i != end(_sublists)) ? i->second.get() : nullptr;
|
||||
}
|
||||
|
||||
rpl::producer<> SavedMessages::chatsListChanges() const {
|
||||
return _chatsListChanges.events();
|
||||
}
|
||||
|
@ -78,6 +88,13 @@ rpl::producer<> SavedMessages::chatsListLoadedEvents() const {
|
|||
return _chatsListLoadedEvents.events();
|
||||
}
|
||||
|
||||
void SavedMessages::preloadSublists() {
|
||||
if (parentChat()
|
||||
&& chatsList()->indexed()->size() < kLoadedSublistsMinCount) {
|
||||
loadMore();
|
||||
}
|
||||
}
|
||||
|
||||
void SavedMessages::loadMore() {
|
||||
_loadMoreScheduled = true;
|
||||
_loadMore.call();
|
||||
|
@ -152,7 +169,7 @@ void SavedMessages::sendLoadMore(not_null<SavedSublist*> sublist) {
|
|||
MTPmessages_GetSavedHistory(
|
||||
MTP_flags(_parentChat ? Flag::f_parent_peer : Flag(0)),
|
||||
_parentChat ? _parentChat->input : MTPInputPeer(),
|
||||
sublist->peer()->input,
|
||||
sublist->sublistPeer()->input,
|
||||
MTP_int(offsetId),
|
||||
MTP_int(offsetDate),
|
||||
MTP_int(0), // add_offset
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
|
||||
[[nodiscard]] not_null<Dialogs::MainList*> chatsList();
|
||||
[[nodiscard]] not_null<SavedSublist*> sublist(not_null<PeerData*> peer);
|
||||
[[nodiscard]] SavedSublist *sublistLoaded(not_null<PeerData*> peer);
|
||||
|
||||
[[nodiscard]] rpl::producer<> chatsListChanges() const;
|
||||
[[nodiscard]] rpl::producer<> chatsListLoadedEvents() const;
|
||||
|
@ -41,6 +42,7 @@ public:
|
|||
[[nodiscard]] auto sublistDestroyed() const
|
||||
-> rpl::producer<not_null<SavedSublist*>>;
|
||||
|
||||
void preloadSublists();
|
||||
void loadMore();
|
||||
void loadMore(not_null<SavedSublist*> sublist);
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_item_preview.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_unread_things.h"
|
||||
#include "main/main_session.h"
|
||||
|
||||
namespace Data {
|
||||
|
@ -22,7 +23,7 @@ namespace Data {
|
|||
SavedSublist::SavedSublist(
|
||||
not_null<SavedMessages*> parent,
|
||||
not_null<PeerData*> peer)
|
||||
: Entry(&peer->owner(), Dialogs::Entry::Type::SavedSublist)
|
||||
: Thread(&peer->owner(), Dialogs::Entry::Type::SavedSublist)
|
||||
, _parent(parent)
|
||||
, _history(peer->owner().history(peer)) {
|
||||
}
|
||||
|
@ -33,7 +34,7 @@ not_null<SavedMessages*> SavedSublist::parent() const {
|
|||
return _parent;
|
||||
}
|
||||
|
||||
not_null<History*> SavedSublist::parentHistory() const {
|
||||
not_null<History*> SavedSublist::owningHistory() {
|
||||
const auto chat = parentChat();
|
||||
return _history->owner().history(chat
|
||||
? (PeerData*)chat
|
||||
|
@ -44,18 +45,27 @@ ChannelData *SavedSublist::parentChat() const {
|
|||
return _parent->parentChat();
|
||||
}
|
||||
|
||||
not_null<PeerData*> SavedSublist::peer() const {
|
||||
not_null<PeerData*> SavedSublist::sublistPeer() const {
|
||||
return _history->peer;
|
||||
}
|
||||
|
||||
bool SavedSublist::isHiddenAuthor() const {
|
||||
return peer()->isSavedHiddenAuthor();
|
||||
return sublistPeer()->isSavedHiddenAuthor();
|
||||
}
|
||||
|
||||
bool SavedSublist::isFullLoaded() const {
|
||||
return (_flags & Flag::FullLoaded) != 0;
|
||||
}
|
||||
|
||||
rpl::producer<> SavedSublist::destroyed() const {
|
||||
using namespace rpl::mappers;
|
||||
return rpl::merge(
|
||||
_parent->destroyed(),
|
||||
_parent->sublistDestroyed() | rpl::filter(
|
||||
_1 == this
|
||||
) | rpl::to_empty);
|
||||
}
|
||||
|
||||
auto SavedSublist::messages() const
|
||||
-> const std::vector<not_null<HistoryItem*>> & {
|
||||
return _items;
|
||||
|
@ -231,8 +241,39 @@ void SavedSublist::paintUserpic(
|
|||
_history->paintUserpic(p, view, context);
|
||||
}
|
||||
|
||||
HistoryView::SendActionPainter *SavedSublist::sendActionPainter() {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void SavedSublist::hasUnreadMentionChanged(bool has) {
|
||||
auto was = chatListUnreadState();
|
||||
if (has) {
|
||||
was.mentions = 0;
|
||||
} else {
|
||||
was.mentions = 1;
|
||||
}
|
||||
notifyUnreadStateChange(was);
|
||||
}
|
||||
|
||||
void SavedSublist::hasUnreadReactionChanged(bool has) {
|
||||
auto was = chatListUnreadState();
|
||||
if (has) {
|
||||
was.reactions = was.reactionsMuted = 0;
|
||||
} else {
|
||||
was.reactions = 1;
|
||||
was.reactionsMuted = muted() ? was.reactions : 0;
|
||||
}
|
||||
notifyUnreadStateChange(was);
|
||||
}
|
||||
|
||||
bool SavedSublist::isServerSideUnread(
|
||||
not_null<const HistoryItem*> item) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void SavedSublist::chatListPreloadData() {
|
||||
peer()->loadUserpic();
|
||||
sublistPeer()->loadUserpic();
|
||||
allowChatListMessageResolve();
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "data/data_thread.h"
|
||||
#include "dialogs/ui/dialogs_message_view.h"
|
||||
#include "dialogs/dialogs_entry.h"
|
||||
|
||||
class PeerData;
|
||||
class History;
|
||||
|
@ -18,17 +18,18 @@ namespace Data {
|
|||
class Session;
|
||||
class SavedMessages;
|
||||
|
||||
class SavedSublist final : public Dialogs::Entry {
|
||||
class SavedSublist final : public Data::Thread {
|
||||
public:
|
||||
SavedSublist(not_null<SavedMessages*> parent, not_null<PeerData*> peer);
|
||||
~SavedSublist();
|
||||
|
||||
[[nodiscard]] not_null<SavedMessages*> parent() const;
|
||||
[[nodiscard]] not_null<History*> parentHistory() const;
|
||||
[[nodiscard]] not_null<History*> owningHistory() override;
|
||||
[[nodiscard]] ChannelData *parentChat() const;
|
||||
[[nodiscard]] not_null<PeerData*> peer() const;
|
||||
[[nodiscard]] not_null<PeerData*> sublistPeer() const;
|
||||
[[nodiscard]] bool isHiddenAuthor() const;
|
||||
[[nodiscard]] bool isFullLoaded() const;
|
||||
[[nodiscard]] rpl::producer<> destroyed() const;
|
||||
|
||||
[[nodiscard]] auto messages() const
|
||||
-> const std::vector<not_null<HistoryItem*>> &;
|
||||
|
@ -41,10 +42,6 @@ public:
|
|||
[[nodiscard]] std::optional<int> fullCount() const;
|
||||
[[nodiscard]] rpl::producer<int> fullCountValue() const;
|
||||
|
||||
[[nodiscard]] Dialogs::Ui::MessageView &lastItemDialogsView() {
|
||||
return _lastItemDialogsView;
|
||||
}
|
||||
|
||||
int fixedOnTopIndex() const override;
|
||||
bool shouldBeInChatList() const override;
|
||||
Dialogs::UnreadState chatListUnreadState() const override;
|
||||
|
@ -57,12 +54,21 @@ public:
|
|||
const base::flat_set<QString> &chatListNameWords() const override;
|
||||
const base::flat_set<QChar> &chatListFirstLetters() const override;
|
||||
|
||||
void hasUnreadMentionChanged(bool has) override;
|
||||
void hasUnreadReactionChanged(bool has) override;
|
||||
|
||||
[[nodiscard]] bool isServerSideUnread(
|
||||
not_null<const HistoryItem*> item) const override;
|
||||
|
||||
void chatListPreloadData() override;
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Dialogs::Ui::PaintContext &context) const override;
|
||||
|
||||
[[nodiscard]] auto sendActionPainter()
|
||||
-> HistoryView::SendActionPainter* override;
|
||||
|
||||
private:
|
||||
enum class Flag : uchar {
|
||||
ResolveChatListMessage = (1 << 0),
|
||||
|
@ -81,7 +87,6 @@ private:
|
|||
std::vector<not_null<HistoryItem*>> _items;
|
||||
std::optional<int> _fullCount;
|
||||
rpl::event_stream<> _changed;
|
||||
Dialogs::Ui::MessageView _lastItemDialogsView;
|
||||
Flags _flags;
|
||||
|
||||
};
|
||||
|
|
|
@ -4656,6 +4656,8 @@ void Session::refreshChatListEntry(Dialogs::Key key) {
|
|||
}
|
||||
if (const auto forum = history->peer->forum()) {
|
||||
forum->preloadTopics();
|
||||
} else if (const auto monoforum = history->peer->monoforum()) {
|
||||
monoforum->preloadSublists();
|
||||
}
|
||||
if (history->peer->isMonoforum()
|
||||
&& !history->peer->monoforumBroadcast()) {
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_unread_things.h"
|
||||
|
@ -31,6 +32,13 @@ MsgId Thread::topicRootId() const {
|
|||
return MsgId();
|
||||
}
|
||||
|
||||
PeerData *Thread::maybeSublistPeer() const {
|
||||
if (const auto sublist = asSublist()) {
|
||||
return sublist->sublistPeer();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
not_null<PeerData*> Thread::peer() const {
|
||||
return owningHistory()->peer;
|
||||
}
|
||||
|
|
|
@ -67,6 +67,7 @@ public:
|
|||
return const_cast<Thread*>(this)->owningHistory();
|
||||
}
|
||||
[[nodiscard]] MsgId topicRootId() const;
|
||||
[[nodiscard]] PeerData *maybeSublistPeer() const;
|
||||
[[nodiscard]] not_null<PeerData*> peer() const;
|
||||
[[nodiscard]] PeerNotifySettings ¬ify();
|
||||
[[nodiscard]] const PeerNotifySettings ¬ify() const;
|
||||
|
@ -112,7 +113,7 @@ public:
|
|||
}
|
||||
|
||||
[[nodiscard]] virtual auto sendActionPainter()
|
||||
-> not_null<HistoryView::SendActionPainter*> = 0;
|
||||
-> HistoryView::SendActionPainter* = 0;
|
||||
|
||||
[[nodiscard]] bool hasPinnedMessages() const;
|
||||
void setHasPinnedMessages(bool has);
|
||||
|
|
|
@ -84,9 +84,9 @@ Entry::Entry(not_null<Data::Session*> owner, Type type)
|
|||
, _flags((type == Type::History)
|
||||
? (Flag::IsThread | Flag::IsHistory)
|
||||
: (type == Type::ForumTopic)
|
||||
? Flag::IsThread
|
||||
? (Flag::IsThread | Flag::IsForumTopic)
|
||||
: (type == Type::SavedSublist)
|
||||
? Flag::IsSavedSublist
|
||||
? (Flag::IsThread | Flag::IsSavedSublist)
|
||||
: Flag(0)) {
|
||||
}
|
||||
|
||||
|
@ -113,7 +113,7 @@ Data::Forum *Entry::asForum() {
|
|||
}
|
||||
|
||||
Data::Folder *Entry::asFolder() {
|
||||
return (_flags & (Flag::IsThread | Flag::IsSavedSublist))
|
||||
return (_flags & Flag::IsThread)
|
||||
? nullptr
|
||||
: static_cast<Data::Folder*>(this);
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ Data::Thread *Entry::asThread() {
|
|||
}
|
||||
|
||||
Data::ForumTopic *Entry::asTopic() {
|
||||
return ((_flags & Flag::IsThread) && !(_flags & Flag::IsHistory))
|
||||
return (_flags & Flag::IsForumTopic)
|
||||
? static_cast<Data::ForumTopic*>(this)
|
||||
: nullptr;
|
||||
}
|
||||
|
|
|
@ -27,6 +27,7 @@ class Forum;
|
|||
class Folder;
|
||||
class ForumTopic;
|
||||
class SavedSublist;
|
||||
class SavedMessages;
|
||||
class Thread;
|
||||
} // namespace Data
|
||||
|
||||
|
@ -168,9 +169,10 @@ private:
|
|||
enum class Flag : uchar {
|
||||
IsThread = (1 << 0),
|
||||
IsHistory = (1 << 1),
|
||||
IsSavedSublist = (1 << 2),
|
||||
UpdatePostponed = (1 << 3),
|
||||
InUnreadChangeBlock = (1 << 4),
|
||||
IsForumTopic = (1 << 2),
|
||||
IsSavedSublist = (1 << 3),
|
||||
UpdatePostponed = (1 << 4),
|
||||
InUnreadChangeBlock = (1 << 5),
|
||||
};
|
||||
friend inline constexpr bool is_flag_type(Flag) { return true; }
|
||||
using Flags = base::flags<Flag>;
|
||||
|
|
|
@ -3444,7 +3444,7 @@ void InnerWidget::applySearchState(SearchState state) {
|
|||
_searchFromShown = ignoreInChat
|
||||
? nullptr
|
||||
: sublist
|
||||
? sublist->peer().get()
|
||||
? sublist->sublistPeer().get()
|
||||
: state.fromPeer;
|
||||
if (state.inChat) {
|
||||
onHashtagFilterUpdate(QStringView());
|
||||
|
@ -4222,7 +4222,7 @@ void InnerWidget::updateSearchIn() {
|
|||
const auto peerIcon = peer
|
||||
? Ui::MakeUserpicThumbnail(peer)
|
||||
: sublist
|
||||
? Ui::MakeUserpicThumbnail(sublist->peer())
|
||||
? Ui::MakeUserpicThumbnail(sublist->sublistPeer())
|
||||
: nullptr;
|
||||
const auto myIcon = Ui::MakeIconThumbnail(st::menuIconChats);
|
||||
const auto publicIcon = (_searchHashOrCashtag != HashOrCashtag::None)
|
||||
|
|
|
@ -1001,7 +1001,7 @@ void Widget::chosenRow(const ChosenRow &row) {
|
|||
using namespace HistoryView;
|
||||
controller()->showSection(
|
||||
std::make_shared<ChatMemento>(ChatViewId{
|
||||
.history = sublist->parentHistory(),
|
||||
.history = sublist->owningHistory(),
|
||||
.sublist = sublist,
|
||||
}),
|
||||
params);
|
||||
|
@ -2037,7 +2037,7 @@ void Widget::refreshTopBars() {
|
|||
? Dialogs::Key(history)
|
||||
: Dialogs::Key(_openedFolder)),
|
||||
.section = Dialogs::EntryState::Section::ChatsList,
|
||||
}, history ? history->sendActionPainter().get() : nullptr);
|
||||
}, history ? history->sendActionPainter() : nullptr);
|
||||
if (_forumSearchRequested) {
|
||||
showSearchInTopBar(anim::type::instant);
|
||||
}
|
||||
|
@ -2680,7 +2680,7 @@ bool Widget::search(bool inCache, SearchRequestDelay delay) {
|
|||
: _searchState.inChat.sublist();
|
||||
const auto fromPeer = sublist ? nullptr : _searchQueryFrom;
|
||||
const auto savedPeer = sublist
|
||||
? sublist->peer().get()
|
||||
? sublist->sublistPeer().get()
|
||||
: nullptr;
|
||||
_historiesRequest = histories.sendRequest(history, type, [=](
|
||||
Fn<void()> finish) {
|
||||
|
@ -2856,7 +2856,7 @@ void Widget::searchMore() {
|
|||
: _searchState.inChat.sublist();
|
||||
const auto fromPeer = sublist ? nullptr : _searchQueryFrom;
|
||||
const auto savedPeer = sublist
|
||||
? sublist->peer().get()
|
||||
? sublist->sublistPeer().get()
|
||||
: nullptr;
|
||||
_historiesRequest = histories.sendRequest(history, type, [=](
|
||||
Fn<void()> finish) {
|
||||
|
@ -4284,8 +4284,12 @@ PeerData *Widget::searchInPeer() const {
|
|||
? nullptr
|
||||
: _openedForum
|
||||
? _openedForum->channel().get()
|
||||
: _openedMonoforum
|
||||
? (_openedMonoforum->parentChat()
|
||||
? _openedMonoforum->parentChat()
|
||||
: (PeerData*)session().user().get())
|
||||
: _searchState.inChat.sublist()
|
||||
? session().user().get()
|
||||
? _searchState.inChat.sublist()->owningHistory()->peer.get()
|
||||
: _searchState.inChat.peer();
|
||||
}
|
||||
|
||||
|
|
|
@ -62,7 +62,7 @@ const auto kPsaBadgePrefix = "cloud_lng_badge_psa_";
|
|||
|
||||
[[nodiscard]] bool ShowSendActionInDialogs(Data::Thread *thread) {
|
||||
const auto history = thread ? thread->owningHistory().get() : nullptr;
|
||||
if (!history) {
|
||||
if (!history || thread->asSublist()) {
|
||||
return false;
|
||||
} else if (const auto user = history->peer->asUser()) {
|
||||
return !user->lastseen().isHidden();
|
||||
|
@ -994,7 +994,7 @@ void RowPainter::Paint(
|
|||
? history->peer->migrateTo()
|
||||
: history->peer.get())
|
||||
: sublist
|
||||
? sublist->peer().get()
|
||||
? sublist->sublistPeer().get()
|
||||
: nullptr;
|
||||
const auto allowUserOnline = true;// !context.narrow || badgesState.empty();
|
||||
const auto flags = (allowUserOnline ? Flag::AllowUserOnline : Flag(0))
|
||||
|
|
|
@ -273,7 +273,7 @@ public:
|
|||
void setHasPendingResizedItems();
|
||||
|
||||
[[nodiscard]] auto sendActionPainter()
|
||||
-> not_null<HistoryView::SendActionPainter*> override {
|
||||
-> HistoryView::SendActionPainter* override {
|
||||
return &_sendActionPainter;
|
||||
}
|
||||
|
||||
|
|
|
@ -537,6 +537,7 @@ HistoryItem::HistoryItem(
|
|||
const auto topicRootId = fields.replyTo.topicRootId;
|
||||
config.reply.messageId = config.reply.topMessageId = topicRootId;
|
||||
config.reply.topicPost = (topicRootId != 0) ? 1 : 0;
|
||||
config.reply.monoforumPeerId = fields.replyTo.monoforumPeerId;
|
||||
if (const auto originalReply = original->Get<HistoryMessageReply>()) {
|
||||
if (originalReply->external()) {
|
||||
config.reply = originalReply->fields().clone(this);
|
||||
|
@ -3579,7 +3580,7 @@ Data::SavedSublist *HistoryItem::savedSublist() const {
|
|||
|
||||
PeerData *HistoryItem::savedSublistPeer() const {
|
||||
if (const auto sublist = savedSublist()) {
|
||||
return sublist->peer();
|
||||
return sublist->sublistPeer();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -503,6 +503,8 @@ TimeId NewMessageDate(const Api::SendOptions &options) {
|
|||
PeerId NewMessageFromId(const Api::SendAction &action) {
|
||||
return action.options.sendAs
|
||||
? action.options.sendAs->id
|
||||
: action.history->peer->amMonoforumAdmin()
|
||||
? action.history->peer->monoforumBroadcast()->id
|
||||
: action.history->peer->amAnonymous()
|
||||
? PeerId()
|
||||
: action.history->session().userPeerId();
|
||||
|
|
|
@ -1693,7 +1693,7 @@ SendMenu::Details ChatWidget::sendMenuDetails() const {
|
|||
|
||||
FullReplyTo ChatWidget::replyTo() const {
|
||||
const auto monoforumPeerId = (_sublist && _sublist->parentChat())
|
||||
? _sublist->peer()->id
|
||||
? _sublist->sublistPeer()->id
|
||||
: PeerId();
|
||||
if (auto custom = _composeControls->replyingToMessage()) {
|
||||
const auto item = custom.messageId
|
||||
|
@ -1786,7 +1786,7 @@ void ChatWidget::checkLastPinnedClickedIdReset(
|
|||
}
|
||||
|
||||
void ChatWidget::setupOpenChatButton() {
|
||||
if (!_sublist || _sublist->peer()->isSavedHiddenAuthor()) {
|
||||
if (!_sublist || _sublist->sublistPeer()->isSavedHiddenAuthor()) {
|
||||
return;
|
||||
} else if (_sublist->parentChat()) {
|
||||
_canSendTexts = true;
|
||||
|
@ -1794,22 +1794,22 @@ void ChatWidget::setupOpenChatButton() {
|
|||
}
|
||||
_openChatButton = std::make_unique<Ui::FlatButton>(
|
||||
this,
|
||||
(_sublist->peer()->isBroadcast()
|
||||
(_sublist->sublistPeer()->isBroadcast()
|
||||
? tr::lng_saved_open_channel(tr::now)
|
||||
: _sublist->peer()->isUser()
|
||||
: _sublist->sublistPeer()->isUser()
|
||||
? tr::lng_saved_open_chat(tr::now)
|
||||
: tr::lng_saved_open_group(tr::now)),
|
||||
st::historyComposeButton);
|
||||
|
||||
_openChatButton->setClickedCallback([=] {
|
||||
controller()->showPeerHistory(
|
||||
_sublist->peer(),
|
||||
_sublist->sublistPeer(),
|
||||
Window::SectionShow::Way::Forward);
|
||||
});
|
||||
}
|
||||
|
||||
void ChatWidget::setupAboutHiddenAuthor() {
|
||||
if (!_sublist || !_sublist->peer()->isSavedHiddenAuthor()) {
|
||||
if (!_sublist || !_sublist->sublistPeer()->isSavedHiddenAuthor()) {
|
||||
return;
|
||||
} else if (_sublist->parentChat()) {
|
||||
_canSendTexts = true;
|
||||
|
@ -3260,7 +3260,7 @@ bool ChatWidget::searchInChatEmbedded(
|
|||
this,
|
||||
controller(),
|
||||
_history,
|
||||
sublist->peer(),
|
||||
sublist->sublistPeer(),
|
||||
query);
|
||||
|
||||
updateControlsGeometry();
|
||||
|
|
|
@ -1477,17 +1477,17 @@ void Element::recountMonoforumSenderBarInBlocks() {
|
|||
|| item->isSponsored()) {
|
||||
return nullptr;
|
||||
}
|
||||
const auto peer = sublist->peer();
|
||||
const auto sublistPeer = sublist->sublistPeer();
|
||||
if (const auto previous = previousDisplayedInBlocks()) {
|
||||
const auto prev = previous->data();
|
||||
if (const auto prevSublist = prev->savedSublist()) {
|
||||
Assert(prevSublist->parentChat() == parentChat);
|
||||
if (prevSublist->peer() == peer) {
|
||||
if (prevSublist->sublistPeer() == sublistPeer) {
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
return peer;
|
||||
return sublistPeer;
|
||||
}();
|
||||
if (barPeer && !Has<MonoforumSenderBar>()) {
|
||||
AddComponents(MonoforumSenderBar::Bit());
|
||||
|
|
|
@ -3712,7 +3712,7 @@ bool Message::hasFromName() const {
|
|||
case Context::AdminLog:
|
||||
return true;
|
||||
case Context::Monoforum:
|
||||
return false;
|
||||
return data()->out();
|
||||
case Context::History:
|
||||
case Context::ChatPreview:
|
||||
case Context::TTLViewer:
|
||||
|
|
|
@ -82,7 +82,7 @@ QString TopBarNameText(
|
|||
const Dialogs::EntryState &state) {
|
||||
if (state.section == Dialogs::EntryState::Section::SavedSublist
|
||||
&& state.key.sublist()
|
||||
&& state.key.sublist()->parentHistory()->peer->isSelf()) {
|
||||
&& state.key.sublist()->owningHistory()->peer->isSelf()) {
|
||||
if (peer->isSelf()) {
|
||||
return tr::lng_my_notes(tr::now);
|
||||
} else if (peer->isSavedHiddenAuthor()) {
|
||||
|
@ -490,7 +490,8 @@ void TopBarWidget::paintTopBar(Painter &p) {
|
|||
const auto history = _activeChat.key.history();
|
||||
const auto namePeer = history
|
||||
? history->peer.get()
|
||||
: sublist ? sublist->peer().get()
|
||||
: sublist
|
||||
? sublist->sublistPeer().get()
|
||||
: nullptr;
|
||||
const auto broadcastForMonoforum = history
|
||||
? history->peer->monoforumBroadcast()
|
||||
|
@ -746,9 +747,9 @@ void TopBarWidget::infoClicked() {
|
|||
return;
|
||||
} else if (const auto topic = key.topic()) {
|
||||
_controller->showSection(std::make_shared<Info::Memento>(topic));
|
||||
} else if ([[maybe_unused]] const auto sublist = key.sublist()) {
|
||||
} else if (const auto sublist = key.sublist()) {
|
||||
_controller->showSection(std::make_shared<Info::Memento>(
|
||||
_controller->session().user(),
|
||||
sublist->owningHistory()->peer,
|
||||
Info::Section(Storage::SharedMediaType::Photo)));
|
||||
} else if (key.peer()->savedSublistsInfo()) {
|
||||
_controller->showSection(std::make_shared<Info::Memento>(
|
||||
|
|
|
@ -275,7 +275,7 @@ not_null<Ui::SettingsButton*> AddSavedSublistButton(
|
|||
const auto sublist = peer->owner().savedMessages().sublist(peer);
|
||||
navigation->showSection(
|
||||
std::make_shared<ChatMemento>(ChatViewId{
|
||||
.history = sublist->parentHistory(),
|
||||
.history = sublist->owningHistory(),
|
||||
.sublist = sublist,
|
||||
}));
|
||||
});
|
||||
|
|
|
@ -69,7 +69,7 @@ SublistsWidget::SublistsWidget(
|
|||
params.dropSameFromStack = true;
|
||||
controller->showSection(
|
||||
std::make_shared<ChatMemento>(ChatViewId{
|
||||
.history = sublist->parentHistory(),
|
||||
.history = sublist->owningHistory(),
|
||||
.sublist = sublist,
|
||||
}),
|
||||
params);
|
||||
|
|
|
@ -644,6 +644,17 @@ bool MainWidget::filesOrForwardDrop(
|
|||
clearHider(_hider);
|
||||
}
|
||||
return true;
|
||||
} else if (const auto history = thread->asHistory()
|
||||
; history && history->peer->monoforum()) {
|
||||
Window::ShowDropMediaBox(
|
||||
_controller,
|
||||
Core::ShareMimeMediaData(data),
|
||||
history->peer->monoforum());
|
||||
if (_hider) {
|
||||
_hider->startHide();
|
||||
clearHider(_hider);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (data->hasFormat(u"application/x-td-forward"_q)) {
|
||||
auto draft = Data::ForwardDraft{
|
||||
|
@ -780,7 +791,7 @@ void MainWidget::searchMessages(
|
|||
using namespace HistoryView;
|
||||
controller()->showSection(
|
||||
std::make_shared<ChatMemento>(ChatViewId{
|
||||
.history = sublist->parentHistory(),
|
||||
.history = sublist->owningHistory(),
|
||||
.sublist = sublist,
|
||||
}));
|
||||
} else if (!tags.empty()) {
|
||||
|
@ -1548,6 +1559,12 @@ void MainWidget::showMessage(
|
|||
if (params.activation != anim::activation::background) {
|
||||
_controller->window().activate();
|
||||
}
|
||||
} else if (const auto sublist = item->savedSublist()
|
||||
; sublist && sublist->parentChat()) {
|
||||
_controller->showSublist(sublist, item->id, params);
|
||||
if (params.activation != anim::activation::background) {
|
||||
_controller->window().activate();
|
||||
}
|
||||
} else {
|
||||
// showPeerHistory may be redirected to different window,
|
||||
// so we don't call activate() on current controller's window.
|
||||
|
@ -2621,10 +2638,10 @@ auto MainWidget::thirdSectionForCurrentMainSection(
|
|||
return std::make_shared<Info::Memento>(
|
||||
peer,
|
||||
Info::Memento::DefaultSection(peer));
|
||||
} else if (key.sublist()) {
|
||||
} else if (const auto sublist = key.sublist()) {
|
||||
return std::make_shared<Info::Memento>(
|
||||
session().user(),
|
||||
Info::Memento::DefaultSection(session().user()));
|
||||
sublist->owningHistory()->peer,
|
||||
Info::Memento::DefaultSection(sublist->owningHistory()->peer));
|
||||
}
|
||||
Unexpected("Key in MainWidget::thirdSectionForCurrentMainSection().");
|
||||
}
|
||||
|
|
|
@ -88,6 +88,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_forum.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_saved_messages.h"
|
||||
#include "data/data_saved_sublist.h"
|
||||
#include "data/data_histories.h"
|
||||
#include "data/data_chat_filters.h"
|
||||
|
@ -435,7 +436,7 @@ void TogglePinnedThread(
|
|||
: MTPmessages_ToggleSavedDialogPin::Flag(0);
|
||||
owner->session().api().request(MTPmessages_ToggleSavedDialogPin(
|
||||
MTP_flags(flags),
|
||||
MTP_inputDialogPeer(sublist->peer()->input)
|
||||
MTP_inputDialogPeer(sublist->sublistPeer()->input)
|
||||
)).done([=] {
|
||||
owner->notifyPinnedDialogsOrderUpdated();
|
||||
if (onToggled) {
|
||||
|
@ -655,10 +656,9 @@ void Filler::addNewWindow() {
|
|||
_addAction(tr::lng_context_new_window(tr::now), [=] {
|
||||
Ui::PreventDelayedActivation();
|
||||
if (const auto sublist = weak.get()) {
|
||||
const auto peer = sublist->peer();
|
||||
controller->showInNewWindow(SeparateId(
|
||||
SeparateType::SavedSublist,
|
||||
peer->owner().history(peer)));
|
||||
sublist->owner().history(sublist->sublistPeer())));
|
||||
}
|
||||
}, &st::menuIconNewWindow);
|
||||
AddSeparatorAndShiftUp(_addAction);
|
||||
|
@ -2850,6 +2850,46 @@ QPointer<Ui::BoxContent> ShowDropMediaBox(
|
|||
return weak->data();
|
||||
}
|
||||
|
||||
QPointer<Ui::BoxContent> ShowDropMediaBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
std::shared_ptr<QMimeData> data,
|
||||
not_null<Data::SavedMessages*> monoforum,
|
||||
FnMut<void()> &&successCallback) {
|
||||
const auto weak = std::make_shared<QPointer<Ui::BoxContent>>();
|
||||
auto chosen = [
|
||||
data = std::move(data),
|
||||
callback = std::move(successCallback),
|
||||
weak,
|
||||
navigation
|
||||
](not_null<Data::SavedSublist*> sublist) mutable {
|
||||
const auto content = navigation->parentController()->content();
|
||||
if (!content->filesOrForwardDrop(sublist, data.get())) {
|
||||
return;
|
||||
} else if (const auto strong = *weak) {
|
||||
strong->closeBox();
|
||||
}
|
||||
if (callback) {
|
||||
callback();
|
||||
}
|
||||
};
|
||||
auto initBox = [=](not_null<PeerListBox*> box) {
|
||||
box->addButton(tr::lng_cancel(), [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
|
||||
monoforum->destroyed(
|
||||
) | rpl::start_with_next([=] {
|
||||
box->closeBox();
|
||||
}, box->lifetime());
|
||||
};
|
||||
*weak = navigation->parentController()->show(Box<PeerListBox>(
|
||||
std::make_unique<ChooseSublistBoxController>(
|
||||
monoforum,
|
||||
std::move(chosen)),
|
||||
std::move(initBox)));
|
||||
return weak->data();
|
||||
}
|
||||
|
||||
QPointer<Ui::BoxContent> ShowSendNowMessagesBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
not_null<History*> history,
|
||||
|
|
|
@ -32,6 +32,8 @@ class Folder;
|
|||
class Session;
|
||||
struct ForwardDraft;
|
||||
class ForumTopic;
|
||||
class SavedMessages;
|
||||
class SavedSublist;
|
||||
class Thread;
|
||||
} // namespace Data
|
||||
|
||||
|
@ -188,6 +190,11 @@ QPointer<Ui::BoxContent> ShowDropMediaBox(
|
|||
std::shared_ptr<QMimeData> data,
|
||||
not_null<Data::Forum*> forum,
|
||||
FnMut<void()> &&successCallback = nullptr);
|
||||
QPointer<Ui::BoxContent> ShowDropMediaBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
std::shared_ptr<QMimeData> data,
|
||||
not_null<Data::SavedMessages*> monoforum,
|
||||
FnMut<void()> &&successCallback = nullptr);
|
||||
|
||||
QPointer<Ui::BoxContent> ShowSendNowMessagesBox(
|
||||
not_null<Window::SessionNavigation*> navigation,
|
||||
|
|
|
@ -1259,12 +1259,30 @@ void SessionNavigation::showTopic(
|
|||
params);
|
||||
}
|
||||
|
||||
void SessionNavigation::showSublist(
|
||||
not_null<Data::SavedSublist*> sublist,
|
||||
MsgId itemId,
|
||||
const SectionShow ¶ms) {
|
||||
using namespace HistoryView;
|
||||
auto memento = std::make_shared<ChatMemento>(
|
||||
ChatViewId{
|
||||
.history = sublist->owningHistory(),
|
||||
.sublist = sublist,
|
||||
},
|
||||
itemId,
|
||||
params.highlightPart,
|
||||
params.highlightPartOffsetHint);
|
||||
showSection(std::move(memento), params);
|
||||
}
|
||||
|
||||
void SessionNavigation::showThread(
|
||||
not_null<Data::Thread*> thread,
|
||||
MsgId itemId,
|
||||
const SectionShow ¶ms) {
|
||||
if (const auto topic = thread->asTopic()) {
|
||||
showTopic(topic, itemId, params);
|
||||
} else if (const auto sublist = thread->asSublist()) {
|
||||
showSublist(sublist, itemId, params);
|
||||
} else {
|
||||
showPeerHistory(thread->asHistory(), params, itemId);
|
||||
}
|
||||
|
@ -1346,7 +1364,7 @@ void SessionNavigation::showByInitialId(
|
|||
using namespace HistoryView;
|
||||
showSection(
|
||||
std::make_shared<ChatMemento>(ChatViewId{
|
||||
.history = id.sublist()->parentHistory(),
|
||||
.history = id.sublist()->owningHistory(),
|
||||
.sublist = id.sublist(),
|
||||
}),
|
||||
instant);
|
||||
|
|
|
@ -74,6 +74,7 @@ enum class CloudThemeType;
|
|||
class Thread;
|
||||
class Forum;
|
||||
class ForumTopic;
|
||||
class SavedSublist;
|
||||
class WallPaper;
|
||||
} // namespace Data
|
||||
|
||||
|
@ -201,6 +202,10 @@ public:
|
|||
not_null<Data::ForumTopic*> topic,
|
||||
MsgId itemId = 0,
|
||||
const SectionShow ¶ms = SectionShow());
|
||||
void showSublist(
|
||||
not_null<Data::SavedSublist*> sublist,
|
||||
MsgId itemId = 0,
|
||||
const SectionShow ¶ms = SectionShow());
|
||||
void showThread(
|
||||
not_null<Data::Thread*> thread,
|
||||
MsgId itemId = 0,
|
||||
|
|
Loading…
Add table
Reference in a new issue