Added ability to open box for voice restrictions without premium.

This commit is contained in:
23rd 2024-03-07 19:07:05 +03:00 committed by John Preston
parent 27bd9e3ee5
commit 0fad42b5b4
6 changed files with 158 additions and 29 deletions

View file

@ -10,28 +10,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_global_privacy.h" #include "api/api_global_privacy.h"
#include "ui/layers/generic_box.h" #include "ui/layers/generic_box.h"
#include "ui/widgets/checkbox.h" #include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h"
#include "ui/widgets/buttons.h"
#include "ui/widgets/shadow.h" #include "ui/widgets/shadow.h"
#include "ui/text/text_utilities.h" #include "ui/text/text_utilities.h"
#include "ui/toast/toast.h" #include "ui/toast/toast.h"
#include "ui/wrap/slide_wrap.h" #include "ui/wrap/slide_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "ui/painter.h" #include "ui/painter.h"
#include "ui/vertical_list.h" #include "ui/vertical_list.h"
#include "history/history.h" #include "history/history.h"
#include "boxes/peer_list_controllers.h" #include "boxes/peer_list_controllers.h"
#include "settings/settings_common.h"
#include "settings/settings_premium.h" #include "settings/settings_premium.h"
#include "settings/settings_privacy_security.h" #include "settings/settings_privacy_security.h"
#include "calls/calls_instance.h" #include "calls/calls_instance.h"
#include "base/binary_guard.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "apiwrap.h" #include "apiwrap.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "data/data_user.h" #include "data/data_user.h"
#include "data/data_chat.h" #include "data/data_chat.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_peer_values.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "styles/style_settings.h" #include "styles/style_settings.h"
#include "styles/style_layers.h" #include "styles/style_layers.h"
@ -67,6 +63,32 @@ void CreateRadiobuttonLock(
}, lock->lifetime()); }, lock->lifetime());
} }
void AddPremiumRequiredRow(
not_null<Ui::RpWidget*> widget,
not_null<Main::Session*> session,
Fn<void()> clickedCallback,
Fn<void()> setDefaultOption,
const style::Checkbox &st) {
const auto row = Ui::CreateChild<Ui::AbstractButton>(widget.get());
widget->sizeValue(
) | rpl::start_with_next([=](const QSize &s) {
row->resize(s);
}, row->lifetime());
row->setClickedCallback(std::move(clickedCallback));
CreateRadiobuttonLock(row, st);
Data::AmPremiumValue(
session
) | rpl::start_with_next([=](bool premium) {
row->setVisible(!premium);
if (!premium) {
setDefaultOption();
}
}, row->lifetime());
}
} // namespace } // namespace
class PrivacyExceptionsBoxController : public ChatsListBoxController { class PrivacyExceptionsBoxController : public ChatsListBoxController {
@ -363,10 +385,29 @@ void EditPrivacyBox::setupContent() {
content, content,
_controller->optionsTitleKey(), _controller->optionsTitleKey(),
{ 0, st::settingsPrivacySkipTop, 0, 0 }); { 0, st::settingsPrivacySkipTop, 0, 0 });
addOptionRow(Option::Everyone);
addOptionRow(Option::Contacts); const auto options = {
addOptionRow(Option::CloseFriends); Option::Everyone,
addOptionRow(Option::Nobody); Option::Contacts,
Option::CloseFriends,
Option::Nobody,
};
for (const auto &option : options) {
if (const auto row = addOptionRow(option)) {
const auto premiumCallback = _controller->premiumClickedCallback(
option,
_window);
if (premiumCallback) {
AddPremiumRequiredRow(
row,
&_window->session(),
premiumCallback,
[=] { group->setValue(Option::Everyone); },
st::messagePrivacyCheck);
}
}
}
const auto warning = addLabelOrDivider( const auto warning = addLabelOrDivider(
content, content,
_controller->warning(), _controller->warning(),

View file

@ -88,6 +88,12 @@ public:
virtual void saveAdditional() { virtual void saveAdditional() {
} }
[[nodiscard]] virtual Fn<void()> premiumClickedCallback(
Option option,
not_null<Window::SessionController*> controller) {
return nullptr;
}
virtual ~EditPrivacyController() = default; virtual ~EditPrivacyController() = default;
protected: protected:

View file

@ -19,7 +19,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/peers/prepare_short_info_box.h" #include "boxes/peers/prepare_short_info_box.h"
#include "calls/calls_instance.h" #include "calls/calls_instance.h"
#include "core/application.h" #include "core/application.h"
#include "core/core_settings.h"
#include "data/data_changes.h" #include "data/data_changes.h"
#include "data/data_file_origin.h" #include "data/data_file_origin.h"
#include "data/data_peer_values.h" // Data::AmPremiumValue. #include "data/data_peer_values.h" // Data::AmPremiumValue.
@ -31,34 +30,27 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "editor/photo_editor_layer_widget.h" #include "editor/photo_editor_layer_widget.h"
#include "history/admin_log/history_admin_log_item.h" #include "history/admin_log/history_admin_log_item.h"
#include "history/history.h" #include "history/history.h"
#include "history/history_item.h"
#include "history/history_item_components.h" #include "history/history_item_components.h"
#include "history/view/history_view_element.h"
#include "history/view/history_view_message.h" #include "history/view/history_view_message.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "settings/settings_premium.h" #include "settings/settings_premium.h"
#include "settings/settings_privacy_security.h" #include "settings/settings_privacy_security.h"
#include "ui/boxes/confirm_box.h" #include "ui/boxes/confirm_box.h"
#include "ui/cached_round_corners.h"
#include "ui/chat/chat_style.h" #include "ui/chat/chat_style.h"
#include "ui/chat/chat_theme.h" #include "ui/chat/chat_theme.h"
#include "ui/image/image_prepare.h"
#include "ui/image/image_prepare.h"
#include "ui/painter.h" #include "ui/painter.h"
#include "ui/vertical_list.h" #include "ui/vertical_list.h"
#include "ui/text/format_values.h" // Ui::FormatPhone #include "ui/text/format_values.h" // Ui::FormatPhone
#include "ui/text/text_utilities.h" #include "ui/text/text_utilities.h"
#include "ui/toast/toast.h"
#include "ui/widgets/checkbox.h" #include "ui/widgets/checkbox.h"
#include "ui/wrap/padding_wrap.h"
#include "ui/wrap/slide_wrap.h" #include "ui/wrap/slide_wrap.h"
#include "ui/wrap/vertical_layout.h"
#include "window/section_widget.h" #include "window/section_widget.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "styles/style_chat.h" #include "styles/style_chat.h"
#include "styles/style_chat_helpers.h" #include "styles/style_chat_helpers.h"
#include "styles/style_boxes.h"
#include "styles/style_settings.h" #include "styles/style_settings.h"
#include "styles/style_info.h" #include "styles/style_info.h"
#include "styles/style_menu_icons.h" #include "styles/style_menu_icons.h"
@ -1377,6 +1369,78 @@ auto VoicesPrivacyController::exceptionsDescription() const
return tr::lng_edit_privacy_voices_exceptions(); return tr::lng_edit_privacy_voices_exceptions();
} }
object_ptr<Ui::RpWidget> VoicesPrivacyController::setupBelowWidget(
not_null<Window::SessionController*> controller,
not_null<QWidget*> parent,
rpl::producer<Option> option) {
using namespace rpl::mappers;
auto result = object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
parent,
object_ptr<Ui::VerticalLayout>(parent));
result->toggleOn(
Data::AmPremiumValue(&controller->session()) | rpl::map(!_1),
anim::type::instant);
const auto content = result->entity();
Ui::AddSkip(content);
Settings::AddButtonWithIcon(
content,
tr::lng_messages_privacy_premium_button(),
st::messagePrivacySubscribe,
{ .icon = &st::menuBlueIconPremium }
)->setClickedCallback([=] {
Settings::ShowPremium(
controller,
u"voice_restrictions_require_premium"_q);
});
Ui::AddSkip(content);
Ui::AddDividerText(content, tr::lng_messages_privacy_premium_about());
return result;
}
Fn<void()> VoicesPrivacyController::premiumClickedCallback(
Option option,
not_null<Window::SessionController*> controller) {
if (option == Option::Everyone) {
return nullptr;
}
const auto showToast = [=] {
auto link = Ui::Text::Link(
Ui::Text::Semibold(
tr::lng_settings_privacy_premium_link(tr::now)));
_toastInstance = controller->showToast({
.text = tr::lng_settings_privacy_premium(
tr::now,
lt_link,
link,
Ui::Text::WithEntities),
.st = &st::defaultMultilineToast,
.duration = Ui::Toast::kDefaultDuration * 2,
.multiline = true,
.filter = crl::guard(&controller->session(), [=](
const ClickHandlerPtr &,
Qt::MouseButton button) {
if (button == Qt::LeftButton) {
if (const auto strong = _toastInstance.get()) {
strong->hideAnimated();
_toastInstance = nullptr;
Settings::ShowPremium(
controller,
u"voice_restrictions_require_premium"_q);
return true;
}
}
return false;
}),
});
};
return showToast;
}
UserPrivacy::Key AboutPrivacyController::key() const { UserPrivacy::Key AboutPrivacyController::key() const {
return Key::About; return Key::About;
} }

