Handle disabling direct messages in channel.

This commit is contained in:
John Preston 2025-06-05 14:58:45 +04:00
parent 73ea86ceeb
commit dc61faace1
8 changed files with 66 additions and 10 deletions

View file

@ -337,7 +337,18 @@ bool ChannelData::discussionLinkKnown() const {
} }
void ChannelData::setMonoforumLink(ChannelData *link) { void ChannelData::setMonoforumLink(ChannelData *link) {
if (_monoforumLink || !link) { if (_monoforumLink) {
if (isBroadcast()) {
_monoforumLink->setMonoforumLink(link ? this : nullptr);
} else if (isMonoforum()) {
if (!link && !monoforumDisabled()) {
setFlags(flags() | Flag::MonoforumDisabled);
} else if (link && monoforumDisabled()) {
setFlags(flags() & ~Flag::MonoforumDisabled);
}
}
return;
} else if (!link) {
return; return;
} }
_monoforumLink = link; _monoforumLink = link;
@ -352,6 +363,10 @@ ChannelData *ChannelData::monoforumLink() const {
return _monoforumLink; return _monoforumLink;
} }
bool ChannelData::monoforumDisabled() const {
return flags() & Flag::MonoforumDisabled;
}
void ChannelData::setMembersCount(int newMembersCount) { void ChannelData::setMembersCount(int newMembersCount) {
if (_membersCount != newMembersCount) { if (_membersCount != newMembersCount) {
if (isMegagroup() if (isMegagroup()

View file

@ -81,6 +81,7 @@ enum class ChannelDataFlag : uint64 {
AutoTranslation = (1ULL << 38), AutoTranslation = (1ULL << 38),
Monoforum = (1ULL << 39), Monoforum = (1ULL << 39),
MonoforumAdmin = (1ULL << 40), MonoforumAdmin = (1ULL << 40),
MonoforumDisabled = (1ULL << 41),
ForumTabs = (1ULL << 41), ForumTabs = (1ULL << 41),
}; };
inline constexpr bool is_flag_type(ChannelDataFlag) { return true; }; inline constexpr bool is_flag_type(ChannelDataFlag) { return true; };
@ -432,6 +433,7 @@ public:
void setMonoforumLink(ChannelData *link); void setMonoforumLink(ChannelData *link);
[[nodiscard]] ChannelData *monoforumLink() const; [[nodiscard]] ChannelData *monoforumLink() const;
[[nodiscard]] bool monoforumDisabled() const;
void ptsInit(int32 pts) { void ptsInit(int32 pts) {
_ptsWaiter.init(pts); _ptsWaiter.init(pts);

View file

@ -156,6 +156,9 @@ bool CanSendAnyOf(
} }
return false; return false;
} else if (const auto channel = peer->asChannel()) { } else if (const auto channel = peer->asChannel()) {
if (channel->monoforumDisabled()) {
return false;
}
using Flag = ChannelDataFlag; using Flag = ChannelDataFlag;
const auto allowed = channel->amIn() const auto allowed = channel->amIn()
|| ((channel->flags() & Flag::HasLink) || ((channel->flags() & Flag::HasLink)
@ -221,6 +224,9 @@ SendError RestrictionError(
} }
const auto all = restricted.isWithEveryone(); const auto all = restricted.isWithEveryone();
const auto channel = peer->asChannel(); const auto channel = peer->asChannel();
if (channel && channel->monoforumDisabled()) {
return tr::lng_action_direct_messages_disabled(tr::now);
}
if (!all && channel) { if (!all && channel) {
auto restrictedUntil = channel->restrictedUntil(); auto restrictedUntil = channel->restrictedUntil();
if (restrictedUntil > 0 if (restrictedUntil > 0

View file

@ -1542,6 +1542,9 @@ Data::RestrictionCheckResult PeerData::amRestricted(
: Result::Explicit()) : Result::Explicit())
: Result::Allowed(); : Result::Allowed();
} else if (const auto channel = asChannel()) { } else if (const auto channel = asChannel()) {
if (channel->monoforumDisabled()) {
return Result::WithEveryone();
}
const auto defaultRestrictions = channel->defaultRestrictions() const auto defaultRestrictions = channel->defaultRestrictions()
| (channel->isPublic() | (channel->isPublic()
? (ChatRestriction::PinMessages ? (ChatRestriction::PinMessages

View file

@ -273,7 +273,8 @@ inline auto DefaultRestrictionValue(
| Flag::HasLink | Flag::HasLink
| Flag::Forbidden | Flag::Forbidden
| Flag::Creator | Flag::Creator
| Flag::Broadcast; | Flag::Broadcast
| Flag::MonoforumDisabled;
return rpl::combine( return rpl::combine(
PeerFlagsValue(channel, mask), PeerFlagsValue(channel, mask),
AdminRightValue( AdminRightValue(
@ -288,6 +289,9 @@ inline auto DefaultRestrictionValue(
bool unrestrictedByBoosts, bool unrestrictedByBoosts,
ChatRestrictions sendRestriction, ChatRestrictions sendRestriction,
ChatRestrictions defaultSendRestriction) { ChatRestrictions defaultSendRestriction) {
if (flags & Flag::MonoforumDisabled) {
return false;
}
const auto notAmInFlags = Flag::Left | Flag::Forbidden; const auto notAmInFlags = Flag::Left | Flag::Forbidden;
const auto forumRestriction = forbidInForums const auto forumRestriction = forbidInForums
&& (flags & Flag::Forum); && (flags & Flag::Forum);

View file

@ -527,7 +527,13 @@ InnerWidget::InnerWidget(
RowDescriptor previous, RowDescriptor previous,
RowDescriptor next) { RowDescriptor next) {
updateDialogRow(previous); updateDialogRow(previous);
if (const auto sublist = previous.key.sublist()) {
updateDialogRow({ { sublist->owningHistory() }, {} });
}
updateDialogRow(next); updateDialogRow(next);
if (const auto sublist = next.key.sublist()) {
updateDialogRow({ { sublist->owningHistory() }, {} });
}
}, lifetime()); }, lifetime());
_controller->activeChatsFilter( _controller->activeChatsFilter(

View file

@ -1067,9 +1067,20 @@ void HistoryWidget::refreshDirectMessageShown() {
return; return;
} }
const auto channel = _peer->asChannel(); const auto channel = _peer->asChannel();
_directMessage->setVisible(channel const auto monoforum = channel ? channel->broadcastMonoforum() : nullptr;
&& channel->isBroadcast() const auto visible = monoforum && !monoforum->monoforumDisabled();
&& channel->monoforumLink()); _directMessage->setVisible(visible);
if (visible) {
using Flags = Data::Flags<ChannelDataFlags>;
_directMessageLifetime = monoforum->flagsValue(
) | rpl::skip(
1
) | rpl::start_with_next([=](Flags::Change change) {
if (change.diff & ChannelDataFlag::MonoforumDisabled) {
refreshDirectMessageShown();
}
});
}
} }
void HistoryWidget::refreshTopBarActiveChat() { void HistoryWidget::refreshTopBarActiveChat() {
@ -2624,13 +2635,19 @@ void HistoryWidget::showHistory(
if (const auto channel = _peer->asChannel()) { if (const auto channel = _peer->asChannel()) {
channel->updateFull(); channel->updateFull();
if (!channel->isBroadcast()) { if (!channel->isBroadcast()) {
channel->flagsValue( using Flags = Data::Flags<ChannelDataFlags>;
) | rpl::start_with_next([=] { channel->flagsValue() | rpl::skip(
refreshJoinChannelText(); 1
}, _list->lifetime()); ) | rpl::start_with_next([=](Flags::Change change) {
} else {
refreshJoinChannelText(); refreshJoinChannelText();
if (change.diff & ChannelDataFlag::MonoforumDisabled) {
updateCanSendMessage();
updateSendRestriction();
updateHistoryGeometry();
} }
}, _list->lifetime());
}
refreshJoinChannelText();
} }
controller()->adaptive().changes( controller()->adaptive().changes(
@ -6645,7 +6662,9 @@ int HistoryWidget::countAutomaticScrollTop() {
} }
Data::SendError HistoryWidget::computeSendRestriction() const { Data::SendError HistoryWidget::computeSendRestriction() const {
if (!_canSendMessages && _peer->amMonoforumAdmin()) { if (!_canSendMessages
&& _peer->amMonoforumAdmin()
&& !_peer->asChannel()->monoforumDisabled()) {
return Data::SendError({ return Data::SendError({
.text = tr::lng_monoforum_choose_to_reply(tr::now), .text = tr::lng_monoforum_choose_to_reply(tr::now),
.monoforumAdmin = true, .monoforumAdmin = true,

View file

@ -807,6 +807,7 @@ private:
object_ptr<Ui::FlatButton> _muteUnmute; object_ptr<Ui::FlatButton> _muteUnmute;
QPointer<Ui::IconButton> _giftToChannel; QPointer<Ui::IconButton> _giftToChannel;
QPointer<Ui::IconButton> _directMessage; QPointer<Ui::IconButton> _directMessage;
rpl::lifetime _directMessageLifetime;
object_ptr<Ui::FlatButton> _reportMessages; object_ptr<Ui::FlatButton> _reportMessages;
struct { struct {
object_ptr<Ui::RoundButton> button = { nullptr }; object_ptr<Ui::RoundButton> button = { nullptr };