Implement private chat noforward following.

This commit is contained in:
John Preston
2026-02-06 14:18:30 +04:00
parent 5c7d2723ed
commit 4e9c0ea3a5
12 changed files with 120 additions and 36 deletions
@@ -504,40 +504,65 @@ Main::Session &HistoryInner::session() const {
void HistoryInner::setupSharingDisallowed() {
Expects(_peer != nullptr);
if (_peer->isUser()) {
_sharingDisallowed = false;
return;
if (const auto user = _peer->asUser()) {
_sharingDisallowed = rpl::combine(
Data::PeerFlagValue(user, UserDataFlag::NoForwardsMyEnabled),
Data::PeerFlagValue(user, UserDataFlag::NoForwardsPeerEnabled)
) | rpl::map([](bool my, bool peer) {
return my || peer;
});
} else {
const auto chat = _peer->asChat();
const auto channel = _peer->asChannel();
_sharingDisallowed = chat
? Data::PeerFlagValue(chat, ChatDataFlag::NoForwards)
: Data::PeerFlagValue(
channel,
ChannelDataFlag::NoForwards
) | rpl::type_erased;
}
const auto chat = _peer->asChat();
const auto channel = _peer->asChannel();
_sharingDisallowed = chat
? Data::PeerFlagValue(chat, ChatDataFlag::NoForwards)
: Data::PeerFlagValue(
channel,
ChannelDataFlag::NoForwards
) | rpl::type_erased;
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::on_next([=] {
_widget->clearSelected();
if (_mouseAction == MouseAction::PrepareSelect) {
mouseActionCancel();
const auto clearIfRestricted = [=] {
if (hasSelectRestriction() && !getSelectedItems().empty()) {
_widget->clearSelected();
if (_mouseAction == MouseAction::PrepareSelect) {
mouseActionCancel();
}
}
}, lifetime());
};
if (const auto chat = _peer->asChat()) {
auto rights = chat->adminRightsValue();
auto canDelete = std::move(
rights
) | rpl::map([=] {
return chat->canDeleteMessages();
});
rpl::combine(
_sharingDisallowed.value(),
std::move(canDelete)
) | rpl::on_next([=] {
clearIfRestricted();
}, lifetime());
} else if (const auto channel = _peer->asChannel()) {
auto rights = channel->adminRightsValue();
auto canDelete = std::move(
rights
) | rpl::map([=] {
return channel->canDeleteMessages();
});
rpl::combine(
_sharingDisallowed.value(),
std::move(canDelete)
) | rpl::on_next([=] {
clearIfRestricted();
}, lifetime());
} else {
_sharingDisallowed.value(
) | rpl::on_next([=] {
clearIfRestricted();
}, lifetime());
}
}
void HistoryInner::setupSwipeReplyAndBack() {
@@ -3322,6 +3347,8 @@ bool HistoryInner::showCopyRestriction(HistoryItem *item) {
}
_controller->showToast(_peer->isBroadcast()
? tr::lng_error_nocopy_channel(tr::now)
: _peer->isUser()
? tr::lng_error_nocopy_user(tr::now)
: tr::lng_error_nocopy_group(tr::now));
return true;
}
@@ -3332,6 +3359,8 @@ bool HistoryInner::showCopyMediaRestriction(not_null<HistoryItem*> item) {
}
_controller->showToast(_peer->isBroadcast()
? tr::lng_error_nocopy_channel(tr::now)
: _peer->isUser()
? tr::lng_error_nocopy_user(tr::now)
: tr::lng_error_nocopy_group(tr::now));
return true;
}
@@ -2061,6 +2061,8 @@ void AddSelectRestrictionAction(
? tr::lng_context_noforwards_info_channel
: (peer->isUser() && peer->asUser()->isBot())
? tr::lng_context_noforwards_info_bot
: peer->isUser()
? tr::lng_context_noforwards_info_user
: tr::lng_context_noforwards_info_channel)(
tr::now,
tr::rich),
@@ -1617,6 +1617,8 @@ bool ListWidget::showCopyRestriction(HistoryItem *item) {
}
_delegate->listUiShow()->showToast((type == CopyRestrictionType::Channel)
? tr::lng_error_nocopy_channel(tr::now)
: (type == CopyRestrictionType::User)
? tr::lng_error_nocopy_user(tr::now)
: tr::lng_error_nocopy_group(tr::now));
return true;
}
@@ -1628,6 +1630,8 @@ bool ListWidget::showCopyMediaRestriction(not_null<HistoryItem*> item) {
}
_delegate->listUiShow()->showToast((type == CopyRestrictionType::Channel)
? tr::lng_error_nocopy_channel(tr::now)
: (type == CopyRestrictionType::User)
? tr::lng_error_nocopy_user(tr::now)
: tr::lng_error_nocopy_group(tr::now));
return true;
}
@@ -4508,6 +4512,8 @@ CopyRestrictionType CopyRestrictionTypeFor(
HistoryItem *item) {
return (peer->allowsForwarding() && (!item || !item->forbidsForward()))
? CopyRestrictionType::None
: peer->isUser()
? CopyRestrictionType::User
: peer->isBroadcast()
? CopyRestrictionType::Channel
: CopyRestrictionType::Group;
@@ -4522,6 +4528,8 @@ CopyRestrictionType CopyMediaRestrictionTypeFor(
}
return !item->forbidsSaving()
? CopyRestrictionType::None
: peer->isUser()
? CopyRestrictionType::User
: peer->isBroadcast()
? CopyRestrictionType::Channel
: CopyRestrictionType::Group;
@@ -4538,7 +4546,7 @@ CopyRestrictionType SelectRestrictionTypeFor(
? CopyRestrictionType::None
: CopyRestrictionTypeFor(peer);
}
return CopyRestrictionType::None;
return CopyRestrictionTypeFor(peer);
}
} // namespace HistoryView
@@ -71,6 +71,7 @@ enum class CopyRestrictionType : char {
None,
Group,
Channel,
User,
};
struct SelectedItem {