Allow editing sensitive content filtering.

This commit is contained in:
John Preston 2019-12-09 15:59:08 +03:00
parent c301be3826
commit 431b7445c3
12 changed files with 265 additions and 52 deletions

View File

@ -101,8 +101,12 @@ PRIVATE
api/api_common.h
api/api_hash.h
api/api_self_destruct.cpp
api/api_self_destruct.h
api/api_sending.cpp
api/api_sending.h
api/api_sensitive_content.cpp
api/api_sensitive_content.h
api/api_single_message_search.cpp
api/api_single_message_search.h
api/api_text_entities.cpp

View File

@ -416,6 +416,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_settings_performance" = "Performance";
"lng_settings_enable_animations" = "Enable animations";
"lng_settings_autoplay_gifs" = "Autoplay GIFs";
"lng_settings_sensitive_title" = "Sensitive content";
"lng_settings_sensitive_disable_filtering" = "Disable filtering";
"lng_settings_sensitive_about" = "Display sensitive media in public channels on all your Telegram devices.";
"lng_settings_spellchecker" = "Spell checker";
"lng_settings_system_spellchecker" = "Use system spell checker";

View File

@ -1091,6 +1091,8 @@ auth.loginTokenSuccess#390d5c5e authorization:auth.Authorization = auth.LoginTok
auth.loginTokenInfo#5203303a dc_id:int auth_key_id:long device_model:string platform:string system_version:string api_id:int app_name:string app_version:string ip:string region:string = auth.LoginTokenInfo;
account.contentSettings#57e28221 flags:# sensitive_enabled:flags.0?true sensitive_can_change:flags.1?true = account.ContentSettings;
---functions---
invokeAfterMsg#cb9f372d {X:Type} msg_id:long query:!X = X;
@ -1183,6 +1185,8 @@ account.saveTheme#f257106c theme:InputTheme unsave:Bool = Bool;
account.installTheme#7ae43737 flags:# dark:flags.0?true format:flags.1?string theme:flags.1?InputTheme = Bool;
account.getTheme#8d9d742b format:string theme:InputTheme document_id:long = Theme;
account.getThemes#285946f8 format:string hash:int = account.Themes;
account.setContentSettings#b574b16b flags:# sensitive_enabled:flags.0?true = Bool;
account.getContentSettings#8b9b4dae = account.ContentSettings;
users.getUsers#d91a548 id:Vector<InputUser> = Vector<User>;
users.getFullUser#ca30a5b1 id:InputUser = UserFull;

View File

@ -0,0 +1,51 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_self_destruct.h"
#include "apiwrap.h"
namespace Api {
SelfDestruct::SelfDestruct(not_null<ApiWrap*> api)
: _api(api->instance()) {
}
void SelfDestruct::reload() {
if (_requestId) {
return;
}
_requestId = _api.request(MTPaccount_GetAccountTTL(
)).done([=](const MTPAccountDaysTTL &result) {
_requestId = 0;
result.match([&](const MTPDaccountDaysTTL &data) {
_days = data.vdays().v;
});
}).fail([=](const RPCError &error) {
_requestId = 0;
}).send();
}
rpl::producer<int> SelfDestruct::days() const {
using namespace rpl::mappers;
return _days.value() | rpl::filter(_1 != 0);
}
void SelfDestruct::update(int days) {
_api.request(_requestId).cancel();
_requestId = _api.request(MTPaccount_SetAccountTTL(
MTP_accountDaysTTL(MTP_int(days))
)).done([=](const MTPBool &result) {
_requestId = 0;
}).fail([=](const RPCError &result) {
_requestId = 0;
}).send();
_days = days;
}
} // namespace Api

View File

@ -0,0 +1,32 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "mtproto/sender.h"
class ApiWrap;
namespace Api {
class SelfDestruct final {
public:
explicit SelfDestruct(not_null<ApiWrap*> api);
void reload();
void update(int days);
rpl::producer<int> days() const;
private:
MTP::Sender _api;
mtpRequestId _requestId = 0;
rpl::variable<int> _days = 0;
};
} // namespace Api

View File

@ -0,0 +1,62 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "api/api_sensitive_content.h"
#include "apiwrap.h"
namespace Api {
SensitiveContent::SensitiveContent(not_null<ApiWrap*> api)
: _api(api->instance()) {
}
void SensitiveContent::reload() {
if (_requestId) {
return;
}
_requestId = _api.request(MTPaccount_GetContentSettings(
)).done([=](const MTPaccount_ContentSettings &result) {
_requestId = 0;
result.match([&](const MTPDaccount_contentSettings &data) {
_enabled = data.is_sensitive_enabled();
_canChange = data.is_sensitive_can_change();
});
}).fail([=](const RPCError &error) {
_requestId = 0;
}).send();
}
bool SensitiveContent::enabledCurrent() const {
return _enabled.current();
}
rpl::producer<bool> SensitiveContent::enabled() const {
return _enabled.value();
}
rpl::producer<bool> SensitiveContent::canChange() const {
return _canChange.value();
}
void SensitiveContent::update(bool enabled) {
if (!_canChange.current()) {
return;
}
using Flag = MTPaccount_SetContentSettings::Flag;
_api.request(_requestId).cancel();
_requestId = _api.request(MTPaccount_SetContentSettings(
MTP_flags(enabled ? Flag::f_sensitive_enabled : Flag(0))
)).done([=](const MTPBool &result) {
_requestId = 0;
}).fail([=](const RPCError &error) {
_requestId = 0;
}).send();
_enabled = enabled;
}
} // namespace Api

View File

@ -0,0 +1,35 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "mtproto/sender.h"
class ApiWrap;
namespace Api {
class SensitiveContent final {
public:
explicit SensitiveContent(not_null<ApiWrap*> api);
void reload();
void update(bool enabled);
[[nodiscard]] bool enabledCurrent() const;
[[nodiscard]] rpl::producer<bool> enabled() const;
[[nodiscard]] rpl::producer<bool> canChange() const;
private:
MTP::Sender _api;
mtpRequestId _requestId = 0;
rpl::variable<bool> _enabled = false;
rpl::variable<bool> _canChange = false;
};
} // namespace Api

View File

@ -8,6 +8,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "apiwrap.h"
#include "api/api_text_entities.h"
#include "api/api_self_destruct.h"
#include "api/api_sensitive_content.h"
#include "data/data_drafts.h"
#include "data/data_photo.h"
#include "data/data_web_page.h"
@ -233,7 +235,9 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
, _fileLoader(std::make_unique<TaskQueue>(kFileLoaderQueueStopTimeout))
//, _feedReadTimer([=] { readFeeds(); }) // #feed
, _proxyPromotionTimer([=] { refreshProxyPromotion(); })
, _updateNotifySettingsTimer([=] { sendNotifySettingsUpdates(); }) {
, _updateNotifySettingsTimer([=] { sendNotifySettingsUpdates(); })
, _selfDestruct(std::make_unique<Api::SelfDestruct>(this))
, _sensitiveContent(std::make_unique<Api::SensitiveContent>(this)) {
crl::on_main([=] {
// You can't use _session->lifetime() in the constructor,
// only queued, because it is not constructed yet.
@ -246,6 +250,8 @@ ApiWrap::ApiWrap(not_null<Main::Session*> session)
});
}
ApiWrap::~ApiWrap() = default;
Main::Session &ApiWrap::session() const {
return *_session;
}
@ -5800,42 +5806,12 @@ auto ApiWrap::blockedUsersSlice() -> rpl::producer<BlockedUsersSlice> {
: (_blockedUsersChanges.events() | rpl::type_erased());
}
void ApiWrap::reloadSelfDestruct() {
if (_selfDestructRequestId) {
return;
}
_selfDestructRequestId = request(MTPaccount_GetAccountTTL(
)).done([=](const MTPAccountDaysTTL &result) {
_selfDestructRequestId = 0;
result.match([&](const MTPDaccountDaysTTL &data) {
setSelfDestructDays(data.vdays().v);
});
}).fail([=](const RPCError &error) {
_selfDestructRequestId = 0;
}).send();
Api::SelfDestruct &ApiWrap::selfDestruct() {
return *_selfDestruct;
}
rpl::producer<int> ApiWrap::selfDestructValue() const {
return _selfDestructDays
? _selfDestructChanges.events_starting_with_copy(*_selfDestructDays)
: (_selfDestructChanges.events() | rpl::type_erased());
}
void ApiWrap::saveSelfDestruct(int days) {
request(_selfDestructRequestId).cancel();
_selfDestructRequestId = request(MTPaccount_SetAccountTTL(
MTP_accountDaysTTL(MTP_int(days))
)).done([=](const MTPBool &result) {
_selfDestructRequestId = 0;
}).fail([=](const RPCError &result) {
_selfDestructRequestId = 0;
}).send();
setSelfDestructDays(days);
}
void ApiWrap::setSelfDestructDays(int days) {
_selfDestructDays = days;
_selfDestructChanges.fire_copy(days);
Api::SensitiveContent &ApiWrap::sensitiveContent() {
return *_sensitiveContent;
}
void ApiWrap::createPoll(
@ -6107,5 +6083,3 @@ void ApiWrap::sendReadRequest(not_null<PeerData*> peer, MsgId upTo) {
}();
_readRequests.emplace(peer, requestId, upTo);
}
ApiWrap::~ApiWrap() = default;

View File

@ -83,6 +83,9 @@ QString RequestKey(Types &&...values) {
return result;
}
class SelfDestruct;
class SensitiveContent;
} // namespace Api
class ApiWrap : public MTP::Sender, private base::Subscriber {
@ -131,6 +134,7 @@ public:
};
explicit ApiWrap(not_null<Main::Session*> session);
~ApiWrap();
Main::Session &session() const;
@ -465,9 +469,8 @@ public:
void reloadBlockedUsers();
rpl::producer<BlockedUsersSlice> blockedUsersSlice();
void reloadSelfDestruct();
rpl::producer<int> selfDestructValue() const;
void saveSelfDestruct(int days);
[[nodiscard]] Api::SelfDestruct &selfDestruct();
[[nodiscard]] Api::SensitiveContent &sensitiveContent();
void createPoll(
const PollData &data,
@ -480,8 +483,6 @@ public:
void closePoll(not_null<HistoryItem*> item);
void reloadPollResults(not_null<HistoryItem*> item);
~ApiWrap();
private:
struct MessageDataRequest {
using Callbacks = QList<RequestMessageDataCallback>;
@ -679,8 +680,6 @@ private:
const QVector<MTPPrivacyRule> &rules);
void updatePrivacyLastSeens(const QVector<MTPPrivacyRule> &rules);
void setSelfDestructDays(int days);
void migrateDone(
not_null<PeerData*> peer,
not_null<ChannelData*> channel);
@ -874,9 +873,8 @@ private:
std::optional<BlockedUsersSlice> _blockedUsersSlice;
rpl::event_stream<BlockedUsersSlice> _blockedUsersChanges;
mtpRequestId _selfDestructRequestId = 0;
std::optional<int> _selfDestructDays;
rpl::event_stream<int> _selfDestructChanges;
const std::unique_ptr<Api::SelfDestruct> _selfDestruct;
const std::unique_ptr<Api::SensitiveContent> _sensitiveContent;
base::flat_map<FullMsgId, mtpRequestId> _pollVotesRequestIds;
base::flat_map<FullMsgId, mtpRequestId> _pollCloseRequestIds;

View File

@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/widgets/checkbox.h"
#include "ui/widgets/labels.h"
#include "apiwrap.h"
#include "api/api_self_destruct.h"
#include "main/main_session.h"
#include "styles/style_layers.h"
#include "styles/style_boxes.h"
@ -76,7 +77,7 @@ void SelfDestructionBox::showContent() {
clearButtons();
addButton(tr::lng_settings_save(), [=] {
_session->api().saveSelfDestruct(_ttlGroup->value());
_session->api().selfDestruct().update(_ttlGroup->value());
closeBox();
});
addButton(tr::lng_cancel(), [=] { closeBox(); });

View File

@ -7,6 +7,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "settings/settings_privacy_security.h"
#include "api/api_self_destruct.h"
#include "api/api_sensitive_content.h"
#include "settings/settings_common.h"
#include "settings/settings_privacy_controllers.h"
#include "boxes/peer_list_box.h"
@ -428,20 +430,56 @@ void SetupCloudPassword(
session->api().reloadPasswordState();
AddSkip(container);
AddDivider(container);
}
void SetupSensitiveContent(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container) {
using namespace rpl::mappers;
const auto wrap = container->add(
object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
container,
object_ptr<Ui::VerticalLayout>(container)));
const auto inner = wrap->entity();
AddSkip(inner);
AddSubsectionTitle(inner, tr::lng_settings_sensitive_title());
const auto session = &controller->session();
session->api().sensitiveContent().reload();
AddButton(
inner,
tr::lng_settings_sensitive_disable_filtering(),
st::settingsButton
)->toggleOn(
session->api().sensitiveContent().enabled()
)->toggledChanges(
) | rpl::filter([=](bool toggled) {
return toggled != session->api().sensitiveContent().enabledCurrent();
}) | rpl::start_with_next([=](bool toggled) {
session->api().sensitiveContent().update(toggled);
}, container->lifetime());
AddSkip(inner);
AddDividerText(inner, tr::lng_settings_sensitive_about());
wrap->toggleOn(session->api().sensitiveContent().canChange());
}
void SetupSelfDestruction(
not_null<Window::SessionController*> controller,
not_null<Ui::VerticalLayout*> container) {
AddDivider(container);
AddSkip(container);
AddSubsectionTitle(container, tr::lng_settings_destroy_title());
const auto session = &controller->session();
session->api().reloadSelfDestruct();
session->api().selfDestruct().reload();
const auto label = [&] {
return session->api().selfDestructValue(
return session->api().selfDestruct().days(
) | rpl::map(
SelfDestructionBox::DaysLabel
);
@ -455,7 +493,7 @@ void SetupSelfDestruction(
)->addClickHandler([=] {
Ui::show(Box<SelfDestructionBox>(
session,
session->api().selfDestructValue()));
session->api().selfDestruct().days()));
});
AddSkip(container);
@ -609,6 +647,11 @@ void PrivacySecurity::setupContent(
SetupSessionsList(controller, content);
SetupLocalPasscode(controller, content);
SetupCloudPassword(controller, content);
#if !defined OS_MAC_STORE && !defined OS_WIN_STORE
SetupSensitiveContent(controller, content);
#else // !OS_MAC_STORE && !OS_WIN_STORE
AddDivider(content);
#endif // !OS_MAC_STORE && !OS_WIN_STORE
SetupSelfDestruction(controller, content);
Ui::ResizeFitChild(this, content);

View File

@ -17,6 +17,12 @@ set(scheme_files
generate_scheme(lib_scheme ${src_loc}/codegen/scheme/codegen_scheme.py "${scheme_files}")
nice_target_sources(lib_scheme ${res_loc}
PRIVATE
tl/mtproto.tl
tl/api.tl
)
target_include_directories(lib_scheme
PUBLIC
${src_loc}