Apply ignore_restriction_reasons from config.

This commit is contained in:
John Preston 2019-12-09 16:57:33 +03:00
parent 431b7445c3
commit 41e13e39bc
13 changed files with 127 additions and 43 deletions

View File

@ -8,11 +8,21 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "api/api_sensitive_content.h"
#include "apiwrap.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
namespace Api {
namespace {
constexpr auto kRefreshAppConfigTimeout = 3 * crl::time(1000);
} // namespace
SensitiveContent::SensitiveContent(not_null<ApiWrap*> api)
: _api(api->instance()) {
: _session(&api->session())
, _api(api->instance())
, _appConfigReloadTimer([=] { _session->account().appConfig().refresh(); }) {
}
void SensitiveContent::reload() {
@ -57,6 +67,8 @@ void SensitiveContent::update(bool enabled) {
_requestId = 0;
}).send();
_enabled = enabled;
_appConfigReloadTimer.callOnce(kRefreshAppConfigTimeout);
}
} // namespace Api

View File

@ -8,9 +8,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once
#include "mtproto/sender.h"
#include "base/timer.h"
class ApiWrap;
namespace Main {
class Session;
} // namespace Main
namespace Api {
class SensitiveContent final {
@ -25,10 +30,12 @@ public:
[[nodiscard]] rpl::producer<bool> canChange() const;
private:
const not_null<Main::Session*> _session;
MTP::Sender _api;
mtpRequestId _requestId = 0;
rpl::variable<bool> _enabled = false;
rpl::variable<bool> _canChange = false;
base::Timer _appConfigReloadTimer;
};

View File

@ -339,13 +339,14 @@ bool ChannelData::isGroupAdmin(not_null<UserData*> user) const {
return false;
}
QString ChannelData::unavailableReason() const {
return _unavailableReason;
auto ChannelData::unavailableReasons() const
-> const std::vector<Data::UnavailableReason> & {
return _unavailableReasons;
}
void ChannelData::setUnavailableReason(const QString &text) {
if (_unavailableReason != text) {
_unavailableReason = text;
void ChannelData::setUnavailableReasons(std::vector<Data::UnavailableReason> &&reasons) {
if (_unavailableReasons != reasons) {
_unavailableReasons = std::move(reasons);
Notify::peerUpdatedDelayed(
this,
Notify::PeerUpdate::Flag::UnavailableReasonChanged);

View File

@ -368,8 +368,8 @@ public:
return _ptsWaiter.waitingForShortPoll();
}
[[nodiscard]] QString unavailableReason() const override;
void setUnavailableReason(const QString &reason);
void setUnavailableReasons(
std::vector<Data::UnavailableReason> &&reason);
[[nodiscard]] MsgId availableMinId() const {
return _availableMinId;
@ -412,6 +412,8 @@ public:
TimeId inviteDate = 0;
private:
auto unavailableReasons() const
-> const std::vector<Data::UnavailableReason> & override;
bool canEditLastAdmin(not_null<UserData*> user) const;
Flags _flags = Flags(MTPDchannel_ClientFlag::f_forbidden | 0);
@ -431,7 +433,7 @@ private:
RestrictionFlags _restrictions;
TimeId _restrictedUntil;
QString _unavailableReason;
std::vector<Data::UnavailableReason> _unavailableReasons;
QString _inviteLink;
ChannelData *_linkedChat = nullptr;

View File

@ -21,6 +21,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "boxes/confirm_box.h"
#include "main/main_session.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
#include "core/application.h"
#include "mainwindow.h"
#include "window/window_session_controller.h"
@ -376,6 +378,27 @@ void PeerData::setUserpicChecked(
}
}
auto PeerData::unavailableReasons() const
-> const std::vector<Data::UnavailableReason> & {
static const auto result = std::vector<Data::UnavailableReason>();
return result;
}
QString PeerData::computeUnavailableReason() const {
const auto &list = unavailableReasons();
const auto &config = session().account().appConfig();
const auto skip = config.get<std::vector<QString>>(
"ignore_restriction_reasons",
std::vector<QString>());
auto &&filtered = ranges::view::all(
list
) | ranges::view::filter([&](const Data::UnavailableReason &reason) {
return ranges::find(skip, reason.reason) == end(skip);
});
const auto first = filtered.begin();
return (first != filtered.end()) ? first->text : QString();
}
bool PeerData::canPinMessages() const {
if (const auto user = asUser()) {
return user->fullFlags() & MTPDuserFull::Flag::f_can_pin_message;

View File

@ -84,6 +84,18 @@ private:
};
struct UnavailableReason {
QString reason;
QString text;
bool operator==(const UnavailableReason &other) const {
return (reason == other.reason) && (text == other.text);
}
bool operator!=(const UnavailableReason &other) const {
return !(*this == other);
}
};
} // namespace Data
class PeerClickHandler : public ClickHandler {
@ -271,9 +283,7 @@ public:
// If this string is not empty we must not allow to open the
// conversation and we must show this string instead.
[[nodiscard]] virtual QString unavailableReason() const {
return QString();
}
[[nodiscard]] QString computeUnavailableReason() const;
[[nodiscard]] ClickHandlerPtr createOpenLink();
[[nodiscard]] const ClickHandlerPtr &openLink() {
@ -346,6 +356,8 @@ private:
void fillNames();
std::unique_ptr<Ui::EmptyUserpic> createEmptyUserpic() const;
void refreshEmptyUserpic() const;
[[nodiscard]] virtual auto unavailableReasons() const
-> const std::vector<Data::UnavailableReason> &;
void setUserpicChecked(
PhotoId photoId,

View File

@ -101,30 +101,26 @@ void CheckForSwitchInlineButton(not_null<HistoryItem*> item) {
// We should get a full restriction in "{full}: {reason}" format and we
// need to find an "-all" tag in {full}, otherwise ignore this restriction.
QString ExtractUnavailableReason(
std::vector<UnavailableReason> ExtractUnavailableReasons(
const QVector<MTPRestrictionReason> &restrictions) {
auto &&texts = ranges::view::all(
return ranges::view::all(
restrictions
) | ranges::view::transform([](const MTPRestrictionReason &restriction) {
) | ranges::view::filter([](const MTPRestrictionReason &restriction) {
return restriction.match([&](const MTPDrestrictionReason &data) {
const auto platform = qs(data.vplatform());
return (false
return false
#ifdef OS_MAC_STORE
|| (platform == qstr("ios"))
#elif defined OS_WIN_STORE // OS_MAC_STORE
|| (platform == qstr("ms"))
#endif // OS_MAC_STORE || OS_WIN_STORE
|| (platform == qstr("all")))
? std::make_optional(qs(data.vtext()))
: std::nullopt;
|| (platform == qstr("all"));
});
}) | ranges::view::filter([](const std::optional<QString> &value) {
return value.has_value();
}) | ranges::view::transform([](const std::optional<QString> &value) {
return *value;
});
const auto begin = texts.begin();
return (begin != texts.end()) ? *begin : nullptr;
}) | ranges::view::transform([](const MTPRestrictionReason &restriction) {
return restriction.match([&](const MTPDrestrictionReason &data) {
return UnavailableReason{ qs(data.vreason()), qs(data.vtext()) };
});
}) | ranges::to_vector;
}
MTPPhotoSize FindDocumentInlineThumbnail(const MTPDdocument &data) {
@ -365,10 +361,10 @@ not_null<UserData*> Session::processUser(const MTPUser &data) {
result->inputUser = MTP_inputUser(data.vid(), MTP_long(result->accessHash()));
}
if (const auto restriction = data.vrestriction_reason()) {
result->setUnavailableReason(
ExtractUnavailableReason(restriction->v));
result->setUnavailableReasons(
ExtractUnavailableReasons(restriction->v));
} else {
result->setUnavailableReason(QString());
result->setUnavailableReasons({});
}
}
if (data.is_deleted()) {
@ -636,10 +632,10 @@ not_null<PeerData*> Session::processChat(const MTPChat &data) {
channel->setVersion(data.vversion().v);
}
if (const auto restriction = data.vrestriction_reason()) {
channel->setUnavailableReason(
ExtractUnavailableReason(restriction->v));
channel->setUnavailableReasons(
ExtractUnavailableReasons(restriction->v));
} else {
channel->setUnavailableReason(QString());
channel->setUnavailableReasons({});
}
channel->setFlags(data.vflags().v);
//if (const auto feedId = data.vfeed_id()) { // #feed

View File

@ -81,13 +81,15 @@ void UserData::setPhoto(const MTPUserProfilePhoto &photo) {
}
}
QString UserData::unavailableReason() const {
return _unavailableReason;
auto UserData::unavailableReasons() const
-> const std::vector<Data::UnavailableReason> & {
return _unavailableReasons;
}
void UserData::setUnavailableReason(const QString &text) {
if (_unavailableReason != text) {
_unavailableReason = text;
void UserData::setUnavailableReasons(
std::vector<Data::UnavailableReason> &&reasons) {
if (_unavailableReasons != reasons) {
_unavailableReasons = std::move(reasons);
Notify::peerUpdatedDelayed(
this,
Notify::PeerUpdate::Flag::UnavailableReasonChanged);

View File

@ -207,8 +207,8 @@ public:
std::unique_ptr<BotInfo> botInfo;
QString unavailableReason() const override;
void setUnavailableReason(const QString &reason);
void setUnavailableReasons(
std::vector<Data::UnavailableReason> &&reasons);
int commonChatsCount() const {
return _commonChatsCount;
@ -216,10 +216,13 @@ public:
void setCommonChatsCount(int count);
private:
auto unavailableReasons() const
-> const std::vector<Data::UnavailableReason> & override;
Flags _flags;
FullFlags _fullFlags;
QString _unavailableReason;
std::vector<Data::UnavailableReason> _unavailableReasons;
QString _phone;
ContactStatus _contactStatus = ContactStatus::Unknown;
BlockStatus _blockStatus = BlockStatus::Unknown;

View File

@ -562,7 +562,7 @@ HistoryWidget::HistoryWidget(
updateNotifyControls();
}
if (update.flags & UpdateFlag::UnavailableReasonChanged) {
const auto unavailable = _peer->unavailableReason();
const auto unavailable = _peer->computeUnavailableReason();
if (!unavailable.isEmpty()) {
controller->showBackFromStack();
Ui::show(Box<InformBox>(unavailable));

View File

@ -41,6 +41,7 @@ void AppConfig::refresh() {
_requestId = 0;
refreshDelayed();
if (result.type() == mtpc_jsonObject) {
_data.clear();
for (const auto &element : result.c_jsonObject().vvalue().v) {
element.match([&](const MTPDjsonObjectValue &data) {
_data.emplace_or_assign(qs(data.vkey()), data.vvalue());
@ -94,4 +95,23 @@ QString AppConfig::getString(
});
}
std::vector<QString> AppConfig::getStringArray(
const QString &key,
std::vector<QString> &&fallback) const {
return getValue(key, [&](const MTPJSONValue &value) {
return value.match([&](const MTPDjsonArray &data) {
auto result = std::vector<QString>();
for (const auto &entry : data.vvalue().v) {
if (entry.type() != mtpc_jsonString) {
return std::move(fallback);
}
result.push_back(qs(entry.c_jsonString().vvalue()));
}
return result;
}, [&](const auto &data) {
return std::move(fallback);
});
});
}
} // namespace Main

View File

@ -23,13 +23,16 @@ public:
return getDouble(key, fallback);
} else if constexpr (std::is_same_v<Type, QString>) {
return getString(key, fallback);
} else if constexpr (std::is_same_v<Type, std::vector<QString>>) {
return getStringArray(key, std::move(fallback));
}
}
[[nodiscard]] rpl::producer<> refreshed() const;
private:
void refresh();
private:
void refreshDelayed();
template <typename Extractor>
@ -43,6 +46,9 @@ private:
[[nodiscard]] QString getString(
const QString &key,
const QString &fallback) const;
[[nodiscard]] std::vector<QString> getStringArray(
const QString &key,
std::vector<QString> &&fallback) const;
const not_null<Account*> _account;
std::optional<MTP::Sender> _api;

View File

@ -1593,7 +1593,7 @@ void MainWidget::ui_showPeerHistory(
peerId = peer->id;
if (showAtMsgId > 0) showAtMsgId = -showAtMsgId;
}
const auto unavailable = peer->unavailableReason();
const auto unavailable = peer->computeUnavailableReason();
if (!unavailable.isEmpty()) {
if (params.activation != anim::activation::background) {
Ui::show(Box<InformBox>(unavailable));