From bd1d7f4d96b0e785dd124f6066d04a3e46419d98 Mon Sep 17 00:00:00 2001 From: John Preston Date: Tue, 13 Dec 2022 17:31:54 +0400 Subject: [PATCH] Allow apply spoiler when editing to another media. --- .../SourceFiles/boxes/edit_caption_box.cpp | 41 +++++++++++++++---- Telegram/SourceFiles/boxes/edit_caption_box.h | 5 ++- Telegram/SourceFiles/boxes/send_files_box.cpp | 13 ++++-- .../attach_abstract_single_media_preview.cpp | 16 +++++--- .../attach_abstract_single_media_preview.h | 3 ++ .../ui/chat/attach/attach_album_preview.cpp | 4 ++ .../ui/chat/attach/attach_album_preview.h | 1 + .../attach_item_single_media_preview.cpp | 4 ++ .../attach/attach_item_single_media_preview.h | 1 + .../attach/attach_single_media_preview.cpp | 4 ++ .../chat/attach/attach_single_media_preview.h | 1 + 11 files changed, 77 insertions(+), 16 deletions(-) diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.cpp b/Telegram/SourceFiles/boxes/edit_caption_box.cpp index bbc185802..f712506cc 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.cpp +++ b/Telegram/SourceFiles/boxes/edit_caption_box.cpp @@ -175,12 +175,15 @@ void EditCaptionBox::rebuildPreview() { Window::GifPauseReason::Layer); }; + applyChanges(); + + _previewHasSpoiler = nullptr; if (_preparedList.files.empty()) { const auto media = _historyItem->media(); const auto photo = media->photo(); const auto document = media->document(); + _isPhoto = (photo != nullptr); if (photo || document->isVideoFile() || document->isAnimation()) { - _isPhoto = (photo != nullptr); const auto media = Ui::CreateChild( this, gifPaused, @@ -189,7 +192,6 @@ void EditCaptionBox::rebuildPreview() { _photoMedia = media->sharedPhotoMedia(); _content.reset(media); } else { - _isPhoto = false; _content.reset(Ui::CreateChild( this, _historyItem, @@ -203,11 +205,12 @@ void EditCaptionBox::rebuildPreview() { gifPaused, file, Ui::AttachControls::Type::EditOnly); - if (media) { - _isPhoto = media->isPhoto(); + _isPhoto = (media && media->isPhoto()); + const auto withCheckbox = _isPhoto && CanBeCompressed(_albumType); + if (media && (!withCheckbox || !_asFile)) { + _previewHasSpoiler = [media] { return media->hasSpoiler(); }; _content.reset(media); } else { - _isPhoto = false; _content.reset(Ui::CreateChild( this, file, @@ -299,7 +302,7 @@ void EditCaptionBox::setupControls() { {} ) | rpl::map([=] { return _controller->session().settings().photoEditorHintShown() - ? _isPhoto + ? (_isPhoto && !_asFile) : false; }); @@ -329,7 +332,9 @@ void EditCaptionBox::setupControls() { anim::type::instant )->entity()->checkedChanges( ) | rpl::start_with_next([&](bool checked) { + applyChanges(); _asFile = !checked; + rebuildPreview(); }, _controls->lifetime()); _controls->resizeToWidth(st::sendMediaPreviewSize); @@ -430,6 +435,8 @@ void EditCaptionBox::setupPhotoEditorEventHandler() { return; } auto copy = large->original(); + const auto wasSpoiler = hasSpoiler(); + _preparedList = Storage::PrepareMediaFromImage( std::move(copy), QByteArray(), @@ -437,6 +444,7 @@ void EditCaptionBox::setupPhotoEditorEventHandler() { using ImageInfo = Ui::PreparedFileInformation::Image; auto &file = _preparedList.files.front(); + file.spoiler = wasSpoiler; const auto image = std::get_if( &file.information->media); @@ -581,11 +589,20 @@ bool EditCaptionBox::setPreparedList(Ui::PreparedList &&list) { tr::lng_edit_media_album_error(tr::now)); return false; } + const auto wasSpoiler = hasSpoiler(); _preparedList = std::move(list); + _preparedList.files.front().spoiler = wasSpoiler; rebuildPreview(); return true; } +bool EditCaptionBox::hasSpoiler() const { + return _preparedList.files.empty() + ? (_historyItem->media() + && _historyItem->media()->hasSpoiler()) + : _preparedList.files.front().spoiler; +} + void EditCaptionBox::captionResized() { updateBoxSize(); resizeEvent(0); @@ -690,6 +707,12 @@ bool EditCaptionBox::validateLength(const QString &text) const { return false; } +void EditCaptionBox::applyChanges() { + if (!_preparedList.files.empty() && _previewHasSpoiler) { + _preparedList.files.front().spoiler = _previewHasSpoiler(); + } +} + void EditCaptionBox::save() { if (_saveRequestId) { return; @@ -727,10 +750,14 @@ void EditCaptionBox::save() { action.replaceMediaOf = item->fullId().msg; Storage::ApplyModifications(_preparedList); + if (!_preparedList.files.empty()) { + _preparedList.files.front().spoiler = false; + applyChanges(); + } _controller->session().api().editMedia( std::move(_preparedList), - (!_asFile && _isPhoto && CanBeCompressed(_albumType)) + (_isPhoto && !_asFile && CanBeCompressed(_albumType)) ? SendMediaType::Photo : SendMediaType::File, _field->getTextWithAppliedMarkdown(), diff --git a/Telegram/SourceFiles/boxes/edit_caption_box.h b/Telegram/SourceFiles/boxes/edit_caption_box.h index c671b0852..5a5910f9a 100644 --- a/Telegram/SourceFiles/boxes/edit_caption_box.h +++ b/Telegram/SourceFiles/boxes/edit_caption_box.h @@ -64,11 +64,13 @@ private: void setupDragArea(); bool validateLength(const QString &text) const; + void applyChanges(); void save(); bool fileFromClipboard(not_null data); - int errorTopSkip() const; + [[nodiscard]] int errorTopSkip() const; + [[nodiscard]] bool hasSpoiler() const; bool setPreparedList(Ui::PreparedList &&list); @@ -83,6 +85,7 @@ private: const base::unique_qptr _emojiToggle; base::unique_qptr _content; + Fn _previewHasSpoiler; base::unique_qptr _emojiPanel; base::unique_qptr _emojiFilter; diff --git a/Telegram/SourceFiles/boxes/send_files_box.cpp b/Telegram/SourceFiles/boxes/send_files_box.cpp index c11928fa3..e47fe9083 100644 --- a/Telegram/SourceFiles/boxes/send_files_box.cpp +++ b/Telegram/SourceFiles/boxes/send_files_box.cpp @@ -232,16 +232,20 @@ void SendFilesBox::Block::applyChanges() { if (_isSingleMedia) { const auto media = static_cast( _preview.get()); - (*_items)[_from].spoiler = media->hasSpoiler(); + if (media->canHaveSpoiler()) { + (*_items)[_from].spoiler = media->hasSpoiler(); + } } return; } const auto album = static_cast(_preview.get()); const auto order = album->takeOrder(); - const auto spoilered = album->collectSpoileredIndices(); const auto guard = gsl::finally([&] { + const auto spoilered = album->collectSpoileredIndices(); for (auto i = 0, count = int(order.size()); i != count; ++i) { - (*_items)[_from + i].spoiler = spoilered.contains(i); + if (album->canHaveSpoiler(i)) { + (*_items)[_from + i].spoiler = spoilered.contains(i); + } } }); const auto isIdentity = [&] { @@ -1095,6 +1099,9 @@ void SendFilesBox::send( saveSendWaySettings(); } + for (auto &item : _list.files) { + item.spoiler = false; + } for (auto &block : _blocks) { block.applyChanges(); } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_abstract_single_media_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_abstract_single_media_preview.cpp index 5898a5bf2..64cc29718 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_abstract_single_media_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_abstract_single_media_preview.cpp @@ -51,12 +51,14 @@ rpl::producer<> AbstractSingleMediaPreview::modifyRequests() const { } void AbstractSingleMediaPreview::setSendWay(SendFilesWay way) { - if (_sendWay != way) { - _sendWay = way; - } + _sendWay = way; update(); } +SendFilesWay AbstractSingleMediaPreview::sendWay() const { + return _sendWay; +} + void AbstractSingleMediaPreview::setSpoiler(bool spoiler) { _spoiler = spoiler ? std::make_unique([=] { update(); }) @@ -68,6 +70,10 @@ bool AbstractSingleMediaPreview::hasSpoiler() const { return _spoiler != nullptr; } +bool AbstractSingleMediaPreview::canHaveSpoiler() const { + return supportsSpoilers(); +} + void AbstractSingleMediaPreview::preparePreview(QImage preview) { auto maxW = 0; auto maxH = 0; @@ -149,7 +155,7 @@ void AbstractSingleMediaPreview::resizeEvent(QResizeEvent *e) { void AbstractSingleMediaPreview::paintEvent(QPaintEvent *e) { auto p = QPainter(this); - auto takenSpoiler = (drawBackground() || _sendWay.sendImagesAsPhotos()) + auto takenSpoiler = supportsSpoilers() ? nullptr : base::take(_spoiler); const auto guard = gsl::finally([&] { @@ -251,7 +257,7 @@ void AbstractSingleMediaPreview::applyCursor(style::cursor cursor) { } void AbstractSingleMediaPreview::showContextMenu(QPoint position) { - if (!_sendWay.sendImagesAsPhotos()) { + if (!_sendWay.sendImagesAsPhotos() || !supportsSpoilers()) { return; } _menu = base::make_unique_q( diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_abstract_single_media_preview.h b/Telegram/SourceFiles/ui/chat/attach/attach_abstract_single_media_preview.h index ffdd83d5b..ef85bf0d2 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_abstract_single_media_preview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_abstract_single_media_preview.h @@ -22,6 +22,7 @@ public: ~AbstractSingleMediaPreview(); void setSendWay(SendFilesWay way); + [[nodiscard]] SendFilesWay sendWay() const; [[nodiscard]] rpl::producer<> deleteRequests() const override; [[nodiscard]] rpl::producer<> editRequests() const override; @@ -31,8 +32,10 @@ public: void setSpoiler(bool spoiler); [[nodiscard]] bool hasSpoiler() const; + [[nodiscard]] bool canHaveSpoiler() const; protected: + virtual bool supportsSpoilers() const = 0; virtual bool drawBackground() const = 0; virtual bool tryPaintAnimation(QPainter &p) = 0; virtual bool isAnimatedPreviewReady() const = 0; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp index 00dcc182a..8acd66726 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.cpp @@ -77,6 +77,10 @@ base::flat_set AlbumPreview::collectSpoileredIndices() { return result; } +bool AlbumPreview::canHaveSpoiler(int index) const { + return _sendWay.sendImagesAsPhotos(); +} + std::vector AlbumPreview::takeOrder() { //Expects(_thumbs.size() == _order.size()); //Expects(_itemsShownDimensions.size() == _order.size()); diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h index 50c239d8e..4732ad33c 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_album_preview.h @@ -29,6 +29,7 @@ public: void setSendWay(SendFilesWay way); [[nodiscard]] base::flat_set collectSpoileredIndices(); + [[nodiscard]] bool canHaveSpoiler(int index) const; [[nodiscard]] std::vector takeOrder(); [[nodiscard]] rpl::producer thumbDeleted() const { diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_item_single_media_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_media_preview.cpp index 1e1ec6847..a04d75e4c 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_item_single_media_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_media_preview.cpp @@ -190,6 +190,10 @@ void ItemSingleMediaPreview::startStreamedPlayer() { _streamed->play(options); } +bool ItemSingleMediaPreview::supportsSpoilers() const { + return false; // We are not allowed to change existing spoiler setting. +} + bool ItemSingleMediaPreview::drawBackground() const { return true; // A sticker can't be here. } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_item_single_media_preview.h b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_media_preview.h index 12dfe05ca..07b93b73b 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_item_single_media_preview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_item_single_media_preview.h @@ -39,6 +39,7 @@ public: std::shared_ptr<::Data::PhotoMedia> sharedPhotoMedia() const; protected: + bool supportsSpoilers() const override; bool drawBackground() const override; bool tryPaintAnimation(QPainter &p) override; bool isAnimatedPreviewReady() const override; diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp index 600b3066a..41ee35c87 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp +++ b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.cpp @@ -72,6 +72,10 @@ SingleMediaPreview::SingleMediaPreview( setSpoiler(spoiler); } +bool SingleMediaPreview::supportsSpoilers() const { + return !_sticker || sendWay().sendImagesAsPhotos(); +} + bool SingleMediaPreview::drawBackground() const { return !_sticker; } diff --git a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.h b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.h index e5d03d245..546de452d 100644 --- a/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.h +++ b/Telegram/SourceFiles/ui/chat/attach/attach_single_media_preview.h @@ -37,6 +37,7 @@ public: AttachControls::Type type); protected: + bool supportsSpoilers() const override; bool drawBackground() const override; bool tryPaintAnimation(QPainter &p) override; bool isAnimatedPreviewReady() const override;