Allow apply spoiler when editing to another media.

This commit is contained in:
John Preston 2022-12-13 17:31:54 +04:00
parent 5bee6310c0
commit bd1d7f4d96
11 changed files with 77 additions and 16 deletions

View file

@ -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<Ui::ItemSingleMediaPreview>(
this,
gifPaused,
@ -189,7 +192,6 @@ void EditCaptionBox::rebuildPreview() {
_photoMedia = media->sharedPhotoMedia();
_content.reset(media);
} else {
_isPhoto = false;
_content.reset(Ui::CreateChild<Ui::ItemSingleFilePreview>(
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<Ui::SingleFilePreview>(
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<ImageInfo>(
&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(),

View file

@ -64,11 +64,13 @@ private:
void setupDragArea();
bool validateLength(const QString &text) const;
void applyChanges();
void save();
bool fileFromClipboard(not_null<const QMimeData*> 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<Ui::EmojiButton> _emojiToggle;
base::unique_qptr<Ui::AbstractSinglePreview> _content;
Fn<bool()> _previewHasSpoiler;
base::unique_qptr<ChatHelpers::TabbedPanel> _emojiPanel;
base::unique_qptr<QObject> _emojiFilter;

View file

@ -232,16 +232,20 @@ void SendFilesBox::Block::applyChanges() {
if (_isSingleMedia) {
const auto media = static_cast<Ui::SingleMediaPreview*>(
_preview.get());
(*_items)[_from].spoiler = media->hasSpoiler();
if (media->canHaveSpoiler()) {
(*_items)[_from].spoiler = media->hasSpoiler();
}
}
return;
}
const auto album = static_cast<Ui::AlbumPreview*>(_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();
}

View file

@ -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<SpoilerAnimation>([=] { 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<Ui::PopupMenu>(

View file

@ -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;

View file

@ -77,6 +77,10 @@ base::flat_set<int> AlbumPreview::collectSpoileredIndices() {
return result;
}
bool AlbumPreview::canHaveSpoiler(int index) const {
return _sendWay.sendImagesAsPhotos();
}
std::vector<int> AlbumPreview::takeOrder() {
//Expects(_thumbs.size() == _order.size());
//Expects(_itemsShownDimensions.size() == _order.size());

View file

@ -29,6 +29,7 @@ public:
void setSendWay(SendFilesWay way);
[[nodiscard]] base::flat_set<int> collectSpoileredIndices();
[[nodiscard]] bool canHaveSpoiler(int index) const;
[[nodiscard]] std::vector<int> takeOrder();
[[nodiscard]] rpl::producer<int> thumbDeleted() const {

View file

@ -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.
}

View file

@ -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;

View file

@ -72,6 +72,10 @@ SingleMediaPreview::SingleMediaPreview(
setSpoiler(spoiler);
}
bool SingleMediaPreview::supportsSpoilers() const {
return !_sticker || sendWay().sendImagesAsPhotos();
}
bool SingleMediaPreview::drawBackground() const {
return !_sticker;
}

View file

@ -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;