Support no-topics recipient state in bot-forums.

This commit is contained in:
John Preston
2026-02-13 16:10:50 +04:00
parent 2e538b5d38
commit 4c2d72d00b
19 changed files with 304 additions and 190 deletions
+1
View File
@@ -459,6 +459,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_contacts_not_found" = "No contacts found";
"lng_topics_not_found" = "No topics found.";
"lng_forum_all_messages" = "All Messages";
"lng_forum_create_new_topic" = "Create New Thread";
"lng_dlg_search_for_messages" = "Search for messages";
"lng_update_telegram" = "Update Telegram";
"lng_dlg_search_in" = "Search messages in";
+48 -26
View File
@@ -3529,7 +3529,6 @@ void ApiWrap::forwardMessages(
if (shared) {
++shared->requestsLeft;
}
const auto requestType = Data::Histories::RequestType::Send;
const auto idsCopy = localIds;
const auto scheduled = action.options.scheduled;
const auto starsPaid = std::min(
@@ -3540,57 +3539,80 @@ void ApiWrap::forwardMessages(
action.options.starsApproved -= starsPaid;
oneFlags |= SendFlag::f_allow_paid_stars;
}
histories.sendRequest(history, requestType, [=](Fn<void()> finish) {
history->sendRequestId = request(MTPmessages_ForwardMessages(
MTP_flags(oneFlags),
auto buildMessage = [=](
not_null<History*> history,
FullReplyTo replyTo)
-> Data::Histories::PreparedMessage {
const auto kGeneralId = Data::ForumTopic::kGeneralId;
const auto realTopMsgId = (replyTo.topicRootId == kGeneralId)
? MsgId(0)
: replyTo.topicRootId;
auto flags = oneFlags;
if (realTopMsgId) {
flags |= SendFlag::f_top_msg_id;
} else {
flags &= ~SendFlag::f_top_msg_id;
}
return MTPmessages_ForwardMessages(
MTP_flags(flags),
forwardFrom->input(),
MTP_vector<MTPint>(ids),
MTP_vector<MTPlong>(randomIds),
peer->input(),
MTP_int(topMsgId),
history->peer->input(),
MTP_int(realTopMsgId),
(action.options.suggest
? ReplyToForMTP(history, action.replyTo)
? ReplyToForMTP(history, replyTo)
: monoforumPeer
? MTP_inputReplyToMonoForum(monoforumPeer->input())
? MTP_inputReplyToMonoForum(
monoforumPeer->input())
: MTPInputReplyTo()),
MTP_int(action.options.scheduled),
MTP_int(action.options.scheduleRepeatPeriod),
(sendAs ? sendAs->input() : MTP_inputPeerEmpty()),
Data::ShortcutIdToMTP(_session, action.options.shortcutId),
(sendAs
? sendAs->input()
: MTP_inputPeerEmpty()),
Data::ShortcutIdToMTP(
&history->session(),
action.options.shortcutId),
MTP_long(action.options.effectId),
MTPint(), // video_timestamp
MTPint(),
MTP_long(starsPaid),
Api::SuggestToMTP(action.options.suggest)
)).done([=](const MTPUpdates &result) {
Api::SuggestToMTP(action.options.suggest));
};
histories.sendPreparedMessage(
history,
FullReplyTo{ .topicRootId = topicRootId },
uint64(0),
std::move(buildMessage),
[=](const MTPUpdates &result, const MTP::Response &) {
if (!scheduled) {
this->updates().checkForSentToScheduled(result);
_session->api().updates().checkForSentToScheduled(
result);
}
applyUpdates(result);
if (shared && !--shared->requestsLeft) {
shared->callback();
}
finish();
if (peer->isSelf() && session().premium()) {
if (peer->isSelf() && _session->premium()) {
ProcessRecentSelfForwards(
_session,
result,
peer->id,
forwardFrom->id);
}
}).fail([=](const MTP::Error &error) {
},
[=](const MTP::Error &error, const MTP::Response &) {
if (idsCopy) {
for (const auto &[randomId, itemId] : *idsCopy) {
sendMessageFail(error, peer, randomId, itemId);
_session->api().sendMessageFail(
error,
peer,
randomId,
itemId);
}
} else {
sendMessageFail(error, peer);
_session->api().sendMessageFail(error, peer);
}
finish();
}).afterRequest(
history->sendRequestId
).send();
return history->sendRequestId;
});
});
ids.resize(0);
randomIds.resize(0);
@@ -1096,10 +1096,16 @@ auto ChooseTopicBoxController::Row::generateNameWords() const
return _topic->chatListNameWords();
}
ChooseTopicBoxController::AllMessagesRow::AllMessagesRow()
: PeerListRow(PeerListRowId(0)) {
const auto name = tr::lng_forum_all_messages(tr::now);
const auto words = TextUtilities::PrepareSearchWords(name);
QString ChooseTopicBoxController::AllMessagesRow::name() const {
return _userCreatesTopics
? tr::lng_forum_create_new_topic(tr::now)
: tr::lng_forum_all_messages(tr::now);
}
ChooseTopicBoxController::AllMessagesRow::AllMessagesRow(bool userCreatesTopics)
: PeerListRow(PeerListRowId(0))
, _userCreatesTopics(userCreatesTopics) {
const auto words = TextUtilities::PrepareSearchWords(name());
for (const auto &word : words) {
_nameWords.emplace(word);
_nameFirstLetters.emplace(word[0]);
@@ -1107,23 +1113,26 @@ ChooseTopicBoxController::AllMessagesRow::AllMessagesRow()
}
QString ChooseTopicBoxController::AllMessagesRow::generateName() {
return tr::lng_forum_all_messages(tr::now);
return name();
}
QString ChooseTopicBoxController::AllMessagesRow::generateShortName() {
return tr::lng_forum_all_messages(tr::now);
return name();
}
auto ChooseTopicBoxController::AllMessagesRow::generatePaintUserpicCallback(
bool forceRound)
-> PaintRoundImageCallback {
return [](
return [userCreatesTopics = _userCreatesTopics](
Painter &p,
int x,
int y,
int outerWidth,
int size) {
st::menuIconChats.paintInCenter(
const auto &icon = userCreatesTopics
? st::menuIconDiscussion
: st::menuIconChats;
icon.paintInCenter(
p,
QRect(x, y - st::lineWidth, size, size));
};
@@ -1206,8 +1215,10 @@ void ChooseTopicBoxController::refreshRows(bool initial) {
if (_forum->bot()
&& !delegate()->peerListFindRow(PeerListRowId(0))
&& (!_filter || _filter(_forum->history()))) {
const auto userCreatesTopics = Data::IsBotUserCreatesTopics(
_forum->peer());
delegate()->peerListAppendRow(
std::make_unique<AllMessagesRow>());
std::make_unique<AllMessagesRow>(userCreatesTopics));
added = true;
}
for (const auto &row : _forum->topicsList()->indexed()->all()) {
@@ -393,7 +393,7 @@ private:
class AllMessagesRow final : public PeerListRow {
public:
AllMessagesRow();
explicit AllMessagesRow(bool userCreatesTopics);
QString generateName() override;
QString generateShortName() override;
@@ -406,8 +406,11 @@ private:
-> const base::flat_set<QString> & override;
private:
[[nodiscard]] QString name() const;
base::flat_set<QChar> _nameFirstLetters;
base::flat_set<QString> _nameWords;
bool _userCreatesTopics = false;
};
+149 -88
View File
@@ -1683,6 +1683,7 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
std::optional<TimeId> videoTimestamp) {
struct State final {
base::flat_set<mtpRequestId> requests;
mtpRequestId nextRequestKey = 0;
};
const auto state = std::make_shared<State>();
return [=](
@@ -1732,13 +1733,6 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
for (const auto &fullId : existingIds) {
mtpMsgIds.push_back(MTP_int(fullId.msg));
}
const auto generateRandom = [&] {
auto result = QVector<MTPlong>(existingIds.size());
for (auto &value : result) {
value = base::RandomValue<MTPlong>();
}
return result;
};
auto &api = history->session().api();
auto &histories = history->owner().histories();
const auto donePhraseArgs = CreateForwardedMessagePhraseArgs(
@@ -1747,103 +1741,170 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
const auto showRecentForwardsToSelf = result.size() == 1
&& result.front()->peer()->isSelf()
&& history->session().premium();
const auto requestType = Data::Histories::RequestType::Send;
for (const auto thread : result) {
const auto peer = thread->peer();
const auto threadHistory = thread->owningHistory();
const auto forum = threadHistory->asForum();
const auto needNewTopic = forum
&& forum->bot()
&& Data::IsBotUserCreatesTopics(peer)
&& !thread->asTopic();
const auto effectiveThread = [&]() -> not_null<Data::Thread*> {
if (needNewTopic) {
const auto topic = forum->reserveNewBotTopic();
Assert(topic != nullptr);
return topic;
}
return thread;
}();
if (!comment.text.isEmpty()) {
auto message = Api::MessageToSend(
Api::SendAction(thread, options));
Api::SendAction(effectiveThread, options));
message.textWithTags = comment;
message.action.clearDraft = false;
api.sendMessage(std::move(message));
}
const auto topicRootId = thread->topicRootId();
const auto sublistPeer = thread->maybeSublistPeer();
const auto kGeneralId = Data::ForumTopic::kGeneralId;
const auto topMsgId = (topicRootId == kGeneralId)
? MsgId(0)
: topicRootId;
const auto peer = thread->peer();
const auto threadHistory = thread->owningHistory();
const auto topicRootId = effectiveThread->topicRootId();
const auto sublistPeer = needNewTopic
? nullptr
: thread->maybeSublistPeer();
const auto fromPeer = history->peer;
const auto msgCount = int(existingIds.size());
const auto starsPaid = std::min(
peer->starsPerMessageChecked(),
options.starsApproved);
if (starsPaid) {
options.starsApproved -= starsPaid;
}
histories.sendRequest(threadHistory, requestType, [=](
Fn<void()> finish) {
const auto session = &threadHistory->session();
auto &api = session->api();
const auto sendFlags = commonSendFlags
| (topMsgId ? Flag::f_top_msg_id : Flag(0))
| (ShouldSendSilent(peer, options)
? Flag::f_silent
: Flag(0))
| (options.shortcutId
? Flag::f_quick_reply_shortcut
: Flag(0))
| (starsPaid ? Flag::f_allow_paid_stars : Flag())
| (sublistPeer ? Flag::f_reply_to : Flag())
| (options.suggest ? Flag::f_suggested_post : Flag())
| (options.effectId ? Flag::f_effect : Flag());
threadHistory->sendRequestId = api.request(
MTPmessages_ForwardMessages(
MTP_flags(sendFlags),
history->peer->input(),
MTP_vector<MTPint>(mtpMsgIds),
MTP_vector<MTPlong>(generateRandom()),
peer->input(),
MTP_int(topMsgId),
(sublistPeer
? MTP_inputReplyToMonoForum(sublistPeer->input())
: MTPInputReplyTo()),
MTP_int(options.scheduled),
MTP_int(options.scheduleRepeatPeriod),
MTP_inputPeerEmpty(), // send_as
Data::ShortcutIdToMTP(session, options.shortcutId),
MTP_long(options.effectId),
MTP_int(videoTimestamp.value_or(0)),
MTP_long(starsPaid),
Api::SuggestToMTP(options.suggest)
)).done([=](const MTPUpdates &updates, mtpRequestId reqId) {
threadHistory->session().api().applyUpdates(updates);
if (showRecentForwardsToSelf) {
ApiWrap::ProcessRecentSelfForwards(
&threadHistory->session(),
updates,
peer->id,
history->peer->id);
}
state->requests.remove(reqId);
if (state->requests.empty()) {
if (show->valid()) {
auto phrase = rpl::variable<TextWithEntities>(
ChatHelpers::ForwardedMessagePhrase(
donePhraseArgs)).current();
if (!phrase.empty()) {
show->showToast(std::move(phrase));
}
show->hideLayer();
const auto sendFlags = commonSendFlags
| (ShouldSendSilent(peer, options)
? Flag::f_silent
: Flag(0))
| (options.shortcutId
? Flag::f_quick_reply_shortcut
: Flag(0))
| (starsPaid ? Flag::f_allow_paid_stars : Flag())
| (sublistPeer ? Flag::f_reply_to : Flag())
| (options.suggest ? Flag::f_suggested_post : Flag())
| (options.effectId ? Flag::f_effect : Flag());
auto buildMessage = [=](
not_null<History*> history,
FullReplyTo replyTo)
-> Data::Histories::PreparedMessage {
const auto kGeneralId
= Data::ForumTopic::kGeneralId;
const auto realTopMsgId
= (replyTo.topicRootId == kGeneralId)
? MsgId(0)
: replyTo.topicRootId;
auto flags = sendFlags;
if (realTopMsgId) {
flags |= Flag::f_top_msg_id;
} else {
flags &= ~Flag::f_top_msg_id;
}
auto randoms = QVector<MTPlong>(msgCount);
for (auto &value : randoms) {
value = base::RandomValue<MTPlong>();
}
return MTPmessages_ForwardMessages(
MTP_flags(flags),
fromPeer->input(),
MTP_vector<MTPint>(mtpMsgIds),
MTP_vector<MTPlong>(randoms),
history->peer->input(),
MTP_int(realTopMsgId),
(sublistPeer
? MTP_inputReplyToMonoForum(
sublistPeer->input())
: MTPInputReplyTo()),
MTP_int(options.scheduled),
MTP_int(options.scheduleRepeatPeriod),
MTP_inputPeerEmpty(),
Data::ShortcutIdToMTP(
&history->session(),
options.shortcutId),
MTP_long(options.effectId),
MTP_int(videoTimestamp.value_or(0)),
MTP_long(starsPaid),
Api::SuggestToMTP(options.suggest));
};
const auto requestDone = [=](
const MTPUpdates &updates,
mtpRequestId requestKey) {
if (showRecentForwardsToSelf) {
ApiWrap::ProcessRecentSelfForwards(
&threadHistory->session(),
updates,
peer->id,
history->peer->id);
}
state->requests.remove(requestKey);
if (state->requests.empty()) {
if (show->valid()) {
auto phrase = rpl::variable<
TextWithEntities>(
ChatHelpers::ForwardedMessagePhrase(
donePhraseArgs)).current();
if (!phrase.empty()) {
show->showToast(std::move(phrase));
}
show->hideLayer();
}
finish();
}).fail([=](const MTP::Error &error) {
const auto type = error.type();
if (type.startsWith(u"ALLOW_PAYMENT_REQUIRED_"_q)) {
show->showToast(u"Payment requirements changed. "
"Please, try again."_q);
} else if (type == u"VOICE_MESSAGES_FORBIDDEN"_q) {
show->showToast(
tr::lng_restricted_send_voice_messages(
tr::now,
lt_user,
peer->name()));
}
};
const auto requestFail = [=](
const MTP::Error &error,
mtpRequestId requestKey) {
const auto type = error.type();
if (type.startsWith(
u"ALLOW_PAYMENT_REQUIRED_"_q)) {
show->showToast(
u"Payment requirements changed. "
"Please, try again."_q);
} else if (type
== u"VOICE_MESSAGES_FORBIDDEN"_q) {
show->showToast(
tr::lng_restricted_send_voice_messages(
tr::now,
lt_user,
peer->name()));
}
state->requests.remove(requestKey);
if (state->requests.empty()) {
if (show->valid()) {
show->hideLayer();
}
finish();
}).afterRequest(threadHistory->sendRequestId).send();
return threadHistory->sendRequestId;
});
state->requests.insert(threadHistory->sendRequestId);
}
};
const auto requestKey = ++state->nextRequestKey;
state->requests.insert(requestKey);
histories.sendPreparedMessage(
threadHistory,
FullReplyTo{ .topicRootId = topicRootId },
uint64(0),
std::move(buildMessage),
[=](const MTPUpdates &updates,
const MTP::Response &) {
requestDone(updates, requestKey);
},
[=](const MTP::Error &error,
const MTP::Response &) {
requestFail(error, requestKey);
});
}
if (state->requests.empty()) {
if (show->valid()) {
auto phrase = rpl::variable<TextWithEntities>(
ChatHelpers::ForwardedMessagePhrase(
donePhraseArgs)).current();
if (!phrase.empty()) {
show->showToast(std::move(phrase));
}
show->hideLayer();
}
}
};
}
+9
View File
@@ -527,6 +527,15 @@ MsgId Forum::reserveCreatingId(
return result;
}
ForumTopic *Forum::reserveNewBotTopic() {
const auto &colors = ForumTopicColorIds();
const auto colorId = colors[base::RandomIndex(colors.size())];
return topicFor(reserveCreatingId(
tr::lng_bot_new_chat(tr::now),
colorId,
DocumentId()));
}
void Forum::discardCreatingId(MsgId rootId) {
Expects(creating(rootId));
+1
View File
@@ -87,6 +87,7 @@ public:
void discardCreatingId(MsgId rootId);
[[nodiscard]] bool creating(MsgId rootId) const;
void created(MsgId rootId, MsgId realId);
[[nodiscard]] ForumTopic *reserveNewBotTopic();
void clearAllUnreadMentions();
void clearAllUnreadReactions();
+2 -1
View File
@@ -112,7 +112,8 @@ public:
MTPmessages_SendMessage,
MTPmessages_SendMedia,
MTPmessages_SendInlineBotResult,
MTPmessages_SendMultiMedia>;
MTPmessages_SendMultiMedia,
MTPmessages_ForwardMessages>;
int sendPreparedMessage(
not_null<History*> history,
FullReplyTo replyTo,
+2 -2
View File
@@ -2231,9 +2231,9 @@ std::optional<uint8> ColorIndexFromColor(const MTPPeerColor *color) {
});
}
bool IsBotCanManageTopics(not_null<PeerData*> peer) {
bool IsBotUserCreatesTopics(not_null<PeerData*> peer) {
if (const auto user = peer->asUser()) {
return user->botInfo && user->botInfo->canManageTopics;
return user->botInfo && user->botInfo->userCreatesTopics;
}
return false;
}
+1 -1
View File
@@ -678,6 +678,6 @@ void SetTopPinnedMessageId(
[[nodiscard]] uint64 BackgroundEmojiIdFromColor(const MTPPeerColor *color);
[[nodiscard]] std::optional<uint8> ColorIndexFromColor(const MTPPeerColor *);
[[nodiscard]] bool IsBotCanManageTopics(not_null<PeerData*>);
[[nodiscard]] bool IsBotUserCreatesTopics(not_null<PeerData*>);
} // namespace Data
+22 -22
View File
@@ -564,6 +564,28 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
result->setStarsPerMessage(0);
}
if (!minimal) {
result->setBotInfoVersion(data.vbot_info_version().value_or(-1));
if (const auto info = result->botInfo.get()) {
info->readsAllHistory = data.is_bot_chat_history();
if (info->cantJoinGroups != data.is_bot_nochats()) {
info->cantJoinGroups = data.is_bot_nochats();
flags |= UpdateFlag::BotCanBeInvited;
}
if (const auto value = data.vbot_inline_placeholder()) {
info->inlinePlaceholder = '_' + qs(*value);
} else {
info->inlinePlaceholder = QString();
}
info->supportsAttachMenu = data.is_bot_attach_menu();
info->supportsBusiness = data.is_bot_business();
info->canEditInformation = data.is_bot_can_edit();
info->activeUsers = data.vbot_active_users().value_or_empty();
info->hasMainApp = data.is_bot_has_main_app();
info->userCreatesTopics = data.is_bot_forum_can_manage_topics();
}
}
using Flag = UserDataFlag;
const auto flagsMask = Flag::Deleted
| Flag::Verified
@@ -739,28 +761,6 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
result->setEmojiStatus(EmojiStatusId());
}
if (!minimal) {
if (const auto botInfoVersion = data.vbot_info_version()) {
result->setBotInfoVersion(botInfoVersion->v);
result->botInfo->readsAllHistory = data.is_bot_chat_history();
if (result->botInfo->cantJoinGroups != data.is_bot_nochats()) {
result->botInfo->cantJoinGroups = data.is_bot_nochats();
flags |= UpdateFlag::BotCanBeInvited;
}
if (const auto placeholder = data.vbot_inline_placeholder()) {
result->botInfo->inlinePlaceholder = '_' + qs(*placeholder);
} else {
result->botInfo->inlinePlaceholder = QString();
}
result->botInfo->supportsAttachMenu = data.is_bot_attach_menu();
result->botInfo->supportsBusiness = data.is_bot_business();
result->botInfo->canEditInformation = data.is_bot_can_edit();
result->botInfo->activeUsers = data.vbot_active_users().value_or_empty();
result->botInfo->hasMainApp = data.is_bot_has_main_app();
result->botInfo->canManageTopics
= data.is_bot_forum_can_manage_topics();
} else {
result->setBotInfoVersion(-1);
}
result->setIsContact(data.is_contact()
|| data.is_mutual_contact());
}
+1 -1
View File
@@ -98,7 +98,7 @@ struct BotInfo {
bool canManageEmojiStatus : 1 = false;
bool supportsBusiness : 1 = false;
bool hasMainApp : 1 = false;
bool canManageTopics : 1 = false;
bool userCreatesTopics : 1 = false;
private:
std::unique_ptr<Data::Forum> _forum;
+12 -11
View File
@@ -4719,12 +4719,12 @@ void HistoryWidget::hideSelectorControlsAnimated() {
}
Api::SendAction HistoryWidget::prepareSendAction(
Api::SendOptions options) const {
Api::SendOptions options) {
auto result = Api::SendAction(_history, options);
result.replyTo = replyTo();
if (const auto forum = _history->asForum()) {
if (Data::IsBotCanManageTopics(_history->peer)) {
if (forum->bot() && Data::IsBotUserCreatesTopics(_history->peer)) {
const auto readyRootId = [&]() -> MsgId {
if (const auto id = result.replyTo.messageId) {
if (const auto item = session().data().message(id)) {
@@ -4737,14 +4737,15 @@ Api::SendAction HistoryWidget::prepareSendAction(
result.replyTo.topicRootId = readyRootId;
} else {
if (!_creatingBotTopic) {
const auto &colors = Data::ForumTopicColorIds();
const auto colorId
= colors[base::RandomIndex(colors.size())];
_creatingBotTopic = forum->topicFor(
forum->reserveCreatingId(
tr::lng_bot_new_chat(tr::now),
colorId,
DocumentId()));
_creatingBotTopic = forum->reserveNewBotTopic();
auto draft = _history->forwardDraft(MsgId(0), PeerId());
if (!draft.ids.empty()) {
_history->setForwardDraft(MsgId(0), PeerId(), {});
_history->setForwardDraft(
_creatingBotTopic->rootId(),
PeerId(),
std::move(draft));
}
}
result = Api::SendAction(_creatingBotTopic, options);
result.replyTo.topicRootId = _creatingBotTopic->rootId();
@@ -6302,7 +6303,7 @@ void HistoryWidget::updateFieldPlaceholder() {
}
} else if (const auto user = peer->asUser()) {
if (const auto &info = user->botInfo) {
if (info->forum() && !info->canManageTopics) {
if (info->forum() && !info->userCreatesTopics) {
return tr::lng_bot_off_thread_ph();
}
}
@@ -422,7 +422,7 @@ private:
void messageDataReceived(not_null<PeerData*> peer, MsgId msgId);
[[nodiscard]] Api::SendAction prepareSendAction(
Api::SendOptions options) const;
Api::SendOptions options);
void sendVoice(const VoiceToSend &data);
void send(Api::SendOptions options);
void sendWithModifiers(Qt::KeyboardModifiers modifiers);
@@ -636,7 +636,7 @@ bool AboutView::aboveHistory() const {
return true;
}
const auto info = _history->peer->asUser()->botInfo.get();
return !(info->canManageTopics
return !(info->userCreatesTopics
&& info->startToken.isEmpty()
&& (!_history->isEmpty() || _history->lastMessage()));
}
@@ -696,7 +696,7 @@ bool AboutView::refresh() {
_version = 0;
return false;
} else if (_history->peer->isForum()
&& info->canManageTopics
&& info->userCreatesTopics
&& info->startToken.isEmpty()
&& (!_history->isEmpty() || _history->lastMessage())) {
if (_item) {
@@ -453,7 +453,7 @@ void SubsectionTabs::startFillingSlider(
).append(' ').append(peer->shortName()),
});
}
// } else if (Data::IsBotCanManageTopics(item.thread->peer())) {
// } else if (Data::IsBotUserCreatesTopics(item.thread->peer())) {
// sections.push_back({
// .text = { tr::lng_bot_new_chat(tr::now) },
// });
+24 -21
View File
@@ -654,28 +654,31 @@ bool MainWidget::sendPaths(
bool MainWidget::filesOrForwardDrop(
not_null<Data::Thread*> thread,
not_null<const QMimeData*> data) {
if (const auto forum = thread->asForum()) {
Window::ShowDropMediaBox(
_controller,
Core::ShareMimeMediaData(data),
forum);
if (_hider) {
_hider->startHide();
clearHider(_hider);
not_null<const QMimeData*> data,
bool forumResolved) {
if (!forumResolved) {
if (const auto forum = thread->asForum()) {
Window::ShowDropMediaBox(
_controller,
Core::ShareMimeMediaData(data),
forum);
if (_hider) {
_hider->startHide();
clearHider(_hider);
}
return true;
} else if (const auto history = thread->asHistory()
; history && history->peer->monoforum()) {
Window::ShowDropMediaBox(
_controller,
Core::ShareMimeMediaData(data),
history->peer->monoforum());
if (_hider) {
_hider->startHide();
clearHider(_hider);
}
return true;
}
return true;
} else if (const auto history = thread->asHistory()
; history && history->peer->monoforum()) {
Window::ShowDropMediaBox(
_controller,
Core::ShareMimeMediaData(data),
history->peer->monoforum());
if (_hider) {
_hider->startHide();
clearHider(_hider);
}
return true;
}
if (data->hasFormat(u"application/x-td-forward"_q)) {
auto draft = Data::ForwardDraft{
+2 -1
View File
@@ -161,7 +161,8 @@ public:
const QString &text) const;
bool filesOrForwardDrop(
not_null<Data::Thread*> thread,
not_null<const QMimeData*> data);
not_null<const QMimeData*> data,
bool forumResolved = false);
void sendBotCommand(Bot::SendCommandRequest request);
void hideSingleUseKeyboard(FullMsgId replyToId);
@@ -3278,7 +3278,7 @@ base::weak_qptr<Ui::BoxContent> ShowDropMediaBox(
navigation
](not_null<Data::Thread*> thread) mutable {
const auto content = navigation->parentController()->content();
if (!content->filesOrForwardDrop(thread, data.get())) {
if (!content->filesOrForwardDrop(thread, data.get(), true)) {
return;
} else if (const auto strong = *weak) {
strong->closeBox();
@@ -3318,7 +3318,7 @@ base::weak_qptr<Ui::BoxContent> ShowDropMediaBox(
navigation
](not_null<Data::SavedSublist*> sublist) mutable {
const auto content = navigation->parentController()->content();
if (!content->filesOrForwardDrop(sublist, data.get())) {
if (!content->filesOrForwardDrop(sublist, data.get(), true)) {
return;
} else if (const auto strong = *weak) {
strong->closeBox();