Allow delete / replace items in SendFilesBox.

This commit is contained in:
John Preston 2020-10-17 20:09:06 +03:00
parent bb4fdde616
commit 5589f51369
3 changed files with 94 additions and 66 deletions

View file

@ -153,6 +153,22 @@ object_ptr<Ui::RpWidget> SendFilesBox::Block::takeWidget() {
return object_ptr<Ui::RpWidget>::fromRaw(_preview.get()); return object_ptr<Ui::RpWidget>::fromRaw(_preview.get());
} }
rpl::producer<int> SendFilesBox::Block::itemDeleteRequest() const {
if (!_isAlbum) {
return rpl::never<int>();
}
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
return album->thumbDeleted();
}
rpl::producer<int> SendFilesBox::Block::itemReplaceRequest() const {
if (!_isAlbum) {
return rpl::never<int>();
}
const auto album = static_cast<Ui::AlbumPreview*>(_preview.get());
return album->thumbChanged();
}
void SendFilesBox::Block::setSendWay(Ui::SendFilesWay way) { void SendFilesBox::Block::setSendWay(Ui::SendFilesWay way) {
if (!_isAlbum) { if (!_isAlbum) {
return; return;
@ -238,52 +254,6 @@ void SendFilesBox::initPreview() {
}, _dimensionsLifetime); }, _dimensionsLifetime);
} }
void SendFilesBox::addThumbButtonHandlers(not_null<Ui::ScrollArea*> wrap) {
// #TODO files
//_albumPreview->thumbDeleted(
//) | rpl::start_with_next([=](auto index) {
// _lastScrollTop = wrap->scrollTop();
// _list.files.erase(_list.files.begin() + index);
// applyAlbumOrder();
// if (_preview) {
// _preview->deleteLater();
// }
// _albumPreview = nullptr;
// refreshAllAfterAlbumChanges();
//}, _albumPreview->lifetime());
//_albumPreview->thumbChanged(
//) | rpl::start_with_next([=](auto index) {
// _lastScrollTop = wrap->scrollTop();
// const auto callback = [=](FileDialog::OpenResult &&result) {
// FileDialogCallback(
// std::move(result),
// [=] (auto list) {
// _list.files[index] = std::move(list.files.front());
// applyAlbumOrder();
// if (_preview) {
// _preview->deleteLater();
// }
// _albumPreview = nullptr;
// refreshAllAfterAlbumChanges();
// });
// };
// FileDialog::GetOpenPath(
// this,
// tr::lng_choose_file(tr::now),
// FileDialog::AllOrImagesFilter(),
// crl::guard(this, callback));
//}, _albumPreview->lifetime());
}
void SendFilesBox::enqueueNextPrepare() { void SendFilesBox::enqueueNextPrepare() {
if (_preparing) { if (_preparing) {
return; return;
@ -497,20 +467,6 @@ void SendFilesBox::generatePreviewFrom(int fromBlock) {
Assert(fromItem <= _list.files.size()); Assert(fromItem <= _list.files.size());
auto albumStart = -1; auto albumStart = -1;
const auto gifPaused = [controller = _controller] {
return controller->isGifPausedAtLeastFor(
Window::GifPauseReason::Layer);
};
const auto pushBlock = [&](int from, int till) {
_blocks.emplace_back(
_inner.data(),
&_list.files,
from,
till,
gifPaused,
_sendWay.current());
_inner->add(_blocks.back().takeWidget());
};
for (auto i = fromItem, till = int(_list.files.size()); i != till; ++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) {
@ -536,6 +492,77 @@ void SendFilesBox::generatePreviewFrom(int fromBlock) {
} }
} }
void SendFilesBox::pushBlock(int from, int till) {
const auto gifPaused = [controller = _controller] {
return controller->isGifPausedAtLeastFor(
Window::GifPauseReason::Layer);
};
const auto index = int(_blocks.size());
_blocks.emplace_back(
_inner.data(),
&_list.files,
from,
till,
gifPaused,
_sendWay.current());
auto &block = _blocks.back();
const auto widget = _inner->add(block.takeWidget());
block.itemDeleteRequest(
) | rpl::filter([=] {
return !_removingIndex;
}) | rpl::start_with_next([=](int index) {
_removingIndex = from + index;
crl::on_main(this, [=] {
const auto index = base::take(_removingIndex).value_or(-1);
if (index < 0 || index >= _list.files.size()) {
return;
}
_list.files.erase(_list.files.begin() + index);
refreshAllAfterChanges(from);
});
}, widget->lifetime());
block.itemReplaceRequest(
) | rpl::start_with_next([=](int index) {
const auto replace = [=](Ui::PreparedList list) {
if (list.files.empty()) {
return;
}
_list.files[from + index] = std::move(list.files.front());
refreshAllAfterChanges(from);
};
const auto checkResult = [=](const Ui::PreparedList &list) {
if (_sendLimit != SendLimit::One) {
return true;
}
auto removing = std::move(_list.files[from + index]);
std::swap(_list.files[from + index], _list.files.back());
_list.files.pop_back();
const auto result = _list.canBeSentInSlowmodeWith(list);
_list.files.push_back(std::move(removing));
std::swap(_list.files[from + index], _list.files.back());
if (!result) {
Ui::Toast::Show(tr::lng_slowmode_no_many(tr::now));
return false;
}
return true;
};
const auto callback = [=](FileDialog::OpenResult &&result) {
FileDialogCallback(
std::move(result),
checkResult,
replace);
};
FileDialog::GetOpenPath(
this,
tr::lng_choose_file(tr::now),
FileDialog::AllOrImagesFilter(),
crl::guard(this, callback));
}, widget->lifetime());
}
void SendFilesBox::refreshControls() { void SendFilesBox::refreshControls() {
refreshTitleText(); refreshTitleText();
updateSendWayControlsVisibility(); updateSendWayControlsVisibility();

View file

@ -100,6 +100,9 @@ private:
[[nodiscard]] int tillIndex() const; [[nodiscard]] int tillIndex() const;
[[nodiscard]] object_ptr<Ui::RpWidget> takeWidget(); [[nodiscard]] object_ptr<Ui::RpWidget> takeWidget();
[[nodiscard]] rpl::producer<int> itemDeleteRequest() const;
[[nodiscard]] rpl::producer<int> itemReplaceRequest() const;
void setSendWay(Ui::SendFilesWay way); void setSendWay(Ui::SendFilesWay way);
void applyAlbumOrder(); void applyAlbumOrder();
@ -138,12 +141,11 @@ private:
void updateControlsGeometry(); void updateControlsGeometry();
void updateCaptionPlaceholder(); void updateCaptionPlaceholder();
void addThumbButtonHandlers(not_null<Ui::ScrollArea*> wrap);
bool canAddFiles(not_null<const QMimeData*> data) const; bool canAddFiles(not_null<const QMimeData*> data) const;
bool addFiles(not_null<const QMimeData*> data); bool addFiles(not_null<const QMimeData*> data);
bool addFiles(Ui::PreparedList list); bool addFiles(Ui::PreparedList list);
void addFile(Ui::PreparedFile &&file); void addFile(Ui::PreparedFile &&file);
void pushBlock(int from, int till);
void openDialogToAddFileToAlbum(); void openDialogToAddFileToAlbum();
void refreshAllAfterChanges(int fromItem); void refreshAllAfterChanges(int fromItem);
@ -158,6 +160,7 @@ private:
int _titleHeight = 0; int _titleHeight = 0;
Ui::PreparedList _list; Ui::PreparedList _list;
std::optional<int> _removingIndex;
SendLimit _sendLimit = SendLimit::Many; SendLimit _sendLimit = SendLimit::Many;
SendMenu::Type _sendMenuType = SendMenu::Type(); SendMenu::Type _sendMenuType = SendMenu::Type();

View file

@ -54,8 +54,8 @@ void AlbumPreview::updateFileRows() {
} }
std::vector<int> AlbumPreview::takeOrder() { std::vector<int> AlbumPreview::takeOrder() {
Expects(_thumbs.size() == _order.size()); //Expects(_thumbs.size() == _order.size());
Expects(_itemsShownDimensions.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>(); auto reorderedShownDimensions = std::vector<QSize>();
@ -82,8 +82,6 @@ auto AlbumPreview::generateOrderedLayout() const
} }
std::vector<int> AlbumPreview::defaultOrder(int count) const { std::vector<int> AlbumPreview::defaultOrder(int count) const {
Expects(count > 0 || !_order.empty());
if (count < 0) { if (count < 0) {
count = _order.size(); count = _order.size();
} }