mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Disable selecting items with actions.
This commit is contained in:
parent
487e8a9009
commit
fd6751233e
11 changed files with 157 additions and 67 deletions
|
@ -66,6 +66,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_poll.h"
|
||||
#include "data/data_photo.h"
|
||||
#include "data/data_photo_media.h"
|
||||
#include "data/data_peer_values.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_file_click_handler.h"
|
||||
#include "data/data_file_origin.h"
|
||||
|
@ -258,12 +260,61 @@ HistoryInner::HistoryInner(
|
|||
) | rpl::start_with_next([=](int d) {
|
||||
_scroll->scrollToY(_scroll->scrollTop() + d);
|
||||
}, _scroll->lifetime());
|
||||
|
||||
setupSharingDisallowed();
|
||||
}
|
||||
|
||||
Main::Session &HistoryInner::session() const {
|
||||
return _controller->session();
|
||||
}
|
||||
|
||||
void HistoryInner::setupSharingDisallowed() {
|
||||
Expects(_peer != nullptr);
|
||||
|
||||
if (_peer->isUser()) {
|
||||
_sharingDisallowed = false;
|
||||
return;
|
||||
}
|
||||
const auto chat = _peer->asChat();
|
||||
const auto channel = _peer->asChannel();
|
||||
_sharingDisallowed = chat
|
||||
? Data::PeerFlagValue(chat, ChatDataFlag::NoForwards)
|
||||
: Data::PeerFlagValue(channel, ChannelDataFlag::NoForwards);
|
||||
|
||||
auto rights = chat
|
||||
? chat->adminRightsValue()
|
||||
: channel->adminRightsValue();
|
||||
auto canDelete = std::move(
|
||||
rights
|
||||
) | rpl::map([=] {
|
||||
return chat
|
||||
? chat->canDeleteMessages()
|
||||
: channel->canDeleteMessages();
|
||||
});
|
||||
rpl::combine(
|
||||
_sharingDisallowed.value(),
|
||||
std::move(canDelete)
|
||||
) | rpl::filter([=](bool disallowed, bool canDelete) {
|
||||
return hasSelectRestriction() && !getSelectedItems().empty();
|
||||
}) | rpl::start_with_next([=] {
|
||||
_widget->clearSelected();
|
||||
if (_mouseAction == MouseAction::PrepareSelect) {
|
||||
mouseActionCancel();
|
||||
}
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
bool HistoryInner::hasSelectRestriction() const {
|
||||
if (!_sharingDisallowed.current()) {
|
||||
return false;
|
||||
} else if (const auto chat = _peer->asChat()) {
|
||||
return !chat->canDeleteMessages();
|
||||
} else if (const auto channel = _peer->asChannel()) {
|
||||
return !channel->canDeleteMessages();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void HistoryInner::messagesReceived(
|
||||
PeerData *peer,
|
||||
const QVector<MTPMessage> &messages) {
|
||||
|
@ -1216,12 +1267,12 @@ void HistoryInner::mouseActionStart(const QPoint &screenPos, Qt::MouseButton but
|
|||
_selected.emplace(_mouseActionItem, selStatus);
|
||||
_mouseAction = MouseAction::Selecting;
|
||||
repaintItem(_mouseActionItem);
|
||||
} else {
|
||||
} else if (!hasSelectRestriction()) {
|
||||
_mouseAction = MouseAction::PrepareSelect;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (!_pressWasInactive) {
|
||||
} else if (!_pressWasInactive && !hasSelectRestriction()) {
|
||||
_mouseAction = MouseAction::PrepareSelect; // start items select
|
||||
}
|
||||
}
|
||||
|
@ -1250,7 +1301,8 @@ std::unique_ptr<QMimeData> HistoryInner::prepareDrag() {
|
|||
}
|
||||
|
||||
const auto pressedHandler = ClickHandler::getPressed();
|
||||
if (dynamic_cast<VoiceSeekClickHandler*>(pressedHandler.get())) {
|
||||
if (dynamic_cast<VoiceSeekClickHandler*>(pressedHandler.get())
|
||||
|| !_peer->allowsForwarding()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -1281,7 +1333,6 @@ std::unique_ptr<QMimeData> HistoryInner::prepareDrag() {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto urls = QList<QUrl>();
|
||||
const auto selectedText = [&] {
|
||||
if (uponSelected) {
|
||||
|
@ -1737,6 +1788,29 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||
}
|
||||
};
|
||||
|
||||
const auto addSelectMessageAction = [&](
|
||||
not_null<HistoryItem*> item,
|
||||
bool asGroup = true) {
|
||||
if (item->isRegular()
|
||||
&& !item->isService()
|
||||
&& !hasSelectRestriction()) {
|
||||
const auto itemId = item->fullId();
|
||||
_menu->addAction(tr::lng_context_select_msg(tr::now), [=] {
|
||||
if (const auto item = session->data().message(itemId)) {
|
||||
if (const auto view = item->mainView()) {
|
||||
if (asGroup) {
|
||||
changeSelectionAsGroup(&_selected, item, SelectAction::Select);
|
||||
} else {
|
||||
changeSelection(&_selected, item, SelectAction::Select);
|
||||
}
|
||||
repaintItem(item);
|
||||
_widget->updateTopBarSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
if (hasWhoReadItem) {
|
||||
const auto participantChosen = [=](uint64 id) {
|
||||
controller->showPeerInfo(PeerId(id));
|
||||
|
@ -1808,17 +1882,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||
});
|
||||
}
|
||||
}
|
||||
if (item->isRegular() && !item->isService()) {
|
||||
_menu->addAction(tr::lng_context_select_msg(tr::now), [=] {
|
||||
if (const auto item = session->data().message(itemId)) {
|
||||
if (const auto view = item->mainView()) {
|
||||
changeSelection(&_selected, item, SelectAction::Select);
|
||||
repaintItem(item);
|
||||
_widget->updateTopBarSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
addSelectMessageAction(item, false);
|
||||
if (isUponSelected != -2 && blockSender) {
|
||||
_menu->addAction(tr::lng_profile_block_user(tr::now), [=] {
|
||||
blockSenderItem(itemId);
|
||||
|
@ -1959,37 +2023,14 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||
});
|
||||
}
|
||||
}
|
||||
if (item->isRegular() && !item->isService()) {
|
||||
_menu->addAction(tr::lng_context_select_msg(tr::now), [=] {
|
||||
if (const auto item = session->data().message(itemId)) {
|
||||
if (const auto view = item->mainView()) {
|
||||
changeSelectionAsGroup(&_selected, item, SelectAction::Select);
|
||||
repaintItem(view);
|
||||
_widget->updateTopBarSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
addSelectMessageAction(item);
|
||||
if (isUponSelected != -2 && canBlockSender) {
|
||||
_menu->addAction(tr::lng_profile_block_user(tr::now), [=] {
|
||||
blockSenderAsGroup(itemId);
|
||||
});
|
||||
}
|
||||
} else {
|
||||
if (App::mousedItem()
|
||||
&& App::mousedItem()->data()->isRegular()
|
||||
&& !App::mousedItem()->data()->isService()) {
|
||||
const auto itemId = App::mousedItem()->data()->fullId();
|
||||
_menu->addAction(tr::lng_context_select_msg(tr::now), [=] {
|
||||
if (const auto item = session->data().message(itemId)) {
|
||||
if (const auto view = item->mainView()) {
|
||||
changeSelectionAsGroup(&_selected, item, SelectAction::Select);
|
||||
repaintItem(item);
|
||||
_widget->updateTopBarSelection();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
} else if (App::mousedItem()) {
|
||||
addSelectMessageAction(App::mousedItem()->data());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2001,8 +2042,12 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
|||
}
|
||||
}
|
||||
|
||||
bool HistoryInner::hasCopyRestriction() const {
|
||||
return !_peer->allowsForwarding();
|
||||
}
|
||||
|
||||
bool HistoryInner::showCopyRestriction() {
|
||||
if (_peer->allowsForwarding()) {
|
||||
if (!hasCopyRestriction()) {
|
||||
return false;
|
||||
}
|
||||
Ui::ShowMultilineToast({
|
||||
|
@ -2817,18 +2862,6 @@ MessageIdsList HistoryInner::getSelectedItems() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
void HistoryInner::selectItem(not_null<HistoryItem*> item) {
|
||||
if (!_selected.empty() && _selected.cbegin()->second != FullSelection) {
|
||||
_selected.clear();
|
||||
} else if (_selected.size() == MaxSelectedItems
|
||||
&& _selected.find(item) == _selected.cend()) {
|
||||
return;
|
||||
}
|
||||
_selected.emplace(item, FullSelection);
|
||||
_widget->updateTopBarSelection();
|
||||
_widget->update();
|
||||
}
|
||||
|
||||
void HistoryInner::onTouchSelect() {
|
||||
_touchSelect = true;
|
||||
mouseActionStart(_touchPos, Qt::LeftButton);
|
||||
|
@ -3115,6 +3148,9 @@ void HistoryInner::mouseActionUpdate() {
|
|||
void HistoryInner::updateDragSelection(Element *dragSelFrom, Element *dragSelTo, bool dragSelecting) {
|
||||
if (_dragSelFrom == dragSelFrom && _dragSelTo == dragSelTo && _dragSelecting == dragSelecting) {
|
||||
return;
|
||||
} else if (dragSelFrom && hasSelectRestriction()) {
|
||||
updateDragSelection(nullptr, nullptr, false);
|
||||
return;
|
||||
}
|
||||
_dragSelFrom = dragSelFrom;
|
||||
_dragSelTo = dragSelTo;
|
||||
|
@ -3248,7 +3284,9 @@ void HistoryInner::notifyMigrateUpdated() {
|
|||
}
|
||||
|
||||
void HistoryInner::applyDragSelection() {
|
||||
applyDragSelection(&_selected);
|
||||
if (!hasSelectRestriction()) {
|
||||
applyDragSelection(&_selected);
|
||||
}
|
||||
}
|
||||
|
||||
bool HistoryInner::isSelected(
|
||||
|
|
|
@ -85,7 +85,6 @@ public:
|
|||
HistoryView::TopBarWidget::SelectedState getSelectionState() const;
|
||||
void clearSelected(bool onlyTextSelection = false);
|
||||
MessageIdsList getSelectedItems() const;
|
||||
void selectItem(not_null<HistoryItem*> item);
|
||||
bool inSelectionMode() const;
|
||||
bool elementIntersectsRange(
|
||||
not_null<const Element*> view,
|
||||
|
@ -342,7 +341,11 @@ private:
|
|||
void blockSenderItem(FullMsgId itemId);
|
||||
void blockSenderAsGroup(FullMsgId itemId);
|
||||
void copySelectedText();
|
||||
|
||||
void setupSharingDisallowed();
|
||||
[[nodiscard]] bool hasCopyRestriction() const;
|
||||
bool showCopyRestriction();
|
||||
[[nodiscard]] bool hasSelectRestriction() const;
|
||||
|
||||
// Does any of the shown histories has this flag set.
|
||||
bool hasPendingResizedItems() const;
|
||||
|
@ -416,6 +419,8 @@ private:
|
|||
|
||||
Ui::SelectScrollManager _selectScroll;
|
||||
|
||||
rpl::variable<bool> _sharingDisallowed = false;
|
||||
|
||||
Ui::TouchScrollState _touchScrollState = Ui::TouchScrollState::Manual;
|
||||
bool _touchPrevPosValid = false;
|
||||
bool _touchWaitingAcceleration = false;
|
||||
|
|
|
@ -811,7 +811,10 @@ bool AddSelectMessageAction(
|
|||
const auto item = request.item;
|
||||
if (request.overSelection && !request.selectedItems.empty()) {
|
||||
return false;
|
||||
} else if (!item || item->isLocal() || item->isService()) {
|
||||
} else if (!item
|
||||
|| item->isLocal()
|
||||
|| item->isService()
|
||||
|| list->hasSelectRestriction()) {
|
||||
return false;
|
||||
}
|
||||
const auto owner = &item->history()->owner();
|
||||
|
|
|
@ -1076,7 +1076,9 @@ void ListWidget::cancelSelection() {
|
|||
}
|
||||
|
||||
void ListWidget::selectItem(not_null<HistoryItem*> item) {
|
||||
if (const auto view = viewForItem(item)) {
|
||||
if (hasSelectRestriction()) {
|
||||
return;
|
||||
} else if (const auto view = viewForItem(item)) {
|
||||
clearTextSelection();
|
||||
changeSelection(
|
||||
_selected,
|
||||
|
@ -1087,7 +1089,9 @@ void ListWidget::selectItem(not_null<HistoryItem*> item) {
|
|||
}
|
||||
|
||||
void ListWidget::selectItemAsGroup(not_null<HistoryItem*> item) {
|
||||
if (const auto view = viewForItem(item)) {
|
||||
if (hasSelectRestriction()) {
|
||||
return;
|
||||
} else if (const auto view = viewForItem(item)) {
|
||||
clearTextSelection();
|
||||
changeSelectionAsGroup(
|
||||
_selected,
|
||||
|
@ -1165,8 +1169,6 @@ bool ListWidget::isEmpty() const {
|
|||
&& (_itemsHeight + _itemsRevealHeight == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool ListWidget::hasCopyRestriction() const {
|
||||
return _delegate->listCopyRestrictionType() != CopyRestrictionType::None;
|
||||
}
|
||||
|
@ -1184,6 +1186,11 @@ bool ListWidget::showCopyRestriction() {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool ListWidget::hasSelectRestriction() const {
|
||||
return _delegate->listSelectRestrictionType()
|
||||
!= CopyRestrictionType::None;
|
||||
}
|
||||
|
||||
int ListWidget::itemMinimalHeight() const {
|
||||
return st::msgMarginTopAttached
|
||||
+ st::msgPhotoSize
|
||||
|
@ -1751,7 +1758,9 @@ void ListWidget::paintEvent(QPaintEvent *e) {
|
|||
}
|
||||
|
||||
void ListWidget::applyDragSelection() {
|
||||
applyDragSelection(_selected);
|
||||
if (!hasSelectRestriction()) {
|
||||
applyDragSelection(_selected);
|
||||
}
|
||||
clearDragSelection();
|
||||
pushSelectedItems();
|
||||
}
|
||||
|
@ -2080,7 +2089,9 @@ void ListWidget::leaveEventHook(QEvent *e) {
|
|||
}
|
||||
|
||||
void ListWidget::updateDragSelection() {
|
||||
if (!_overState.itemId || !_pressState.itemId) {
|
||||
if (!_overState.itemId
|
||||
|| !_pressState.itemId
|
||||
|| hasSelectRestriction()) {
|
||||
clearDragSelection();
|
||||
return;
|
||||
} else if (_items.empty() || !_overElement || !_selectEnabled) {
|
||||
|
@ -2281,7 +2292,7 @@ void ListWidget::mouseActionStart(
|
|||
} else if (hasSelectedItems()) {
|
||||
if (overSelectedItems()) {
|
||||
_mouseAction = MouseAction::PrepareDrag;
|
||||
} else if (!_pressWasInactive) {
|
||||
} else if (!_pressWasInactive && !hasSelectRestriction()) {
|
||||
_mouseAction = MouseAction::PrepareSelect;
|
||||
}
|
||||
}
|
||||
|
@ -2326,7 +2337,7 @@ void ListWidget::mouseActionStart(
|
|||
_mouseTextSymbol,
|
||||
_mouseTextSymbol));
|
||||
_mouseAction = MouseAction::Selecting;
|
||||
} else {
|
||||
} else if (!hasSelectRestriction()) {
|
||||
_mouseAction = MouseAction::PrepareSelect;
|
||||
}
|
||||
}
|
||||
|
@ -2653,7 +2664,8 @@ std::unique_ptr<QMimeData> ListWidget::prepareDrag() {
|
|||
return nullptr;
|
||||
}
|
||||
auto pressedHandler = ClickHandler::getPressed();
|
||||
if (dynamic_cast<VoiceSeekClickHandler*>(pressedHandler.get())) {
|
||||
if (dynamic_cast<VoiceSeekClickHandler*>(pressedHandler.get())
|
||||
|| hasCopyRestriction()) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
@ -3081,7 +3093,6 @@ void ConfirmSendNowSelectedItems(not_null<ListWidget*> widget) {
|
|||
clearSelection);
|
||||
}
|
||||
|
||||
|
||||
CopyRestrictionType CopyRestrictionTypeFor(
|
||||
not_null<PeerData*> peer) {
|
||||
return peer->allowsForwarding()
|
||||
|
@ -3091,4 +3102,18 @@ CopyRestrictionType CopyRestrictionTypeFor(
|
|||
: CopyRestrictionType::Group;
|
||||
}
|
||||
|
||||
CopyRestrictionType SelectRestrictionTypeFor(
|
||||
not_null<PeerData*> peer) {
|
||||
if (const auto chat = peer->asChat()) {
|
||||
return chat->canDeleteMessages()
|
||||
? CopyRestrictionType::None
|
||||
: CopyRestrictionTypeFor(peer);
|
||||
} else if (const auto channel = peer->asChannel()) {
|
||||
return channel->canDeleteMessages()
|
||||
? CopyRestrictionType::None
|
||||
: CopyRestrictionTypeFor(peer);
|
||||
}
|
||||
return CopyRestrictionType::None;
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -101,6 +101,7 @@ public:
|
|||
virtual void listHandleViaClick(not_null<UserData*> bot) = 0;
|
||||
virtual not_null<Ui::ChatTheme*> listChatTheme() = 0;
|
||||
virtual CopyRestrictionType listCopyRestrictionType() = 0;
|
||||
virtual CopyRestrictionType listSelectRestrictionType() = 0;
|
||||
|
||||
};
|
||||
|
||||
|
@ -213,6 +214,7 @@ public:
|
|||
|
||||
[[nodiscard]] bool hasCopyRestriction() const;
|
||||
[[nodiscard]] bool showCopyRestriction();
|
||||
[[nodiscard]] bool hasSelectRestriction() const;
|
||||
|
||||
// AbstractTooltipShower interface
|
||||
QString tooltipText() const override;
|
||||
|
@ -616,5 +618,7 @@ void ConfirmSendNowSelectedItems(not_null<ListWidget*> widget);
|
|||
|
||||
[[nodiscard]] CopyRestrictionType CopyRestrictionTypeFor(
|
||||
not_null<PeerData*> peer);
|
||||
[[nodiscard]] CopyRestrictionType SelectRestrictionTypeFor(
|
||||
not_null<PeerData*> peer);
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -680,6 +680,10 @@ CopyRestrictionType PinnedWidget::listCopyRestrictionType() {
|
|||
return CopyRestrictionTypeFor(_history->peer);
|
||||
}
|
||||
|
||||
CopyRestrictionType PinnedWidget::listSelectRestrictionType() {
|
||||
return SelectRestrictionTypeFor(_history->peer);
|
||||
}
|
||||
|
||||
void PinnedWidget::confirmDeleteSelected() {
|
||||
ConfirmDeleteSelectedItems(_inner);
|
||||
}
|
||||
|
|
|
@ -104,6 +104,7 @@ public:
|
|||
void listHandleViaClick(not_null<UserData*> bot) override;
|
||||
not_null<Ui::ChatTheme*> listChatTheme() override;
|
||||
CopyRestrictionType listCopyRestrictionType() override;
|
||||
CopyRestrictionType listSelectRestrictionType() override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
|
|
@ -1931,6 +1931,10 @@ CopyRestrictionType RepliesWidget::listCopyRestrictionType() {
|
|||
return CopyRestrictionTypeFor(_history->peer);
|
||||
}
|
||||
|
||||
CopyRestrictionType RepliesWidget::listSelectRestrictionType() {
|
||||
return SelectRestrictionTypeFor(_history->peer);
|
||||
}
|
||||
|
||||
void RepliesWidget::confirmDeleteSelected() {
|
||||
ConfirmDeleteSelectedItems(_inner);
|
||||
}
|
||||
|
|
|
@ -139,6 +139,7 @@ public:
|
|||
void listHandleViaClick(not_null<UserData*> bot) override;
|
||||
not_null<Ui::ChatTheme*> listChatTheme() override;
|
||||
CopyRestrictionType listCopyRestrictionType() override;
|
||||
CopyRestrictionType listSelectRestrictionType() override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
|
|
@ -1235,6 +1235,10 @@ CopyRestrictionType ScheduledWidget::listCopyRestrictionType() {
|
|||
return CopyRestrictionType::None;
|
||||
}
|
||||
|
||||
CopyRestrictionType ScheduledWidget::listSelectRestrictionType() {
|
||||
return CopyRestrictionType::None;
|
||||
}
|
||||
|
||||
void ScheduledWidget::confirmSendNowSelected() {
|
||||
ConfirmSendNowSelectedItems(_inner);
|
||||
}
|
||||
|
|
|
@ -120,6 +120,7 @@ public:
|
|||
void listHandleViaClick(not_null<UserData*> bot) override;
|
||||
not_null<Ui::ChatTheme*> listChatTheme() override;
|
||||
CopyRestrictionType listCopyRestrictionType() override;
|
||||
CopyRestrictionType listSelectRestrictionType() override;
|
||||
|
||||
protected:
|
||||
void resizeEvent(QResizeEvent *e) override;
|
||||
|
|
Loading…
Add table
Reference in a new issue