Add a way to recreate SendFilesBox content.

This commit is contained in:
John Preston 2020-10-16 13:38:12 +03:00
parent 202534575b
commit 0539cc9448
11 changed files with 217 additions and 155 deletions

View file

@ -4235,6 +4235,7 @@ void ApiWrap::sendFiles(
type = SendMediaType::Photo; type = SendMediaType::Photo;
break; break;
case Ui::PreparedFile::AlbumType::Video: case Ui::PreparedFile::AlbumType::Video:
case Ui::PreparedFile::AlbumType::File:
type = SendMediaType::File; type = SendMediaType::File;
break; break;
default: Unexpected("AlbumType in uploadFilesAfterConfirmation"); default: Unexpected("AlbumType in uploadFilesAfterConfirmation");

View file

@ -489,7 +489,7 @@ backgroundScroll: ScrollArea(boxScroll) {
deltab: 10px; deltab: 10px;
} }
editMediaButtonSize: 29px; editMediaButtonSize: 28px;
editMediaButtonSkip: 8px; editMediaButtonSkip: 8px;
editMediaButtonFileSkipRight: 1px; editMediaButtonFileSkipRight: 1px;
editMediaButtonFileSkipTop: 7px; editMediaButtonFileSkipTop: 7px;
@ -514,6 +514,10 @@ sendBoxAlbumGroupSkipTop: 6px;
sendBoxAlbumGroupRadius: 12px; sendBoxAlbumGroupRadius: 12px;
sendBoxAlbumGroupHeight: 25px; sendBoxAlbumGroupHeight: 25px;
sendBoxFileGroupSkipTop: 2px;
sendBoxFileGroupSkipRight: 0px;
sendBoxFileGroupEditInternalSkip: 4px;
sendBoxAlbumGroupEditButtonIcon: editMediaButtonIconPhoto; sendBoxAlbumGroupEditButtonIcon: editMediaButtonIconPhoto;
sendBoxAlbumGroupEditButtonIconPosition: point(4px, -1px); sendBoxAlbumGroupEditButtonIconPosition: point(4px, -1px);

View file

