diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 9c67ebcfbc..bfd9318571 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -1085,6 +1085,8 @@ PRIVATE ui/chat/attach/attach_item_single_file_preview.h ui/chat/attach/attach_item_single_media_preview.cpp ui/chat/attach/attach_item_single_media_preview.h + ui/chat/choose_send_as.cpp + ui/chat/choose_send_as.h ui/chat/choose_theme_controller.cpp ui/chat/choose_theme_controller.h ui/effects/fireworks_animation.cpp diff --git a/Telegram/SourceFiles/api/api_common.h b/Telegram/SourceFiles/api/api_common.h index 112727cc55..6f5b15b35f 100644 --- a/Telegram/SourceFiles/api/api_common.h +++ b/Telegram/SourceFiles/api/api_common.h @@ -12,6 +12,7 @@ class History; namespace Api { struct SendOptions { + PeerData *sendAs = nullptr; TimeId scheduled = 0; bool silent = false; bool handleSupportSwitch = false; @@ -25,7 +26,11 @@ enum class SendType { }; struct SendAction { - explicit SendAction(not_null history) : history(history) { + explicit SendAction( + not_null history, + SendOptions options = SendOptions()) + : history(history) + , options(options) { } not_null history; @@ -37,7 +42,7 @@ struct SendAction { }; struct MessageToSend { - explicit MessageToSend(not_null history) : action(history) { + explicit MessageToSend(SendAction action) : action(action) { } SendAction action; diff --git a/Telegram/SourceFiles/api/api_polls.cpp b/Telegram/SourceFiles/api/api_polls.cpp index 65d00b58f5..80c3c55ae2 100644 --- a/Telegram/SourceFiles/api/api_polls.cpp +++ b/Telegram/SourceFiles/api/api_polls.cpp @@ -60,6 +60,10 @@ void Polls::create( if (action.options.scheduled) { sendFlags |= MTPmessages_SendMedia::Flag::f_schedule_date; } + const auto sendAs = action.options.sendAs; + if (sendAs) { + sendFlags |= MTPmessages_SendMedia::Flag::f_send_as; + } auto &histories = history->owner().histories(); const auto requestType = Data::Histories::RequestType::Send; histories.sendRequest(history, requestType, [=](Fn finish) { @@ -74,7 +78,7 @@ void Polls::create( MTPReplyMarkup(), MTPVector(), MTP_int(action.options.scheduled), - MTPInputPeer() // #TODO send_as + (sendAs ? sendAs->input : MTP_inputPeerEmpty()) )).done([=]( const MTPUpdates &result, const MTP::Response &response) mutable { diff --git a/Telegram/SourceFiles/api/api_sending.cpp b/Telegram/SourceFiles/api/api_sending.cpp index 4afdc695a4..bb7973423c 100644 --- a/Telegram/SourceFiles/api/api_sending.cpp +++ b/Telegram/SourceFiles/api/api_sending.cpp @@ -90,8 +90,18 @@ void SendExistingMedia( if (silentPost) { sendFlags |= MTPmessages_SendMedia::Flag::f_silent; } - auto messageFromId = anonymousPost ? 0 : session->userPeerId(); - auto messagePostAuthor = peer->isBroadcast() ? session->user()->name : QString(); + const auto sendAs = message.action.options.sendAs; + const auto messageFromId = sendAs + ? sendAs->id + : anonymousPost + ? 0 + : session->userPeerId(); + if (sendAs) { + sendFlags |= MTPmessages_SendMedia::Flag::f_send_as; + } + const auto messagePostAuthor = peer->isBroadcast() + ? session->user()->name + : QString(); auto caption = TextWithEntities{ message.textWithTags.text, @@ -143,7 +153,7 @@ void SendExistingMedia( MTPReplyMarkup(), sentEntities, MTP_int(message.action.options.scheduled), - MTPInputPeer() // #TODO send_as + (sendAs ? sendAs->input : MTP_inputPeerEmpty()) )).done([=](const MTPUpdates &result) { api->applyUpdates(result, randomId); finish(); @@ -263,8 +273,18 @@ bool SendDice(MessageToSend &message) { if (silentPost) { sendFlags |= MTPmessages_SendMedia::Flag::f_silent; } - auto messageFromId = anonymousPost ? 0 : session->userPeerId(); - auto messagePostAuthor = peer->isBroadcast() ? session->user()->name : QString(); + const auto sendAs = message.action.options.sendAs; + const auto messageFromId = sendAs + ? sendAs->id + : anonymousPost + ? 0 + : session->userPeerId(); + if (sendAs) { + sendFlags |= MTPmessages_SendMedia::Flag::f_send_as; + } + const auto messagePostAuthor = peer->isBroadcast() + ? session->user()->name + : QString(); const auto replyTo = message.action.replyTo; if (message.action.options.scheduled) { @@ -299,7 +319,7 @@ bool SendDice(MessageToSend &message) { MTPReplyMarkup(), MTP_vector(), MTP_int(message.action.options.scheduled), - MTPInputPeer() // #TODO send_as + (sendAs ? sendAs->input : MTP_inputPeerEmpty()) )).done([=](const MTPUpdates &result) { api->applyUpdates(result, randomId); finish(); @@ -352,8 +372,7 @@ void SendConfirmedFile( const auto history = session->data().history(file->to.peer); const auto peer = history->peer; - auto action = SendAction(history); - action.options = file->to.options; + auto action = SendAction(history, file->to.options); action.clearDraft = false; action.replyTo = file->to.replyTo; action.generateLocal = true; @@ -392,7 +411,12 @@ void SendConfirmedFile( } } - const auto messageFromId = anonymousPost ? 0 : session->userPeerId(); + const auto messageFromId = + file->to.options.sendAs + ? file->to.options.sendAs->id + : anonymousPost + ? PeerId() + : session->userPeerId(); const auto messagePostAuthor = peer->isBroadcast() ? session->user()->name : QString(); diff --git a/Telegram/SourceFiles/apiwrap.cpp b/Telegram/SourceFiles/apiwrap.cpp index b8b6bfca91..750c522aa0 100644 --- a/Telegram/SourceFiles/apiwrap.cpp +++ b/Telegram/SourceFiles/apiwrap.cpp @@ -3676,6 +3676,7 @@ void ApiWrap::forwardMessages( } const auto anonymousPost = peer->amAnonymous(); const auto silentPost = ShouldSendSilent(peer, action.options); + const auto sendAs = action.options.sendAs; auto flags = MessageFlags(); auto sendFlags = MTPmessages_ForwardMessages::Flags(0); @@ -3693,6 +3694,9 @@ void ApiWrap::forwardMessages( if (draft.options == Data::ForwardOptions::NoNamesAndCaptions) { sendFlags |= MTPmessages_ForwardMessages::Flag::f_drop_media_captions; } + if (sendAs) { + sendFlags |= MTPmessages_ForwardMessages::Flag::f_send_as; + } auto forwardFrom = draft.items.front()->history()->peer; auto ids = QVector(); @@ -3713,7 +3717,7 @@ void ApiWrap::forwardMessages( MTP_vector(randomIds), peer->input, MTP_int(action.options.scheduled), - MTPInputPeer() // #TODO send_as + (sendAs ? sendAs->input : MTP_inputPeerEmpty()) )).done([=](const MTPUpdates &result) { applyUpdates(result); if (shared && !--shared->requestsLeft) { @@ -3749,7 +3753,9 @@ void ApiWrap::forwardMessages( peerToChannel(peer->id), _session->data().nextLocalMessageId()); const auto self = _session->user(); - const auto messageFromId = anonymousPost + const auto messageFromId = sendAs + ? sendAs->id + : anonymousPost ? PeerId(0) : self->id; const auto messagePostAuthor = peer->isBroadcast() @@ -3830,7 +3836,11 @@ void ApiWrap::sendSharedContact( if (action.options.scheduled) { flags |= MessageFlag::IsOrWasScheduled; } - const auto messageFromId = anonymousPost ? 0 : _session->userPeerId(); + const auto messageFromId = action.options.sendAs + ? action.options.sendAs->id + : anonymousPost + ? PeerId() + : _session->userPeerId(); const auto messagePostAuthor = peer->isBroadcast() ? _session->user()->name : QString(); @@ -3910,9 +3920,8 @@ void ApiWrap::sendFiles( const SendAction &action) { const auto haveCaption = !caption.text.isEmpty(); if (haveCaption && !list.canAddCaption(album != nullptr)) { - auto message = MessageToSend(action.history); + auto message = MessageToSend(action); message.textWithTags = base::take(caption); - message.action = action; message.action.clearDraft = false; sendMessage(std::move(message)); } @@ -4086,8 +4095,16 @@ void ApiWrap::sendMessage(MessageToSend &&message) { history->clearCloudDraft(); history->startSavingCloudDraft(); } - auto messageFromId = anonymousPost ? 0 : _session->userPeerId(); - auto messagePostAuthor = peer->isBroadcast() + const auto sendAs = action.options.sendAs; + const auto messageFromId = sendAs + ? sendAs->id + : anonymousPost + ? PeerId() + : _session->userPeerId(); + if (sendAs) { + sendFlags |= MTPmessages_SendMessage::Flag::f_send_as; + } + const auto messagePostAuthor = peer->isBroadcast() ? _session->user()->name : QString(); if (action.options.scheduled) { @@ -4116,7 +4133,7 @@ void ApiWrap::sendMessage(MessageToSend &&message) { MTPReplyMarkup(), sentEntities, MTP_int(action.options.scheduled), - MTPInputPeer() // #TODO send_as + (sendAs ? sendAs->input : MTP_inputPeerEmpty()) )).done([=]( const MTPUpdates &result, const MTP::Response &response) { @@ -4160,7 +4177,8 @@ void ApiWrap::sendBotStart(not_null bot, PeerData *chat) { auto &info = bot->botInfo; auto &token = chat ? info->startGroupToken : info->startToken; if (token.isEmpty()) { - auto message = ApiWrap::MessageToSend(_session->data().history(bot)); + auto message = MessageToSend( + Api::SendAction(_session->data().history(bot))); message.textWithTags = { qsl("/start"), TextWithTags::Tags() }; sendMessage(std::move(message)); return; @@ -4213,7 +4231,14 @@ void ApiWrap::sendInlineResult( sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_schedule_date; } - const auto messageFromId = anonymousPost ? 0 : _session->userPeerId(); + const auto sendAs = action.options.sendAs; + const auto messageFromId = sendAs + ? sendAs->id + : anonymousPost ? PeerId() + : _session->userPeerId(); + if (sendAs) { + sendFlags |= MTPmessages_SendInlineBotResult::Flag::f_send_as; + } const auto messagePostAuthor = peer->isBroadcast() ? _session->user()->name : QString(); @@ -4244,7 +4269,7 @@ void ApiWrap::sendInlineResult( MTP_long(data->getQueryId()), MTP_string(data->getId()), MTP_int(action.options.scheduled), - MTPInputPeer() // #TODO send_as + (sendAs ? sendAs->input : MTP_inputPeerEmpty()) )).done([=]( const MTPUpdates &result, const MTP::Response &response) { @@ -4381,6 +4406,9 @@ void ApiWrap::sendMediaWithRandomId( : MTPmessages_SendMedia::Flag(0)) | (options.scheduled ? MTPmessages_SendMedia::Flag::f_schedule_date + : MTPmessages_SendMedia::Flag(0)) + | (options.sendAs + ? MTPmessages_SendMedia::Flag::f_send_as : MTPmessages_SendMedia::Flag(0)); auto &histories = history->owner().histories(); @@ -4398,7 +4426,7 @@ void ApiWrap::sendMediaWithRandomId( MTPReplyMarkup(), sentEntities, MTP_int(options.scheduled), - MTPInputPeer() // #TODO send_as + (options.sendAs ? options.sendAs->input : MTP_inputPeerEmpty()) )).done([=](const MTPUpdates &result) { applyUpdates(result); finish(); @@ -4481,6 +4509,7 @@ void ApiWrap::sendAlbumIfReady(not_null album) { } const auto history = sample->history(); const auto replyTo = sample->replyToId(); + const auto sendAs = album->options.sendAs; const auto flags = MTPmessages_SendMultiMedia::Flags(0) | (replyTo ? MTPmessages_SendMultiMedia::Flag::f_reply_to_msg_id @@ -4490,6 +4519,9 @@ void ApiWrap::sendAlbumIfReady(not_null album) { : MTPmessages_SendMultiMedia::Flag(0)) | (album->options.scheduled ? MTPmessages_SendMultiMedia::Flag::f_schedule_date + : MTPmessages_SendMultiMedia::Flag(0)) + | (sendAs + ? MTPmessages_SendMultiMedia::Flag::f_send_as : MTPmessages_SendMultiMedia::Flag(0)); auto &histories = history->owner().histories(); const auto requestType = Data::Histories::RequestType::Send; @@ -4501,7 +4533,7 @@ void ApiWrap::sendAlbumIfReady(not_null album) { MTP_int(replyTo), MTP_vector(medias), MTP_int(album->options.scheduled), - MTPInputPeer() // #TODO send_as + (sendAs ? sendAs->input : MTP_inputPeerEmpty()) )).done([=](const MTPUpdates &result) { _sendingAlbums.remove(groupId); applyUpdates(result); diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index 09c9ccdd0e..e5a438b9df 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -670,8 +670,7 @@ void EditCaptionBox::save() { options.scheduled = item->isScheduled() ? item->date() : 0; if (!_preparedList.files.empty()) { - auto action = Api::SendAction(item->history()); - action.options = options; + auto action = Api::SendAction(item->history(), options); action.replaceMediaOf = item->fullId().msg; Storage::ApplyModifications(_preparedList); diff --git a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp index 455c885437..39aacbd067 100644 --- a/Telegram/SourceFiles/boxes/peer_list_controllers.cpp +++ b/Telegram/SourceFiles/boxes/peer_list_controllers.cpp @@ -51,7 +51,7 @@ void ShareBotGame(not_null bot, not_null chat) { MTPReplyMarkup(), MTPVector(), MTP_int(0), // schedule_date - MTPInputPeer() // #TODO send_as + MTPInputPeer() // send_as )).done([=](const MTPUpdates &result) { api->applyUpdates(result, randomId); finish(); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp index 9c4c747207..61b6af1008 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_invite_link.cpp @@ -1144,9 +1144,8 @@ void ShareInviteLinkBox(not_null peer, const QString &link) { auto &api = peer->session().api(); for (const auto peer : result) { const auto history = owner->history(peer); - auto message = ApiWrap::MessageToSend(history); + auto message = Api::MessageToSend(Api::SendAction(history, options)); message.textWithTags = comment; - message.action.options = options; message.action.clearDraft = false; api.sendMessage(std::move(message)); } diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index d59f9559d8..b85eb88d41 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -1026,9 +1026,7 @@ void SendFilesBox::send( } void SendFilesBox::sendSilent() { - auto options = Api::SendOptions(); - options.silent = true; - send(options); + send({ .silent = true }); } void SendFilesBox::sendScheduled() { diff --git a/Telegram/SourceFiles/boxes/share_box.cpp b/Telegram/SourceFiles/boxes/share_box.cpp index 138a2575d0..802a943c0f 100644 --- a/Telegram/SourceFiles/boxes/share_box.cpp +++ b/Telegram/SourceFiles/boxes/share_box.cpp @@ -496,9 +496,7 @@ void ShareBox::submit(Api::SendOptions options) { } void ShareBox::submitSilent() { - auto options = Api::SendOptions(); - options.silent = true; - submit(options); + submit({ .silent = true }); } void ShareBox::submitScheduled() { diff --git a/Telegram/SourceFiles/boxes/sticker_set_box.cpp b/Telegram/SourceFiles/boxes/sticker_set_box.cpp index 003257f910..7aacd11fd6 100644 --- a/Telegram/SourceFiles/boxes/sticker_set_box.cpp +++ b/Telegram/SourceFiles/boxes/sticker_set_box.cpp @@ -625,7 +625,7 @@ void StickerSetBox::Inner::mouseReleaseEvent(QMouseEvent *e) { if (index < 0 || index >= _pack.size() || isMasksSet()) { return; } - send(_pack[index], Api::SendOptions()); + send(_pack[index], {}); } void StickerSetBox::Inner::send( diff --git a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp index ce9a89669b..a7a011b6c7 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp @@ -175,9 +175,9 @@ object_ptr ShareInviteLinkBox( auto &api = peer->session().api(); for (const auto peer : result) { const auto history = owner->history(peer); - auto message = ApiWrap::MessageToSend(history); + auto message = Api::MessageToSend( + Api::SendAction(history, options)); message.textWithTags = comment; - message.action.options = options; message.action.clearDraft = false; api.sendMessage(std::move(message)); } diff --git a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp index 45b55a9f4f..48ac4888a7 100644 --- a/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp +++ b/Telegram/SourceFiles/chat_helpers/field_autocomplete.cpp @@ -66,7 +66,7 @@ public: bool chooseAtIndex( FieldAutocomplete::ChooseMethod method, int index, - Api::SendOptions options = Api::SendOptions()) const; + Api::SendOptions options = {}) const; void setRecentInlineBotsInRows(int32 bots); void setSendMenuType(Fn &&callback); diff --git a/Telegram/SourceFiles/data/data_media_types.cpp b/Telegram/SourceFiles/data/data_media_types.cpp index 91eaba4b1f..ae4d3c25ab 100644 --- a/Telegram/SourceFiles/data/data_media_types.cpp +++ b/Telegram/SourceFiles/data/data_media_types.cpp @@ -1683,7 +1683,8 @@ ClickHandlerPtr MediaDice::MakeHandler( const ClickHandlerPtr &handler, Qt::MouseButton button) { if (button == Qt::LeftButton && !ShownToast.empty()) { - auto message = Api::MessageToSend(history); + auto message = Api::MessageToSend( + Api::SendAction(history)); message.action.clearDraft = false; message.textWithTags.text = emoji; diff --git a/Telegram/SourceFiles/data/data_scheduled_messages.cpp b/Telegram/SourceFiles/data/data_scheduled_messages.cpp index 374b4cc306..f90a0da49a 100644 --- a/Telegram/SourceFiles/data/data_scheduled_messages.cpp +++ b/Telegram/SourceFiles/data/data_scheduled_messages.cpp @@ -195,7 +195,7 @@ void ScheduledMessages::sendNowSimpleMessage( MTP_message( MTP_flags(flags), update.vid(), - peerToMTP(_session->userPeerId()), + peerToMTP(local->from()->id), peerToMTP(history->peer->id), MTPMessageFwdHeader(), MTPlong(), // via_bot_id diff --git a/Telegram/SourceFiles/history/history_message.cpp b/Telegram/SourceFiles/history/history_message.cpp index ddde57fce6..2fccf51b71 100644 --- a/Telegram/SourceFiles/history/history_message.cpp +++ b/Telegram/SourceFiles/history/history_message.cpp @@ -293,9 +293,9 @@ void FastShareMessage(not_null item) { for (const auto peer : result) { const auto history = owner->history(peer); if (!comment.text.isEmpty()) { - auto message = ApiWrap::MessageToSend(history); + auto message = Api::MessageToSend( + Api::SendAction(history, options)); message.textWithTags = comment; - message.action.options = options; message.action.clearDraft = false; api.sendMessage(std::move(message)); } @@ -312,7 +312,7 @@ void FastShareMessage(not_null item) { MTP_vector(generateRandom()), peer->input, MTP_int(options.scheduled), - MTPInputPeer() // #TODO send_as + MTP_inputPeerEmpty() // send_as )).done([=](const MTPUpdates &updates, mtpRequestId requestId) { history->session().api().applyUpdates(updates); data->requests.remove(requestId); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index 9bcaa4d54b..9caa842c29 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -890,9 +890,7 @@ void HistoryWidget::initVoiceRecordBar() { return; } - auto action = Api::SendAction(_history); - action.replyTo = replyToId(); - action.options = data.options; + auto action = prepareSendAction(data.options); session().api().sendVoiceMessage( data.bytes, data.waveform, @@ -1025,7 +1023,9 @@ void HistoryWidget::supportShareContact(Support::Contact contact) { if (!history) { return; } - auto options = Api::SendOptions(); + auto options = Api::SendOptions{ + .sendAs = prepareSendAction({}).options.sendAs, + }; auto action = Api::SendAction(history); send(options); options.handleSupportSwitch = Support::HandleSwitch(modifiers); @@ -1298,7 +1298,7 @@ void HistoryWidget::insertHashtagOrBotCommand( // Send bot command at once, if it was not inserted by pressing Tab. if (str.at(0) == '/' && method != FieldAutocomplete::ChooseMethod::ByTab) { sendBotCommand({ _peer, str, FullMsgId(), replyToId() }); - session().api().finishForwarding(Api::SendAction(_history)); + session().api().finishForwarding(prepareSendAction({})); setFieldText(_field->getTextWithTagsPart(_field->textCursor().position())); } else { _field->insertTag(str); @@ -3405,10 +3405,12 @@ void HistoryWidget::saveEditMsg() { })(); }; + auto options = Api::SendOptions(); + options.removeWebPageId = (webPageId == CancelledWebPageId); _saveEditMsgRequestId = Api::EditTextMessage( item, sending, - { .removeWebPageId = (webPageId == CancelledWebPageId) }, + options, done, fail); } @@ -3448,6 +3450,17 @@ void HistoryWidget::hideSelectorControlsAnimated() { } } +Api::SendAction HistoryWidget::prepareSendAction( + Api::SendOptions options) const { + auto result = Api::SendAction(_history, options); + result.replyTo = replyToId(); + result.options.sendAs = _sendAs + ? _history->session().sendAsPeers().resolveChosen( + _history->peer).get() + : nullptr; + return result; +} + void HistoryWidget::send(Api::SendOptions options) { if (!_history) { return; @@ -3469,10 +3482,8 @@ void HistoryWidget::send(Api::SendOptions options) { ? _previewData->id : WebPageId(0)); - auto message = ApiWrap::MessageToSend(_history); + auto message = ApiWrap::MessageToSend(prepareSendAction(options)); message.textWithTags = _field->getTextWithAppliedMarkdown(); - message.action.options = options; - message.action.replyTo = replyToId(); message.webPageId = webPageId; if (_canSendMessages) { @@ -3512,15 +3523,11 @@ void HistoryWidget::send(Api::SendOptions options) { } void HistoryWidget::sendWithModifiers(Qt::KeyboardModifiers modifiers) { - auto options = Api::SendOptions(); - options.handleSupportSwitch = Support::HandleSwitch(modifiers); - send(options); + send({ .handleSupportSwitch = Support::HandleSwitch(modifiers) }); } void HistoryWidget::sendSilent() { - auto options = Api::SendOptions(); - options.silent = true; - send(options); + send({ .silent = true }); } void HistoryWidget::sendScheduled() { @@ -3894,7 +3901,7 @@ void HistoryWidget::sendBotCommand(const Bot::SendCommandRequest &request) { ? request.command : Bot::WrapCommandInChat(_peer, request.command, request.context); - auto message = ApiWrap::MessageToSend(_history); + auto message = Api::MessageToSend(prepareSendAction({})); message.textWithTags = { toSend, TextWithTags::Tags() }; message.action.replyTo = request.replyTo ? ((!_peer->isUser()/* && (botStatus == 0 || botStatus == 2)*/) @@ -4675,15 +4682,12 @@ void HistoryWidget::sendingFilesConfirmed( const auto type = way.sendImagesAsPhotos() ? SendMediaType::Photo : SendMediaType::File; - auto action = Api::SendAction(_history); - action.replyTo = replyToId(); - action.options = options; + auto action = prepareSendAction(options); action.clearDraft = false; if ((groups.size() != 1 || !groups.front().sentWithCaption()) && !caption.text.isEmpty()) { - auto message = Api::MessageToSend(_history); + auto message = Api::MessageToSend(action); message.textWithTags = base::take(caption); - message.action = action; session().api().sendMessage(std::move(message)); } for (auto &group : groups) { @@ -4773,9 +4777,7 @@ void HistoryWidget::uploadFile( SendMediaType type) { if (!canWriteMessage()) return; - auto action = Api::SendAction(_history); - action.replyTo = replyToId(); - session().api().sendFile(fileContent, type, action); + session().api().sendFile(fileContent, type, prepareSendAction({})); } void HistoryWidget::handleHistoryChange(not_null history) { @@ -5791,9 +5793,7 @@ void HistoryWidget::sendInlineResult(InlineBots::ResultSelected result) { return; } - auto action = Api::SendAction(_history); - action.replyTo = replyToId(); - action.options = std::move(result.options); + auto action = prepareSendAction(result.options); action.generateLocal = true; session().api().sendInlineResult(result.bot, result.result, action); @@ -6175,10 +6175,9 @@ bool HistoryWidget::sendExistingDocument( return false; } - auto message = Api::MessageToSend(_history); - message.action.options = std::move(options); - message.action.replyTo = replyToId(); - Api::SendExistingDocument(std::move(message), document); + Api::SendExistingDocument( + Api::MessageToSend(prepareSendAction(options)), + document); if (_fieldAutocomplete->stickersShown()) { clearFieldText(); @@ -6211,10 +6210,9 @@ bool HistoryWidget::sendExistingPhoto( return false; } - auto message = Api::MessageToSend(_history); - message.action.replyTo = replyToId(); - message.action.options = std::move(options); - Api::SendExistingPhoto(std::move(message), photo); + Api::SendExistingPhoto( + Api::MessageToSend(prepareSendAction(options)), + photo); hideSelectorControlsAnimated(); diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 3406eda253..30399fe9d6 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -42,6 +42,7 @@ enum class Type; namespace Api { struct SendOptions; +struct SendAction; } // namespace Api namespace InlineBots { @@ -372,6 +373,8 @@ private: void requestMessageData(MsgId msgId); void messageDataReceived(ChannelData *channel, MsgId msgId); + [[nodiscard]] Api::SendAction prepareSendAction( + Api::SendOptions options) const; void send(Api::SendOptions options); void sendWithModifiers(Qt::KeyboardModifiers modifiers); void sendSilent(); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index f6b7600ae6..c86ba7b1ff 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -570,12 +570,10 @@ MessageToEdit FieldHeader::queryToEdit() { return {}; } return { - item->fullId(), - { - item->isScheduled() ? item->date() : 0, - false, - false, - !hasPreview(), + .fullId = item->fullId(), + .options = { + .scheduled = item->isScheduled() ? item->date() : 0, + .removeWebPageId = !hasPreview(), }, }; } diff --git a/Telegram/SourceFiles/history/view/history_view_message.cpp b/Telegram/SourceFiles/history/view/history_view_message.cpp index 3645541773..d6ebd1d6c2 100644 --- a/Telegram/SourceFiles/history/view/history_view_message.cpp +++ b/Telegram/SourceFiles/history/view/history_view_message.cpp @@ -2062,7 +2062,7 @@ bool Message::hasFromName() const { case Context::Replies: { const auto item = message(); const auto peer = item->history()->peer; - if (hasOutLayout() && !item->from()->isMegagroup()) { + if (hasOutLayout() && !item->from()->isChannel()) { return false; } else if (!peer->isUser()) { return true; diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp index 7071d6f247..02474893a8 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.cpp @@ -735,19 +735,15 @@ void RepliesWidget::sendingFilesConfirmed( std::move(list), way, _history->peer->slowmodeApplied()); - const auto replyTo = replyToId(); const auto type = way.sendImagesAsPhotos() ? SendMediaType::Photo : SendMediaType::File; - auto action = Api::SendAction(_history); - action.replyTo = replyTo ? replyTo : _rootId; - action.options = options; + auto action = prepareSendAction(options); action.clearDraft = false; if ((groups.size() != 1 || !groups.front().sentWithCaption()) && !caption.text.isEmpty()) { - auto message = Api::MessageToSend(_history); + auto message = Api::MessageToSend(action); message.textWithTags = base::take(caption); - message.action = action; session().api().sendMessage(std::move(message)); } for (auto &group : groups) { @@ -761,7 +757,7 @@ void RepliesWidget::sendingFilesConfirmed( album, action); } - if (_composeControls->replyingToMessage().msg == replyTo) { + if (_composeControls->replyingToMessage().msg == action.replyTo) { _composeControls->cancelReplyMessage(); refreshTopBarActiveChat(); } @@ -869,9 +865,7 @@ void RepliesWidget::uploadFile( const QByteArray &fileContent, SendMediaType type) { // #TODO replies schedule - auto action = Api::SendAction(_history); - action.replyTo = replyToId(); - session().api().sendFile(fileContent, type, action); + session().api().sendFile(fileContent, type, prepareSendAction({})); } bool RepliesWidget::showSendingFilesError( @@ -918,11 +912,18 @@ bool RepliesWidget::showSendingFilesError( return true; } +Api::SendAction RepliesWidget::prepareSendAction( + Api::SendOptions options) const { + auto result = Api::SendAction(_history, options); + result.replyTo = replyToId(); + return result; +} + void RepliesWidget::send() { if (_composeControls->getTextWithAppliedMarkdown().text.isEmpty()) { return; } - send(Api::SendOptions()); + send({}); // #TODO replies schedule //const auto callback = [=](Api::SendOptions options) { send(options); }; //Ui::show( @@ -931,9 +932,7 @@ void RepliesWidget::send() { } void RepliesWidget::sendVoice(ComposeControls::VoiceToSend &&data) { - auto action = Api::SendAction(_history); - action.replyTo = replyToId(); - action.options = data.options; + auto action = prepareSendAction(data.options); session().api().sendVoiceMessage( data.bytes, data.waveform, @@ -952,10 +951,8 @@ void RepliesWidget::send(Api::SendOptions options) { const auto webPageId = _composeControls->webPageId(); - auto message = ApiWrap::MessageToSend(_history); + auto message = ApiWrap::MessageToSend(prepareSendAction(options)); message.textWithTags = _composeControls->getTextWithAppliedMarkdown(); - message.action.options = options; - message.action.replyTo = replyToId(); message.webPageId = webPageId; //const auto error = GetErrorTextForSending( @@ -1063,7 +1060,7 @@ void RepliesWidget::edit( void RepliesWidget::sendExistingDocument( not_null document) { - sendExistingDocument(document, Api::SendOptions()); + sendExistingDocument(document, {}); // #TODO replies schedule //const auto callback = [=](Api::SendOptions options) { // sendExistingDocument(document, options); @@ -1088,10 +1085,9 @@ bool RepliesWidget::sendExistingDocument( return false; } - auto message = Api::MessageToSend(_history); - message.action.replyTo = replyToId(); - message.action.options = options; - Api::SendExistingDocument(std::move(message), document); + Api::SendExistingDocument( + Api::MessageToSend(prepareSendAction(options)), + document); _composeControls->cancelReplyMessage(); finishSending(); @@ -1099,7 +1095,7 @@ bool RepliesWidget::sendExistingDocument( } void RepliesWidget::sendExistingPhoto(not_null photo) { - sendExistingPhoto(photo, Api::SendOptions()); + sendExistingPhoto(photo, {}); // #TODO replies schedule //const auto callback = [=](Api::SendOptions options) { // sendExistingPhoto(photo, options); @@ -1124,10 +1120,9 @@ bool RepliesWidget::sendExistingPhoto( return false; } - auto message = Api::MessageToSend(_history); - message.action.replyTo = replyToId(); - message.action.options = options; - Api::SendExistingPhoto(std::move(message), photo); + Api::SendExistingPhoto( + Api::MessageToSend(prepareSendAction(options)), + photo); _composeControls->cancelReplyMessage(); finishSending(); @@ -1142,7 +1137,7 @@ void RepliesWidget::sendInlineResult( controller()->show(Box(errorText)); return; } - sendInlineResult(result, bot, Api::SendOptions()); + sendInlineResult(result, bot, {}); //const auto callback = [=](Api::SendOptions options) { // sendInlineResult(result, bot, options); //}; @@ -1155,9 +1150,7 @@ void RepliesWidget::sendInlineResult( not_null result, not_null bot, Api::SendOptions options) { - auto action = Api::SendAction(_history); - action.replyTo = replyToId(); - action.options = options; + auto action = prepareSendAction(options); action.generateLocal = true; session().api().sendInlineResult(bot, result, action); @@ -1912,9 +1905,9 @@ void RepliesWidget::listSendBotCommand( _history->peer, command, context); - auto message = ApiWrap::MessageToSend(_history); + auto message = ApiWrap::MessageToSend( + prepareSendAction({})); message.textWithTags = { text }; - message.action.replyTo = replyToId(); session().api().sendMessage(std::move(message)); finishSending(); } diff --git a/Telegram/SourceFiles/history/view/history_view_replies_section.h b/Telegram/SourceFiles/history/view/history_view_replies_section.h index c7a83473eb..f2700f3641 100644 --- a/Telegram/SourceFiles/history/view/history_view_replies_section.h +++ b/Telegram/SourceFiles/history/view/history_view_replies_section.h @@ -23,6 +23,7 @@ enum class Type; namespace Api { struct SendOptions; +struct SendAction; } // namespace Api namespace Storage { @@ -190,6 +191,8 @@ private: void clearSelected(); void setPinnedVisibility(bool shown); + [[nodiscard]] Api::SendAction prepareSendAction( + Api::SendOptions options) const; void send(); void send(Api::SendOptions options); void sendVoice(Controls::VoiceToSend &&data); diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp index 1cc373f0e5..6230bd041e 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.cpp @@ -429,14 +429,12 @@ void ScheduledWidget::sendingFilesConfirmed( const auto type = way.sendImagesAsPhotos() ? SendMediaType::Photo : SendMediaType::File; - auto action = Api::SendAction(_history); - action.options = options; + auto action = prepareSendAction(options); action.clearDraft = false; if ((groups.size() != 1 || !groups.front().sentWithCaption()) && !caption.text.isEmpty()) { - auto message = Api::MessageToSend(_history); + auto message = Api::MessageToSend(action); message.textWithTags = base::take(caption); - message.action = action; session().api().sendMessage(std::move(message)); } for (auto &group : groups) { @@ -473,10 +471,10 @@ void ScheduledWidget::uploadFile( const QByteArray &fileContent, SendMediaType type) { const auto callback = [=](Api::SendOptions options) { - auto action = Api::SendAction(_history); - //action.replyTo = replyToId(); - action.options = options; - session().api().sendFile(fileContent, type, action); + session().api().sendFile( + fileContent, + type, + prepareSendAction(options)); }; controller()->show( PrepareScheduleBox(this, sendMenuType(), callback), @@ -518,6 +516,12 @@ bool ScheduledWidget::showSendingFilesError( return true; } +Api::SendAction ScheduledWidget::prepareSendAction( + Api::SendOptions options) const { + auto result = Api::SendAction(_history, options); + return result; +} + void ScheduledWidget::send() { if (_composeControls->getTextWithAppliedMarkdown().text.isEmpty()) { return; @@ -531,10 +535,8 @@ void ScheduledWidget::send() { void ScheduledWidget::send(Api::SendOptions options) { const auto webPageId = _composeControls->webPageId(); - auto message = ApiWrap::MessageToSend(_history); + auto message = ApiWrap::MessageToSend(prepareSendAction(options)); message.textWithTags = _composeControls->getTextWithAppliedMarkdown(); - message.action.options = options; - //message.action.replyTo = replyToId(); message.webPageId = webPageId; //const auto error = GetErrorTextForSending( @@ -578,9 +580,11 @@ void ScheduledWidget::sendVoice( VoiceWaveform waveform, int duration, Api::SendOptions options) { - auto action = Api::SendAction(_history); - action.options = options; - session().api().sendVoiceMessage(bytes, waveform, duration, action); + session().api().sendVoiceMessage( + bytes, + waveform, + duration, + prepareSendAction(options)); _composeControls->clearListenState(); } @@ -683,10 +687,9 @@ bool ScheduledWidget::sendExistingDocument( return false; } - auto message = Api::MessageToSend(_history); - //message.action.replyTo = replyToId(); - message.action.options = options; - Api::SendExistingDocument(std::move(message), document); + Api::SendExistingDocument( + Api::MessageToSend(prepareSendAction(options)), + document); _composeControls->hidePanelsAnimated(); _composeControls->focus(); @@ -715,10 +718,9 @@ bool ScheduledWidget::sendExistingPhoto( return false; } - auto message = Api::MessageToSend(_history); - //message.action.replyTo = replyToId(); - message.action.options = options; - Api::SendExistingPhoto(std::move(message), photo); + Api::SendExistingPhoto( + Api::MessageToSend(prepareSendAction(options)), + photo); _composeControls->hidePanelsAnimated(); _composeControls->focus(); @@ -745,9 +747,7 @@ void ScheduledWidget::sendInlineResult( not_null result, not_null bot, Api::SendOptions options) { - auto action = Api::SendAction(_history); - //action.replyTo = replyToId(); - action.options = options; + auto action = prepareSendAction(options); action.generateLocal = true; session().api().sendInlineResult(bot, result, action); @@ -1213,9 +1213,8 @@ void ScheduledWidget::listSendBotCommand( _history->peer, command, context); - auto message = ApiWrap::MessageToSend(_history); + auto message = ApiWrap::MessageToSend(prepareSendAction(options)); message.textWithTags = { text }; - message.action.options = options; session().api().sendMessage(std::move(message)); }; controller()->show( diff --git a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h index 47a805c40d..2352eb0c13 100644 --- a/Telegram/SourceFiles/history/view/history_view_scheduled_section.h +++ b/Telegram/SourceFiles/history/view/history_view_scheduled_section.h @@ -22,6 +22,7 @@ enum class Type; namespace Api { struct SendOptions; +struct SendAction; } // namespace Api namespace Ui { @@ -155,6 +156,8 @@ private: void confirmDeleteSelected(); void clearSelected(); + [[nodiscard]] Api::SendAction prepareSendAction( + Api::SendOptions options) const; void send(); void send(Api::SendOptions options); void sendVoice(QByteArray bytes, VoiceWaveform waveform, int duration); diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index 5de7f7355e..0becb62838 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -1076,7 +1076,7 @@ SendMenu::Type MainWidget::sendMenuType() const { } bool MainWidget::sendExistingDocument(not_null document) { - return sendExistingDocument(document, Api::SendOptions()); + return sendExistingDocument(document, {}); } bool MainWidget::sendExistingDocument( diff --git a/Telegram/SourceFiles/passport/passport_form_controller.cpp b/Telegram/SourceFiles/passport/passport_form_controller.cpp index aa54ed1df8..7680cd0ecc 100644 --- a/Telegram/SourceFiles/passport/passport_form_controller.cpp +++ b/Telegram/SourceFiles/passport/passport_form_controller.cpp @@ -1581,7 +1581,7 @@ void FormController::uploadEncryptedFile( auto prepared = std::make_shared( TaskId(), file.uploadData->fileId, - FileLoadTo(PeerId(0), Api::SendOptions(), MsgId(0), MsgId(0)), + FileLoadTo(PeerId(), Api::SendOptions(), MsgId(), MsgId()), TextWithTags(), std::shared_ptr(nullptr)); prepared->type = SendMediaType::Secure; diff --git a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm index 36be91b02d..8bdbdff6d4 100644 --- a/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm +++ b/Telegram/SourceFiles/platform/mac/touchbar/items/mac_scrubber_item.mm @@ -466,7 +466,8 @@ void AppendEmojiPacks( return true; } Api::SendExistingDocument( - Api::MessageToSend(ActiveChat(_controller).history()), + Api::MessageToSend( + Api::SendAction(ActiveChat(_controller).history())), document); return true; } else if (emoji) { diff --git a/Telegram/SourceFiles/storage/localimageloader.h b/Telegram/SourceFiles/storage/localimageloader.h index e2c44da029..6bb5ba88e1 100644 --- a/Telegram/SourceFiles/storage/localimageloader.h +++ b/Telegram/SourceFiles/storage/localimageloader.h @@ -193,7 +193,7 @@ struct SendingAlbum { struct FileLoadTo { FileLoadTo( - const PeerId &peer, + PeerId peer, Api::SendOptions options, MsgId replyTo, MsgId replaceMediaOf) diff --git a/Telegram/SourceFiles/ui/chat/chat.style b/Telegram/SourceFiles/ui/chat/chat.style index 81b45668bd..d231ba3e2a 100644 --- a/Telegram/SourceFiles/ui/chat/chat.style +++ b/Telegram/SourceFiles/ui/chat/chat.style @@ -931,11 +931,11 @@ SendAsButton { sendAsButton: SendAsButton { width: 44px; height: 46px; - size: 32px; + size: 28px; activeBg: activeButtonBg; activeFg: activeButtonFg; cross: CrossAnimation { - size: 32px; + size: 28px; skip: 10px; stroke: 2px; minScale: 0.3; diff --git a/Telegram/SourceFiles/ui/chat/choose_send_as.cpp b/Telegram/SourceFiles/ui/chat/choose_send_as.cpp index 1a0b9681dd..16ff421193 100644 --- a/Telegram/SourceFiles/ui/chat/choose_send_as.cpp +++ b/Telegram/SourceFiles/ui/chat/choose_send_as.cpp @@ -137,7 +137,11 @@ void ChooseSendAsBox( delegate->setContent(content); controller->setDelegate(delegate); box->addButton(tr::lng_settings_save(), [=] { + const auto weak = MakeWeak(box); done(controller->selected()); + if (weak) { + box->closeBox(); + } }); box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); } diff --git a/Telegram/SourceFiles/window/notifications_manager.cpp b/Telegram/SourceFiles/window/notifications_manager.cpp index 04af477ed1..fcb8876ab1 100644 --- a/Telegram/SourceFiles/window/notifications_manager.cpp +++ b/Telegram/SourceFiles/window/notifications_manager.cpp @@ -706,7 +706,7 @@ void Manager::notificationReplied( } const auto history = session->data().history(id.full.peerId); - auto message = Api::MessageToSend(history); + auto message = Api::MessageToSend(Api::SendAction(history)); message.textWithTags = reply; message.action.replyTo = (id.msgId > 0 && !history->peer->isUser()) ? id.msgId diff --git a/Telegram/SourceFiles/window/window_peer_menu.cpp b/Telegram/SourceFiles/window/window_peer_menu.cpp index fb3faa80c4..2abdd59cf3 100644 --- a/Telegram/SourceFiles/window/window_peer_menu.cpp +++ b/Telegram/SourceFiles/window/window_peer_menu.cpp @@ -821,9 +821,10 @@ void PeerMenuCreatePoll( if (std::exchange(*lock, true)) { return; } - auto action = Api::SendAction(peer->owner().history(peer)); + auto action = Api::SendAction( + peer->owner().history(peer), + result.options); action.clearDraft = false; - action.options = result.options; action.replyTo = replyToId; if (const auto localDraft = action.history->localDraft()) { action.clearDraft = localDraft->textWithTags.text.isEmpty();