Remove legacy context menu in send files box.

This commit is contained in:
John Preston
2026-04-03 10:35:21 +07:00
parent beeb4663c4
commit cd1e0d710d
15 changed files with 16 additions and 260 deletions
@@ -508,21 +508,11 @@ void EditCaptionBox::rebuildPreview() {
st::defaultComposeControls,
gifPaused,
file,
[=](Ui::AttachActionType type) {
return (type != Ui::AttachActionType::EditCover) || _isVideo;
},
Ui::AttachControls::Type::EditOnly);
_isPhoto = (media && media->isPhoto());
if (media && !_asFile) {
media->setSendWay(currentSendWay());
media->setCanShowHighQualityBadge(file.canUseHighQualityPhoto());
media->spoileredChanges(
) | rpl::on_next([=](bool spoilered) {
_mediaEditManager.apply({ .type = spoilered
? SendMenu::ActionType::SpoilerOn
: SendMenu::ActionType::SpoilerOff
});
}, media->lifetime());
_content.reset(media);
} else {
_content.reset(Ui::CreateChild<Ui::SingleFilePreview>(
@@ -552,14 +542,6 @@ void EditCaptionBox::rebuildPreview() {
_content->modifyRequests(
) | rpl::start_to_stream(_photoEditorOpens, _content->lifetime());
_content->editCoverRequests() | rpl::on_next([=] {
setupEditCoverHandler();
}, _content->lifetime());
_content->clearCoverRequests() | rpl::on_next([=] {
setupClearCoverHandler();
}, _content->lifetime());
_content->heightValue(
) | rpl::start_to_stream(_contentHeight, _content->lifetime());
+4 -61
View File
@@ -381,8 +381,7 @@ SendFilesBox::Block::Block(
int till,
const Ui::Text::MarkedContext &captionContext,
Fn<bool()> gifPaused,
SendFilesWay way,
Fn<bool(const Ui::PreparedFile &, Ui::AttachActionType)> actionAllowed)
SendFilesWay way)
: _items(items)
, _from(from)
, _till(till) {
@@ -400,10 +399,7 @@ SendFilesBox::Block::Block(
st,
my,
captionContext,
way,
[=](int index, Ui::AttachActionType type) {
return actionAllowed((*_items)[from + index], type);
});
way);
_preview.reset(preview);
} else {
const auto media = way.sendImagesAsPhotos()
@@ -411,10 +407,7 @@ SendFilesBox::Block::Block(
parent,
st,
gifPaused,
first,
[=](Ui::AttachActionType type) {
return actionAllowed((*_items)[from], type);
})
first)
: nullptr;
if (media) {
_isSingleMedia = true;
@@ -494,38 +487,6 @@ rpl::producer<int> SendFilesBox::Block::itemModifyRequest() const {
}
}
rpl::producer<int> SendFilesBox::Block::itemEditCoverRequest() const {
using namespace rpl::mappers;
const auto preview = _preview.get();
const auto from = _from;
if (_isAlbum) {
const auto album = static_cast<Ui::AlbumPreview*>(preview);
return album->thumbEditCoverRequested() | rpl::map(_1 + from);
} else if (_isSingleMedia) {
const auto media = static_cast<Ui::SingleMediaPreview*>(preview);
return media->editCoverRequests() | rpl::map_to(from);
} else {
return rpl::never<int>();
}
}
rpl::producer<int> SendFilesBox::Block::itemClearCoverRequest() const {
using namespace rpl::mappers;
const auto preview = _preview.get();
const auto from = _from;
if (_isAlbum) {
const auto album = static_cast<Ui::AlbumPreview*>(preview);
return album->thumbClearCoverRequested() | rpl::map(_1 + from);
} else if (_isSingleMedia) {
const auto media = static_cast<Ui::SingleMediaPreview*>(preview);
return media->clearCoverRequests() | rpl::map_to(from);
} else {
return rpl::never<int>();
}
}
rpl::producer<> SendFilesBox::Block::orderUpdated() const {
if (_isAlbum) {
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
@@ -1275,15 +1236,7 @@ void SendFilesBox::pushBlock(int from, int till) {
till,
captionContext,
gifPaused,
_sendWay.current(),
[=](const Ui::PreparedFile &file, Ui::AttachActionType type) {
return (type == Ui::AttachActionType::ToggleSpoiler)
? !hasPrice()
: (type == Ui::AttachActionType::EditCover)
? (file.isVideoFile()
&& (_toPeer->isBroadcast() || _toPeer->isSelf()))
: (file.videoCover != nullptr);
});
_sendWay.current());
auto &block = _blocks.back();
const auto widget = _inner->add(
block.takeWidget(),
@@ -1607,16 +1560,6 @@ void SendFilesBox::pushBlock(int from, int till) {
openInPhotoEditor(index);
}, widget->lifetime());
block.itemEditCoverRequest(
) | rpl::on_next([=](int index) {
editCover(index);
}, widget->lifetime());
block.itemClearCoverRequest(
) | rpl::on_next([=](int index) {
clearCover(index);
}, widget->lifetime());
block.orderUpdated() | rpl::on_next([=]{
if (_priceTag) {
_priceTagBg = QImage();
+1 -6
View File
@@ -158,10 +158,7 @@ private:
int till,
const Ui::Text::MarkedContext &captionContext,
Fn<bool()> gifPaused,
Ui::SendFilesWay way,
Fn<bool(
const Ui::PreparedFile &,
Ui::AttachActionType)> actionAllowed);
Ui::SendFilesWay way);
Block(Block &&other) = default;
Block &operator=(Block &&other) = default;
@@ -172,8 +169,6 @@ private:
[[nodiscard]] rpl::producer<int> itemDeleteRequest() const;
[[nodiscard]] rpl::producer<int> itemReplaceRequest() const;
[[nodiscard]] rpl::producer<int> itemModifyRequest() const;
[[nodiscard]] rpl::producer<int> itemEditCoverRequest() const;
[[nodiscard]] rpl::producer<int> itemClearCoverRequest() const;
[[nodiscard]] rpl::producer<> orderUpdated() const;
void setSendWay(Ui::SendFilesWay way);
@@ -74,14 +74,6 @@ rpl::producer<> AbstractSingleFilePreview::modifyRequests() const {
return rpl::never<>();
}
rpl::producer<> AbstractSingleFilePreview::editCoverRequests() const {
return rpl::never<>();
}
rpl::producer<> AbstractSingleFilePreview::clearCoverRequests() const {
return rpl::never<>();
}
void AbstractSingleFilePreview::setDisplayName(const QString &displayName) {
_data.name = displayName;
updateTextWidthFor(_data);
@@ -31,8 +31,6 @@ public:
[[nodiscard]] rpl::producer<> deleteRequests() const override;
[[nodiscard]] rpl::producer<> editRequests() const override;
[[nodiscard]] rpl::producer<> modifyRequests() const override;
[[nodiscard]] rpl::producer<> editCoverRequests() const override;
[[nodiscard]] rpl::producer<> clearCoverRequests() const override;
virtual void setDisplayName(const QString &displayName);
virtual void setCaption(const TextWithTags &caption);
@@ -8,8 +8,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/chat/attach/attach_abstract_single_media_preview.h"
#include "editor/photo_editor_common.h"
#include "lang/lang_keys.h"
#include "menu/menu_checked_action.h"
#include "ui/chat/attach/attach_controls.h"
#include "ui/chat/attach/attach_prepare.h"
#include "ui/effects/spoiler_mess.h"
@@ -17,12 +15,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/painter.h"
#include "ui/power_saving.h"
#include "ui/ui_utility.h"
#include "ui/widgets/popup_menu.h"
#include "styles/style_boxes.h"
#include "styles/style_chat.h"
#include "styles/style_chat_helpers.h"
#include "styles/style_layers.h"
#include "styles/style_menu_icons.h"
namespace Ui {
namespace {
@@ -34,11 +30,9 @@ constexpr auto kMinPreviewWidth = 20;
AbstractSingleMediaPreview::AbstractSingleMediaPreview(
QWidget *parent,
const style::ComposeControls &st,
AttachControls::Type type,
Fn<bool(AttachActionType)> actionAllowed)
AttachControls::Type type)
: AbstractSinglePreview(parent)
, _st(st)
, _actionAllowed(std::move(actionAllowed))
, _minThumbH(st::sendBoxAlbumGroupSize.height()
+ st::sendBoxAlbumGroupSkipTop * 2)
, _controls(base::make_unique_q<AttachControlsWidget>(this, type)) {
@@ -58,14 +52,6 @@ rpl::producer<> AbstractSingleMediaPreview::modifyRequests() const {
return _photoEditorRequests.events();
}
rpl::producer<> AbstractSingleMediaPreview::editCoverRequests() const {
return _editCoverRequests.events();
}
rpl::producer<> AbstractSingleMediaPreview::clearCoverRequests() const {
return _clearCoverRequests.events();
}
void AbstractSingleMediaPreview::setSendWay(SendFilesWay way) {
_sendWay = way;
update();
@@ -95,10 +81,6 @@ bool AbstractSingleMediaPreview::canHaveSpoiler() const {
return supportsSpoilers();
}
rpl::producer<bool> AbstractSingleMediaPreview::spoileredChanges() const {
return _spoileredChanges.events();
}
QImage AbstractSingleMediaPreview::generatePriceTagBackground() const {
return (_previewBlurred.isNull() ? _preview : _previewBlurred).toImage();
}
@@ -277,9 +259,7 @@ void AbstractSingleMediaPreview::mouseMoveEvent(QMouseEvent *e) {
void AbstractSingleMediaPreview::mouseReleaseEvent(QMouseEvent *e) {
if (base::take(_pressed) && isOverPreview(e->pos())) {
if (e->button() == Qt::RightButton) {
showContextMenu(e->globalPos());
} else if (isPhoto()) {
if (isPhoto()) {
_photoEditorRequests.fire({});
}
}
@@ -292,44 +272,6 @@ void AbstractSingleMediaPreview::applyCursor(style::cursor cursor) {
}
}
void AbstractSingleMediaPreview::showContextMenu(QPoint position) {
_menu = base::make_unique_q<Ui::PopupMenu>(
this,
_st.tabbed.menu);
const auto &icons = _st.tabbed.icons;
if (_actionAllowed(AttachActionType::ToggleSpoiler)
&& _sendWay.sendImagesAsPhotos()
&& supportsSpoilers()) {
const auto spoilered = hasSpoiler();
::Menu::AddCheckedAction(
_menu.get(),
tr::lng_context_spoiler_effect(tr::now),
[=] {
setSpoiler(!spoilered);
_spoileredChanges.fire_copy(!spoilered);
},
&icons.menuSpoiler,
spoilered);
}
if (_actionAllowed(AttachActionType::EditCover)) {
_menu->addAction(tr::lng_context_edit_cover(tr::now), [=] {
_editCoverRequests.fire({});
}, &st::menuIconEdit);
if (_actionAllowed(AttachActionType::ClearCover)) {
_menu->addAction(tr::lng_context_clear_cover(tr::now), [=] {
_clearCoverRequests.fire({});
}, &st::menuIconCancel);
}
}
if (_menu->empty()) {
_menu = nullptr;
} else {
_menu->popup(position);
}
}
int AbstractSingleMediaPreview::previewLeft() const {
return _previewLeft;
}
@@ -19,15 +19,12 @@ struct ComposeControls;
namespace Ui {
class PopupMenu;
class AbstractSingleMediaPreview : public AbstractSinglePreview {
public:
AbstractSingleMediaPreview(
QWidget *parent,
const style::ComposeControls &st,
AttachControls::Type type,
Fn<bool(AttachActionType)> actionAllowed);
AttachControls::Type type);
~AbstractSingleMediaPreview();
void setSendWay(SendFilesWay way);
@@ -36,8 +33,6 @@ public:
[[nodiscard]] rpl::producer<> deleteRequests() const override;
[[nodiscard]] rpl::producer<> editRequests() const override;
[[nodiscard]] rpl::producer<> modifyRequests() const override;
[[nodiscard]] rpl::producer<> editCoverRequests() const override;
[[nodiscard]] rpl::producer<> clearCoverRequests() const override;
[[nodiscard]] bool isPhoto() const;
@@ -45,7 +40,6 @@ public:
void setCanShowHighQualityBadge(bool value);
[[nodiscard]] bool hasSpoiler() const;
[[nodiscard]] bool canHaveSpoiler() const;
[[nodiscard]] rpl::producer<bool> spoileredChanges() const;
[[nodiscard]] QImage generatePriceTagBackground() const;
@@ -73,11 +67,9 @@ private:
[[nodiscard]] bool isOverPreview(QPoint position) const;
void applyCursor(style::cursor cursor);
void showContextMenu(QPoint position);
const style::ComposeControls &_st;
SendFilesWay _sendWay;
Fn<bool(AttachActionType)> _actionAllowed;
bool _animated = false;
QPixmap _preview;
QPixmap _previewBlurred;
@@ -87,20 +79,15 @@ private:
int _previewHeight = 0;
std::unique_ptr<SpoilerAnimation> _spoiler;
rpl::event_stream<bool> _spoileredChanges;
bool _canShowHighQualityBadge = false;
const int _minThumbH;
const base::unique_qptr<AttachControlsWidget> _controls;
rpl::event_stream<> _photoEditorRequests;
rpl::event_stream<> _editCoverRequests;
rpl::event_stream<> _clearCoverRequests;
style::cursor _cursor = style::cur_default;
bool _pressed = false;
base::unique_qptr<PopupMenu> _menu;
rpl::event_stream<> _modifyRequests;
};
@@ -18,8 +18,6 @@ public:
[[nodiscard]] virtual rpl::producer<> deleteRequests() const = 0;
[[nodiscard]] virtual rpl::producer<> editRequests() const = 0;
[[nodiscard]] virtual rpl::producer<> modifyRequests() const = 0;
[[nodiscard]] virtual rpl::producer<> editCoverRequests() const = 0;
[[nodiscard]] virtual rpl::producer<> clearCoverRequests() const = 0;
};
@@ -7,17 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "ui/chat/attach/attach_album_preview.h"
#include "menu/menu_checked_action.h"
#include "ui/chat/attach/attach_album_thumbnail.h"
#include "ui/chat/attach/attach_prepare.h"
#include "ui/effects/spoiler_mess.h"
#include "ui/widgets/popup_menu.h"
#include "ui/painter.h"
#include "lang/lang_keys.h"
#include "styles/style_chat.h"
#include "styles/style_boxes.h"
#include "styles/style_layers.h"
#include "styles/style_menu_icons.h"
#include <QtWidgets/QApplication>
@@ -39,13 +35,11 @@ AlbumPreview::AlbumPreview(
const style::ComposeControls &st,
gsl::span<Ui::PreparedFile> items,
const Text::MarkedContext &captionContext,
SendFilesWay way,
Fn<bool(int, AttachActionType)> actionAllowed)
SendFilesWay way)
: RpWidget(parent)
, _st(st)
, _captionContext(captionContext)
, _sendWay(way)
, _actionAllowed(std::move(actionAllowed))
, _dragTimer([=] { switchToDrag(); }) {
setMouseTracking(true);
prepareThumbs(items);
@@ -624,54 +618,13 @@ void AlbumPreview::mouseReleaseEvent(QMouseEvent *e) {
} else if (const auto thumb = base::take(_pressedThumb)) {
const auto was = _pressedButtonType;
const auto now = thumb->buttonTypeFromPoint(e->pos());
if (e->button() == Qt::RightButton) {
showContextMenu(thumb, e->globalPos());
} else if (was == now) {
if (e->button() != Qt::RightButton && was == now) {
thumbButtonsCallback(thumb, now);
}
}
_pressedButtonType = AttachButtonType::None;
}
void AlbumPreview::showContextMenu(
not_null<AlbumThumbnail*> thumb,
QPoint position) {
_menu = base::make_unique_q<Ui::PopupMenu>(
this,
st::popupMenuWithIcons);
const auto index = orderIndex(thumb);
if (_actionAllowed(index, AttachActionType::ToggleSpoiler)
&& _sendWay.sendImagesAsPhotos()) {
const auto spoilered = thumb->hasSpoiler();
::Menu::AddCheckedAction(
_menu.get(),
tr::lng_context_spoiler_effect(tr::now),
[=] {
thumb->setSpoiler(!spoilered);
},
&st::menuIconSpoiler,
spoilered);
}
if (_actionAllowed(index, AttachActionType::EditCover)) {
_menu->addAction(tr::lng_context_edit_cover(tr::now), [=] {
_thumbEditCoverRequested.fire_copy(index);
}, &st::menuIconEdit);
if (_actionAllowed(index, AttachActionType::ClearCover)) {
_menu->addAction(tr::lng_context_clear_cover(tr::now), [=] {
_thumbClearCoverRequested.fire_copy(index);
}, &st::menuIconCancel);
}
}
if (_menu->empty()) {
_menu = nullptr;
} else {
_menu->popup(position);
}
}
void AlbumPreview::switchToDrag() {
_paintedAbove
= _suggestedThumb
@@ -21,7 +21,6 @@ namespace Ui {
struct PreparedFile;
struct GroupMediaLayout;
class AlbumThumbnail;
class PopupMenu;
class AlbumPreview final : public RpWidget {
public:
@@ -30,8 +29,7 @@ public:
const style::ComposeControls &st,
gsl::span<Ui::PreparedFile> items,
const Text::MarkedContext &captionContext,
SendFilesWay way,
Fn<bool(int, AttachActionType)> actionAllowed);
SendFilesWay way);
~AlbumPreview();
void setSendWay(SendFilesWay way);
@@ -52,12 +50,6 @@ public:
[[nodiscard]] rpl::producer<int> thumbModified() const {
return _thumbModified.events();
}
[[nodiscard]] rpl::producer<int> thumbEditCoverRequested() const {
return _thumbEditCoverRequested.events();
}
[[nodiscard]] rpl::producer<int> thumbClearCoverRequested() const {
return _thumbClearCoverRequested.events();
}
[[nodiscard]] rpl::producer<> orderUpdated() const {
return _orderUpdated.events();
}
@@ -104,12 +96,9 @@ private:
void cancelDrag();
void finishDrag();
void showContextMenu(not_null<AlbumThumbnail*> thumb, QPoint position);
const style::ComposeControls &_st;
const Text::MarkedContext _captionContext;
SendFilesWay _sendWay;
Fn<bool(int, AttachActionType)> _actionAllowed;
style::cursor _cursor = style::cur_default;
std::vector<int> _order;
std::vector<QSize> _itemsShownDimensions;
@@ -132,12 +121,8 @@ private:
rpl::event_stream<int> _thumbDeleted;
rpl::event_stream<int> _thumbChanged;
rpl::event_stream<int> _thumbModified;
rpl::event_stream<int> _thumbEditCoverRequested;
rpl::event_stream<int> _thumbClearCoverRequested;
rpl::event_stream<> _orderUpdated;
base::unique_qptr<PopupMenu> _menu;
mutable Animations::Simple _thumbsHeightAnimation;
mutable Animations::Simple _shrinkAnimation;
mutable Animations::Simple _finishDragAnimation;
@@ -36,15 +36,8 @@ ItemSingleMediaPreview::ItemSingleMediaPreview(
Fn<bool()> gifPaused,
not_null<HistoryItem*> item,
AttachControls::Type type)
: AbstractSingleMediaPreview(parent, st, type, [=](AttachActionType type) {
if (type == AttachActionType::EditCover) {
return _isVideoFile;
}
return true;
})
: AbstractSingleMediaPreview(parent, st, type)
, _gifPaused(std::move(gifPaused))
, _isVideoFile(item->media()->document()
&& item->media()->document()->isVideoFile())
, _fullId(item->fullId()) {
const auto media = item->media();
Assert(media != nullptr);
@@ -56,7 +56,6 @@ private:
void startStreamedPlayer();
const Fn<bool()> _gifPaused;
const bool _isVideoFile;
const FullMsgId _fullId;
std::shared_ptr<::Data::PhotoMedia> _photoMedia;
@@ -11,12 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Ui {
enum class AttachActionType {
ToggleSpoiler,
EditCover,
ClearCover,
};
enum class AttachButtonType {
Edit,
Delete,
@@ -19,7 +19,6 @@ SingleMediaPreview *SingleMediaPreview::Create(
const style::ComposeControls &st,
Fn<bool()> gifPaused,
const PreparedFile &file,
Fn<bool(AttachActionType)> actionAllowed,
AttachControls::Type type) {
auto preview = QImage();
auto animated = false;
@@ -54,8 +53,7 @@ SingleMediaPreview *SingleMediaPreview::Create(
Core::IsMimeSticker(file.information->filemime),
file.spoiler,
animationPreview ? file.path : QString(),
type,
std::move(actionAllowed));
type);
result->setCanShowHighQualityBadge(file.canUseHighQualityPhoto());
return result;
}
@@ -69,9 +67,8 @@ SingleMediaPreview::SingleMediaPreview(
bool sticker,
bool spoiler,
const QString &animatedPreviewPath,
AttachControls::Type type,
Fn<bool(AttachActionType)> actionAllowed)
: AbstractSingleMediaPreview(parent, st, type, std::move(actionAllowed))
AttachControls::Type type)
: AbstractSingleMediaPreview(parent, st, type)
, _gifPaused(std::move(gifPaused))
, _sticker(sticker) {
Expects(!preview.isNull());
@@ -25,7 +25,6 @@ public:
const style::ComposeControls &st,
Fn<bool()> gifPaused,
const PreparedFile &file,
Fn<bool(AttachActionType)> actionAllowed,
AttachControls::Type type = AttachControls::Type::Full);
SingleMediaPreview(
@@ -37,8 +36,7 @@ public:
bool sticker,
bool spoiler,
const QString &animatedPreviewPath,
AttachControls::Type type,
Fn<bool(AttachActionType)> actionAllowed);
AttachControls::Type type);
protected:
bool supportsSpoilers() const override;