Track chat business bot state.

This commit is contained in:
John Preston 2024-03-17 13:17:34 +04:00
parent caa4c5428a
commit 3d97ea6f96
8 changed files with 106 additions and 65 deletions

View file

@ -1943,7 +1943,7 @@ void Updates::feedUpdate(const MTPUpdate &update) {
const auto &d = update.c_updatePeerSettings(); const auto &d = update.c_updatePeerSettings();
const auto peerId = peerFromMTP(d.vpeer()); const auto peerId = peerFromMTP(d.vpeer());
if (const auto peer = session().data().peerLoaded(peerId)) { if (const auto peer = session().data().peerLoaded(peerId)) {
peer->setSettings(d.vsettings()); peer->setBarSettings(d.vsettings());
} }
} break; } break;

View file

@ -1229,7 +1229,7 @@ void ApiWrap::requestPeerSettings(not_null<PeerData*> peer) {
result.match([&](const MTPDmessages_peerSettings &data) { result.match([&](const MTPDmessages_peerSettings &data) {
_session->data().processUsers(data.vusers()); _session->data().processUsers(data.vusers());
_session->data().processChats(data.vchats()); _session->data().processChats(data.vchats());
peer->setSettings(data.vsettings()); peer->setBarSettings(data.vsettings());
_requestedPeerSettings.erase(peer); _requestedPeerSettings.erase(peer);
}); });
}).fail([=] { }).fail([=] {

View file

@ -61,11 +61,11 @@ void SendRequest(
user->nameOrPhone, user->nameOrPhone,
user->username()); user->username());
user->session().api().applyUpdates(result); user->session().api().applyUpdates(result);
if (const auto settings = user->settings()) { if (const auto settings = user->barSettings()) {
const auto flags = PeerSetting::AddContact const auto flags = PeerBarSetting::AddContact
| PeerSetting::BlockContact | PeerBarSetting::BlockContact
| PeerSetting::ReportSpam; | PeerBarSetting::ReportSpam;
user->setSettings(*settings & ~flags); user->setBarSettings(*settings & ~flags);
} }
if (box) { if (box) {
if (!wasContact) { if (!wasContact) {
@ -258,9 +258,9 @@ void Controller::setupWarning() {
} }
void Controller::setupSharePhoneNumber() { void Controller::setupSharePhoneNumber() {
const auto settings = _user->settings(); const auto settings = _user->barSettings();
if (!settings if (!settings
|| !((*settings) & PeerSetting::NeedContactsException)) { || !((*settings) & PeerBarSetting::NeedContactsException)) {
return; return;
} }
_sharePhone = _box->addRow( _sharePhone = _box->addRow(

View file

@ -634,13 +634,26 @@ void PeerData::saveTranslationDisabled(bool disabled) {
)).send(); )).send();
} }
void PeerData::setSettings(const MTPPeerSettings &data) { void PeerData::setBarSettings(const MTPPeerSettings &data) {
data.match([&](const MTPDpeerSettings &data) { data.match([&](const MTPDpeerSettings &data) {
_requestChatTitle = data.vrequest_chat_title().value_or_empty(); if (!data.vbusiness_bot_id() && !data.vrequest_chat_title()) {
_requestChatDate = data.vrequest_chat_date().value_or_empty(); _barDetails = nullptr;
} else if (!_barDetails) {
using Flag = PeerSetting; _barDetails = std::make_unique<PeerBarDetails>();
setSettings((data.is_add_contact() ? Flag::AddContact : Flag()) }
if (_barDetails) {
_barDetails->requestChatTitle
= qs(data.vrequest_chat_title().value_or_empty());
_barDetails->requestChatDate
= data.vrequest_chat_date().value_or_empty();
_barDetails->businessBot = data.vbusiness_bot_id()
? _owner->user(data.vbusiness_bot_id()->v).get()
: nullptr;
_barDetails->businessBotManageUrl
= qs(data.vbusiness_bot_manage_url().value_or_empty());
}
using Flag = PeerBarSetting;
setBarSettings((data.is_add_contact() ? Flag::AddContact : Flag())
| (data.is_autoarchived() ? Flag::AutoArchived : Flag()) | (data.is_autoarchived() ? Flag::AutoArchived : Flag())
| (data.is_block_contact() ? Flag::BlockContact : Flag()) | (data.is_block_contact() ? Flag::BlockContact : Flag())
//| (data.is_invite_members() ? Flag::InviteMembers : Flag()) //| (data.is_invite_members() ? Flag::InviteMembers : Flag())
@ -651,11 +664,33 @@ void PeerData::setSettings(const MTPPeerSettings &data) {
| (data.is_report_spam() ? Flag::ReportSpam : Flag()) | (data.is_report_spam() ? Flag::ReportSpam : Flag())
| (data.is_share_contact() ? Flag::ShareContact : Flag()) | (data.is_share_contact() ? Flag::ShareContact : Flag())
| (data.vrequest_chat_title() ? Flag::RequestChat : Flag()) | (data.vrequest_chat_title() ? Flag::RequestChat : Flag())
| (data.vbusiness_bot_id() ? Flag::HasBusinessBot : Flag())
| (data.is_request_chat_broadcast() | (data.is_request_chat_broadcast()
? Flag::RequestChatIsBroadcast ? Flag::RequestChatIsBroadcast
: Flag())
| (data.is_business_bot_paused()
? Flag::BusinessBotPaused
: Flag())
| (data.is_business_bot_can_reply()
? Flag::BusinessBotCanReply
: Flag())); : Flag()));
}); });
} }
QString PeerData::requestChatTitle() const {
return _barDetails ? _barDetails->requestChatTitle : QString();
}
TimeId PeerData::requestChatDate() const {
return _barDetails ? _barDetails->requestChatDate : 0;
}
UserData *PeerData::businessBot() const {
return _barDetails ? _barDetails->businessBot : nullptr;
}
QString PeerData::businessBotManageUrl() const {
return _barDetails ? _barDetails->businessBotManageUrl : QString();
}
bool PeerData::changeColorIndex( bool PeerData::changeColorIndex(
const tl::conditional<MTPint> &cloudColorIndex) { const tl::conditional<MTPint> &cloudColorIndex) {

View file

@ -139,7 +139,7 @@ private:
}; };
enum class PeerSetting { enum class PeerBarSetting {
ReportSpam = (1 << 0), ReportSpam = (1 << 0),
AddContact = (1 << 1), AddContact = (1 << 1),
BlockContact = (1 << 2), BlockContact = (1 << 2),
@ -148,10 +148,20 @@ enum class PeerSetting {
AutoArchived = (1 << 5), AutoArchived = (1 << 5),
RequestChat = (1 << 6), RequestChat = (1 << 6),
RequestChatIsBroadcast = (1 << 7), RequestChatIsBroadcast = (1 << 7),
Unknown = (1 << 8), HasBusinessBot = (1 << 8),
BusinessBotPaused = (1 << 9),
BusinessBotCanReply = (1 << 10),
Unknown = (1 << 11),
};
inline constexpr bool is_flag_type(PeerBarSetting) { return true; };
using PeerBarSettings = base::flags<PeerBarSetting>;
struct PeerBarDetails {
QString requestChatTitle;
TimeId requestChatDate;
UserData *businessBot = nullptr;
QString businessBotManageUrl;
}; };
inline constexpr bool is_flag_type(PeerSetting) { return true; };
using PeerSettings = base::flags<PeerSetting>;
class PeerData { class PeerData {
protected: protected:
@ -160,7 +170,7 @@ protected:
PeerData &operator=(const PeerData &other) = delete; PeerData &operator=(const PeerData &other) = delete;
public: public:
using Settings = Data::Flags<PeerSettings>; using BarSettings = Data::Flags<PeerBarSettings>;
virtual ~PeerData(); virtual ~PeerData();
@ -346,25 +356,23 @@ public:
void checkFolder(FolderId folderId); void checkFolder(FolderId folderId);
void setSettings(PeerSettings which) { void setBarSettings(PeerBarSettings which) {
_settings.set(which); _barSettings.set(which);
} }
[[nodiscard]] auto settings() const { [[nodiscard]] auto barSettings() const {
return (_settings.current() & PeerSetting::Unknown) return (_barSettings.current() & PeerBarSetting::Unknown)
? std::nullopt ? std::nullopt
: std::make_optional(_settings.current()); : std::make_optional(_barSettings.current());
} }
[[nodiscard]] auto settingsValue() const { [[nodiscard]] auto barSettingsValue() const {
return (_settings.current() & PeerSetting::Unknown) return (_barSettings.current() & PeerBarSetting::Unknown)
? _settings.changes() ? _barSettings.changes()
: (_settings.value() | rpl::type_erased()); : (_barSettings.value() | rpl::type_erased());
}
[[nodiscard]] QString requestChatTitle() const {
return _requestChatTitle;
}
[[nodiscard]] TimeId requestChatDate() const {
return _requestChatDate;
} }
[[nodiscard]] QString requestChatTitle() const;
[[nodiscard]] TimeId requestChatDate() const;
[[nodiscard]] UserData *businessBot() const;
[[nodiscard]] QString businessBotManageUrl() const;
enum class TranslationFlag : uchar { enum class TranslationFlag : uchar {
Unknown, Unknown,
@ -375,7 +383,7 @@ public:
[[nodiscard]] TranslationFlag translationFlag() const; [[nodiscard]] TranslationFlag translationFlag() const;
void saveTranslationDisabled(bool disabled); void saveTranslationDisabled(bool disabled);
void setSettings(const MTPPeerSettings &data); void setBarSettings(const MTPPeerSettings &data);
bool changeColorIndex(const tl::conditional<MTPint> &cloudColorIndex); bool changeColorIndex(const tl::conditional<MTPint> &cloudColorIndex);
bool changeBackgroundEmojiId( bool changeBackgroundEmojiId(
const tl::conditional<MTPlong> &cloudBackgroundEmoji); const tl::conditional<MTPlong> &cloudBackgroundEmoji);
@ -485,10 +493,8 @@ private:
TimeId _ttlPeriod = 0; TimeId _ttlPeriod = 0;
QString _requestChatTitle; BarSettings _barSettings = PeerBarSettings(PeerBarSetting::Unknown);
TimeId _requestChatDate = 0; std::unique_ptr<PeerBarDetails> _barDetails;
Settings _settings = PeerSettings(PeerSetting::Unknown);
BlockStatus _blockStatus = BlockStatus::Unknown; BlockStatus _blockStatus = BlockStatus::Unknown;
LoadedStatus _loadedStatus = LoadedStatus::Not; LoadedStatus _loadedStatus = LoadedStatus::Not;

View file

@ -512,7 +512,7 @@ void ApplyUserUpdate(not_null<UserData*> user, const MTPDuserFull &update) {
)); ));
} }
} }
user->setSettings(update.vsettings()); user->setBarSettings(update.vsettings());
user->owner().notifySettings().apply(user, update.vnotify_settings()); user->owner().notifySettings().apply(user, update.vnotify_settings());
user->setMessagesTTL(update.vttl_period().value_or_empty()); user->setMessagesTTL(update.vttl_period().value_or_empty());

View file

@ -49,7 +49,7 @@ namespace HistoryView {
namespace { namespace {
[[nodiscard]] bool BarCurrentlyHidden(not_null<PeerData*> peer) { [[nodiscard]] bool BarCurrentlyHidden(not_null<PeerData*> peer) {
const auto settings = peer->settings(); const auto settings = peer->barSettings();
if (!settings) { if (!settings) {
return false; return false;
} else if (!(*settings)) { } else if (!(*settings)) {
@ -59,10 +59,10 @@ namespace {
if (user->isBlocked()) { if (user->isBlocked()) {
return true; return true;
} else if (user->isContact() } else if (user->isContact()
&& !((*settings) & PeerSetting::ShareContact)) { && !((*settings) & PeerBarSetting::ShareContact)) {
return true; return true;
} }
} else if (!((*settings) & PeerSetting::ReportSpam)) { } else if (!((*settings) & PeerBarSetting::ReportSpam)) {
return true; return true;
} }
return false; return false;
@ -557,7 +557,7 @@ ContactStatus::ContactStatus(
auto ContactStatus::PeerState(not_null<PeerData*> peer) auto ContactStatus::PeerState(not_null<PeerData*> peer)
-> rpl::producer<State> { -> rpl::producer<State> {
using SettingsChange = PeerData::Settings::Change; using SettingsChange = PeerData::BarSettings::Change;
using Type = State::Type; using Type = State::Type;
if (const auto user = peer->asUser()) { if (const auto user = peer->asUser()) {
using FlagsChange = UserData::Flags::Change; using FlagsChange = UserData::Flags::Change;
@ -570,31 +570,31 @@ auto ContactStatus::PeerState(not_null<PeerData*> peer)
}); });
return rpl::combine( return rpl::combine(
std::move(changes), std::move(changes),
user->settingsValue() user->barSettingsValue()
) | rpl::map([=]( ) | rpl::map([=](
FlagsChange flags, FlagsChange flags,
SettingsChange settings) -> State { SettingsChange settings) -> State {
if (flags.value & Flag::Blocked) { if (flags.value & Flag::Blocked) {
return { Type::None }; return { Type::None };
} else if (user->isContact()) { } else if (user->isContact()) {
if (settings.value & PeerSetting::ShareContact) { if (settings.value & PeerBarSetting::ShareContact) {
return { Type::SharePhoneNumber }; return { Type::SharePhoneNumber };
} else { } else {
return { Type::None }; return { Type::None };
} }
} else if (settings.value & PeerSetting::RequestChat) { } else if (settings.value & PeerBarSetting::RequestChat) {
return { return {
.type = Type::RequestChatInfo, .type = Type::RequestChatInfo,
.requestChatName = peer->requestChatTitle(), .requestChatName = peer->requestChatTitle(),
.requestChatIsBroadcast = !!(settings.value .requestChatIsBroadcast = !!(settings.value
& PeerSetting::RequestChatIsBroadcast), & PeerBarSetting::RequestChatIsBroadcast),
.requestDate = peer->requestChatDate(), .requestDate = peer->requestChatDate(),
}; };
} else if (settings.value & PeerSetting::AutoArchived) { } else if (settings.value & PeerBarSetting::AutoArchived) {
return { Type::UnarchiveOrBlock }; return { Type::UnarchiveOrBlock };
} else if (settings.value & PeerSetting::BlockContact) { } else if (settings.value & PeerBarSetting::BlockContact) {
return { Type::AddOrBlock }; return { Type::AddOrBlock };
} else if (settings.value & PeerSetting::AddContact) { } else if (settings.value & PeerBarSetting::AddContact) {
return { Type::Add }; return { Type::Add };
} else { } else {
return { Type::None }; return { Type::None };
@ -602,12 +602,12 @@ auto ContactStatus::PeerState(not_null<PeerData*> peer)
}); });
} }
return peer->settingsValue( return peer->barSettingsValue(
) | rpl::map([=](SettingsChange settings) { ) | rpl::map([=](SettingsChange settings) {
using Type = State::Type; using Type = State::Type;
return (settings.value & PeerSetting::AutoArchived) return (settings.value & PeerBarSetting::AutoArchived)
? State{ Type::UnarchiveOrReport } ? State{ Type::UnarchiveOrReport }
: (settings.value & PeerSetting::ReportSpam) : (settings.value & PeerBarSetting::ReportSpam)
? State{ Type::ReportSpam } ? State{ Type::ReportSpam }
: State{ Type::None }; : State{ Type::None };
}); });
@ -685,7 +685,7 @@ void ContactStatus::setupShareHandler(not_null<UserData*> user) {
) | rpl::start_with_next([=] { ) | rpl::start_with_next([=] {
const auto show = _controller->uiShow(); const auto show = _controller->uiShow();
const auto share = [=](Fn<void()> &&close) { const auto share = [=](Fn<void()> &&close) {
user->setSettings(0); user->setBarSettings(0);
user->session().api().request(MTPcontacts_AcceptContact( user->session().api().request(MTPcontacts_AcceptContact(
user->inputUser user->inputUser
)).done([=](const MTPUpdates &result) { )).done([=](const MTPUpdates &result) {
@ -718,11 +718,11 @@ void ContactStatus::setupUnarchiveHandler(not_null<PeerData*> peer) {
using namespace Window; using namespace Window;
ToggleHistoryArchived(show, peer->owner().history(peer), false); ToggleHistoryArchived(show, peer->owner().history(peer), false);
peer->owner().notifySettings().resetToDefault(peer); peer->owner().notifySettings().resetToDefault(peer);
if (const auto settings = peer->settings()) { if (const auto settings = peer->barSettings()) {
const auto flags = PeerSetting::AutoArchived const auto flags = PeerBarSetting::AutoArchived
| PeerSetting::BlockContact | PeerBarSetting::BlockContact
| PeerSetting::ReportSpam; | PeerBarSetting::ReportSpam;
peer->setSettings(*settings & ~flags); peer->setBarSettings(*settings & ~flags);
} }
}, _bar.lifetime()); }, _bar.lifetime());
} }
@ -773,7 +773,7 @@ void ContactStatus::setupCloseHandler(not_null<PeerData*> peer) {
) | rpl::filter([=] { ) | rpl::filter([=] {
return !(*request); return !(*request);
}) | rpl::start_with_next([=] { }) | rpl::start_with_next([=] {
peer->setSettings(0); peer->setBarSettings(0);
*request = peer->session().api().request( *request = peer->session().api().request(
MTPmessages_HidePeerSettingsBar(peer->input) MTPmessages_HidePeerSettingsBar(peer->input)
).send(); ).send();
@ -807,7 +807,7 @@ void ContactStatus::setupRequestInfoHandler(not_null<PeerData*> peer) {
if (*request) { if (*request) {
return; return;
} }
peer->setSettings(0); peer->setBarSettings(0);
*request = peer->session().api().request( *request = peer->session().api().request(
MTPmessages_HidePeerSettingsBar(peer->input) MTPmessages_HidePeerSettingsBar(peer->input)
).send(); ).send();

View file

@ -1584,9 +1584,9 @@ void PeerMenuBlockUserBox(
not_null<PeerData*> peer, not_null<PeerData*> peer,
std::variant<v::null_t, bool> suggestReport, std::variant<v::null_t, bool> suggestReport,
std::variant<v::null_t, ClearChat, ClearReply> suggestClear) { std::variant<v::null_t, ClearChat, ClearReply> suggestClear) {
const auto settings = peer->settings().value_or(PeerSettings(0)); const auto settings = peer->barSettings().value_or(PeerBarSettings(0));
const auto reportNeeded = v::is_null(suggestReport) const auto reportNeeded = v::is_null(suggestReport)
? ((settings & PeerSetting::ReportSpam) != 0) ? ((settings & PeerBarSetting::ReportSpam) != 0)
: v::get<bool>(suggestReport); : v::get<bool>(suggestReport);
const auto user = peer->asUser(); const auto user = peer->asUser();