Added ability to perform bulk selection from menu in HistoryWidget.

This commit is contained in:
23rd 2024-03-15 19:07:22 +03:00
parent ad101dc8a0
commit f4ecfeaddd
2 changed files with 82 additions and 0 deletions

View file

@ -3013,6 +3013,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_context_delete_msg" = "Delete Message";
"lng_context_auto_delete_in" = "auto-delete in {duration}";
"lng_context_select_msg" = "Select Message";
"lng_context_select_msg_bulk" = "Select up to this message";
"lng_context_report_msg" = "Report Message";
"lng_context_pin_msg" = "Pin Message";
"lng_context_unpin_msg" = "Unpin Message";

View file

@ -2277,6 +2277,87 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
}
}
}, &st::menuIconSelect);
const auto collectBetween = [=](
not_null<HistoryItem*> from,
not_null<HistoryItem*> to,
int max) -> HistoryItemsList {
auto current = from;
auto collected = HistoryItemsList();
collected.reserve(max);
collected.push_back(from);
collected.push_back(to);
const auto toId = to->fullId();
while (true) {
if (collected.size() > max) {
return {};
}
const auto view = viewByItem(current);
const auto nextView = nextItem(view);
if (!nextView) {
return {};
}
const auto nextItem = nextView->data();
if (nextItem->fullId() == toId) {
return collected;
}
if (nextItem->isRegular() && !nextItem->isService()) {
collected.push_back(nextItem);
}
current = nextItem;
}
};
[&] { // Select up to this message.
if (selectedState.count <= 0) {
return;
}
const auto toItem = groupLeaderOrSelf(item);
auto topToBottom = false;
auto nearestItem = (HistoryItem*)(nullptr);
{
auto minDiff = std::numeric_limits<int>::max();
for (const auto &[item, _] : _selected) {
const auto diff = item->fullId().msg.bare
- toItem->fullId().msg.bare;
if (std::abs(diff) < minDiff) {
nearestItem = item;
minDiff = std::abs(diff);
topToBottom = (diff < 0);
}
}
}
if (!nearestItem) {
return;
}
const auto start = (topToBottom ? nearestItem : toItem);
const auto end = (topToBottom ? toItem : nearestItem);
const auto left = MaxSelectedItems
- selectedState.count
+ (topToBottom ? 0 : 1);
if (collectBetween(start, end, left).empty()) {
return;
}
const auto startId = start->fullId();
const auto endId = end->fullId();
const auto callback = [=] {
const auto from = session->data().message(startId);
const auto to = session->data().message(endId);
if (from && to) {
for (const auto &i : collectBetween(from, to, left)) {
changeSelectionAsGroup(
&_selected,
i,
SelectAction::Select);
}
update();
_widget->updateTopBarSelection();
}
};
_menu->addAction(
tr::lng_context_select_msg_bulk(tr::now),
callback,
&st::menuIconSelect);
}();
}
};