mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-18 07:07:08 +02:00
Added initial ability to send and receive scheduled messages in forums.
This commit is contained in:
parent
cd59f1d576
commit
672ad64e53
9 changed files with 246 additions and 37 deletions
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_scheduled_messages.h"
|
||||
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "api/api_hash.h"
|
||||
|
@ -173,6 +174,16 @@ int ScheduledMessages::count(not_null<History*> history) const {
|
|||
return (i != end(_data)) ? i->second.items.size() : 0;
|
||||
}
|
||||
|
||||
bool ScheduledMessages::hasFor(not_null<Data::ForumTopic*> topic) const {
|
||||
const auto i = _data.find(topic->owningHistory());
|
||||
if (i == end(_data)) {
|
||||
return false;
|
||||
}
|
||||
return ranges::any_of(i->second.items, [&](const OwnedItem &item) {
|
||||
return item->topic() == topic;
|
||||
});
|
||||
}
|
||||
|
||||
void ScheduledMessages::sendNowSimpleMessage(
|
||||
const MTPDupdateShortSentMessage &update,
|
||||
not_null<HistoryItem*> local) {
|
||||
|
@ -374,7 +385,8 @@ rpl::producer<> ScheduledMessages::updates(not_null<History*> history) {
|
|||
}) | rpl::to_empty;
|
||||
}
|
||||
|
||||
Data::MessagesSlice ScheduledMessages::list(not_null<History*> history) {
|
||||
Data::MessagesSlice ScheduledMessages::list(
|
||||
not_null<History*> history) const {
|
||||
auto result = Data::MessagesSlice();
|
||||
const auto i = _data.find(history);
|
||||
if (i == end(_data)) {
|
||||
|
@ -396,6 +408,31 @@ Data::MessagesSlice ScheduledMessages::list(not_null<History*> history) {
|
|||
return result;
|
||||
}
|
||||
|
||||
Data::MessagesSlice ScheduledMessages::list(
|
||||
not_null<const Data::ForumTopic*> topic) const {
|
||||
auto result = Data::MessagesSlice();
|
||||
const auto i = _data.find(topic->Data::Thread::owningHistory());
|
||||
if (i == end(_data)) {
|
||||
const auto i = _requests.find(topic->Data::Thread::owningHistory());
|
||||
if (i == end(_requests)) {
|
||||
return result;
|
||||
}
|
||||
result.fullCount = result.skippedAfter = result.skippedBefore = 0;
|
||||
return result;
|
||||
}
|
||||
const auto &list = i->second.items;
|
||||
result.skippedAfter = result.skippedBefore = 0;
|
||||
result.fullCount = int(list.size());
|
||||
result.ids = ranges::views::all(
|
||||
list
|
||||
) | ranges::views::filter([&](const OwnedItem &item) {
|
||||
return item->topic() == topic;
|
||||
}) | ranges::views::transform(
|
||||
&HistoryItem::fullId
|
||||
) | ranges::to_vector;
|
||||
return result;
|
||||
}
|
||||
|
||||
void ScheduledMessages::request(not_null<History*> history) {
|
||||
const auto peer = history->peer;
|
||||
if (peer->isBroadcast() && !Data::CanSendAnything(peer)) {
|
||||
|
|
|
@ -34,6 +34,7 @@ public:
|
|||
[[nodiscard]] HistoryItem *lookupItem(PeerId peer, MsgId msg) const;
|
||||
[[nodiscard]] HistoryItem *lookupItem(FullMsgId itemId) const;
|
||||
[[nodiscard]] int count(not_null<History*> history) const;
|
||||
[[nodiscard]] bool hasFor(not_null<Data::ForumTopic*> topic) const;
|
||||
[[nodiscard]] MsgId localMessageId(MsgId remoteId) const;
|
||||
|
||||
void checkEntitiesAndUpdate(const MTPDmessage &data);
|
||||
|
@ -51,7 +52,9 @@ public:
|
|||
not_null<HistoryItem*> local);
|
||||
|
||||
[[nodiscard]] rpl::producer<> updates(not_null<History*> history);
|
||||
[[nodiscard]] Data::MessagesSlice list(not_null<History*> history);
|
||||
[[nodiscard]] Data::MessagesSlice list(not_null<History*> history) const;
|
||||
[[nodiscard]] Data::MessagesSlice list(
|
||||
not_null<const Data::ForumTopic*> topic) const;
|
||||
|
||||
private:
|
||||
using OwnedItem = std::unique_ptr<HistoryItem, HistoryItem::Destroyer>;
|
||||
|
|
|
@ -2723,6 +2723,9 @@ void HistoryWidget::setupScheduledToggle() {
|
|||
) | rpl::map([=](Dialogs::Key key) -> rpl::producer<> {
|
||||
if (const auto history = key.history()) {
|
||||
return session().data().scheduledMessages().updates(history);
|
||||
} else if (const auto topic = key.topic()) {
|
||||
return session().data().scheduledMessages().updates(
|
||||
topic->owningHistory());
|
||||
}
|
||||
return rpl::never<rpl::empty_value>();
|
||||
}) | rpl::flatten_latest(
|
||||
|
|
|
@ -850,9 +850,36 @@ ComposeControls::ComposeControls(
|
|||
descriptor.stickerOrEmojiChosen
|
||||
) | rpl::start_to_stream(_stickerOrEmojiChosen, _wrap->lifetime());
|
||||
}
|
||||
if (descriptor.scheduledToggleValue) {
|
||||
std::move(
|
||||
descriptor.scheduledToggleValue
|
||||
) | rpl::start_with_next([=](bool hasScheduled) {
|
||||
if (!_scheduled && hasScheduled) {
|
||||
_scheduled = base::make_unique_q<Ui::IconButton>(
|
||||
_wrap.get(),
|
||||
st::historyScheduledToggle);
|
||||
_scheduled->show();
|
||||
_scheduled->clicks(
|
||||
) | rpl::filter(
|
||||
rpl::mappers::_1 == Qt::LeftButton
|
||||
) | rpl::to_empty | rpl::start_to_stream(
|
||||
_showScheduledRequests,
|
||||
_scheduled->lifetime());
|
||||
orderControls(); // Raise drag areas to the top.
|
||||
updateControlsVisibility();
|
||||
updateControlsGeometry(_wrap->size());
|
||||
} else if (_scheduled && !hasScheduled) {
|
||||
_scheduled = nullptr;
|
||||
}
|
||||
}, _wrap->lifetime());
|
||||
}
|
||||
init();
|
||||
}
|
||||
|
||||
rpl::producer<> ComposeControls::showScheduledRequests() const {
|
||||
return _showScheduledRequests.events();
|
||||
}
|
||||
|
||||
ComposeControls::~ComposeControls() {
|
||||
saveFieldToHistoryLocalDraft();
|
||||
unregisterDraftSources();
|
||||
|
@ -2497,7 +2524,7 @@ void ComposeControls::finishAnimating() {
|
|||
|
||||
void ComposeControls::updateControlsGeometry(QSize size) {
|
||||
// (_attachToggle|_replaceMedia) (_sendAs) -- _inlineResults ------ _tabbedPanel -- _fieldBarCancel
|
||||
// (_attachDocument|_attachPhoto) _field (_ttlInfo) (_silent|_botCommandStart) _tabbedSelectorToggle _send
|
||||
// (_attachDocument|_attachPhoto) _field (_ttlInfo) (_scheduled) (_silent|_botCommandStart) _tabbedSelectorToggle _send
|
||||
|
||||
const auto fieldWidth = size.width()
|
||||
- _attachToggle->width()
|
||||
|
@ -2508,6 +2535,7 @@ void ComposeControls::updateControlsGeometry(QSize size) {
|
|||
- (_likeShown ? _like->width() : 0)
|
||||
- (_botCommandShown ? _botCommandStart->width() : 0)
|
||||
- (_silent ? _silent->width() : 0)
|
||||
- (_scheduled ? _scheduled->width() : 0)
|
||||
- (_ttlInfo ? _ttlInfo->width() : 0);
|
||||
{
|
||||
const auto oldFieldHeight = _field->height();
|
||||
|
@ -2566,6 +2594,10 @@ void ComposeControls::updateControlsGeometry(QSize size) {
|
|||
_silent->moveToRight(right, buttonsTop);
|
||||
right += _silent->width();
|
||||
}
|
||||
if (_scheduled) {
|
||||
_scheduled->moveToRight(right, buttonsTop);
|
||||
right += _scheduled->width();
|
||||
}
|
||||
if (_ttlInfo) {
|
||||
_ttlInfo->move(size.width() - right - _ttlInfo->width(), buttonsTop);
|
||||
}
|
||||
|
@ -2595,6 +2627,9 @@ void ComposeControls::updateControlsVisibility() {
|
|||
} else {
|
||||
_attachToggle->show();
|
||||
}
|
||||
if (_scheduled) {
|
||||
_scheduled->setVisible(!isEditingMessage());
|
||||
}
|
||||
}
|
||||
|
||||
bool ComposeControls::updateLikeShown() {
|
||||
|
|
|
@ -112,6 +112,7 @@ struct ComposeControlsDescriptor {
|
|||
QString voiceCustomCancelText;
|
||||
bool voiceLockFromBottom = false;
|
||||
ChatHelpers::ComposeFeatures features;
|
||||
rpl::producer<bool> scheduledToggleValue;
|
||||
};
|
||||
|
||||
class ComposeControls final {
|
||||
|
@ -172,6 +173,7 @@ public:
|
|||
[[nodiscard]] auto replyNextRequests() const
|
||||
-> rpl::producer<ReplyNextRequest>;
|
||||
[[nodiscard]] rpl::producer<> focusRequests() const;
|
||||
[[nodiscard]] rpl::producer<> showScheduledRequests() const;
|
||||
|
||||
using MimeDataHook = Fn<bool(
|
||||
not_null<const QMimeData*> data,
|
||||
|
@ -382,6 +384,7 @@ private:
|
|||
std::unique_ptr<Ui::SilentToggle> _silent;
|
||||
std::unique_ptr<Controls::TTLButton> _ttlInfo;
|
||||
base::unique_qptr<Controls::CharactersLimitLabel> _charsLimitation;
|
||||
base::unique_qptr<Ui::IconButton> _scheduled;
|
||||
|
||||
std::unique_ptr<InlineBots::Layout::Widget> _inlineResults;
|
||||
std::unique_ptr<ChatHelpers::TabbedPanel> _tabbedPanel;
|
||||
|
@ -408,6 +411,7 @@ private:
|
|||
rpl::event_stream<> _likeToggled;
|
||||
rpl::event_stream<ReplyNextRequest> _replyNextRequests;
|
||||
rpl::event_stream<> _focusRequests;
|
||||
rpl::event_stream<> _showScheduledRequests;
|
||||
rpl::variable<bool> _recording;
|
||||
rpl::variable<bool> _hasSendText;
|
||||
|
||||
|
|
|
@ -861,7 +861,9 @@ QSize Message::performCountOptimalSize() {
|
|||
|
||||
void Message::refreshTopicButton() {
|
||||
const auto item = data();
|
||||
if (isAttachedToPrevious() || context() != Context::History) {
|
||||
if (isAttachedToPrevious()
|
||||
|| (context() != Context::History)
|
||||
|| item->isScheduled()) {
|
||||
_topicButton = nullptr;
|
||||
} else if (const auto topic = item->topic()) {
|
||||
if (!_topicButton) {
|
||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_sticker_toast.h"
|
||||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "history/view/history_view_contact_status.h"
|
||||
#include "history/view/history_view_scheduled_section.h"
|
||||
#include "history/view/history_view_service_message.h"
|
||||
#include "history/view/history_view_pinned_tracker.h"
|
||||
#include "history/view/history_view_pinned_section.h"
|
||||
|
@ -62,6 +63,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_changes.h"
|
||||
#include "data/data_shared_media.h"
|
||||
#include "data/data_send_action.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
#include "data/data_premium_limits.h"
|
||||
#include "storage/storage_media_prepare.h"
|
||||
#include "storage/storage_account.h"
|
||||
|
@ -221,9 +223,19 @@ RepliesWidget::RepliesWidget(
|
|||
listShowPremiumToast(emoji);
|
||||
},
|
||||
.mode = ComposeControls::Mode::Normal,
|
||||
.sendMenuType = SendMenu::Type::SilentOnly,
|
||||
.sendMenuType = _topic
|
||||
? SendMenu::Type::Scheduled
|
||||
: SendMenu::Type::SilentOnly,
|
||||
.regularWindow = controller,
|
||||
.stickerOrEmojiChosen = controller->stickerOrEmojiChosen(),
|
||||
.scheduledToggleValue = _topic
|
||||
? rpl::single(rpl::empty_value()) | rpl::then(
|
||||
session().data().scheduledMessages().updates(
|
||||
_topic->owningHistory())
|
||||
) | rpl::map([=] {
|
||||
return session().data().scheduledMessages().hasFor(_topic);
|
||||
})
|
||||
: rpl::single(false),
|
||||
}))
|
||||
, _translateBar(std::make_unique<TranslateBar>(this, controller, history))
|
||||
, _scroll(std::make_unique<Ui::ScrollArea>(
|
||||
|
@ -364,6 +376,20 @@ RepliesWidget::RepliesWidget(
|
|||
) | rpl::start_with_next([=] {
|
||||
_inner->update();
|
||||
}, lifetime());
|
||||
} else {
|
||||
session().api().sendActions(
|
||||
) | rpl::filter([=](const Api::SendAction &action) {
|
||||
return (action.history == _history)
|
||||
&& (action.replyTo.topicRootId == _topic->topicRootId());
|
||||
}) | rpl::start_with_next([=](const Api::SendAction &action) {
|
||||
if (action.options.scheduled) {
|
||||
_composeControls->cancelReplyMessage();
|
||||
crl::on_main(this, [=, t = _topic] {
|
||||
controller->showSection(
|
||||
std::make_shared<HistoryView::ScheduledMemento>(t));
|
||||
});
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
setupTopicViewer();
|
||||
|
@ -778,6 +804,14 @@ void RepliesWidget::setupComposeControls() {
|
|||
data.direction == Direction::Next);
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->showScheduledRequests(
|
||||
) | rpl::start_with_next([=] {
|
||||
controller()->showSection(
|
||||
_topic
|
||||
? std::make_shared<HistoryView::ScheduledMemento>(_topic)
|
||||
: std::make_shared<HistoryView::ScheduledMemento>(_history));
|
||||
}, lifetime());
|
||||
|
||||
_composeControls->setMimeDataHook([=](
|
||||
not_null<const QMimeData*> data,
|
||||
Ui::InputField::MimeAction action) {
|
||||
|
|
|
@ -33,6 +33,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "core/mime_type.h"
|
||||
#include "chat_helpers/tabbed_selector.h"
|
||||
#include "main/main_session.h"
|
||||
#include "data/data_forum.h"
|
||||
#include "data/data_forum_topic.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_changes.h"
|
||||
#include "data/data_scheduled_messages.h"
|
||||
|
@ -53,6 +55,16 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace HistoryView {
|
||||
|
||||
ScheduledMemento::ScheduledMemento(not_null<History*> history)
|
||||
: _history(history)
|
||||
, _forumTopic(nullptr) {
|
||||
}
|
||||
|
||||
ScheduledMemento::ScheduledMemento(not_null<Data::ForumTopic*> forumTopic)
|
||||
: _history(forumTopic->owningHistory())
|
||||
, _forumTopic(forumTopic) {
|
||||
}
|
||||
|
||||
object_ptr<Window::SectionWidget> ScheduledMemento::createWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
|
@ -61,7 +73,11 @@ object_ptr<Window::SectionWidget> ScheduledMemento::createWidget(
|
|||
if (column == Window::Column::Third) {
|
||||
return nullptr;
|
||||
}
|
||||
auto result = object_ptr<ScheduledWidget>(parent, controller, _history);
|
||||
auto result = object_ptr<ScheduledWidget>(
|
||||
parent,
|
||||
controller,
|
||||
_history,
|
||||
_forumTopic);
|
||||
result->setInternalState(geometry, this);
|
||||
return result;
|
||||
}
|
||||
|
@ -69,9 +85,11 @@ object_ptr<Window::SectionWidget> ScheduledMemento::createWidget(
|
|||
ScheduledWidget::ScheduledWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<History*> history)
|
||||
not_null<History*> history,
|
||||
const Data::ForumTopic *forumTopic)
|
||||
: Window::SectionWidget(parent, controller, history->peer)
|
||||
, _history(history)
|
||||
, _forumTopic(forumTopic)
|
||||
, _scroll(
|
||||
this,
|
||||
controller->chatStyle()->value(lifetime(), st::historyScroll),
|
||||
|
@ -175,30 +193,80 @@ ScheduledWidget::ScheduledWidget(
|
|||
ScheduledWidget::~ScheduledWidget() = default;
|
||||
|
||||
void ScheduledWidget::setupComposeControls() {
|
||||
auto writeRestriction = rpl::combine(
|
||||
session().changes().peerFlagsValue(
|
||||
_history->peer,
|
||||
Data::PeerUpdate::Flag::Rights),
|
||||
Data::CanSendAnythingValue(_history->peer)
|
||||
) | rpl::map([=] {
|
||||
const auto allWithoutPolls = Data::AllSendRestrictions()
|
||||
& ~ChatRestriction::SendPolls;
|
||||
const auto canSendAnything = Data::CanSendAnyOf(
|
||||
_history->peer,
|
||||
allWithoutPolls);
|
||||
const auto restriction = Data::RestrictionError(
|
||||
_history->peer,
|
||||
ChatRestriction::SendOther);
|
||||
auto text = !canSendAnything
|
||||
? (restriction
|
||||
? restriction
|
||||
: tr::lng_group_not_accessible(tr::now))
|
||||
: std::optional<QString>();
|
||||
return text ? Controls::WriteRestriction{
|
||||
.text = std::move(*text),
|
||||
.type = Controls::WriteRestrictionType::Rights,
|
||||
} : Controls::WriteRestriction();
|
||||
});
|
||||
auto writeRestriction = _forumTopic
|
||||
? [&] {
|
||||
auto topicWriteRestrictions = rpl::single(
|
||||
) | rpl::then(session().changes().topicUpdates(
|
||||
Data::TopicUpdate::Flag::Closed
|
||||
) | rpl::filter([=](const Data::TopicUpdate &update) {
|
||||
return (update.topic->history() == _history)
|
||||
&& (update.topic->rootId() == _forumTopic->rootId());
|
||||
}) | rpl::to_empty) | rpl::map([=] {
|
||||
return (!_forumTopic
|
||||
|| _forumTopic->canToggleClosed()
|
||||
|| !_forumTopic->closed())
|
||||
? std::optional<QString>()
|
||||
: tr::lng_forum_topic_closed(tr::now);
|
||||
});
|
||||
return rpl::combine(
|
||||
session().changes().peerFlagsValue(
|
||||
_history->peer,
|
||||
Data::PeerUpdate::Flag::Rights),
|
||||
Data::CanSendAnythingValue(_history->peer),
|
||||
std::move(topicWriteRestrictions)
|
||||
) | rpl::map([=](
|
||||
auto,
|
||||
auto,
|
||||
std::optional<QString> topicRestriction) {
|
||||
const auto allWithoutPolls = Data::AllSendRestrictions()
|
||||
& ~ChatRestriction::SendPolls;
|
||||
const auto canSendAnything = Data::CanSendAnyOf(
|
||||
_forumTopic,
|
||||
allWithoutPolls);
|
||||
const auto restriction = Data::RestrictionError(
|
||||
_history->peer,
|
||||
ChatRestriction::SendOther);
|
||||
auto text = !canSendAnything
|
||||
? (restriction
|
||||
? restriction
|
||||
: topicRestriction
|
||||
? std::move(topicRestriction)
|
||||
: tr::lng_group_not_accessible(tr::now))
|
||||
: topicRestriction
|
||||
? std::move(topicRestriction)
|
||||
: std::optional<QString>();
|
||||
return text ? Controls::WriteRestriction{
|
||||
.text = std::move(*text),
|
||||
.type = Controls::WriteRestrictionType::Rights,
|
||||
} : Controls::WriteRestriction();
|
||||
});
|
||||
}()
|
||||
: [&] {
|
||||
return rpl::combine(
|
||||
session().changes().peerFlagsValue(
|
||||
_history->peer,
|
||||
Data::PeerUpdate::Flag::Rights),
|
||||
Data::CanSendAnythingValue(_history->peer)
|
||||
) | rpl::map([=] {
|
||||
const auto allWithoutPolls = Data::AllSendRestrictions()
|
||||
& ~ChatRestriction::SendPolls;
|
||||
const auto canSendAnything = Data::CanSendAnyOf(
|
||||
_history->peer,
|
||||
allWithoutPolls);
|
||||
const auto restriction = Data::RestrictionError(
|
||||
_history->peer,
|
||||
ChatRestriction::SendOther);
|
||||
auto text = !canSendAnything
|
||||
? (restriction
|
||||
? restriction
|
||||
: tr::lng_group_not_accessible(tr::now))
|
||||
: std::optional<QString>();
|
||||
return text ? Controls::WriteRestriction{
|
||||
.text = std::move(*text),
|
||||
.type = Controls::WriteRestrictionType::Rights,
|
||||
} : Controls::WriteRestriction();
|
||||
});
|
||||
}();
|
||||
_composeControls->setHistory({
|
||||
.history = _history.get(),
|
||||
.writeRestriction = std::move(writeRestriction),
|
||||
|
@ -564,6 +632,12 @@ Api::SendAction ScheduledWidget::prepareSendAction(
|
|||
Api::SendOptions options) const {
|
||||
auto result = Api::SendAction(_history, options);
|
||||
result.options.sendAs = _composeControls->sendAsPeer();
|
||||
if (_forumTopic) {
|
||||
result.replyTo.topicRootId = _forumTopic->topicRootId();
|
||||
result.replyTo.messageId = FullMsgId(
|
||||
history()->peer->id,
|
||||
_forumTopic->topicRootId());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -576,7 +650,7 @@ void ScheduledWidget::send() {
|
|||
const auto error = GetErrorTextForSending(
|
||||
_history->peer,
|
||||
{
|
||||
.topicRootId = MsgId(),
|
||||
.topicRootId = _forumTopic ? _forumTopic->topicRootId() : MsgId(),
|
||||
.forward = nullptr,
|
||||
.text = &textWithTags,
|
||||
.ignoreSlowmodeCountdown = true,
|
||||
|
@ -943,6 +1017,16 @@ bool ScheduledWidget::returnTabbedSelector() {
|
|||
}
|
||||
|
||||
std::shared_ptr<Window::SectionMemento> ScheduledWidget::createMemento() {
|
||||
if (_forumTopic) {
|
||||
if (const auto forum = history()->asForum()) {
|
||||
const auto rootId = _forumTopic->topicRootId();
|
||||
if (const auto topic = forum->topicFor(rootId)) {
|
||||
auto result = std::make_shared<ScheduledMemento>(topic);
|
||||
saveState(result.get());
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
auto result = std::make_shared<ScheduledMemento>(history());
|
||||
saveState(result.get());
|
||||
return result;
|
||||
|
@ -1098,7 +1182,9 @@ rpl::producer<Data::MessagesSlice> ScheduledWidget::listSource(
|
|||
return rpl::single(rpl::empty) | rpl::then(
|
||||
data->scheduledMessages().updates(_history)
|
||||
) | rpl::map([=] {
|
||||
return data->scheduledMessages().list(_history);
|
||||
return _forumTopic
|
||||
? data->scheduledMessages().list(_forumTopic)
|
||||
: data->scheduledMessages().list(_history);
|
||||
}) | rpl::after_next([=](const Data::MessagesSlice &slice) {
|
||||
highlightSingleNewMessage(slice);
|
||||
});
|
||||
|
@ -1187,6 +1273,9 @@ void ScheduledWidget::listUpdateDateLink(
|
|||
}
|
||||
|
||||
bool ScheduledWidget::listElementHideReply(not_null<const Element*> view) {
|
||||
if (const auto root = view->data()->topicRootId()) {
|
||||
return root == view->data()->replyTo().messageId.msg;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -58,7 +58,8 @@ public:
|
|||
ScheduledWidget(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<History*> history);
|
||||
not_null<History*> history,
|
||||
const Data::ForumTopic *forumTopic);
|
||||
~ScheduledWidget();
|
||||
|
||||
not_null<History*> history() const;
|
||||
|
@ -261,6 +262,7 @@ private:
|
|||
Api::SendOptions options);
|
||||
|
||||
const not_null<History*> _history;
|
||||
const Data::ForumTopic *_forumTopic;
|
||||
std::shared_ptr<Ui::ChatTheme> _theme;
|
||||
object_ptr<Ui::ScrollArea> _scroll;
|
||||
QPointer<ListWidget> _inner;
|
||||
|
@ -280,9 +282,8 @@ private:
|
|||
|
||||
class ScheduledMemento : public Window::SectionMemento {
|
||||
public:
|
||||
ScheduledMemento(not_null<History*> history)
|
||||
: _history(history) {
|
||||
}
|
||||
ScheduledMemento(not_null<History*> history);
|
||||
ScheduledMemento(not_null<Data::ForumTopic*> forumTopic);
|
||||
|
||||
object_ptr<Window::SectionWidget> createWidget(
|
||||
QWidget *parent,
|
||||
|
@ -300,6 +301,7 @@ public:
|
|||
|
||||
private:
|
||||
const not_null<History*> _history;
|
||||
const Data::ForumTopic *_forumTopic;
|
||||
ListMemento _list;
|
||||
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue