diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.cpp b/Telegram/SourceFiles/calls/group/calls_group_call.cpp index 7f66d3d3b0..3daa89c915 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_call.cpp @@ -1364,7 +1364,7 @@ void GroupCall::initialJoinRequested() { } }, _lifetime); - if (_sharedCall) { + if (_sharedCall && conference()) { _canManage = _sharedCall->canManage(); return; } diff --git a/Telegram/SourceFiles/calls/group/calls_group_call.h b/Telegram/SourceFiles/calls/group/calls_group_call.h index 8ec742e1b9..f5752c4a1f 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_call.h +++ b/Telegram/SourceFiles/calls/group/calls_group_call.h @@ -49,9 +49,7 @@ class Call; class EncryptDecrypt; } // namespace TdE2E -namespace Calls { - -namespace Group { +namespace Calls::Group { struct MuteRequest; struct VolumeRequest; struct ParticipantState; @@ -62,7 +60,9 @@ struct RtmpInfo; enum class VideoQuality; enum class Error; class Messages; -} // namespace Group +} // namespace Calls::Group + +namespace Calls { struct InviteRequest; struct InviteResult; diff --git a/Telegram/SourceFiles/calls/group/calls_group_messages.cpp b/Telegram/SourceFiles/calls/group/calls_group_messages.cpp index 53228ac31a..49e2055ddf 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_messages.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_messages.cpp @@ -137,7 +137,9 @@ bool Messages::ready() const { } void Messages::send(TextWithTags text, int stars) { - if (!ready()) { + if (text.empty() && !stars) { + return; + } else if (!ready()) { _pending.push_back({ std::move(text), stars }); return; } diff --git a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp index 40999692dd..9f73004af9 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_settings.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_settings.cpp @@ -75,6 +75,7 @@ void SaveCallJoinMuted( const auto call = peer->groupCall(); if (!call || call->id() != callId + || peer->isUser() || !peer->canManageGroupCall() || !call->canChangeJoinMuted() || call->joinMuted() == joinMuted) { @@ -99,7 +100,7 @@ void SaveCallMessagesEnabled( if (!call || call->id() != callId || !peer->canManageGroupCall() - || !call->canChangeJoinMuted() + || !call->canChangeMessagesEnabled() || call->messagesEnabled() == messagesEnabled) { return; } @@ -890,7 +891,7 @@ std::pair, rpl::lifetime> ShareInviteLinkAction( bool generatingLink = false; }; const auto state = lifetime.make_state(&peer->session()); - if (!peer->canManageGroupCall()) { + if (peer->isUser() || !peer->canManageGroupCall()) { state->linkSpeaker = QString(); } diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index aa33c7d2c6..a81805ceaa 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -1852,7 +1852,9 @@ int PeerData::slowmodeSecondsLeft() const { } bool PeerData::canManageGroupCall() const { - if (const auto chat = asChat()) { + if (const auto user = asUser()) { + return user->isSelf(); + } else if (const auto chat = asChat()) { return chat->amCreator() || (chat->adminRights() & ChatAdminRight::ManageCall); } else if (const auto group = asChannel()) { @@ -1862,7 +1864,7 @@ bool PeerData::canManageGroupCall() const { return group->amCreator() || (group->adminRights() & ChatAdminRight::ManageCall); } - return false; + Unexpected("Peer type in PeerData::canManageGroupCall."); } bool PeerData::amMonoforumAdmin() const { diff --git a/Telegram/SourceFiles/data/data_peer_values.cpp b/Telegram/SourceFiles/data/data_peer_values.cpp index 1e09e5978c..6af9a53c53 100644 --- a/Telegram/SourceFiles/data/data_peer_values.cpp +++ b/Telegram/SourceFiles/data/data_peer_values.cpp @@ -376,7 +376,9 @@ rpl::producer CanPinMessagesValue(not_null peer) { rpl::producer CanManageGroupCallValue(not_null peer) { const auto flag = ChatAdminRight::ManageCall; - if (const auto chat = peer->asChat()) { + if (const auto user = peer->asUser()) { + return rpl::single(user->isSelf()); + } else if (const auto chat = peer->asChat()) { return chat->amCreator() ? (rpl::single(true) | rpl::type_erased()) : AdminRightValue(chat, flag); diff --git a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp index b8144e842a..7d44e31e55 100644 --- a/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp +++ b/Telegram/SourceFiles/history/view/history_view_top_bar_widget.cpp @@ -76,7 +76,9 @@ namespace { constexpr auto kEmojiInteractionSeenDuration = 3 * crl::time(1000); [[nodiscard]] inline bool HasGroupCallMenu(not_null peer) { - return !peer->groupCall() && peer->canManageGroupCall(); + return !peer->isUser() + && !peer->groupCall() + && peer->canManageGroupCall(); } QString TopBarNameText( @@ -1226,7 +1228,7 @@ void TopBarWidget::updateControlsVisibility() { && !_chooseForReportReason); const auto groupCallsEnabled = [&] { if (const auto peer = _activeChat.key.peer()) { - if (peer->canManageGroupCall()) { + if (!peer->isUser() && peer->canManageGroupCall()) { return true; } else if (const auto call = peer->groupCall()) { return (call->fullCount() == 0); diff --git a/Telegram/SourceFiles/media/stories/media_stories_reply.cpp b/Telegram/SourceFiles/media/stories/media_stories_reply.cpp index ddb07519cf..6c3d58b847 100644 --- a/Telegram/SourceFiles/media/stories/media_stories_reply.cpp +++ b/Telegram/SourceFiles/media/stories/media_stories_reply.cpp @@ -107,7 +107,9 @@ namespace { }) | rpl::flatten_latest(); } -[[nodiscard]] ChatHelpers::ComposeFeatures Features(bool videoStream) { +[[nodiscard]] ChatHelpers::ComposeFeatures Features( + bool videoStream, + bool videoStreamManager) { return { .likes = !videoStream, .sendAs = videoStream, @@ -124,7 +126,7 @@ namespace { .autocompleteMentions = false, .autocompleteCommands = false, .recordMediaMessage = !videoStream, - .editMessageStars = videoStream, + .editMessageStars = videoStream && !videoStreamManager, .emojiOnlyPanel = videoStream, }; } @@ -179,7 +181,7 @@ ReplyArea::ReplyArea(not_null controller) rpl::deferred([=] { return _starsForMessage.value(); })), .voiceCustomCancelText = tr::lng_record_cancel_stories(tr::now), .voiceLockFromBottom = true, - .features = Features(false), + .features = Features(false, false), } )) { initGeometry(); @@ -623,7 +625,7 @@ Fn ReplyArea::sendMenuDetails() const { ? uint64(_controls->chosenStarsForMessage()) : std::optional()), .commentPriceMin = (call - ? uint64(call->messagesMinPrice()) + ? uint64(call->canManage() ? call->messagesMinPrice() : 0) : std::optional()), .effectAllowed = (!_data.videoStream && _data.peer @@ -865,7 +867,8 @@ void ReplyArea::show( const auto streamChanged = (_data.videoStream.get() != stream); _data = data; if (streamChanged) { - _controls->updateFeatures(Features(stream != nullptr)); + const auto manager = stream && stream->canManage(); + _controls->updateFeatures(Features(stream != nullptr, manager)); _controls->setToggleCommentsButton(stream ? _controller->commentsStateValue() : nullptr); @@ -970,7 +973,12 @@ void ReplyArea::show( rpl::producer ReplyArea::starsPerMessageValue() const { if (const auto stream = _data.videoStream.get()) { - return stream->messagesMinPriceValue(); + return rpl::combine( + Data::CanManageGroupCallValue(stream->peer()), + stream->messagesMinPriceValue() + ) | rpl::map([=](bool canManage, int price) { + return canManage ? 0 : price; + }); } else if (const auto peer = _data.peer) { using Flag = Data::PeerUpdate::Flag; return peer->session().changes().peerFlagsValue(