@ -689,7 +689,7 @@ bool EditCaptionBox::fileFromClipboard(not_null<const QMimeData*> data) {
} }
const auto file = &list.files.front(); const auto file = &list.files.front();
if (_isAlbum && (file->type == AlbumType::File)) { if (_isAlbum && (file->type == AlbumType::File || file->type == AlbumType::None)) {
const auto imageAsDoc = [&] { const auto imageAsDoc = [&] {
using Info = Ui::PreparedFileInformation; using Info = Ui::PreparedFileInformation;
const auto fileMedia = &file->information->media; const auto fileMedia = &file->information->media;

View file

@ -100,6 +100,95 @@ rpl::producer<QString> FieldPlaceholder(
} // namespace } // namespace
SendFilesBox::Block::Block(
not_null<QWidget*> parent,
not_null<std::vector<Ui::PreparedFile>*> items,
int from,
int till,
Fn<bool()> gifPaused,
SendFilesWay way)
: _items(items)
, _from(from)
, _till(till) {
Expects(from >= 0);
Expects(till > from);
Expects(till <= items->size());
const auto count = till - from;
const auto my = gsl::make_span(*items).subspan(from, count);
const auto &first = my.front();
_isAlbum = (my.size() > 1)
|| (first.type == Ui::PreparedFile::AlbumType::Photo);
if (_isAlbum) {
const auto preview = Ui::CreateChild<Ui::AlbumPreview>(
parent.get(),
my,
way);
_preview.reset(preview);
} else {
const auto media = Ui::SingleMediaPreview::Create(
parent,
gifPaused,
first);
if (media) {
_preview.reset(media);
} else {
_preview.reset(
Ui::CreateChild<Ui::SingleFilePreview>(parent.get(), first));
}
}
_preview->show();
}
int SendFilesBox::Block::fromIndex() const {
return _from;
}
int SendFilesBox::Block::tillIndex() const {
return _till;
}
object_ptr<Ui::RpWidget> SendFilesBox::Block::takeWidget() {
return object_ptr<Ui::RpWidget>::fromRaw(_preview.get());
}
void SendFilesBox::Block::setSendWay(Ui::SendFilesWay way) {
if (!_isAlbum) {
return;
}
applyAlbumOrder();
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
album->setSendWay(way);
}
void SendFilesBox::Block::applyAlbumOrder() {
if (!_isAlbum) {
return;
}
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
const auto order = album->takeOrder();
const auto isIdentity = [&] {
for (auto i = 0, count = int(order.size()); i != count; ++i) {
if (order[i] != i) {
return false;
}
}
return true;
}();
if (isIdentity) {
return;
}
auto elements = std::vector<Ui::PreparedFile>();
elements.reserve(order.size());
for (const auto index : order) {
elements.push_back(std::move((*_items)[_from + index]));
}
for (auto i = 0, count = int(order.size()); i != count; ++i) {
(*_items)[_from + i] = std::move(elements[i]);
}
}
SendFilesBox::SendFilesBox( SendFilesBox::SendFilesBox(
QWidget*, QWidget*,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
@ -147,36 +236,6 @@ void SendFilesBox::initPreview() {
}, _dimensionsLifetime); }, _dimensionsLifetime);
} }
//void SendFilesBox::prepareSingleFilePreview() {
// const auto &file = _list.files[0];
// const auto controller = _controller;
// const auto media = Ui::SingleMediaPreview::Create(this, [=] {
// return controller->isGifPausedAtLeastFor(
// Window::GifPauseReason::Layer);
// }, file);
// if (media) {
// _preview = media;
// initPreview(media->desiredHeightValue());
// } else {
// const auto preview = Ui::CreateChild<Ui::SingleFilePreview>(this, file);
// _preview = preview;
// initPreview(preview->desiredHeightValue());
// }
//}
//void SendFilesBox::prepareAlbumPreview() {
// addThumbButtonHandlers(wrap); // #TODO files
//
// setupShadows(wrap, _albumPreview);
//
// initPreview(_albumPreview->desiredHeightValue());
//
// crl::on_main([=] {
// wrap->scrollToY(_lastScrollTop);
// _lastScrollTop = 0;
// });
//}
void SendFilesBox::addThumbButtonHandlers(not_null<Ui::ScrollArea*> wrap) { void SendFilesBox::addThumbButtonHandlers(not_null<Ui::ScrollArea*> wrap) {
// #TODO files // #TODO files
//_albumPreview->thumbDeleted( //_albumPreview->thumbDeleted(
@ -224,14 +283,12 @@ void SendFilesBox::addThumbButtonHandlers(not_null<Ui::ScrollArea*> wrap) {
//}, _albumPreview->lifetime()); //}, _albumPreview->lifetime());
} }
void SendFilesBox::setupShadows( void SendFilesBox::setupShadows() {
not_null<Ui::ScrollArea*> wrap,
not_null<Ui::AlbumPreview*> content) {
using namespace rpl::mappers; using namespace rpl::mappers;
const auto topShadow = Ui::CreateChild<Ui::FadeShadow>(this); const auto topShadow = Ui::CreateChild<Ui::FadeShadow>(this);
const auto bottomShadow = Ui::CreateChild<Ui::FadeShadow>(this); const auto bottomShadow = Ui::CreateChild<Ui::FadeShadow>(this);
wrap->geometryValue( _scroll->geometryValue(
) | rpl::start_with_next_done([=](const QRect &geometry) { ) | rpl::start_with_next_done([=](const QRect &geometry) {
topShadow->resizeToWidth(geometry.width()); topShadow->resizeToWidth(geometry.width());
topShadow->move( topShadow->move(
@ -246,11 +303,11 @@ void SendFilesBox::setupShadows(
Ui::DestroyChild(b.data()); Ui::DestroyChild(b.data());
}, topShadow->lifetime()); }, topShadow->lifetime());
topShadow->toggleOn(wrap->scrollTopValue() | rpl::map(_1 > 0)); topShadow->toggleOn(_scroll->scrollTopValue() | rpl::map(_1 > 0));
bottomShadow->toggleOn(rpl::combine( bottomShadow->toggleOn(rpl::combine(
wrap->scrollTopValue(), _scroll->scrollTopValue(),
wrap->heightValue(), _scroll->heightValue(),
content->heightValue(), _inner->heightValue(),
_1 + _2 < _3)); _1 + _2 < _3));
} }
@ -269,9 +326,7 @@ void SendFilesBox::prepare() {
setupSendWayControls(); setupSendWayControls();
preparePreview(); preparePreview();
initPreview(); initPreview();
setupShadows();
_scroll->show();
_inner->show();
boxClosing() | rpl::start_with_next([=] { boxClosing() | rpl::start_with_next([=] {
if (!_confirmed && _cancelledCallback) { if (!_confirmed && _cancelledCallback) {
@ -364,6 +419,9 @@ void SendFilesBox::initSendWay() {
) | rpl::start_with_next([=](SendFilesWay value) { ) | rpl::start_with_next([=](SendFilesWay value) {
updateCaptionPlaceholder(); updateCaptionPlaceholder();
updateEmojiPanelGeometry(); updateEmojiPanelGeometry();
for (auto &block : _blocks) {
block.setSendWay(value);
}
setInnerFocus(); setInnerFocus();
}, lifetime()); }, lifetime());
} }
@ -389,73 +447,59 @@ void SendFilesBox::updateCaptionPlaceholder() {
} }
void SendFilesBox::preparePreview() { void SendFilesBox::preparePreview() {
generatePreviewFrom(0);
}
void SendFilesBox::generatePreviewFrom(int fromBlock) {
Expects(fromBlock <= _blocks.size());
using Type = Ui::PreparedFile::AlbumType; using Type = Ui::PreparedFile::AlbumType;
_blocks.clear(); _blocks.erase(_blocks.begin() + fromBlock, _blocks.end());
const auto fromItem = _blocks.empty() ? 0 : _blocks.back().tillIndex();
Assert(fromItem <= _list.files.size());
auto albumStart = -1; auto albumStart = -1;
const auto finishAlbum = [&](int till) { const auto gifPaused = [controller = _controller] {
if (albumStart < 0) { return controller->isGifPausedAtLeastFor(
return; Window::GifPauseReason::Layer);
}
const auto count = (till - albumStart);
const auto preview = _inner->add(object_ptr<Ui::AlbumPreview>(
this,
gsl::make_span(_list.files).subspan(albumStart, count),
_sendWay.current()));
auto &block = _blocks.emplace_back();
block.fromIndex = albumStart;
block.tillIndex = albumStart + count;
block.preview.reset(preview);
block.preview->show();
_sendWay.changes(
) | rpl::start_with_next([=](SendFilesWay value) {
applyAlbumOrder(preview, albumStart);
preview->setSendWay(value);
}, preview->lifetime());
albumStart = -1;
}; };
const auto finishSingle = [&](int index) { const auto pushBlock = [&](int from, int till) {
const auto &file = _list.files[index]; _blocks.emplace_back(
const auto controller = _controller; _inner.data(),
auto &block = _blocks.emplace_back(); &_list.files,
block.fromIndex = index; from,
block.tillIndex = index + 1; till,
const auto media = Ui::SingleMediaPreview::Create(this, [=] { gifPaused,
return controller->isGifPausedAtLeastFor( _sendWay.current());
Window::GifPauseReason::Layer); _inner->add(_blocks.back().takeWidget());
}, file);
if (media) {
block.preview.reset(
_inner->add(object_ptr<Ui::SingleMediaPreview>::fromRaw(
media)));
} else {
block.preview.reset(
_inner->add(object_ptr<Ui::SingleFilePreview>(this, file)));
}
block.preview->show();
}; };
for (auto i = 0, count = int(_list.files.size()); i != count; ++i) { for (auto i = fromItem, till = int(_list.files.size()); i != till; ++i) {
const auto type = _list.files[i].type; const auto type = _list.files[i].type;
if (albumStart >= 0) { if (albumStart >= 0) {
const auto albumCount = (i - albumStart); const auto albumCount = (i - albumStart);
if (type == Type::File || (albumCount == Ui::MaxAlbumItems())) { if ((type == Type::File)
finishAlbum(i); || (type == Type::None)
|| (albumCount == Ui::MaxAlbumItems())) {
pushBlock(std::exchange(albumStart, -1), i);
} else { } else {
continue; continue;
} }
} }
if (type != Type::File) { if (type != Type::File && type != Type::None) {
if (albumStart < 0) { if (albumStart < 0) {
albumStart = i; albumStart = i;
} }
continue; continue;
} }
finishSingle(i); pushBlock(i, i + 1);
} }
finishAlbum(_list.files.size()); if (albumStart >= 0) {
pushBlock(albumStart, _list.files.size());
}
_scroll->scrollToY(0);
} }
void SendFilesBox::setupControls() { void SendFilesBox::setupControls() {
@ -520,32 +564,6 @@ void SendFilesBox::updateSendWayControlsVisibility() {
_groupFiles->setVisible(!onlyOne); _groupFiles->setVisible(!onlyOne);
} }
void SendFilesBox::applyAlbumOrder(
not_null<Ui::AlbumPreview*> preview,
int from) {
const auto order = preview->takeOrder();
const auto isDefault = [&] {
for (auto i = 0, count = int(order.size()); i != count; ++i) {
if (order[i] != i) {
return false;
}
}
return true;
}();
if (isDefault) {
return;
}
auto elements = std::vector<Ui::PreparedFile>();
elements.reserve(order.size());
for (const auto index : order) {
elements.push_back(std::move(_list.files[from + index]));
}
for (auto i = 0, count = int(order.size()); i != count; ++i) {
_list.files[from + i] = std::move(elements[i]);
}
}
void SendFilesBox::setupCaption() { void SendFilesBox::setupCaption() {
_caption->setMaxLength( _caption->setMaxLength(
_controller->session().serverConfig().captionLengthMax); _controller->session().serverConfig().captionLengthMax);
@ -854,7 +872,9 @@ void SendFilesBox::send(
Core::App().saveSettingsDelayed(); Core::App().saveSettingsDelayed();
} }
//applyAlbumOrder(); // #TODO files for (auto &block : _blocks) {
block.applyAlbumOrder();
}
_confirmed = true; _confirmed = true;
if (_confirmedCallback) { if (_confirmedCallback) {
auto caption = (_caption && !_caption->isHidden()) auto caption = (_caption && !_caption->isHidden())

View file

@ -84,10 +84,32 @@ protected:
void resizeEvent(QResizeEvent *e) override; void resizeEvent(QResizeEvent *e) override;
private: private:
struct Block { class Block final {
base::unique_qptr<Ui::RpWidget> preview; public:
int fromIndex = 0; Block(
int tillIndex = 0; not_null<QWidget*> parent,
not_null<std::vector<Ui::PreparedFile>*> items,
int from,
int till,
Fn<bool()> gifPaused,
Ui::SendFilesWay way);
Block(Block &&other) = default;
Block &operator=(Block &&other) = default;
[[nodiscard]] int fromIndex() const;
[[nodiscard]] int tillIndex() const;
[[nodiscard]] object_ptr<Ui::RpWidget> takeWidget();
void setSendWay(Ui::SendFilesWay way);
void applyAlbumOrder();
private:
base::unique_qptr<Ui::RpWidget> _preview;
not_null<std::vector<Ui::PreparedFile>*> _items;
int _from = 0;
int _till = 0;
bool _isAlbum = false;
}; };
void initSendWay(); void initSendWay();
void initPreview(); void initPreview();
@ -95,9 +117,7 @@ private:
void setupControls(); void setupControls();
void setupSendWayControls(); void setupSendWayControls();
void setupCaption(); void setupCaption();
void setupShadows( void setupShadows();
not_null<Ui::ScrollArea*> wrap,
not_null<Ui::AlbumPreview*> content);
void setupEmojiPanel(); void setupEmojiPanel();
void updateSendWayControlsVisibility(); void updateSendWayControlsVisibility();
@ -105,7 +125,7 @@ private:
void emojiFilterForGeometry(not_null<QEvent*> event); void emojiFilterForGeometry(not_null<QEvent*> event);
void preparePreview(); void preparePreview();
void applyAlbumOrder(not_null<Ui::AlbumPreview*> preview, int from); void generatePreviewFrom(int fromBlock);
void send(Api::SendOptions options, bool ctrlShiftEnter = false); void send(Api::SendOptions options, bool ctrlShiftEnter = false);
void sendSilent(); void sendSilent();

View file

@ -97,6 +97,8 @@ bool PrepareDetailsIsWaiting(
Assert(!file.preview.isNull()); Assert(!file.preview.isNull());
file.preview.setDevicePixelRatio(cRetinaFactor()); file.preview.setDevicePixelRatio(cRetinaFactor());
file.type = PreparedFile::AlbumType::Photo; file.type = PreparedFile::AlbumType::Photo;
} else if (Core::IsMimeSticker(file.mime)) {
file.type = PreparedFile::AlbumType::None;
} }
} else if (const auto video = std::get_if<Video>( } else if (const auto video = std::get_if<Video>(
&file.information->media)) { &file.information->media)) {
@ -257,7 +259,7 @@ PreparedList PrepareMediaFromImage(
QImage &&image, QImage &&image,
QByteArray &&content, QByteArray &&content,
int previewWidth) { int previewWidth) {
auto result = Storage::PreparedList(); auto result = PreparedList();
auto file = PreparedFile(QString()); auto file = PreparedFile(QString());
file.content = content; file.content = content;
if (file.content.isEmpty()) { if (file.content.isEmpty()) {
@ -283,7 +285,7 @@ std::optional<PreparedList> PreparedFileFromFilesDialog(
} }
if (!result.remoteContent.isEmpty()) { if (!result.remoteContent.isEmpty()) {
auto list = Storage::PrepareMediaFromImage( auto list = PrepareMediaFromImage(
QImage(), QImage(),
std::move(result.remoteContent), std::move(result.remoteContent),
previewWidth); previewWidth);
@ -297,7 +299,8 @@ std::optional<PreparedList> PreparedFileFromFilesDialog(
if (isAlbum) { if (isAlbum) {
const auto file = &list.files.front(); const auto file = &list.files.front();
if (!Core::IsMimeAcceptedForAlbum(mimeFile) if (!Core::IsMimeAcceptedForAlbum(mimeFile)
|| file->type == Storage::PreparedFile::AlbumType::File) { || file->type == PreparedFile::AlbumType::File
|| file->type == PreparedFile::AlbumType::File) {
errorCallback(tr::lng_edit_media_album_error); errorCallback(tr::lng_edit_media_album_error);
return std::nullopt; return std::nullopt;
} }
@ -306,7 +309,7 @@ std::optional<PreparedList> PreparedFileFromFilesDialog(
return list; return list;
} else if (!result.paths.isEmpty()) { } else if (!result.paths.isEmpty()) {
const auto isSingleFile = (result.paths.size() == 1); const auto isSingleFile = (result.paths.size() == 1);
auto temp = Storage::PrepareMediaList(result.paths, previewWidth); auto temp = PrepareMediaList(result.paths, previewWidth);
if (temp.error != PreparedList::Error::None) { if (temp.error != PreparedList::Error::None) {
errorCallback(tr::lng_send_media_invalid_files); errorCallback(tr::lng_send_media_invalid_files);
return std::nullopt; return std::nullopt;

View file

@ -22,13 +22,12 @@ constexpr auto kDragDuration = crl::time(200);
AlbumPreview::AlbumPreview( AlbumPreview::AlbumPreview(
QWidget *parent, QWidget *parent,
gsl::span<PreparedFile> list, gsl::span<Ui::PreparedFile> items,
SendFilesWay way) SendFilesWay way)
: RpWidget(parent) : RpWidget(parent)
, _list(list)
, _sendWay(way) { , _sendWay(way) {
setMouseTracking(true); setMouseTracking(true);
prepareThumbs(); prepareThumbs(items);
updateSize(); updateSize();
updateFileRows(); updateFileRows();
} }
@ -55,25 +54,26 @@ void AlbumPreview::updateFileRows() {
} }
std::vector<int> AlbumPreview::takeOrder() { std::vector<int> AlbumPreview::takeOrder() {
Expects(_thumbs.size() == _order.size());
Expects(_itemsShownDimensions.size() == _order.size());
auto reordered = std::vector<std::unique_ptr<AlbumThumbnail>>(); auto reordered = std::vector<std::unique_ptr<AlbumThumbnail>>();
auto reorderedShownDimensions = std::vector<QSize>();
reordered.reserve(_thumbs.size()); reordered.reserve(_thumbs.size());
reorderedShownDimensions.reserve(_itemsShownDimensions.size());
for (auto index : _order) { for (auto index : _order) {
reordered.push_back(std::move(_thumbs[index])); reordered.push_back(std::move(_thumbs[index]));
reorderedShownDimensions.push_back(_itemsShownDimensions[index]);
} }
_thumbs = std::move(reordered); _thumbs = std::move(reordered);
_itemsShownDimensions = std::move(reorderedShownDimensions);
return std::exchange(_order, defaultOrder()); return std::exchange(_order, defaultOrder());
} }
auto AlbumPreview::generateOrderedLayout() const auto AlbumPreview::generateOrderedLayout() const
-> std::vector<GroupMediaLayout> { -> std::vector<GroupMediaLayout> {
auto sizes = ranges::view::all(
_order
) | ranges::view::transform([&](int index) {
return _list[index].shownDimensions;
}) | ranges::to_vector;
auto layout = LayoutMediaGroup( auto layout = LayoutMediaGroup(
sizes, _itemsShownDimensions,
st::sendMediaPreviewSize, st::sendMediaPreviewSize,
st::historyGroupWidthMin / 2, st::historyGroupWidthMin / 2,
st::historyGroupSkip / 2); st::historyGroupSkip / 2);
@ -81,20 +81,29 @@ auto AlbumPreview::generateOrderedLayout() const
return layout; return layout;
} }
std::vector<int> AlbumPreview::defaultOrder() const { std::vector<int> AlbumPreview::defaultOrder(int count) const {
const auto count = int(_list.size()); Expects(count > 0 || !_order.empty());
if (count < 0) {
count = _order.size();
}
return ranges::view::ints(0, count) | ranges::to_vector; return ranges::view::ints(0, count) | ranges::to_vector;
} }
void AlbumPreview::prepareThumbs() { void AlbumPreview::prepareThumbs(gsl::span<Ui::PreparedFile> items) {
_order = defaultOrder(); _order = defaultOrder(items.size());
_itemsShownDimensions = ranges::view::all(
_order
) | ranges::view::transform([&](int index) {
return items[index].shownDimensions;
}) | ranges::to_vector;
const auto count = int(_list.size()); const auto count = int(_order.size());
const auto layout = generateOrderedLayout(); const auto layout = generateOrderedLayout();
_thumbs.reserve(count); _thumbs.reserve(count);
for (auto i = 0; i != count; ++i) { for (auto i = 0; i != count; ++i) {
_thumbs.push_back(std::make_unique<AlbumThumbnail>( _thumbs.push_back(std::make_unique<AlbumThumbnail>(
_list[i], items[i],
layout[i], layout[i],
this, this,
[=] { changeThumbByIndex(thumbIndex(thumbUnderCursor())); }, [=] { changeThumbByIndex(thumbIndex(thumbUnderCursor())); },

View file

@ -20,7 +20,7 @@ class AlbumPreview final : public RpWidget {
public: public:
AlbumPreview( AlbumPreview(
QWidget *parent, QWidget *parent,
gsl::span<PreparedFile> list, gsl::span<Ui::PreparedFile> items,
SendFilesWay way); SendFilesWay way);
~AlbumPreview(); ~AlbumPreview();
@ -45,8 +45,8 @@ private:
int countLayoutHeight( int countLayoutHeight(
const std::vector<GroupMediaLayout> &layout) const; const std::vector<GroupMediaLayout> &layout) const;
std::vector<GroupMediaLayout> generateOrderedLayout() const; std::vector<GroupMediaLayout> generateOrderedLayout() const;
std::vector<int> defaultOrder() const; std::vector<int> defaultOrder(int count = -1) const;
void prepareThumbs(); void prepareThumbs(gsl::span<Ui::PreparedFile> items);
void updateSizeAnimated(const std::vector<GroupMediaLayout> &layout); void updateSizeAnimated(const std::vector<GroupMediaLayout> &layout);
void updateSize(); void updateSize();
void updateFileRows(); void updateFileRows();
@ -73,10 +73,10 @@ private:
void cancelDrag(); void cancelDrag();
void finishDrag(); void finishDrag();
gsl::span<PreparedFile> _list;
SendFilesWay _sendWay; SendFilesWay _sendWay;
style::cursor _cursor = style::cur_default; style::cursor _cursor = style::cur_default;
std::vector<int> _order; std::vector<int> _order;
std::vector<QSize> _itemsShownDimensions;
std::vector<std::unique_ptr<AlbumThumbnail>> _thumbs; std::vector<std::unique_ptr<AlbumThumbnail>> _thumbs;
int _thumbsHeight = 0; int _thumbsHeight = 0;
int _photosHeight = 0; int _photosHeight = 0;

View file

@ -127,12 +127,12 @@ void AlbumThumbnail::updateFileRow(int row) {
const auto fileHeight = st::sendMediaFileThumbSize const auto fileHeight = st::sendMediaFileThumbSize
+ st::sendMediaFileThumbSkip; + st::sendMediaFileThumbSkip;
const auto top = row * fileHeight + st::sendBoxAlbumGroupSkipTop; const auto top = row * fileHeight + st::sendBoxFileGroupSkipTop;
const auto size = st::editMediaButtonSize; const auto size = st::editMediaButtonSize;
auto right = st::sendBoxAlbumGroupSkipRight + size; auto right = st::sendBoxFileGroupSkipRight + size;
_deleteMedia->moveToRight(right, top); _deleteMedia->moveToRight(right, top);
right += st::sendBoxAlbumGroupEditInternalSkip + size; right += st::sendBoxFileGroupEditInternalSkip + size;
_editMedia->moveToRight(right, top); _editMedia->moveToRight(right, top);
} }

View file

@ -68,6 +68,10 @@ bool PreparedList::canBeSentInSlowmode() const {
return false; return false;
} }
const auto hasNonGrouping = ranges::contains(
files,
PreparedFile::AlbumType::None,
&PreparedFile::type);
const auto hasFiles = ranges::contains( const auto hasFiles = ranges::contains(
files, files,
PreparedFile::AlbumType::File, PreparedFile::AlbumType::File,
@ -78,7 +82,7 @@ bool PreparedList::canBeSentInSlowmode() const {
&PreparedFile::type); &PreparedFile::type);
// File-s and Video-s never can be grouped. // File-s and Video-s never can be grouped.
return !hasFiles || !hasVideos; return !hasNonGrouping && (!hasFiles || !hasVideos);
} }
bool PreparedList::canAddCaption(bool groupMediaInAlbums) const { bool PreparedList::canAddCaption(bool groupMediaInAlbums) const {

View file

@ -46,6 +46,7 @@ struct PreparedFile {
File, File,
Photo, Photo,
Video, Video,
None,
}; };
PreparedFile(const QString &path); PreparedFile(const QString &path);