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) {
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;
}
_monoforumLink = link;
@ -352,6 +363,10 @@ ChannelData *ChannelData::monoforumLink() const {
return _monoforumLink;
}
bool ChannelData::monoforumDisabled() const {
return flags() & Flag::MonoforumDisabled;
}
void ChannelData::setMembersCount(int newMembersCount) {
if (_membersCount != newMembersCount) {
if (isMegagroup()

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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