mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-22 09:07:05 +02:00
Added ability to send webp as compressed image.
This commit is contained in:
parent
57c50c8655
commit
3467fe226f
12 changed files with 161 additions and 45 deletions
|
@ -3374,7 +3374,10 @@ void ApiWrap::sendFiles(
|
|||
std::shared_ptr<SendingAlbum> album,
|
||||
const SendAction &action) {
|
||||
const auto haveCaption = !caption.text.isEmpty();
|
||||
if (haveCaption && !list.canAddCaption(album != nullptr)) {
|
||||
if (haveCaption
|
||||
&& !list.canAddCaption(
|
||||
album != nullptr,
|
||||
type == SendMediaType::Photo)) {
|
||||
auto message = MessageToSend(action);
|
||||
message.textWithTags = base::take(caption);
|
||||
message.action.clearDraft = false;
|
||||
|
|
|
@ -102,7 +102,9 @@ void FileDialogCallback(
|
|||
rpl::producer<QString> FieldPlaceholder(
|
||||
const Ui::PreparedList &list,
|
||||
SendFilesWay way) {
|
||||
return list.canAddCaption(way.groupFiles() && way.sendImagesAsPhotos())
|
||||
return list.canAddCaption(
|
||||
way.groupFiles() && way.sendImagesAsPhotos(),
|
||||
way.sendImagesAsPhotos())
|
||||
? tr::lng_photo_caption()
|
||||
: tr::lng_photos_comment();
|
||||
}
|
||||
|
@ -390,6 +392,11 @@ void SendFilesBox::refreshAllAfterChanges(int fromItem) {
|
|||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
auto sendWay = _sendWay.current();
|
||||
sendWay.setHasCompressedStickers(_list.hasSticker());
|
||||
_sendWay = sendWay;
|
||||
}
|
||||
generatePreviewFrom(fromBlock);
|
||||
_inner->resizeToWidth(st::boxWideWidth);
|
||||
refreshControls();
|
||||
|
@ -427,6 +434,7 @@ void SendFilesBox::openDialogToAddFileToAlbum() {
|
|||
void SendFilesBox::initSendWay() {
|
||||
_sendWay = [&] {
|
||||
auto result = Core::App().settings().sendFilesWay();
|
||||
result.setHasCompressedStickers(_list.hasSticker());
|
||||
if (_sendLimit == SendLimit::One) {
|
||||
result.setGroupFiles(true);
|
||||
return result;
|
||||
|
@ -455,7 +463,9 @@ void SendFilesBox::updateCaptionPlaceholder() {
|
|||
return;
|
||||
}
|
||||
const auto way = _sendWay.current();
|
||||
if (!_list.canAddCaption(way.groupFiles() && way.sendImagesAsPhotos())
|
||||
if (!_list.canAddCaption(
|
||||
way.groupFiles() && way.sendImagesAsPhotos(),
|
||||
way.sendImagesAsPhotos())
|
||||
&& _sendLimit == SendLimit::One) {
|
||||
_caption->hide();
|
||||
if (_emojiToggle) {
|
||||
|
@ -668,7 +678,7 @@ void SendFilesBox::updateSendWayControlsVisibility() {
|
|||
|
||||
_hintLabel->setVisible(
|
||||
_controller->session().settings().photoEditorHintShown()
|
||||
? _list.hasSendImagesAsPhotosOption(false)
|
||||
? _list.canHaveEditorHintLabel()
|
||||
: false);
|
||||
}
|
||||
|
||||
|
@ -1019,7 +1029,8 @@ bool SendFilesBox::validateLength(const QString &text) const {
|
|||
const auto way = _sendWay.current();
|
||||
if (remove <= 0
|
||||
|| !_list.canAddCaption(
|
||||
way.groupFiles() && way.sendImagesAsPhotos())) {
|
||||
way.groupFiles() && way.sendImagesAsPhotos(),
|
||||
way.sendImagesAsPhotos())) {
|
||||
return true;
|
||||
}
|
||||
_controller->show(Box(CaptionLimitReachedBox, session, remove));
|
||||
|
|
|
@ -915,7 +915,8 @@ void FileLoadTask::process(Args &&args) {
|
|||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(w), MTP_int(h)));
|
||||
|
||||
if (ValidateThumbDimensions(w, h)) {
|
||||
isSticker = Core::IsMimeSticker(filemime)
|
||||
isSticker = (_type == SendMediaType::File)
|
||||
&& Core::IsMimeSticker(filemime)
|
||||
&& (filesize < Storage::kMaxStickerBytesSize)
|
||||
&& (Core::IsMimeStickerAnimated(filemime)
|
||||
|| GoodStickerDimensions(w, h));
|
||||
|
@ -936,6 +937,9 @@ void FileLoadTask::process(Args &&args) {
|
|||
attributes.push_back(MTP_documentAttributeAnimated());
|
||||
} else if (filemime.startsWith(u"image/"_q)
|
||||
&& _type != SendMediaType::File) {
|
||||
if (Core::IsMimeSticker(filemime)) {
|
||||
fullimage = Images::Opaque(std::move(fullimage));
|
||||
}
|
||||
auto medium = (w > 320 || h > 320) ? fullimage.scaled(320, 320, Qt::KeepAspectRatio, Qt::SmoothTransformation) : fullimage;
|
||||
|
||||
const auto downscaled = (w > 1280 || h > 1280);
|
||||
|
|
|
@ -145,7 +145,8 @@ MimeDataState ComputeMimeDataState(const QMimeData *data) {
|
|||
return MimeDataState::None;
|
||||
}
|
||||
|
||||
const auto imageExtensions = Ui::ImageExtensions();
|
||||
auto imageExtensions = Ui::ImageExtensions();
|
||||
imageExtensions.push_back(u".webp"_q);
|
||||
auto files = QStringList();
|
||||
auto allAreSmallImages = true;
|
||||
for (const auto &url : urls) {
|
||||
|
@ -303,11 +304,11 @@ void PrepareDetails(PreparedFile &file, int previewWidth) {
|
|||
if (const auto image = std::get_if<Image>(
|
||||
&file.information->media)) {
|
||||
Assert(!image->data.isNull());
|
||||
if (ValidPhotoForAlbum(*image, file.information->filemime)) {
|
||||
if (ValidPhotoForAlbum(*image, file.information->filemime)
|
||||
|| Core::IsMimeSticker(file.information->filemime)) {
|
||||
UpdateImageDetails(file, previewWidth);
|
||||
file.type = PreparedFile::Type::Photo;
|
||||
} else if (Core::IsMimeSticker(file.information->filemime)
|
||||
|| image->animated) {
|
||||
} else if (image->animated) {
|
||||
file.type = PreparedFile::Type::None;
|
||||
}
|
||||
} else if (const auto video = std::get_if<Video>(
|
||||
|
|
|
@ -52,8 +52,12 @@ void AlbumPreview::updateFileRows() {
|
|||
Expects(_order.size() == _thumbs.size());
|
||||
|
||||
const auto isFile = !_sendWay.sendImagesAsPhotos();
|
||||
auto top = 0;
|
||||
for (auto i = 0; i < _order.size(); i++) {
|
||||
_thumbs[i]->updateFileRow(isFile ? _order[i] : -1);
|
||||
const auto &thumb = _thumbs[_order[i]];
|
||||
thumb->setButtonVisible(isFile && !thumb->isCompressedSticker());
|
||||
thumb->moveButtons(top);
|
||||
top += thumb->fileHeight() + st::sendMediaRowSkip;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -110,6 +114,9 @@ void AlbumPreview::prepareThumbs(gsl::span<Ui::PreparedFile> items) {
|
|||
this,
|
||||
[=] { changeThumbByIndex(thumbIndex(thumbUnderCursor())); },
|
||||
[=] { deleteThumbByIndex(thumbIndex(thumbUnderCursor())); }));
|
||||
if (_thumbs.back()->isCompressedSticker()) {
|
||||
_hasMixedFileHeights = true;
|
||||
}
|
||||
}
|
||||
_thumbsHeight = countLayoutHeight(layout);
|
||||
_photosHeight = ranges::accumulate(ranges::views::all(
|
||||
|
@ -118,9 +125,16 @@ void AlbumPreview::prepareThumbs(gsl::span<Ui::PreparedFile> items) {
|
|||
return thumb->photoHeight();
|
||||
}), 0) + (count - 1) * st::sendMediaRowSkip;
|
||||
|
||||
const auto &st = st::attachPreviewThumbLayout;
|
||||
_filesHeight = count * st.thumbSize
|
||||
+ (count - 1) * st::sendMediaRowSkip;
|
||||
if (!_hasMixedFileHeights) {
|
||||
_filesHeight = count * _thumbs.front()->fileHeight()
|
||||
+ (count - 1) * st::sendMediaRowSkip;
|
||||
} else {
|
||||
_filesHeight = ranges::accumulate(ranges::views::all(
|
||||
_thumbs
|
||||
) | ranges::views::transform([](const auto &thumb) {
|
||||
return thumb->fileHeight();
|
||||
}), 0) + (count - 1) * st::sendMediaRowSkip;
|
||||
}
|
||||
}
|
||||
|
||||
int AlbumPreview::contentLeft() const {
|
||||
|
@ -143,7 +157,7 @@ AlbumThumbnail *AlbumPreview::findThumb(QPoint position) const {
|
|||
} else {
|
||||
const auto bottom = top + (isPhotosWay
|
||||
? thumb->photoHeight()
|
||||
: st::attachPreviewThumbLayout.thumbSize);
|
||||
: thumb->fileHeight());
|
||||
const auto isUnderTop = (position.y() > top);
|
||||
top = bottom + skip;
|
||||
return isUnderTop && (position.y() < bottom);
|
||||
|
@ -319,18 +333,44 @@ void AlbumPreview::paintPhotos(Painter &p, QRect clip) const {
|
|||
}
|
||||
|
||||
void AlbumPreview::paintFiles(Painter &p, QRect clip) const {
|
||||
const auto fileHeight = st::attachPreviewThumbLayout.thumbSize
|
||||
+ st::sendMediaRowSkip;
|
||||
const auto bottom = clip.y() + clip.height();
|
||||
const auto from = std::clamp(clip.y() / fileHeight, 0, int(_thumbs.size()));
|
||||
const auto till = std::clamp((bottom + fileHeight - 1) / fileHeight, 0, int(_thumbs.size()));
|
||||
const auto left = (st::boxWideWidth - st::sendMediaPreviewSize) / 2;
|
||||
const auto outerWidth = width();
|
||||
if (!_hasMixedFileHeights) {
|
||||
const auto fileHeight = st::attachPreviewThumbLayout.thumbSize
|
||||
+ st::sendMediaRowSkip;
|
||||
const auto bottom = clip.y() + clip.height();
|
||||
const auto from = std::clamp(
|
||||
clip.y() / fileHeight,
|
||||
0,
|
||||
int(_thumbs.size()));
|
||||
const auto till = std::clamp(
|
||||
(bottom + fileHeight - 1) / fileHeight,
|
||||
0,
|
||||
int(_thumbs.size()));
|
||||
|
||||
auto top = from * fileHeight;
|
||||
for (auto i = from; i != till; ++i) {
|
||||
_thumbs[i]->paintFile(p, left, top, outerWidth);
|
||||
top += fileHeight;
|
||||
auto top = from * fileHeight;
|
||||
for (auto i = from; i != till; ++i) {
|
||||
_thumbs[i]->paintFile(p, left, top, outerWidth);
|
||||
top += fileHeight;
|
||||
}
|
||||
} else {
|
||||
auto top = 0;
|
||||
for (const auto &thumb : _thumbs) {
|
||||
const auto bottom = top + thumb->fileHeight();
|
||||
const auto guard = gsl::finally([&] {
|
||||
top = bottom + st::sendMediaRowSkip;
|
||||
});
|
||||
if (top >= clip.y() + clip.height()) {
|
||||
break;
|
||||
} else if (bottom <= clip.y()) {
|
||||
continue;
|
||||
}
|
||||
if (thumb->isCompressedSticker()) {
|
||||
thumb->paintPhoto(p, left, top, outerWidth);
|
||||
} else {
|
||||
thumb->paintFile(p, left, top, outerWidth);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -421,7 +461,7 @@ void AlbumPreview::mousePressEvent(QMouseEvent *e) {
|
|||
}
|
||||
|
||||
void AlbumPreview::mouseMoveEvent(QMouseEvent *e) {
|
||||
if (!_sendWay.sendImagesAsPhotos()) {
|
||||
if (!_sendWay.sendImagesAsPhotos() && !_hasMixedFileHeights) {
|
||||
applyCursor(style::cur_default);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -88,6 +88,8 @@ private:
|
|||
int _photosHeight = 0;
|
||||
int _filesHeight = 0;
|
||||
|
||||
bool _hasMixedFileHeights = false;
|
||||
|
||||
AlbumThumbnail *_draggedThumb = nullptr;
|
||||
AlbumThumbnail *_suggestedThumb = nullptr;
|
||||
AlbumThumbnail *_paintedAbove = nullptr;
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "ui/chat/attach/attach_album_thumbnail.h"
|
||||
|
||||
#include "core/mime_type.h" // Core::IsMimeSticker.
|
||||
#include "ui/chat/attach/attach_prepare.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/text/format_values.h"
|
||||
|
@ -31,7 +32,8 @@ AlbumThumbnail::AlbumThumbnail(
|
|||
, _fullPreview(file.preview)
|
||||
, _shrinkSize(int(std::ceil(st::roundRadiusLarge / 1.4)))
|
||||
, _isPhoto(file.type == PreparedFile::Type::Photo)
|
||||
, _isVideo(file.type == PreparedFile::Type::Video) {
|
||||
, _isVideo(file.type == PreparedFile::Type::Video)
|
||||
, _isCompressedSticker(Core::IsMimeSticker(file.information->filemime)) {
|
||||
Expects(!_fullPreview.isNull());
|
||||
|
||||
moveToLayout(layout);
|
||||
|
@ -105,21 +107,16 @@ AlbumThumbnail::AlbumThumbnail(
|
|||
_editMedia->setIconOverride(&st::sendBoxAlbumGroupEditButtonIconFile);
|
||||
_deleteMedia->setIconOverride(&st::sendBoxAlbumGroupDeleteButtonIconFile);
|
||||
|
||||
updateFileRow(-1);
|
||||
setButtonVisible(false);
|
||||
}
|
||||
|
||||
void AlbumThumbnail::updateFileRow(int row) {
|
||||
if (row < 0) {
|
||||
_editMedia->hide();
|
||||
_deleteMedia->hide();
|
||||
return;
|
||||
}
|
||||
_editMedia->show();
|
||||
_deleteMedia->show();
|
||||
void AlbumThumbnail::setButtonVisible(bool value) {
|
||||
_editMedia->setVisible(value);
|
||||
_deleteMedia->setVisible(value);
|
||||
}
|
||||
|
||||
const auto fileHeight = st::attachPreviewThumbLayout.thumbSize
|
||||
+ st::sendMediaRowSkip;
|
||||
const auto top = row * fileHeight + st::sendBoxFileGroupSkipTop;
|
||||
void AlbumThumbnail::moveButtons(int thumbTop) {
|
||||
const auto top = thumbTop + st::sendBoxFileGroupSkipTop;
|
||||
|
||||
auto right = st::sendBoxFileGroupSkipRight + st::boxPhotoPadding.right();
|
||||
_deleteMedia->moveToRight(right, top);
|
||||
|
@ -173,6 +170,16 @@ int AlbumThumbnail::photoHeight() const {
|
|||
return _photo.height() / style::DevicePixelRatio();
|
||||
}
|
||||
|
||||
int AlbumThumbnail::fileHeight() const {
|
||||
return _isCompressedSticker
|
||||
? photoHeight()
|
||||
: st::attachPreviewThumbLayout.thumbSize;
|
||||
}
|
||||
|
||||
bool AlbumThumbnail::isCompressedSticker() const {
|
||||
return _isCompressedSticker;
|
||||
}
|
||||
|
||||
void AlbumThumbnail::paintInAlbum(
|
||||
QPainter &p,
|
||||
int left,
|
||||
|
@ -422,7 +429,7 @@ bool AlbumThumbnail::containsPoint(QPoint position) const {
|
|||
}
|
||||
|
||||
bool AlbumThumbnail::buttonsContainPoint(QPoint position) const {
|
||||
return (_isPhoto
|
||||
return ((_isPhoto && !_isCompressedSticker)
|
||||
? _lastRectOfModify
|
||||
: _lastRectOfButtons).contains(position);
|
||||
}
|
||||
|
@ -431,7 +438,7 @@ AttachButtonType AlbumThumbnail::buttonTypeFromPoint(QPoint position) const {
|
|||
if (!buttonsContainPoint(position)) {
|
||||
return AttachButtonType::None;
|
||||
}
|
||||
return !_lastRectOfButtons.contains(position)
|
||||
return (!_lastRectOfButtons.contains(position) && !_isCompressedSticker)
|
||||
? AttachButtonType::Modify
|
||||
: (position.x() < _lastRectOfButtons.center().x())
|
||||
? AttachButtonType::Edit
|
||||
|
|
|
@ -33,6 +33,7 @@ public:
|
|||
void resetLayoutAnimation();
|
||||
|
||||
int photoHeight() const;
|
||||
int fileHeight() const;
|
||||
|
||||
void paintInAlbum(
|
||||
QPainter &p,
|
||||
|
@ -53,7 +54,10 @@ public:
|
|||
void suggestMove(float64 delta, Fn<void()> callback);
|
||||
void finishAnimations();
|
||||
|
||||
void updateFileRow(int row);
|
||||
void setButtonVisible(bool value);
|
||||
void moveButtons(int thumbTop);
|
||||
|
||||
bool isCompressedSticker() const;
|
||||
|
||||
static constexpr auto kShrinkDuration = crl::time(150);
|
||||
|
||||
|
@ -89,6 +93,8 @@ private:
|
|||
int _lastShrinkValue = 0;
|
||||
AttachControls _buttons;
|
||||
|
||||
bool _isCompressedSticker = false;
|
||||
|
||||
QRect _lastRectOfModify;
|
||||
QRect _lastRectOfButtons;
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ bool PreparedList::canBeSentInSlowmodeWith(const PreparedList &other) const {
|
|||
return !hasNonGrouping && (!hasFiles || !hasVideos);
|
||||
}
|
||||
|
||||
bool PreparedList::canAddCaption(bool sendingAlbum) const {
|
||||
bool PreparedList::canAddCaption(bool sendingAlbum, bool compress) const {
|
||||
if (!filesToProcess.empty()
|
||||
|| files.empty()
|
||||
|| files.size() > kMaxAlbumCount) {
|
||||
|
@ -146,8 +146,8 @@ bool PreparedList::canAddCaption(bool sendingAlbum) const {
|
|||
}
|
||||
if (files.size() == 1) {
|
||||
Assert(files.front().information != nullptr);
|
||||
const auto isSticker = Core::IsMimeSticker(
|
||||
files.front().information->filemime)
|
||||
const auto isSticker = (!compress
|
||||
&& Core::IsMimeSticker(files.front().information->filemime))
|
||||
|| files.front().path.endsWith(
|
||||
qstr(".tgs"),
|
||||
Qt::CaseInsensitive);
|
||||
|
@ -198,6 +198,26 @@ bool PreparedList::hasSendImagesAsPhotosOption(bool slowmode) const {
|
|||
: ranges::contains(files, Type::Photo, &PreparedFile::type);
|
||||
}
|
||||
|
||||
bool PreparedList::canHaveEditorHintLabel() const {
|
||||
for (const auto &file : files) {
|
||||
if ((file.type == PreparedFile::Type::Photo)
|
||||
&& !Core::IsMimeSticker(file.information->filemime)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool PreparedList::hasSticker() const {
|
||||
for (const auto &file : files) {
|
||||
if ((file.type == PreparedFile::Type::Photo)
|
||||
&& Core::IsMimeSticker(file.information->filemime)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
int MaxAlbumItems() {
|
||||
return kMaxAlbumCount;
|
||||
}
|
||||
|
|
|
@ -106,13 +106,15 @@ struct PreparedList {
|
|||
std::vector<int> order);
|
||||
void mergeToEnd(PreparedList &&other, bool cutToAlbumSize = false);
|
||||
|
||||
[[nodiscard]] bool canAddCaption(bool sendingAlbum) const;
|
||||
[[nodiscard]] bool canAddCaption(bool sendingAlbum, bool compress) const;
|
||||
[[nodiscard]] bool canBeSentInSlowmode() const;
|
||||
[[nodiscard]] bool canBeSentInSlowmodeWith(
|
||||
const PreparedList &other) const;
|
||||
|
||||
[[nodiscard]] bool hasGroupOption(bool slowmode) const;
|
||||
[[nodiscard]] bool hasSendImagesAsPhotosOption(bool slowmode) const;
|
||||
[[nodiscard]] bool canHaveEditorHintLabel() const;
|
||||
[[nodiscard]] bool hasSticker() const;
|
||||
|
||||
Error error = Error::None;
|
||||
QString errorData;
|
||||
|
|
|
@ -13,6 +13,9 @@ void SendFilesWay::setSendImagesAsPhotos(bool value) {
|
|||
if (value) {
|
||||
_flags |= Flag::SendImagesAsPhotos;
|
||||
} else {
|
||||
if (hasCompressedStickers()) {
|
||||
setGroupFiles(false);
|
||||
}
|
||||
_flags &= ~Flag::SendImagesAsPhotos;
|
||||
}
|
||||
}
|
||||
|
@ -20,11 +23,22 @@ void SendFilesWay::setSendImagesAsPhotos(bool value) {
|
|||
void SendFilesWay::setGroupFiles(bool value) {
|
||||
if (value) {
|
||||
_flags |= Flag::GroupFiles;
|
||||
if (hasCompressedStickers()) {
|
||||
setSendImagesAsPhotos(true);
|
||||
}
|
||||
} else {
|
||||
_flags &= ~Flag::GroupFiles;
|
||||
}
|
||||
}
|
||||
|
||||
void SendFilesWay::setHasCompressedStickers(bool value) {
|
||||
if (value) {
|
||||
_flags |= Flag::HasCompressedStickers;
|
||||
} else {
|
||||
_flags &= ~Flag::HasCompressedStickers;
|
||||
}
|
||||
}
|
||||
|
||||
//enum class SendFilesWay { // Old way. Serialize should be compatible.
|
||||
// Album,
|
||||
// Photos,
|
||||
|
|
|
@ -28,6 +28,7 @@ public:
|
|||
}
|
||||
void setGroupFiles(bool value);
|
||||
void setSendImagesAsPhotos(bool value);
|
||||
void setHasCompressedStickers(bool value);
|
||||
|
||||
[[nodiscard]] inline bool operator<(const SendFilesWay &other) const {
|
||||
return _flags < other._flags;
|
||||
|
@ -53,9 +54,14 @@ public:
|
|||
int32 value);
|
||||
|
||||
private:
|
||||
[[nodiscard]] bool hasCompressedStickers() const {
|
||||
return (_flags & Flag::HasCompressedStickers) != 0;
|
||||
}
|
||||
|
||||
enum class Flag : uchar {
|
||||
GroupFiles = (1 << 0),
|
||||
SendImagesAsPhotos = (1 << 1),
|
||||
HasCompressedStickers = (1 << 2),
|
||||
|
||||
Default = GroupFiles | SendImagesAsPhotos,
|
||||
};
|
||||
|
|
Loading…
Add table
Reference in a new issue