diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index c5f460f435..9645249272 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1391,7 +1391,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_delete_for_me_hint#one" = "This will delete it just for you."; "lng_delete_for_me_hint#other" = "This will delete them just for you."; "lng_delete_for_everyone_check" = "Delete for everyone"; -"lng_delete_for_other_check" = "Delete for {user}"; +"lng_delete_for_other_check" = "Also delete for {user}"; +"lng_delete_for_other_my" = "Unsend my messages"; "lng_box_delete" = "Delete"; "lng_box_leave" = "Leave"; diff --git a/Telegram/SourceFiles/boxes/confirm_box.cpp b/Telegram/SourceFiles/boxes/confirm_box.cpp index 0db838bd19..8b74579741 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.cpp +++ b/Telegram/SourceFiles/boxes/confirm_box.cpp @@ -455,8 +455,7 @@ DeleteMessagesBox::DeleteMessagesBox( QWidget*, not_null item, bool suggestModerateActions) -: _ids(1, item->fullId()) -, _singleItem(true) { +: _ids(1, item->fullId()) { if (suggestModerateActions) { _moderateBan = item->suggestBanReport(); _moderateDeleteAll = item->suggestDeleteAllReport(); @@ -487,44 +486,23 @@ void DeleteMessagesBox::prepare() { _deleteAll.create(this, lang(lng_delete_all_from), false, st::defaultBoxCheckbox); } } else { - text = _singleItem ? lang(lng_selected_delete_sure_this) : lng_selected_delete_sure(lt_count, _ids.size()); - auto canDeleteAllForEveryone = true; - auto now = unixtime(); - auto deleteForUser = (UserData*)nullptr; - auto peer = (PeerData*)nullptr; - auto forEveryoneText = lang(lng_delete_for_everyone_check); - for (const auto fullId : std::as_const(_ids)) { - if (const auto item = App::histItemById(fullId)) { - peer = item->history()->peer; - if (!item->canDeleteForEveryone(now)) { - canDeleteAllForEveryone = false; - break; - } else if (auto user = item->history()->peer->asUser()) { - if (!deleteForUser || deleteForUser == user) { - deleteForUser = user; - forEveryoneText = lng_delete_for_other_check( - lt_user, - user->firstName); - } else { - forEveryoneText = lang(lng_delete_for_everyone_check); - } + text = (_ids.size() == 1) + ? lang(lng_selected_delete_sure_this) + : lng_selected_delete_sure(lt_count, _ids.size()); + if (const auto peer = checkFromSinglePeer()) { + auto count = int(_ids.size()); + if (const auto revoke = revokeText(peer); !revoke.isEmpty()) { + _revoke.create(this, revoke, false, st::defaultBoxCheckbox); + } else if (peer && peer->isChannel()) { + if (peer->isMegagroup()) { + text += qsl("\n\n") + lng_delete_for_everyone_hint(lt_count, count); } - } else { - canDeleteAllForEveryone = false; + } else if (peer->isChat()) { + text += qsl("\n\n") + lng_delete_for_me_chat_hint(lt_count, count); + } else if (!peer->isSelf()) { + text += qsl("\n\n") + lng_delete_for_me_hint(lt_count, count); } } - auto count = int(_ids.size()); - if (canDeleteAllForEveryone) { - _forEveryone.create(this, forEveryoneText, false, st::defaultBoxCheckbox); - } else if (peer && peer->isChannel()) { - if (peer->isMegagroup()) { - text += qsl("\n\n") + lng_delete_for_everyone_hint(lt_count, count); - } - } else if (peer->isChat()) { - text += qsl("\n\n") + lng_delete_for_me_chat_hint(lt_count, count); - } else if (!peer->isSelf()) { - text += qsl("\n\n") + lng_delete_for_me_hint(lt_count, count); - } } _text.create(this, text, Ui::FlatLabel::InitType::Simple, st::boxLabel); @@ -541,12 +519,65 @@ void DeleteMessagesBox::prepare() { if (_deleteAll) { fullHeight += st::boxLittleSkip + _deleteAll->heightNoMargins(); } - } else if (_forEveryone) { - fullHeight += st::boxMediumSkip + _forEveryone->heightNoMargins(); + } else if (_revoke) { + fullHeight += st::boxMediumSkip + _revoke->heightNoMargins(); } setDimensions(st::boxWidth, fullHeight); } +PeerData *DeleteMessagesBox::checkFromSinglePeer() const { + auto result = (PeerData*)nullptr; + for (const auto fullId : std::as_const(_ids)) { + if (const auto item = App::histItemById(fullId)) { + const auto peer = item->history()->peer; + if (!result) { + result = peer; + } else if (result != peer) { + return nullptr; + } + } + } + return result; +} + +QString DeleteMessagesBox::revokeText(not_null peer) const { + const auto items = ranges::view::all( + _ids + ) | ranges::view::transform([](FullMsgId id) { + return App::histItemById(id); + }) | ranges::view::filter([](HistoryItem *item) { + return (item != nullptr); + }) | ranges::to_vector; + if (items.size() != _ids.size()) { + // We don't have information about all messages. + return QString(); + } + + const auto now = unixtime(); + const auto cannotRevoke = [&](HistoryItem *item) { + return !item->canDeleteForEveryone(now); + }; + const auto canRevokeAll = ranges::find_if( + items, + cannotRevoke + ) == end(items); + auto outgoing = items | ranges::view::filter(&HistoryItem::out); + const auto canRevokeAllOutgoing = canRevokeAll ? true : ranges::find_if( + outgoing, + cannotRevoke + ) == end(outgoing); + + return canRevokeAll + ? (peer->isUser() + ? lng_delete_for_other_check( + lt_user, + peer->asUser()->firstName) + : lang(lng_delete_for_everyone_check)) + : (canRevokeAllOutgoing && (begin(outgoing) != end(outgoing))) + ? lang(lng_delete_for_other_my) + : QString(); +} + void DeleteMessagesBox::resizeEvent(QResizeEvent *e) { BoxContent::resizeEvent(e); @@ -562,10 +593,10 @@ void DeleteMessagesBox::resizeEvent(QResizeEvent *e) { if (_deleteAll) { _deleteAll->moveToLeft(st::boxPadding.left(), top); } - } else if (_forEveryone) { - auto availableWidth = width() - 2 * st::boxPadding.left(); - _forEveryone->resizeToNaturalWidth(availableWidth); - _forEveryone->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip); + } else if (_revoke) { + const auto availableWidth = width() - 2 * st::boxPadding.left(); + _revoke->resizeToNaturalWidth(availableWidth); + _revoke->moveToLeft(st::boxPadding.left(), _text->bottomNoMargins() + st::boxMediumSkip); } } @@ -621,7 +652,7 @@ void DeleteMessagesBox::deleteAndClear() { } } - const auto revoke = _forEveryone ? _forEveryone->checked() : false; + const auto revoke = _revoke ? _revoke->checked() : false; for (const auto &[peer, ids] : idsByPeer) { App::main()->deleteMessages(peer, ids, revoke); } diff --git a/Telegram/SourceFiles/boxes/confirm_box.h b/Telegram/SourceFiles/boxes/confirm_box.h index ea977b62eb..122d194c8f 100644 --- a/Telegram/SourceFiles/boxes/confirm_box.h +++ b/Telegram/SourceFiles/boxes/confirm_box.h @@ -164,16 +164,17 @@ protected: private: void deleteAndClear(); + PeerData *checkFromSinglePeer() const; + QString revokeText(not_null peer) const; const MessageIdsList _ids; - const bool _singleItem = false; UserData *_moderateFrom = nullptr; ChannelData *_moderateInChannel = nullptr; bool _moderateBan = false; bool _moderateDeleteAll = false; object_ptr _text = { nullptr }; - object_ptr _forEveryone = { nullptr }; + object_ptr _revoke = { nullptr }; object_ptr _banUser = { nullptr }; object_ptr _reportSpam = { nullptr }; object_ptr _deleteAll = { nullptr }; diff --git a/Telegram/SourceFiles/mainwidget.cpp b/Telegram/SourceFiles/mainwidget.cpp index d2b3629568..b5d0199ac1 100644 --- a/Telegram/SourceFiles/mainwidget.cpp +++ b/Telegram/SourceFiles/mainwidget.cpp @@ -835,13 +835,6 @@ void MainWidget::showSendPathsLayer() { } } -void MainWidget::deleteLayer(FullMsgId itemId) { - if (const auto item = App::histItemById(itemId)) { - const auto suggestModerateActions = true; - Ui::show(Box(item, suggestModerateActions)); - } -} - void MainWidget::cancelUploadLayer(not_null item) { const auto itemId = item->fullId(); session().uploader().pause(itemId); diff --git a/Telegram/SourceFiles/mainwidget.h b/Telegram/SourceFiles/mainwidget.h index 4ad0db8055..70b153edd3 100644 --- a/Telegram/SourceFiles/mainwidget.h +++ b/Telegram/SourceFiles/mainwidget.h @@ -177,7 +177,6 @@ public: void showForwardLayer(MessageIdsList &&items); void showSendPathsLayer(); - void deleteLayer(FullMsgId itemId); void cancelUploadLayer(not_null item); void shareUrlLayer(const QString &url, const QString &text); void inlineSwitchLayer(const QString &botAndQuery); diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index 961476add1..3a947e4a4b 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -18,6 +18,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "ui/widgets/buttons.h" #include "ui/image/image.h" #include "ui/text_options.h" +#include "boxes/confirm_box.h" #include "media/audio/media_audio.h" #include "media/view/media_view_playback_controls.h" #include "media/view/media_view_group_thumbs.h" @@ -1227,8 +1228,9 @@ void OverlayWidget::onDelete() { if (deletingPeerPhoto()) { App::main()->deletePhotoLayer(_photo); - } else { - App::main()->deleteLayer(_msgid); + } else if (const auto item = App::histItemById(_msgid)) { + const auto suggestModerateActions = true; + Ui::show(Box(item, suggestModerateActions)); } }