mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow editing charge-for-message privacy.
This commit is contained in:
parent
909b01241b
commit
f2aa3afbbb
8 changed files with 327 additions and 42 deletions
|
@ -1218,6 +1218,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_edit_privacy_contacts" = "My contacts";
|
"lng_edit_privacy_contacts" = "My contacts";
|
||||||
"lng_edit_privacy_close_friends" = "Close friends";
|
"lng_edit_privacy_close_friends" = "Close friends";
|
||||||
"lng_edit_privacy_contacts_and_premium" = "Contacts & Premium";
|
"lng_edit_privacy_contacts_and_premium" = "Contacts & Premium";
|
||||||
|
"lng_edit_privacy_paid" = "Paid";
|
||||||
"lng_edit_privacy_contacts_and_miniapps" = "Contacts & Mini Apps";
|
"lng_edit_privacy_contacts_and_miniapps" = "Contacts & Mini Apps";
|
||||||
"lng_edit_privacy_nobody" = "Nobody";
|
"lng_edit_privacy_nobody" = "Nobody";
|
||||||
"lng_edit_privacy_premium" = "Premium users";
|
"lng_edit_privacy_premium" = "Premium users";
|
||||||
|
@ -1356,6 +1357,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_messages_privacy_premium_about" = "Subscribe now to change this setting and get access to other exclusive features of Telegram Premium.";
|
"lng_messages_privacy_premium_about" = "Subscribe now to change this setting and get access to other exclusive features of Telegram Premium.";
|
||||||
"lng_messages_privacy_premium" = "Only subscribers of {link} can select this option.";
|
"lng_messages_privacy_premium" = "Only subscribers of {link} can select this option.";
|
||||||
"lng_messages_privacy_premium_link" = "Telegram Premium";
|
"lng_messages_privacy_premium_link" = "Telegram Premium";
|
||||||
|
"lng_messages_privacy_charge" = "Charge for messages";
|
||||||
|
"lng_messages_privacy_charge_about" = "Charge a fee for messages from people outside your contacts or those you haven't messaged first.";
|
||||||
|
"lng_messages_privacy_price" = "Set your price per message";
|
||||||
|
"lng_messages_privacy_price_about" = "You will receive {percent} of the selected fee ({amount}) for each incoming message.";
|
||||||
|
"lng_messages_privacy_exceptions" = "Exceptions";
|
||||||
|
"lng_messages_privacy_remove_fee" = "Remove Fee";
|
||||||
|
"lng_messages_privacy_remove_about" = "Add users or entire groups who won't be charged for sending messages to you.";
|
||||||
|
|
||||||
"lng_self_destruct_title" = "Account self-destruction";
|
"lng_self_destruct_title" = "Account self-destruction";
|
||||||
"lng_self_destruct_description" = "If you don't come online at least once within this period, your account will be deleted along with all groups, messages and contacts.";
|
"lng_self_destruct_description" = "If you don't come online at least once within this period, your account will be deleted along with all groups, messages and contacts.";
|
||||||
|
@ -2158,6 +2166,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_action_boost_apply#other" = "{from} boosted the group {count} times";
|
"lng_action_boost_apply#other" = "{from} boosted the group {count} times";
|
||||||
"lng_action_set_chat_intro" = "{from} added the message below for all empty chats. How?";
|
"lng_action_set_chat_intro" = "{from} added the message below for all empty chats. How?";
|
||||||
"lng_action_payment_refunded" = "{peer} refunded {amount}";
|
"lng_action_payment_refunded" = "{peer} refunded {amount}";
|
||||||
|
"lng_action_paid_message_sent#one" = "You paid {count} Star to send a message";
|
||||||
|
"lng_action_paid_message_sent#other" = "You paid {count} Stars to send a message";
|
||||||
|
"lng_action_paid_message_got#one" = "You received {count} Star from {name}";
|
||||||
|
"lng_action_paid_message_got#other" = "You received {count} Stars from {name}";
|
||||||
|
|
||||||
"lng_similar_channels_title" = "Similar channels";
|
"lng_similar_channels_title" = "Similar channels";
|
||||||
"lng_similar_channels_view_all" = "View all";
|
"lng_similar_channels_view_all" = "View all";
|
||||||
|
@ -4798,6 +4810,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_rights_boosts_no_restrict" = "Do not restrict boosters";
|
"lng_rights_boosts_no_restrict" = "Do not restrict boosters";
|
||||||
"lng_rights_boosts_about" = "Turn this on to always allow users who boosted your group to send messages and media.";
|
"lng_rights_boosts_about" = "Turn this on to always allow users who boosted your group to send messages and media.";
|
||||||
"lng_rights_boosts_about_on" = "Choose how many boosts a user must give to the group to bypass restrictions on sending messages.";
|
"lng_rights_boosts_about_on" = "Choose how many boosts a user must give to the group to bypass restrictions on sending messages.";
|
||||||
|
"lng_rights_charge_stars" = "Charge Stars for Messages";
|
||||||
|
"lng_rights_charge_stars_about" = "If you turn this on, regular members of the group will have to pay Stars to send messages.";
|
||||||
|
"lng_rights_charge_price" = "Set price per message";
|
||||||
|
"lng_rights_charge_price_about" = "Your group will receive {percent} of the selected fee ({amount}) for each incoming message.";
|
||||||
|
|
||||||
"lng_slowmode_enabled" = "Slow Mode is active.\nYou can send your next message in {left}.";
|
"lng_slowmode_enabled" = "Slow Mode is active.\nYou can send your next message in {left}.";
|
||||||
"lng_slowmode_no_many" = "Slow mode is enabled. You can't send more than one message at a time.";
|
"lng_slowmode_no_many" = "Slow mode is enabled. You can't send more than one message at a time.";
|
||||||
|
@ -4805,6 +4821,24 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_slowmode_seconds#one" = "{count} second";
|
"lng_slowmode_seconds#one" = "{count} second";
|
||||||
"lng_slowmode_seconds#other" = "{count} seconds";
|
"lng_slowmode_seconds#other" = "{count} seconds";
|
||||||
|
|
||||||
|
"lng_payment_for_message#one" = "Pay {star}{count} for 1 Message";
|
||||||
|
"lng_payment_for_message#other" = "Pay {star}{count} for 1 Message";
|
||||||
|
"lng_payment_confirm_title" = "Confirm payment";
|
||||||
|
"lng_payment_confirm_text#one" = "{name} charges **{count}** Star per message.";
|
||||||
|
"lng_payment_confirm_text#other" = "{name} charges **{count}** Stars per message.";
|
||||||
|
"lng_payment_confirm_sure#one" = "Would you like to pay **{count}** Star to send one message?";
|
||||||
|
"lng_payment_confirm_sure#other" = "Would you like to pay **{count}** Stars to send one message?";
|
||||||
|
"lng_payment_confirm_dont_ask" = "Don't ask me again";
|
||||||
|
"lng_payment_confirm_button" = "Pay for 1 Message";
|
||||||
|
"lng_payment_bar_text#one" = "{name} must pay {star}{count} for each message to you.";
|
||||||
|
"lng_payment_bar_text#other" = "{name} must pay {star}{count} for each message to you.";
|
||||||
|
"lng_payment_bar_button" = "Remove Fee";
|
||||||
|
"lng_payment_refund_title" = "Remove Fee";
|
||||||
|
"lng_payment_refund_text" = "Are you sure you want to allow {name} to message you for free?";
|
||||||
|
"lng_payment_refund_also#one" = "Refund already paid {count} Star";
|
||||||
|
"lng_payment_refund_also#other" = "Refund already paid {count} Stars";
|
||||||
|
"lng_payment_refund_confirm" = "Confirm";
|
||||||
|
|
||||||
"lng_rights_gigagroup_title" = "Broadcast group";
|
"lng_rights_gigagroup_title" = "Broadcast group";
|
||||||
"lng_rights_gigagroup_convert" = "Convert to Broadcast Group";
|
"lng_rights_gigagroup_convert" = "Convert to Broadcast Group";
|
||||||
"lng_rights_gigagroup_about" = "Broadcast groups can have over 200,000 members, but only admins can send messages in them.";
|
"lng_rights_gigagroup_about" = "Broadcast groups can have over 200,000 members, but only admins can send messages in them.";
|
||||||
|
|
|
@ -114,7 +114,8 @@ void GlobalPrivacy::updateHideReadTime(bool hide) {
|
||||||
archiveAndMuteCurrent(),
|
archiveAndMuteCurrent(),
|
||||||
unarchiveOnNewMessageCurrent(),
|
unarchiveOnNewMessageCurrent(),
|
||||||
hide,
|
hide,
|
||||||
newRequirePremiumCurrent());
|
newRequirePremiumCurrent(),
|
||||||
|
newChargeStarsCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool GlobalPrivacy::hideReadTimeCurrent() const {
|
bool GlobalPrivacy::hideReadTimeCurrent() const {
|
||||||
|
@ -125,14 +126,6 @@ rpl::producer<bool> GlobalPrivacy::hideReadTime() const {
|
||||||
return _hideReadTime.value();
|
return _hideReadTime.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalPrivacy::updateNewRequirePremium(bool value) {
|
|
||||||
update(
|
|
||||||
archiveAndMuteCurrent(),
|
|
||||||
unarchiveOnNewMessageCurrent(),
|
|
||||||
hideReadTimeCurrent(),
|
|
||||||
value);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GlobalPrivacy::newRequirePremiumCurrent() const {
|
bool GlobalPrivacy::newRequirePremiumCurrent() const {
|
||||||
return _newRequirePremium.current();
|
return _newRequirePremium.current();
|
||||||
}
|
}
|
||||||
|
@ -141,6 +134,25 @@ rpl::producer<bool> GlobalPrivacy::newRequirePremium() const {
|
||||||
return _newRequirePremium.value();
|
return _newRequirePremium.value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int GlobalPrivacy::newChargeStarsCurrent() const {
|
||||||
|
return _newChargeStars.current();
|
||||||
|
}
|
||||||
|
|
||||||
|
rpl::producer<int> GlobalPrivacy::newChargeStars() const {
|
||||||
|
return _newChargeStars.value();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GlobalPrivacy::updateMessagesPrivacy(
|
||||||
|
bool requirePremium,
|
||||||
|
int chargeStars) {
|
||||||
|
update(
|
||||||
|
archiveAndMuteCurrent(),
|
||||||
|
unarchiveOnNewMessageCurrent(),
|
||||||
|
hideReadTimeCurrent(),
|
||||||
|
requirePremium,
|
||||||
|
chargeStars);
|
||||||
|
}
|
||||||
|
|
||||||
void GlobalPrivacy::loadPaidReactionShownPeer() {
|
void GlobalPrivacy::loadPaidReactionShownPeer() {
|
||||||
if (_paidReactionShownPeerLoaded) {
|
if (_paidReactionShownPeerLoaded) {
|
||||||
return;
|
return;
|
||||||
|
@ -169,7 +181,8 @@ void GlobalPrivacy::updateArchiveAndMute(bool value) {
|
||||||
value,
|
value,
|
||||||
unarchiveOnNewMessageCurrent(),
|
unarchiveOnNewMessageCurrent(),
|
||||||
hideReadTimeCurrent(),
|
hideReadTimeCurrent(),
|
||||||
newRequirePremiumCurrent());
|
newRequirePremiumCurrent(),
|
||||||
|
newChargeStarsCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalPrivacy::updateUnarchiveOnNewMessage(
|
void GlobalPrivacy::updateUnarchiveOnNewMessage(
|
||||||
|
@ -178,14 +191,16 @@ void GlobalPrivacy::updateUnarchiveOnNewMessage(
|
||||||
archiveAndMuteCurrent(),
|
archiveAndMuteCurrent(),
|
||||||
value,
|
value,
|
||||||
hideReadTimeCurrent(),
|
hideReadTimeCurrent(),
|
||||||
newRequirePremiumCurrent());
|
newRequirePremiumCurrent(),
|
||||||
|
newChargeStarsCurrent());
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalPrivacy::update(
|
void GlobalPrivacy::update(
|
||||||
bool archiveAndMute,
|
bool archiveAndMute,
|
||||||
UnarchiveOnNewMessage unarchiveOnNewMessage,
|
UnarchiveOnNewMessage unarchiveOnNewMessage,
|
||||||
bool hideReadTime,
|
bool hideReadTime,
|
||||||
bool newRequirePremium) {
|
bool newRequirePremium,
|
||||||
|
int newChargeStars) {
|
||||||
using Flag = MTPDglobalPrivacySettings::Flag;
|
using Flag = MTPDglobalPrivacySettings::Flag;
|
||||||
|
|
||||||
_api.request(_requestId).cancel();
|
_api.request(_requestId).cancel();
|
||||||
|
@ -204,38 +219,44 @@ void GlobalPrivacy::update(
|
||||||
| (hideReadTime ? Flag::f_hide_read_marks : Flag())
|
| (hideReadTime ? Flag::f_hide_read_marks : Flag())
|
||||||
| ((newRequirePremium && newRequirePremiumAllowed)
|
| ((newRequirePremium && newRequirePremiumAllowed)
|
||||||
? Flag::f_new_noncontact_peers_require_premium
|
? Flag::f_new_noncontact_peers_require_premium
|
||||||
: Flag());
|
: Flag())
|
||||||
auto nonContactPaidStars = int64(0);
|
| Flag::f_noncontact_peers_paid_stars;
|
||||||
_requestId = _api.request(MTPaccount_SetGlobalPrivacySettings(
|
_requestId = _api.request(MTPaccount_SetGlobalPrivacySettings(
|
||||||
MTP_globalPrivacySettings(
|
MTP_globalPrivacySettings(
|
||||||
MTP_flags(flags),
|
MTP_flags(flags),
|
||||||
MTP_long(nonContactPaidStars))
|
MTP_long(newChargeStars))
|
||||||
)).done([=](const MTPGlobalPrivacySettings &result) {
|
)).done([=](const MTPGlobalPrivacySettings &result) {
|
||||||
_requestId = 0;
|
_requestId = 0;
|
||||||
apply(result);
|
apply(result);
|
||||||
}).fail([=](const MTP::Error &error) {
|
}).fail([=](const MTP::Error &error) {
|
||||||
_requestId = 0;
|
_requestId = 0;
|
||||||
if (error.type() == u"PREMIUM_ACCOUNT_REQUIRED"_q) {
|
if (error.type() == u"PREMIUM_ACCOUNT_REQUIRED"_q) {
|
||||||
update(archiveAndMute, unarchiveOnNewMessage, hideReadTime, {});
|
update(
|
||||||
|
archiveAndMute,
|
||||||
|
unarchiveOnNewMessage,
|
||||||
|
hideReadTime,
|
||||||
|
false,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
}).send();
|
}).send();
|
||||||
_archiveAndMute = archiveAndMute;
|
_archiveAndMute = archiveAndMute;
|
||||||
_unarchiveOnNewMessage = unarchiveOnNewMessage;
|
_unarchiveOnNewMessage = unarchiveOnNewMessage;
|
||||||
_hideReadTime = hideReadTime;
|
_hideReadTime = hideReadTime;
|
||||||
_newRequirePremium = newRequirePremium;
|
_newRequirePremium = newRequirePremium;
|
||||||
|
_newChargeStars = newChargeStars;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlobalPrivacy::apply(const MTPGlobalPrivacySettings &data) {
|
void GlobalPrivacy::apply(const MTPGlobalPrivacySettings &settings) {
|
||||||
data.match([&](const MTPDglobalPrivacySettings &data) {
|
const auto &data = settings.data();
|
||||||
_archiveAndMute = data.is_archive_and_mute_new_noncontact_peers();
|
_archiveAndMute = data.is_archive_and_mute_new_noncontact_peers();
|
||||||
_unarchiveOnNewMessage = data.is_keep_archived_unmuted()
|
_unarchiveOnNewMessage = data.is_keep_archived_unmuted()
|
||||||
? UnarchiveOnNewMessage::None
|
? UnarchiveOnNewMessage::None
|
||||||
: data.is_keep_archived_folders()
|
: data.is_keep_archived_folders()
|
||||||
? UnarchiveOnNewMessage::NotInFoldersUnmuted
|
? UnarchiveOnNewMessage::NotInFoldersUnmuted
|
||||||
: UnarchiveOnNewMessage::AnyUnmuted;
|
: UnarchiveOnNewMessage::AnyUnmuted;
|
||||||
_hideReadTime = data.is_hide_read_marks();
|
_hideReadTime = data.is_hide_read_marks();
|
||||||
_newRequirePremium = data.is_new_noncontact_peers_require_premium();
|
_newRequirePremium = data.is_new_noncontact_peers_require_premium();
|
||||||
});
|
_newChargeStars = data.vnoncontact_peers_paid_stars().value_or_empty();
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Api
|
} // namespace Api
|
||||||
|
|
|
@ -49,23 +49,28 @@ public:
|
||||||
[[nodiscard]] bool hideReadTimeCurrent() const;
|
[[nodiscard]] bool hideReadTimeCurrent() const;
|
||||||
[[nodiscard]] rpl::producer<bool> hideReadTime() const;
|
[[nodiscard]] rpl::producer<bool> hideReadTime() const;
|
||||||
|
|
||||||
void updateNewRequirePremium(bool value);
|
|
||||||
[[nodiscard]] bool newRequirePremiumCurrent() const;
|
[[nodiscard]] bool newRequirePremiumCurrent() const;
|
||||||
[[nodiscard]] rpl::producer<bool> newRequirePremium() const;
|
[[nodiscard]] rpl::producer<bool> newRequirePremium() const;
|
||||||
|
|
||||||
|
[[nodiscard]] int newChargeStarsCurrent() const;
|
||||||
|
[[nodiscard]] rpl::producer<int> newChargeStars() const;
|
||||||
|
|
||||||
|
void updateMessagesPrivacy(bool requirePremium, int chargeStars);
|
||||||
|
|
||||||
void loadPaidReactionShownPeer();
|
void loadPaidReactionShownPeer();
|
||||||
void updatePaidReactionShownPeer(PeerId shownPeer);
|
void updatePaidReactionShownPeer(PeerId shownPeer);
|
||||||
[[nodiscard]] PeerId paidReactionShownPeerCurrent() const;
|
[[nodiscard]] PeerId paidReactionShownPeerCurrent() const;
|
||||||
[[nodiscard]] rpl::producer<PeerId> paidReactionShownPeer() const;
|
[[nodiscard]] rpl::producer<PeerId> paidReactionShownPeer() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void apply(const MTPGlobalPrivacySettings &data);
|
void apply(const MTPGlobalPrivacySettings &settings);
|
||||||
|
|
||||||
void update(
|
void update(
|
||||||
bool archiveAndMute,
|
bool archiveAndMute,
|
||||||
UnarchiveOnNewMessage unarchiveOnNewMessage,
|
UnarchiveOnNewMessage unarchiveOnNewMessage,
|
||||||
bool hideReadTime,
|
bool hideReadTime,
|
||||||
bool newRequirePremium);
|
bool newRequirePremium,
|
||||||
|
int newChargeStars);
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Main::Session*> _session;
|
||||||
MTP::Sender _api;
|
MTP::Sender _api;
|
||||||
|
@ -76,6 +81,7 @@ private:
|
||||||
rpl::variable<bool> _showArchiveAndMute = false;
|
rpl::variable<bool> _showArchiveAndMute = false;
|
||||||
rpl::variable<bool> _hideReadTime = false;
|
rpl::variable<bool> _hideReadTime = false;
|
||||||
rpl::variable<bool> _newRequirePremium = false;
|
rpl::variable<bool> _newRequirePremium = false;
|
||||||
|
rpl::variable<int> _newChargeStars = 0;
|
||||||
rpl::variable<PeerId> _paidReactionShownPeer = false;
|
rpl::variable<PeerId> _paidReactionShownPeer = false;
|
||||||
std::vector<Fn<void()>> _callbacks;
|
std::vector<Fn<void()>> _callbacks;
|
||||||
bool _paidReactionShownPeerLoaded = false;
|
bool _paidReactionShownPeerLoaded = false;
|
||||||
|
|
|
@ -12,7 +12,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/effects/premium_graphics.h"
|
#include "ui/effects/premium_graphics.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/continuous_sliders.h"
|
||||||
#include "ui/widgets/shadow.h"
|
#include "ui/widgets/shadow.h"
|
||||||
|
#include "ui/text/format_values.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"
|
||||||
|
@ -42,6 +44,10 @@ namespace {
|
||||||
|
|
||||||
constexpr auto kPremiumsRowId = PeerId(FakeChatId(BareId(1))).value;
|
constexpr auto kPremiumsRowId = PeerId(FakeChatId(BareId(1))).value;
|
||||||
constexpr auto kMiniAppsRowId = PeerId(FakeChatId(BareId(2))).value;
|
constexpr auto kMiniAppsRowId = PeerId(FakeChatId(BareId(2))).value;
|
||||||
|
constexpr auto kGetPercent = 85;
|
||||||
|
constexpr auto kStarsMin = 10;
|
||||||
|
constexpr auto kStarsMax = 9000;
|
||||||
|
constexpr auto kDefaultChargeStars = 200;
|
||||||
|
|
||||||
using Exceptions = Api::UserPrivacy::Exceptions;
|
using Exceptions = Api::UserPrivacy::Exceptions;
|
||||||
|
|
||||||
|
@ -452,6 +458,109 @@ auto PrivacyExceptionsBoxController::createRow(not_null<History*> history)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] object_ptr<Ui::RpWidget> MakeChargeStarsSlider(
|
||||||
|
QWidget *parent,
|
||||||
|
not_null<const style::MediaSlider*> sliderStyle,
|
||||||
|
not_null<const style::FlatLabel*> labelStyle,
|
||||||
|
int valuesCount,
|
||||||
|
Fn<int(int)> valueByIndex,
|
||||||
|
int value,
|
||||||
|
Fn<void(int)> valueProgress,
|
||||||
|
Fn<void(int)> valueFinished) {
|
||||||
|
auto result = object_ptr<Ui::VerticalLayout>(parent);
|
||||||
|
const auto raw = result.data();
|
||||||
|
|
||||||
|
const auto labels = raw->add(object_ptr<Ui::RpWidget>(raw));
|
||||||
|
const auto min = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
QString::number(kStarsMin),
|
||||||
|
*labelStyle);
|
||||||
|
const auto max = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
QString::number(kStarsMax),
|
||||||
|
*labelStyle);
|
||||||
|
const auto current = Ui::CreateChild<Ui::FlatLabel>(
|
||||||
|
raw,
|
||||||
|
QString::number(value),
|
||||||
|
*labelStyle);
|
||||||
|
min->setTextColorOverride(st::windowSubTextFg->c);
|
||||||
|
max->setTextColorOverride(st::windowSubTextFg->c);
|
||||||
|
const auto slider = raw->add(object_ptr<Ui::MediaSliderWheelless>(
|
||||||
|
raw,
|
||||||
|
*sliderStyle));
|
||||||
|
labels->resize(
|
||||||
|
labels->width(),
|
||||||
|
current->height() + st::defaultVerticalListSkip);
|
||||||
|
struct State {
|
||||||
|
int indexMin = 0;
|
||||||
|
int index = 0;
|
||||||
|
};
|
||||||
|
const auto state = raw->lifetime().make_state<State>();
|
||||||
|
const auto updateByIndex = [=] {
|
||||||
|
const auto outer = labels->width();
|
||||||
|
const auto minWidth = min->width();
|
||||||
|
const auto maxWidth = max->width();
|
||||||
|
const auto currentWidth = current->width();
|
||||||
|
if (minWidth + maxWidth + currentWidth > outer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
min->moveToLeft(0, 0, outer);
|
||||||
|
max->moveToRight(0, 0, outer);
|
||||||
|
current->moveToLeft((outer - current->width()) / 2, 0, outer);
|
||||||
|
};
|
||||||
|
const auto updateByValue = [=](int value) {
|
||||||
|
current->setText(
|
||||||
|
tr::lng_action_gift_for_stars(tr::now, lt_count, value));
|
||||||
|
|
||||||
|
state->index = 0;
|
||||||
|
auto maxIndex = valuesCount - 1;
|
||||||
|
while (state->index < maxIndex) {
|
||||||
|
const auto mid = (state->index + maxIndex) / 2;
|
||||||
|
const auto midValue = valueByIndex(mid);
|
||||||
|
if (midValue == value) {
|
||||||
|
state->index = mid;
|
||||||
|
break;
|
||||||
|
} else if (midValue < value) {
|
||||||
|
state->index = mid + 1;
|
||||||
|
} else {
|
||||||
|
maxIndex = mid - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateByIndex();
|
||||||
|
};
|
||||||
|
const auto progress = [=](int value) {
|
||||||
|
updateByValue(value);
|
||||||
|
valueProgress(value);
|
||||||
|
};
|
||||||
|
const auto finished = [=](int value) {
|
||||||
|
updateByValue(value);
|
||||||
|
valueFinished(value);
|
||||||
|
};
|
||||||
|
style::PaletteChanged() | rpl::start_with_next([=] {
|
||||||
|
min->setTextColorOverride(st::windowSubTextFg->c);
|
||||||
|
max->setTextColorOverride(st::windowSubTextFg->c);
|
||||||
|
}, raw->lifetime());
|
||||||
|
updateByValue(value);
|
||||||
|
state->indexMin = 0;
|
||||||
|
|
||||||
|
slider->setPseudoDiscrete(
|
||||||
|
valuesCount,
|
||||||
|
valueByIndex,
|
||||||
|
value,
|
||||||
|
progress,
|
||||||
|
finished,
|
||||||
|
state->indexMin);
|
||||||
|
slider->resize(slider->width(), sliderStyle->seekSize.height());
|
||||||
|
|
||||||
|
raw->widthValue() | rpl::start_with_next([=](int width) {
|
||||||
|
labels->resizeToWidth(width);
|
||||||
|
updateByIndex();
|
||||||
|
}, slider->lifetime());
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
bool EditPrivacyController::hasOption(Option option) const {
|
bool EditPrivacyController::hasOption(Option option) const {
|
||||||
|
@ -812,6 +921,7 @@ void EditMessagesPrivacyBox(
|
||||||
|
|
||||||
constexpr auto kOptionAll = 0;
|
constexpr auto kOptionAll = 0;
|
||||||
constexpr auto kOptionPremium = 1;
|
constexpr auto kOptionPremium = 1;
|
||||||
|
constexpr auto kOptionCharge = 2;
|
||||||
|
|
||||||
const auto allowed = [=] {
|
const auto allowed = [=] {
|
||||||
return controller->session().premium()
|
return controller->session().premium()
|
||||||
|
@ -824,7 +934,11 @@ void EditMessagesPrivacyBox(
|
||||||
Ui::AddSkip(inner, st::messagePrivacyTopSkip);
|
Ui::AddSkip(inner, st::messagePrivacyTopSkip);
|
||||||
Ui::AddSubsectionTitle(inner, tr::lng_messages_privacy_subtitle());
|
Ui::AddSubsectionTitle(inner, tr::lng_messages_privacy_subtitle());
|
||||||
const auto group = std::make_shared<Ui::RadiobuttonGroup>(
|
const auto group = std::make_shared<Ui::RadiobuttonGroup>(
|
||||||
privacy->newRequirePremiumCurrent() ? kOptionPremium : kOptionAll);
|
(privacy->newRequirePremiumCurrent()
|
||||||
|
? kOptionPremium
|
||||||
|
: privacy->newChargeStarsCurrent()
|
||||||
|
? kOptionCharge
|
||||||
|
: kOptionAll));
|
||||||
inner->add(
|
inner->add(
|
||||||
object_ptr<Ui::Radiobutton>(
|
object_ptr<Ui::Radiobutton>(
|
||||||
inner,
|
inner,
|
||||||
|
@ -846,6 +960,107 @@ void EditMessagesPrivacyBox(
|
||||||
0,
|
0,
|
||||||
st::messagePrivacyBottomSkip));
|
st::messagePrivacyBottomSkip));
|
||||||
|
|
||||||
|
Ui::AddDividerText(inner, tr::lng_messages_privacy_about());
|
||||||
|
|
||||||
|
const auto charged = inner->add(
|
||||||
|
object_ptr<Ui::Radiobutton>(
|
||||||
|
inner,
|
||||||
|
group,
|
||||||
|
kOptionCharge,
|
||||||
|
tr::lng_messages_privacy_charge(tr::now),
|
||||||
|
st::messagePrivacyCheck),
|
||||||
|
st::settingsSendTypePadding + style::margins(
|
||||||
|
0,
|
||||||
|
st::messagePrivacyBottomSkip,
|
||||||
|
0,
|
||||||
|
st::messagePrivacyBottomSkip));
|
||||||
|
|
||||||
|
Ui::AddDividerText(inner, tr::lng_messages_privacy_charge_about());
|
||||||
|
|
||||||
|
const auto chargeWrap = inner->add(
|
||||||
|
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||||
|
inner,
|
||||||
|
object_ptr<Ui::VerticalLayout>(inner)));
|
||||||
|
const auto chargeInner = chargeWrap->entity();
|
||||||
|
|
||||||
|
Ui::AddSkip(chargeInner);
|
||||||
|
Ui::AddSubsectionTitle(chargeInner, tr::lng_messages_privacy_price());
|
||||||
|
|
||||||
|
struct State {
|
||||||
|
rpl::variable<int> stars;
|
||||||
|
};
|
||||||
|
const auto state = std::make_shared<State>();
|
||||||
|
const auto savedValue = privacy->newChargeStarsCurrent();
|
||||||
|
const auto chargeStars = savedValue ? savedValue : kDefaultChargeStars;
|
||||||
|
state->stars = chargeStars;
|
||||||
|
|
||||||
|
auto values = std::vector<int>();
|
||||||
|
if (chargeStars < kStarsMin) {
|
||||||
|
values.push_back(chargeStars);
|
||||||
|
}
|
||||||
|
for (auto i = kStarsMin; i < 100; ++i) {
|
||||||
|
values.push_back(i);
|
||||||
|
}
|
||||||
|
for (auto i = 100; i < 1000; i += 10) {
|
||||||
|
if (i < chargeStars + 10 && chargeStars < i) {
|
||||||
|
values.push_back(chargeStars);
|
||||||
|
}
|
||||||
|
values.push_back(i);
|
||||||
|
}
|
||||||
|
for (auto i = 1000; i < kStarsMax + 1; i += 100) {
|
||||||
|
if (i < chargeStars + 100 && chargeStars < i) {
|
||||||
|
values.push_back(chargeStars);
|
||||||
|
}
|
||||||
|
values.push_back(i);
|
||||||
|
}
|
||||||
|
const auto valuesCount = int(values.size());
|
||||||
|
const auto setStars = [=](int value) {
|
||||||
|
state->stars = value;
|
||||||
|
};
|
||||||
|
chargeInner->add(
|
||||||
|
MakeChargeStarsSlider(
|
||||||
|
chargeInner,
|
||||||
|
&st::settingsScale,
|
||||||
|
&st::settingsScaleLabel,
|
||||||
|
valuesCount,
|
||||||
|
[=](int index) { return values[index]; },
|
||||||
|
chargeStars,
|
||||||
|
setStars,
|
||||||
|
setStars),
|
||||||
|
st::boxRowPadding);
|
||||||
|
Ui::AddSkip(chargeInner);
|
||||||
|
|
||||||
|
auto dollars = state->stars.value() | rpl::map([=](int stars) {
|
||||||
|
const auto ratio = controller->session().appConfig().get<float64>(
|
||||||
|
u"stars_usd_withdraw_rate_x1000"_q,
|
||||||
|
1200);
|
||||||
|
const auto dollars = int(base::SafeRound(stars * (ratio / 1000.)));
|
||||||
|
return '~' + Ui::FillAmountAndCurrency(dollars, u"USD"_q);
|
||||||
|
});
|
||||||
|
Ui::AddDividerText(
|
||||||
|
chargeInner,
|
||||||
|
tr::lng_messages_privacy_price_about(
|
||||||
|
lt_percent,
|
||||||
|
rpl::single(QString::number(kGetPercent) + '%'),
|
||||||
|
lt_amount,
|
||||||
|
std::move(dollars)));
|
||||||
|
|
||||||
|
Ui::AddSkip(chargeInner);
|
||||||
|
Ui::AddSubsectionTitle(
|
||||||
|
chargeInner,
|
||||||
|
tr::lng_messages_privacy_exceptions());
|
||||||
|
const auto exceptions = Settings::AddButtonWithLabel(
|
||||||
|
chargeInner,
|
||||||
|
tr::lng_messages_privacy_remove_fee(),
|
||||||
|
rpl::single(u""_q),
|
||||||
|
st::settingsButtonNoIcon);
|
||||||
|
Ui::AddSkip(chargeInner);
|
||||||
|
Ui::AddDividerText(chargeInner, tr::lng_messages_privacy_remove_about());
|
||||||
|
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
chargeWrap->toggleOn(group->value() | rpl::map(_1 == kOptionCharge));
|
||||||
|
chargeWrap->finishAnimating();
|
||||||
|
|
||||||
using WeakToast = base::weak_ptr<Ui::Toast::Instance>;
|
using WeakToast = base::weak_ptr<Ui::Toast::Instance>;
|
||||||
const auto toast = std::make_shared<WeakToast>();
|
const auto toast = std::make_shared<WeakToast>();
|
||||||
const auto showToast = [=] {
|
const auto showToast = [=] {
|
||||||
|
@ -875,19 +1090,18 @@ void EditMessagesPrivacyBox(
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!allowed()) {
|
if (!allowed()) {
|
||||||
CreateRadiobuttonLock(restricted, st::messagePrivacyCheck);
|
CreateRadiobuttonLock(restricted, st::messagePrivacyCheck);
|
||||||
|
CreateRadiobuttonLock(charged, st::messagePrivacyCheck);
|
||||||
|
|
||||||
group->setChangedCallback([=](int value) {
|
group->setChangedCallback([=](int value) {
|
||||||
if (value == kOptionPremium) {
|
if (value == kOptionPremium || value == kOptionCharge) {
|
||||||
group->setValue(kOptionAll);
|
group->setValue(kOptionAll);
|
||||||
showToast();
|
showToast();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
Ui::AddDividerText(inner, tr::lng_messages_privacy_about());
|
|
||||||
if (!allowed()) {
|
|
||||||
Ui::AddSkip(inner);
|
Ui::AddSkip(inner);
|
||||||
Settings::AddButtonWithIcon(
|
Settings::AddButtonWithIcon(
|
||||||
inner,
|
inner,
|
||||||
|
@ -907,8 +1121,12 @@ void EditMessagesPrivacyBox(
|
||||||
} else {
|
} else {
|
||||||
box->addButton(tr::lng_settings_save(), [=] {
|
box->addButton(tr::lng_settings_save(), [=] {
|
||||||
if (allowed()) {
|
if (allowed()) {
|
||||||
privacy->updateNewRequirePremium(
|
const auto value = group->current();
|
||||||
group->current() == kOptionPremium);
|
const auto premiumRequired = (value == kOptionPremium);
|
||||||
|
const auto chargeStars = (value == kOptionCharge)
|
||||||
|
? state->stars.current()
|
||||||
|
: 0;
|
||||||
|
privacy->updateMessagesPrivacy(premiumRequired, chargeStars);
|
||||||
box->closeBox();
|
box->closeBox();
|
||||||
} else {
|
} else {
|
||||||
showToast();
|
showToast();
|
||||||
|
|
|
@ -610,7 +610,6 @@ void UserData::setCallsStatus(CallsStatus callsStatus) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
Data::Birthday UserData::birthday() const {
|
Data::Birthday UserData::birthday() const {
|
||||||
return _birthday;
|
return _birthday;
|
||||||
}
|
}
|
||||||
|
|
|
@ -630,7 +630,7 @@ void Widget::fillTopBarMenu(const Ui::Menu::MenuCallback &addAction) {
|
||||||
});
|
});
|
||||||
}, filter.skipUnique ? nullptr : &st::mediaPlayerMenuCheck);
|
}, filter.skipUnique ? nullptr : &st::mediaPlayerMenuCheck);
|
||||||
|
|
||||||
if (_inner->peer()->canManageGifts() && _inner->peer()->isChannel()) {
|
if (_inner->peer()->canManageGifts()) {
|
||||||
addAction({ .isSeparator = true });
|
addAction({ .isSeparator = true });
|
||||||
|
|
||||||
addAction(tr::lng_peer_gifts_filter_saved(tr::now), [=] {
|
addAction(tr::lng_peer_gifts_filter_saved(tr::now), [=] {
|
||||||
|
|
|
@ -535,6 +535,7 @@ inputPrivacyKeyVoiceMessages#aee69d68 = InputPrivacyKey;
|
||||||
inputPrivacyKeyAbout#3823cc40 = InputPrivacyKey;
|
inputPrivacyKeyAbout#3823cc40 = InputPrivacyKey;
|
||||||
inputPrivacyKeyBirthday#d65a11cc = InputPrivacyKey;
|
inputPrivacyKeyBirthday#d65a11cc = InputPrivacyKey;
|
||||||
inputPrivacyKeyStarGiftsAutoSave#e1732341 = InputPrivacyKey;
|
inputPrivacyKeyStarGiftsAutoSave#e1732341 = InputPrivacyKey;
|
||||||
|
inputPrivacyKeyNoPaidMessages#bdc597b4 = InputPrivacyKey;
|
||||||
|
|
||||||
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
|
privacyKeyStatusTimestamp#bc2eab30 = PrivacyKey;
|
||||||
privacyKeyChatInvite#500e6dfa = PrivacyKey;
|
privacyKeyChatInvite#500e6dfa = PrivacyKey;
|
||||||
|
|
|
@ -356,10 +356,16 @@ void AddMessagesPrivacyButton(
|
||||||
not_null<Ui::VerticalLayout*> container) {
|
not_null<Ui::VerticalLayout*> container) {
|
||||||
const auto session = &controller->session();
|
const auto session = &controller->session();
|
||||||
const auto privacy = &session->api().globalPrivacy();
|
const auto privacy = &session->api().globalPrivacy();
|
||||||
auto label = rpl::conditional(
|
auto label = rpl::combine(
|
||||||
privacy->newRequirePremium(),
|
privacy->newRequirePremium(),
|
||||||
tr::lng_edit_privacy_contacts_and_premium(),
|
privacy->newChargeStars()
|
||||||
tr::lng_edit_privacy_everyone());
|
) | rpl::map([=](bool requirePremium, int chargeStars) {
|
||||||
|
return chargeStars
|
||||||
|
? tr::lng_edit_privacy_paid()
|
||||||
|
: requirePremium
|
||||||
|
? tr::lng_edit_privacy_contacts_and_premium()
|
||||||
|
: tr::lng_edit_privacy_everyone();
|
||||||
|
}) | rpl::flatten_latest();
|
||||||
const auto &st = st::settingsButtonNoIcon;
|
const auto &st = st::settingsButtonNoIcon;
|
||||||
const auto button = AddButtonWithLabel(
|
const auto button = AddButtonWithLabel(
|
||||||
container,
|
container,
|
||||||
|
|
Loading…
Add table
Reference in a new issue