mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 05:07:10 +02:00
Track stars-per-message for users and channels.
This commit is contained in:
parent
f2aa3afbbb
commit
45c7829cd8
10 changed files with 239 additions and 102 deletions
|
@ -45,9 +45,9 @@ namespace {
|
|||
constexpr auto kPremiumsRowId = PeerId(FakeChatId(BareId(1))).value;
|
||||
constexpr auto kMiniAppsRowId = PeerId(FakeChatId(BareId(2))).value;
|
||||
constexpr auto kGetPercent = 85;
|
||||
constexpr auto kStarsMin = 10;
|
||||
constexpr auto kStarsMin = 1;
|
||||
constexpr auto kStarsMax = 9000;
|
||||
constexpr auto kDefaultChargeStars = 200;
|
||||
constexpr auto kDefaultChargeStars = 10;
|
||||
|
||||
using Exceptions = Api::UserPrivacy::Exceptions;
|
||||
|
||||
|
@ -934,7 +934,9 @@ void EditMessagesPrivacyBox(
|
|||
Ui::AddSkip(inner, st::messagePrivacyTopSkip);
|
||||
Ui::AddSubsectionTitle(inner, tr::lng_messages_privacy_subtitle());
|
||||
const auto group = std::make_shared<Ui::RadiobuttonGroup>(
|
||||
(privacy->newRequirePremiumCurrent()
|
||||
(!allowed()
|
||||
? kOptionAll
|
||||
: privacy->newRequirePremiumCurrent()
|
||||
? kOptionPremium
|
||||
: privacy->newChargeStarsCurrent()
|
||||
? kOptionCharge
|
||||
|
@ -984,66 +986,17 @@ void EditMessagesPrivacyBox(
|
|||
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(
|
||||
state->stars = SetupChargeSlider(
|
||||
chargeInner,
|
||||
tr::lng_messages_privacy_price_about(
|
||||
lt_percent,
|
||||
rpl::single(QString::number(kGetPercent) + '%'),
|
||||
lt_amount,
|
||||
std::move(dollars)));
|
||||
controller->session().user(),
|
||||
savedValue);
|
||||
|
||||
Ui::AddSkip(chargeInner);
|
||||
Ui::AddSubsectionTitle(
|
||||
|
@ -1137,3 +1090,77 @@ void EditMessagesPrivacyBox(
|
|||
});
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<int> SetupChargeSlider(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<PeerData*> peer,
|
||||
int savedValue) {
|
||||
struct State {
|
||||
rpl::variable<int> stars;
|
||||
};
|
||||
const auto group = !peer->isUser();
|
||||
const auto state = container->lifetime().make_state<State>();
|
||||
const auto chargeStars = savedValue ? savedValue : kDefaultChargeStars;
|
||||
state->stars = chargeStars;
|
||||
|
||||
Ui::AddSubsectionTitle(container, group
|
||||
? tr::lng_rights_charge_price()
|
||||
: tr::lng_messages_privacy_price());
|
||||
|
||||
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;
|
||||
};
|
||||
container->add(
|
||||
MakeChargeStarsSlider(
|
||||
container,
|
||||
&st::settingsScale,
|
||||
&st::settingsScaleLabel,
|
||||
valuesCount,
|
||||
[=](int index) { return values[index]; },
|
||||
chargeStars,
|
||||
setStars,
|
||||
setStars),
|
||||
st::boxRowPadding);
|
||||
|
||||
const auto skip = 2 * st::defaultVerticalListSkip;
|
||||
Ui::AddSkip(container, skip);
|
||||
|
||||
auto dollars = state->stars.value() | rpl::map([=](int stars) {
|
||||
const auto ratio = peer->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(
|
||||
container,
|
||||
(group
|
||||
? tr::lng_rights_charge_price_about
|
||||
: tr::lng_messages_privacy_price_about)(
|
||||
lt_percent,
|
||||
rpl::single(QString::number(kGetPercent) + '%'),
|
||||
lt_amount,
|
||||
std::move(dollars)));
|
||||
|
||||
return state->stars.value();
|
||||
}
|
||||
|
|
|
@ -169,3 +169,8 @@ private:
|
|||
void EditMessagesPrivacyBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionController*> controller);
|
||||
|
||||
[[nodiscard]] rpl::producer<int> SetupChargeSlider(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<PeerData*> peer,
|
||||
int savedValue);
|
||||
|
|
|
@ -219,6 +219,33 @@ void SaveSlowmodeSeconds(
|
|||
api->registerModifyRequest(key, requestId);
|
||||
}
|
||||
|
||||
void SaveStarsPerMessage(
|
||||
not_null<ChannelData*> channel,
|
||||
int starsPerMessage,
|
||||
Fn<void()> done) {
|
||||
const auto api = &channel->session().api();
|
||||
const auto key = Api::RequestKey("stars_per_message", channel->id);
|
||||
|
||||
const auto requestId = api->request(MTPchannels_UpdatePaidMessagesPrice(
|
||||
channel->inputChannel,
|
||||
MTP_long(starsPerMessage)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->clearModifyRequest(key);
|
||||
api->applyUpdates(result);
|
||||
channel->setStarsPerMessage(starsPerMessage);
|
||||
done();
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
api->clearModifyRequest(key);
|
||||
if (error.type() != u"CHAT_NOT_MODIFIED"_q) {
|
||||
return;
|
||||
}
|
||||
channel->setStarsPerMessage(starsPerMessage);
|
||||
done();
|
||||
}).send();
|
||||
|
||||
api->registerModifyRequest(key, requestId);
|
||||
}
|
||||
|
||||
void SaveBoostsUnrestrict(
|
||||
not_null<ChannelData*> channel,
|
||||
int boostsUnrestrict,
|
||||
|
@ -271,6 +298,7 @@ void ShowEditPermissions(
|
|||
channel,
|
||||
result.boostsUnrestrict,
|
||||
close);
|
||||
SaveStarsPerMessage(channel, result.starsPerMessage, close);
|
||||
}
|
||||
};
|
||||
auto done = [=](EditPeerPermissionsBoxResult result) {
|
||||
|
@ -282,7 +310,9 @@ void ShowEditPermissions(
|
|||
const auto saveFor = peer->migrateToOrMe();
|
||||
const auto chat = saveFor->asChat();
|
||||
if (!chat
|
||||
|| (!result.slowmodeSeconds && !result.boostsUnrestrict)) {
|
||||
|| (!result.slowmodeSeconds
|
||||
&& !result.boostsUnrestrict
|
||||
&& !result.starsPerMessage)) {
|
||||
save(saveFor, result);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "info/profile/info_profile_values.h"
|
||||
#include "boxes/peers/edit_participants_box.h"
|
||||
#include "boxes/peers/edit_peer_info_box.h"
|
||||
#include "boxes/edit_privacy_box.h"
|
||||
#include "settings/settings_power_saving.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "window/window_controller.h"
|
||||
|
@ -940,9 +941,7 @@ rpl::producer<int> AddBoostsUnrestrictSlider(
|
|||
const auto boostsUnrestrict = lifetime.make_state<rpl::variable<int>>(
|
||||
channel ? channel->boostsUnrestrict() : 0);
|
||||
|
||||
container->add(
|
||||
object_ptr<Ui::BoxContentDivider>(container),
|
||||
{ 0, st::infoProfileSkip, 0, st::infoProfileSkip });
|
||||
Ui::AddSkip(container);
|
||||
|
||||
auto enabled = boostsUnrestrict->value(
|
||||
) | rpl::map(_1 > 0);
|
||||
|
@ -1006,19 +1005,20 @@ rpl::producer<int> AddBoostsUnrestrictWrapped(
|
|||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
container,
|
||||
object_ptr<Ui::VerticalLayout>(container)));
|
||||
wrap->toggleOn(rpl::duplicate(shown), anim::type::normal);
|
||||
wrap->toggleOn(std::move(shown), anim::type::normal);
|
||||
wrap->finishAnimating();
|
||||
|
||||
auto result = AddBoostsUnrestrictSlider(wrap->entity(), peer);
|
||||
const auto divider = container->add(
|
||||
const auto inner = wrap->entity();
|
||||
|
||||
auto result = AddBoostsUnrestrictSlider(inner, peer);
|
||||
|
||||
const auto skip = st::defaultVerticalListSkip;
|
||||
const auto divider = inner->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::BoxContentDivider>>(
|
||||
container,
|
||||
object_ptr<Ui::BoxContentDivider>(container),
|
||||
QMargins{ 0, st::infoProfileSkip, 0, st::infoProfileSkip }));
|
||||
divider->toggleOn(rpl::combine(
|
||||
std::move(shown),
|
||||
rpl::duplicate(result),
|
||||
!rpl::mappers::_1 || !rpl::mappers::_2));
|
||||
inner,
|
||||
object_ptr<Ui::BoxContentDivider>(inner),
|
||||
QMargins{ 0, skip, 0, skip }));
|
||||
divider->toggleOn(rpl::duplicate(result) | rpl::map(!rpl::mappers::_1));
|
||||
divider->finishAnimating();
|
||||
|
||||
return result;
|
||||
|
@ -1157,7 +1157,38 @@ void ShowEditPeerPermissionsBox(
|
|||
rpl::variable<int> slowmodeSeconds;
|
||||
rpl::variable<int> boostsUnrestrict;
|
||||
rpl::variable<bool> hasSendRestrictions;
|
||||
rpl::variable<int> starsPerMessage;
|
||||
};
|
||||
const auto state = inner->lifetime().make_state<State>();
|
||||
|
||||
Ui::AddSkip(inner);
|
||||
Ui::AddDivider(inner);
|
||||
Ui::AddSkip(inner);
|
||||
const auto starsPerMessage = peer->isChannel()
|
||||
? peer->asChannel()->starsPerMessage()
|
||||
: 0;
|
||||
const auto charging = inner->add(object_ptr<Ui::SettingsButton>(
|
||||
inner,
|
||||
tr::lng_rights_charge_stars(),
|
||||
st::settingsButtonNoIcon));
|
||||
charging->toggleOn(rpl::single(starsPerMessage > 0));
|
||||
Ui::AddSkip(inner);
|
||||
Ui::AddDividerText(inner, tr::lng_rights_charge_stars_about());
|
||||
|
||||
const auto chargeWrap = inner->add(
|
||||
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
inner,
|
||||
object_ptr<Ui::VerticalLayout>(inner)));
|
||||
chargeWrap->toggleOn(charging->toggledValue());
|
||||
chargeWrap->finishAnimating();
|
||||
const auto chargeInner = chargeWrap->entity();
|
||||
|
||||
Ui::AddSkip(chargeInner);
|
||||
state->starsPerMessage = SetupChargeSlider(
|
||||
chargeInner,
|
||||
peer,
|
||||
starsPerMessage);
|
||||
|
||||
static constexpr auto kSendRestrictions = Flag::EmbedLinks
|
||||
| Flag::SendGames
|
||||
| Flag::SendGifs
|
||||
|
@ -1171,7 +1202,6 @@ void ShowEditPeerPermissionsBox(
|
|||
| Flag::SendVoiceMessages
|
||||
| Flag::SendFiles
|
||||
| Flag::SendOther;
|
||||
const auto state = inner->lifetime().make_state<State>();
|
||||
state->hasSendRestrictions = ((restrictions & kSendRestrictions) != 0)
|
||||
|| (peer->isChannel() && peer->asChannel()->slowmodeSeconds() > 0);
|
||||
state->boostsUnrestrict = AddBoostsUnrestrictWrapped(
|
||||
|
@ -1212,10 +1242,14 @@ void ShowEditPeerPermissionsBox(
|
|||
const auto boostsUnrestrict = hasRestrictions
|
||||
? state->boostsUnrestrict.current()
|
||||
: 0;
|
||||
const auto starsPerMessage = charging->toggled()
|
||||
? state->starsPerMessage.current()
|
||||
: 0;
|
||||
done({
|
||||
restrictions,
|
||||
slowmodeSeconds,
|
||||
boostsUnrestrict,
|
||||
starsPerMessage,
|
||||
});
|
||||
});
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
|
|
|
@ -39,6 +39,7 @@ struct EditPeerPermissionsBoxResult final {
|
|||
ChatRestrictions rights;
|
||||
int slowmodeSeconds = 0;
|
||||
int boostsUnrestrict = 0;
|
||||
int starsPerMessage = 0;
|
||||
};
|
||||
|
||||
void ShowEditPeerPermissionsBox(
|
||||
|
|
|
@ -75,46 +75,47 @@ struct PeerUpdate {
|
|||
BackgroundEmoji = (1ULL << 15),
|
||||
StoriesState = (1ULL << 16),
|
||||
VerifyInfo = (1ULL << 17),
|
||||
StarsPerMessage = (1ULL << 18),
|
||||
|
||||
// For users
|
||||
CanShareContact = (1ULL << 18),
|
||||
IsContact = (1ULL << 19),
|
||||
PhoneNumber = (1ULL << 20),
|
||||
OnlineStatus = (1ULL << 21),
|
||||
BotCommands = (1ULL << 22),
|
||||
BotCanBeInvited = (1ULL << 23),
|
||||
BotStartToken = (1ULL << 24),
|
||||
CommonChats = (1ULL << 25),
|
||||
PeerGifts = (1ULL << 26),
|
||||
HasCalls = (1ULL << 27),
|
||||
SupportInfo = (1ULL << 28),
|
||||
IsBot = (1ULL << 29),
|
||||
EmojiStatus = (1ULL << 30),
|
||||
BusinessDetails = (1ULL << 31),
|
||||
Birthday = (1ULL << 32),
|
||||
PersonalChannel = (1ULL << 33),
|
||||
StarRefProgram = (1ULL << 34),
|
||||
CanShareContact = (1ULL << 19),
|
||||
IsContact = (1ULL << 20),
|
||||
PhoneNumber = (1ULL << 21),
|
||||
OnlineStatus = (1ULL << 22),
|
||||
BotCommands = (1ULL << 23),
|
||||
BotCanBeInvited = (1ULL << 24),
|
||||
BotStartToken = (1ULL << 25),
|
||||
CommonChats = (1ULL << 26),
|
||||
PeerGifts = (1ULL << 27),
|
||||
HasCalls = (1ULL << 28),
|
||||
SupportInfo = (1ULL << 29),
|
||||
IsBot = (1ULL << 30),
|
||||
EmojiStatus = (1ULL << 31),
|
||||
BusinessDetails = (1ULL << 32),
|
||||
Birthday = (1ULL << 33),
|
||||
PersonalChannel = (1ULL << 34),
|
||||
StarRefProgram = (1ULL << 35),
|
||||
|
||||
// For chats and channels
|
||||
InviteLinks = (1ULL << 35),
|
||||
Members = (1ULL << 36),
|
||||
Admins = (1ULL << 37),
|
||||
BannedUsers = (1ULL << 38),
|
||||
Rights = (1ULL << 39),
|
||||
PendingRequests = (1ULL << 40),
|
||||
Reactions = (1ULL << 41),
|
||||
InviteLinks = (1ULL << 36),
|
||||
Members = (1ULL << 37),
|
||||
Admins = (1ULL << 38),
|
||||
BannedUsers = (1ULL << 39),
|
||||
Rights = (1ULL << 40),
|
||||
PendingRequests = (1ULL << 41),
|
||||
Reactions = (1ULL << 42),
|
||||
|
||||
// For channels
|
||||
ChannelAmIn = (1ULL << 42),
|
||||
StickersSet = (1ULL << 43),
|
||||
EmojiSet = (1ULL << 44),
|
||||
ChannelLinkedChat = (1ULL << 45),
|
||||
ChannelLocation = (1ULL << 46),
|
||||
Slowmode = (1ULL << 47),
|
||||
GroupCall = (1ULL << 48),
|
||||
ChannelAmIn = (1ULL << 43),
|
||||
StickersSet = (1ULL << 44),
|
||||
EmojiSet = (1ULL << 45),
|
||||
ChannelLinkedChat = (1ULL << 46),
|
||||
ChannelLocation = (1ULL << 47),
|
||||
Slowmode = (1ULL << 48),
|
||||
GroupCall = (1ULL << 49),
|
||||
|
||||
// For iteration
|
||||
LastUsedBit = (1ULL << 48),
|
||||
LastUsedBit = (1ULL << 49),
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||
|
|
|
@ -859,6 +859,21 @@ void ChannelData::growSlowmodeLastMessage(TimeId when) {
|
|||
session().changes().peerUpdated(this, UpdateFlag::Slowmode);
|
||||
}
|
||||
|
||||
int ChannelData::starsPerMessage() const {
|
||||
if (const auto info = mgInfo.get()) {
|
||||
return info->starsPerMessage;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void ChannelData::setStarsPerMessage(int stars) {
|
||||
if (!mgInfo || starsPerMessage() == stars) {
|
||||
return;
|
||||
}
|
||||
mgInfo->starsPerMessage = stars;
|
||||
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||
}
|
||||
|
||||
int ChannelData::peerGiftsCount() const {
|
||||
return _peerGiftsCount;
|
||||
}
|
||||
|
@ -1209,6 +1224,8 @@ void ApplyChannelUpdate(
|
|||
} else {
|
||||
channel->setLinkedChat(nullptr);
|
||||
}
|
||||
channel->setStarsPerMessage(
|
||||
update.vsend_paid_messages_stars().value_or_empty());
|
||||
if (const auto history = channel->owner().historyLoaded(channel)) {
|
||||
if (const auto available = update.vavailable_min_id()) {
|
||||
history->clearUpTill(available->v);
|
||||
|
|
|
@ -145,6 +145,8 @@ public:
|
|||
int slowmodeSeconds = 0;
|
||||
TimeId slowmodeLastMessage = 0;
|
||||
|
||||
int starsPerMessage = 0;
|
||||
|
||||
private:
|
||||
ChatData *_migratedFrom = nullptr;
|
||||
ChannelLocation _location;
|
||||
|
@ -456,6 +458,9 @@ public:
|
|||
[[nodiscard]] TimeId slowmodeLastMessage() const;
|
||||
void growSlowmodeLastMessage(TimeId when);
|
||||
|
||||
[[nodiscard]] int starsPerMessage() const;
|
||||
void setStarsPerMessage(int stars);
|
||||
|
||||
[[nodiscard]] int peerGiftsCount() const;
|
||||
void setPeerGiftsCount(int count);
|
||||
|
||||
|
|
|
@ -532,6 +532,17 @@ bool UserData::readDatesPrivate() const {
|
|||
return (flags() & UserDataFlag::ReadDatesPrivate);
|
||||
}
|
||||
|
||||
int UserData::starsPerMessage() const {
|
||||
return _starsPerMessage;
|
||||
}
|
||||
|
||||
void UserData::setStarsPerMessage(int stars) {
|
||||
if (_starsPerMessage != stars) {
|
||||
_starsPerMessage = stars;
|
||||
session().changes().peerUpdated(this, UpdateFlag::StarsPerMessage);
|
||||
}
|
||||
}
|
||||
|
||||
bool UserData::canAddContact() const {
|
||||
return canShareThisContact() && !isContact();
|
||||
}
|
||||
|
@ -722,6 +733,8 @@ void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
|
|||
user->setTranslationDisabled(update.is_translations_disabled());
|
||||
user->setPrivateForwardName(
|
||||
update.vprivate_forward_name().value_or_empty());
|
||||
user->setStarsPerMessage(
|
||||
update.vsend_paid_messages_stars().value_or_empty());
|
||||
|
||||
if (const auto info = user->botInfo.get()) {
|
||||
const auto group = update.vbot_group_admin_rights()
|
||||
|
|
|
@ -179,6 +179,9 @@ public:
|
|||
[[nodiscard]] bool canSendIgnoreRequirePremium() const;
|
||||
[[nodiscard]] bool readDatesPrivate() const;
|
||||
|
||||
[[nodiscard]] int starsPerMessage() const;
|
||||
void setStarsPerMessage(int stars);
|
||||
|
||||
[[nodiscard]] bool canShareThisContact() const;
|
||||
[[nodiscard]] bool canAddContact() const;
|
||||
|
||||
|
@ -268,6 +271,7 @@ private:
|
|||
Data::Birthday _birthday;
|
||||
int _commonChatsCount = 0;
|
||||
int _peerGiftsCount = 0;
|
||||
int _starsPerMessage = 0;
|
||||
ContactStatus _contactStatus = ContactStatus::Unknown;
|
||||
CallsStatus _callsStatus = CallsStatus::Unknown;
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue