diff --git a/Telegram/SourceFiles/data/data_channel.cpp b/Telegram/SourceFiles/data/data_channel.cpp index 7a0f6a502a..02a94552ec 100644 --- a/Telegram/SourceFiles/data/data_channel.cpp +++ b/Telegram/SourceFiles/data/data_channel.cpp @@ -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() diff --git a/Telegram/SourceFiles/data/data_channel.h b/Telegram/SourceFiles/data/data_channel.h index 776edb0aa5..15b031199b 100644 --- a/Telegram/SourceFiles/data/data_channel.h +++ b/Telegram/SourceFiles/data/data_channel.h @@ -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); diff --git a/Telegram/SourceFiles/data/data_chat_participant_status.cpp b/Telegram/SourceFiles/data/data_chat_participant_status.cpp index 2a85f44d13..de38444757 100644 --- a/Telegram/SourceFiles/data/data_chat_participant_status.cpp +++ b/Telegram/SourceFiles/data/data_chat_participant_status.cpp @@ -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 diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index 86fb382f0e..46ec093b1e 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -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 diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp index 0c435d5347..5739124d45 100644 --- a/Telegram/SourceFiles/data/data_peer_values.cpp +++ b/Telegram/SourceFiles/data/data_peer_values.cpp @@ -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); diff --git a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp index 312c830d1e..801155646e 100644 --- a/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp +++ b/Telegram/SourceFiles/dialogs/dialogs_inner_widget.cpp @@ -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( diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index b468697738..5aedac9535 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -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; + _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; + 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, diff --git a/Telegram/SourceFiles/history/history_widget.h b/Telegram/SourceFiles/history/history_widget.h index 3c7cc4e82e..42f2cf7f8c 100644 --- a/Telegram/SourceFiles/history/history_widget.h +++ b/Telegram/SourceFiles/history/history_widget.h @@ -807,6 +807,7 @@ private: object_ptr _muteUnmute; QPointer _giftToChannel; QPointer _directMessage; + rpl::lifetime _directMessageLifetime; object_ptr _reportMessages; struct { object_ptr button = { nullptr };