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