diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index df03deaf63..514c9027b1 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -1004,6 +1004,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_manage_public_group_title" = "Public"; "lng_manage_private_peer_title" = "Private"; "lng_manage_public_peer_title" = "Public"; +"lng_manage_peer_no_forwards_title" = "Saving content"; +"lng_manage_peer_no_forwards" = "Restrict saving content"; +"lng_manage_peer_no_forwards_about" = "Participants won't be able to forward messages from this channel or save media files."; "lng_manage_discussion_group" = "Discussion"; "lng_manage_discussion_group_add" = "Add a group"; @@ -1825,7 +1828,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_edit_contact_title" = "Edit contact name"; "lng_edit_channel_title" = "Edit channel"; "lng_edit_sign_messages" = "Sign messages"; -"lng_edit_allow_forwards" = "Allow saving content"; "lng_edit_group" = "Edit group"; "lng_edit_self_title" = "Edit your name"; "lng_confirm_contact_data" = "New Contact"; diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp index e7c32c8ba2..98f9b4e31c 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_info_box.cpp @@ -277,7 +277,7 @@ private: std::optional description; std::optional hiddenPreHistory; std::optional signatures; - std::optional forwards; + std::optional noForwards; std::optional linkedChat; }; @@ -297,7 +297,6 @@ private: void fillLinkedChatButton(); //void fillInviteLinkButton(); void fillSignaturesButton(); - void fillForwardsButton(); void fillHistoryVisibilityButton(); void fillManageSection(); void fillPendingRequestsButton(); @@ -345,7 +344,7 @@ private: std::optional _historyVisibilitySavedValue; std::optional _usernameSavedValue; std::optional _signaturesSavedValue; - std::optional _forwardsSavedValue; + std::optional _noForwardsSavedValue; const not_null _navigation; const not_null _box; @@ -611,10 +610,11 @@ void Controller::refreshHistoryVisibility() { void Controller::showEditPeerTypeBox( std::optional> error) { const auto boxCallback = crl::guard(this, [=]( - Privacy checked, QString publicLink) { + Privacy checked, QString publicLink, bool noForwards) { _privacyTypeUpdates.fire(std::move(checked)); _privacySavedValue = checked; _usernameSavedValue = publicLink; + _noForwardsSavedValue = noForwards; refreshHistoryVisibility(); }); _navigation->parentController()->show( @@ -624,6 +624,7 @@ void Controller::showEditPeerTypeBox( boxCallback, _privacySavedValue, _usernameSavedValue, + _noForwardsSavedValue, error), Ui::LayerOption::KeepOther); } @@ -699,6 +700,7 @@ void Controller::fillPrivacyTypeButton() { && _peer->asChannel()->hasUsername()) ? Privacy::HasUsername : Privacy::NoUsername; + _noForwardsSavedValue = !_peer->allowsForwarding(); const auto isGroup = (_peer->isChat() || _peer->isMegagroup()); AddButtonWithText( @@ -800,21 +802,6 @@ void Controller::fillSignaturesButton() { }, _controls.buttonsLayout->lifetime()); } -void Controller::fillForwardsButton() { - Expects(_controls.buttonsLayout != nullptr); - - AddButtonWithText( - _controls.buttonsLayout, - tr::lng_edit_allow_forwards(), - rpl::single(QString()), - [=] {} - )->toggleOn(rpl::single(_peer->allowsForwarding()) - )->toggledValue( - ) | rpl::start_with_next([=](bool toggled) { - _forwardsSavedValue = toggled; - }, _controls.buttonsLayout->lifetime()); -} - void Controller::fillHistoryVisibilityButton() { Expects(_controls.buttonsLayout != nullptr); @@ -874,19 +861,16 @@ void Controller::fillManageSection() { const auto isChannel = (!chat); if (!chat && !channel) return; - const auto canEditUsername = [&] { + const auto canEditType = [&] { return isChannel - ? channel->canEditUsername() - : chat->canEditUsername(); + ? channel->amCreator() + : chat->amCreator(); }(); const auto canEditSignatures = [&] { return isChannel ? (channel->canEditSignatures() && !channel->isMegagroup()) : false; }(); - const auto canEditForwards = [&] { - return isChannel ? channel->amCreator() : chat->amCreator(); - }(); const auto canEditPreHistoryHidden = [&] { return isChannel ? channel->canEditPreHistoryHidden() @@ -946,7 +930,7 @@ void Controller::fillManageSection() { AddSkip(_controls.buttonsLayout, 0); - if (canEditUsername) { + if (canEditType) { fillPrivacyTypeButton(); //} else if (canEditInviteLinks) { // fillInviteLinkButton(); @@ -960,15 +944,11 @@ void Controller::fillManageSection() { if (canEditSignatures) { fillSignaturesButton(); } - if (canEditForwards) { - fillForwardsButton(); - } if (canEditPreHistoryHidden || canEditSignatures - || canEditForwards //|| canEditInviteLinks || canViewOrEditLinkedChat - || canEditUsername) { + || canEditType) { AddSkip( _controls.buttonsLayout, st::editPeerTopButtonsLayoutSkip, @@ -989,7 +969,7 @@ void Controller::fillManageSection() { st::infoIconPermissions); } if (canEditInviteLinks - && (canEditUsername + && (canEditType || !_peer->isChannel() || !_peer->asChannel()->hasUsername())) { auto count = Info::Profile::MigratedOrMeValue( @@ -1258,10 +1238,10 @@ bool Controller::validateSignatures(Saving &to) const { } bool Controller::validateForwards(Saving &to) const { - if (!_forwardsSavedValue.has_value()) { + if (!_noForwardsSavedValue.has_value()) { return true; } - to.forwards = _forwardsSavedValue; + to.noForwards = _noForwardsSavedValue; return true; } @@ -1537,13 +1517,13 @@ void Controller::saveSignatures() { } void Controller::saveForwards() { - if (!_savingData.forwards - || *_savingData.forwards == _peer->allowsForwarding()) { + if (!_savingData.noForwards + || *_savingData.noForwards != _peer->allowsForwarding()) { return continueSave(); } _api.request(MTPmessages_ToggleNoForwards( _peer->input, - MTP_bool(!*_savingData.forwards) + MTP_bool(*_savingData.noForwards) )).done([=](const MTPUpdates &result) { _peer->session().api().applyUpdates(result); continueSave(); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp index ac777e5ebc..8740691f29 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.cpp @@ -63,13 +63,14 @@ public: not_null peer, bool useLocationPhrases, std::optional privacySavedValue, - std::optional usernameSavedValue); + std::optional usernameSavedValue, + std::optional noForwardsSavedValue); void createContent(); - QString getUsernameInput(); + [[nodiscard]] QString getUsernameInput() const; void setFocusUsername(); - rpl::producer getTitle() { + [[nodiscard]] rpl::producer getTitle() const { return !_privacySavedValue ? tr::lng_create_invite_link_title() : _isGroup @@ -77,14 +78,18 @@ public: : tr::lng_manage_peer_channel_type(); } - bool isAllowSave() { + [[nodiscard]] bool isAllowSave() { return _isAllowSave; } - Privacy getPrivacy() { + [[nodiscard]] Privacy getPrivacy() const { return _controls.privacy->value(); } + [[nodiscard]] bool noForwards() const { + return _controls.noForwards->toggled(); + } + void showError(rpl::producer text) { _controls.usernameInput->showError(); showUsernameError(std::move(text)); @@ -100,6 +105,8 @@ private: Ui::SlideWrap *inviteLinkWrap = nullptr; Ui::FlatLabel *inviteLink = nullptr; + + Ui::SettingsButton *noForwards = nullptr; }; Controls _controls; @@ -133,6 +140,7 @@ private: MTP::Sender _api; std::optional _privacySavedValue; std::optional _usernameSavedValue; + std::optional _noForwardsSavedValue; bool _useLocationPhrases = false; bool _isGroup = false; @@ -153,12 +161,14 @@ Controller::Controller( not_null peer, bool useLocationPhrases, std::optional privacySavedValue, - std::optional usernameSavedValue) + std::optional usernameSavedValue, + std::optional noForwardsSavedValue) : _peer(peer) , _linkOnly(!privacySavedValue.has_value()) , _api(&_peer->session().mtp()) , _privacySavedValue(privacySavedValue) , _usernameSavedValue(usernameSavedValue) +, _noForwardsSavedValue(noForwardsSavedValue) , _useLocationPhrases(useLocationPhrases) , _isGroup(_peer->isChat() || _peer->isMegagroup()) , _isAllowSave(!_usernameSavedValue.value_or(QString()).isEmpty()) @@ -196,6 +206,25 @@ void Controller::createContent() { AddSkip(_wrap.get()); AddDividerText(_wrap.get(), tr::lng_group_invite_manage_about()); + AddSkip(_wrap.get()); + AddSubsectionTitle(_wrap.get(), tr::lng_manage_peer_no_forwards_title()); + _controls.noForwards = _wrap->add(EditPeerInfoBox::CreateButton( + _wrap.get(), + tr::lng_manage_peer_no_forwards(), + rpl::single(QString()), + [=] {}, + st::manageGroupTopButtonWithText, + nullptr + )); + _controls.noForwards->toggleOn( + rpl::single(_noForwardsSavedValue.value_or(false)) + )->toggledValue( + ) | rpl::start_with_next([=](bool toggled) { + _noForwardsSavedValue = toggled; + }, _wrap->lifetime()); + AddSkip(_wrap.get()); + AddDividerText(_wrap.get(), tr::lng_manage_peer_no_forwards_about()); + if (_linkOnly) { _controls.inviteLinkWrap->show(anim::type::instant); } else { @@ -299,7 +328,7 @@ void Controller::setFocusUsername() { } } -QString Controller::getUsernameInput() { +QString Controller::getUsernameInput() const { return _controls.usernameInput->getLastText().trimmed(); } @@ -575,22 +604,24 @@ EditPeerTypeBox::EditPeerTypeBox( QWidget*, not_null peer, bool useLocationPhrases, - std::optional> savedCallback, + std::optional> savedCallback, std::optional privacySaved, std::optional usernameSaved, + std::optional noForwardsValue, std::optional> usernameError) : _peer(peer) , _useLocationPhrases(useLocationPhrases) , _savedCallback(std::move(savedCallback)) , _privacySavedValue(privacySaved) , _usernameSavedValue(usernameSaved) +, _noForwardsValue(noForwardsValue) , _usernameError(usernameError) { } EditPeerTypeBox::EditPeerTypeBox( QWidget*, not_null peer) -: EditPeerTypeBox(nullptr, peer, {}, {}, {}, {}, {}) { +: EditPeerTypeBox(nullptr, peer, {}, {}, {}, {}, {}, {}) { } void EditPeerTypeBox::setInnerFocus() { @@ -608,7 +639,8 @@ void EditPeerTypeBox::prepare() { _peer, _useLocationPhrases, _privacySavedValue, - _usernameSavedValue); + _usernameSavedValue, + _noForwardsValue); _focusRequests.events( ) | rpl::start_with_next( [=] { @@ -632,10 +664,12 @@ void EditPeerTypeBox::prepare() { } auto local = std::move(*_savedCallback); - local(v, - (v == Privacy::HasUsername) + local( + v, + (v == Privacy::HasUsername ? controller->getUsernameInput() - : QString()); // We don't need username with private type. + : QString()), + controller->noForwards()); // We don't need username with private type. closeBox(); }); addButton(tr::lng_cancel(), [=] { closeBox(); }); diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.h b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.h index 0d4a828b1b..fa77441258 100644 --- a/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.h +++ b/Telegram/SourceFiles/boxes/peers/edit_peer_type_box.h @@ -36,9 +36,10 @@ public: QWidget*, not_null peer, bool useLocationPhrases, - std::optional> savedCallback, + std::optional> savedCallback, std::optional privacySaved, std::optional usernameSaved, + std::optional noForwardsSaved, std::optional> usernameError = {}); // For invite link only. @@ -53,10 +54,11 @@ protected: private: not_null _peer; bool _useLocationPhrases = false; - std::optional> _savedCallback; + std::optional> _savedCallback; std::optional _privacySavedValue; std::optional _usernameSavedValue; + std::optional _noForwardsValue; std::optional> _usernameError; rpl::event_stream<> _focusRequests; diff --git a/Telegram/SourceFiles/media/player/media_player_instance.cpp b/Telegram/SourceFiles/media/player/media_player_instance.cpp index 4fe8f80a9a..6ecda92639 100644 --- a/Telegram/SourceFiles/media/player/media_player_instance.cpp +++ b/Telegram/SourceFiles/media/player/media_player_instance.cpp @@ -467,6 +467,10 @@ bool Instance::moveInPlaylist( const auto jumpById = [&](FullMsgId id) { return jumpByItem(data->history->owner().message(id)); }; + + if (data->order.current() == OrderMode::Shuffle) { + } + const auto newIndex = *data->playlistIndex + (data->order.current() == OrderMode::Reverse ? -delta : delta); const auto useIndex = (!data->playlistSlice @@ -499,6 +503,7 @@ bool Instance::previousAvailable(AudioMsgId::Type type) const { return false; } else if (data->repeat.current() == RepeatMode::All) { return true; + } else if (data->order.current() == OrderMode::Shuffle) { } return (data->order.current() == OrderMode::Reverse) ? (*data->playlistIndex + 1 < data->playlistSlice->size()) @@ -513,6 +518,7 @@ bool Instance::nextAvailable(AudioMsgId::Type type) const { return false; } else if (data->repeat.current() == RepeatMode::All) { return true; + } else if (data->order.current() == OrderMode::Shuffle) { } return (data->order.current() == OrderMode::Reverse) ? (*data->playlistIndex > 0)