View file

@ -18,6 +18,9 @@ class SessionController;
namespace Ui { namespace Ui {
class ChatStyle; class ChatStyle;
namespace Toast {
class Instance;
} // namespace Toast
} // namespace Ui } // namespace Ui
namespace Settings { namespace Settings {
@ -280,8 +283,16 @@ public:
rpl::producer<QString> exceptionBoxTitle( rpl::producer<QString> exceptionBoxTitle(
Exception exception) const override; Exception exception) const override;
rpl::producer<QString> exceptionsDescription() const override; rpl::producer<QString> exceptionsDescription() const override;
object_ptr<Ui::RpWidget> setupBelowWidget(
not_null<Window::SessionController*> controller,
not_null<QWidget*> parent,
rpl::producer<Option> option) override;
Fn<void()> premiumClickedCallback(
Option option,
not_null<Window::SessionController*> controller) override;
private: private:
base::weak_ptr<Ui::Toast::Instance> _toastInstance;
rpl::lifetime _lifetime; rpl::lifetime _lifetime;
}; };

View file

@ -164,6 +164,7 @@ rpl::producer<QString> PrivacyString(
}); });
} }
#if 0 // Dead code.
void AddPremiumPrivacyButton( void AddPremiumPrivacyButton(
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container, not_null<Ui::VerticalLayout*> container,
@ -283,6 +284,7 @@ void AddPremiumPrivacyButton(
}); });
}); });
} }
#endif
void AddMessagesPrivacyButton( void AddMessagesPrivacyButton(
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
@ -328,7 +330,7 @@ void SetupPrivacy(
rpl::producer<QString> label, rpl::producer<QString> label,
Key key, Key key,
auto controllerFactory) { auto controllerFactory) {
AddPrivacyButton( return AddPrivacyButton(
controller, controller,
container, container,
std::move(label), std::move(label),
@ -366,12 +368,15 @@ void SetupPrivacy(
tr::lng_settings_groups_invite(), tr::lng_settings_groups_invite(),
Key::Invites, Key::Invites,
[] { return std::make_unique<GroupsInvitePrivacyController>(); }); [] { return std::make_unique<GroupsInvitePrivacyController>(); });
AddPremiumPrivacyButton( {
controller, const auto &phrase = tr::lng_settings_voices_privacy;
container, const auto &st = st::settingsButtonNoIcon;
tr::lng_settings_voices_privacy(), auto callback = [=] {
Key::Voices, return std::make_unique<VoicesPrivacyController>(session);
[=] { return std::make_unique<VoicesPrivacyController>(session); }); };
const auto voices = add(phrase(), Key::Voices, std::move(callback));
AddPremiumStar(voices, session, phrase(), st.padding);
}
AddMessagesPrivacyButton(controller, container); AddMessagesPrivacyButton(controller, container);
session->api().userPrivacy().reload(Api::UserPrivacy::Key::AddedByPhone); session->api().userPrivacy().reload(Api::UserPrivacy::Key::AddedByPhone);
@ -873,7 +878,7 @@ object_ptr<Ui::BoxContent> CloudPasswordAppOutdatedBox() {
}); });
} }
void AddPrivacyButton( not_null<Ui::SettingsButton*> AddPrivacyButton(
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container, not_null<Ui::VerticalLayout*> container,
rpl::producer<QString> label, rpl::producer<QString> label,
@ -883,13 +888,14 @@ void AddPrivacyButton(
const style::SettingsButton *stOverride) { const style::SettingsButton *stOverride) {
const auto shower = Ui::CreateChild<rpl::lifetime>(container.get()); const auto shower = Ui::CreateChild<rpl::lifetime>(container.get());
const auto session = &controller->session(); const auto session = &controller->session();
AddButtonWithLabel( const auto button = AddButtonWithLabel(
container, container,
std::move(label), std::move(label),
PrivacyString(session, key), PrivacyString(session, key),
stOverride ? *stOverride : st::settingsButtonNoIcon, stOverride ? *stOverride : st::settingsButtonNoIcon,
std::move(descriptor) std::move(descriptor)
)->addClickHandler([=] { );
button->addClickHandler([=] {
*shower = session->api().userPrivacy().value( *shower = session->api().userPrivacy().value(
key key
) | rpl::take( ) | rpl::take(
@ -901,6 +907,7 @@ void AddPrivacyButton(
value)); value));
}); });
}); });
return button;
} }
void SetupArchiveAndMute( void SetupArchiveAndMute(

View file

@ -26,7 +26,7 @@ object_ptr<Ui::BoxContent> EditCloudPasswordBox(
void RemoveCloudPassword(not_null<Window::SessionController*> session); void RemoveCloudPassword(not_null<Window::SessionController*> session);
object_ptr<Ui::BoxContent> CloudPasswordAppOutdatedBox(); object_ptr<Ui::BoxContent> CloudPasswordAppOutdatedBox();
void AddPrivacyButton( not_null<Ui::SettingsButton*> AddPrivacyButton(
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container, not_null<Ui::VerticalLayout*> container,
rpl::producer<QString> label, rpl::producer<QString> label,