mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 06:35:14 +00:00
Support groups in privacy settings.
This commit is contained in:
@@ -16,12 +16,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "boxes/peer_list_controllers.h"
|
||||
#include "info/profile/info_profile_button.h"
|
||||
#include "settings/settings_common.h"
|
||||
#include "settings/settings_privacy_security.h"
|
||||
#include "calls/calls_instance.h"
|
||||
#include "base/binary_guard.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "apiwrap.h"
|
||||
#include "auth_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_chat.h"
|
||||
#include "data/data_channel.h"
|
||||
#include "styles/style_settings.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
||||
@@ -29,10 +32,10 @@ namespace {
|
||||
|
||||
class PrivacyExceptionsBoxController : public ChatsListBoxController {
|
||||
public:
|
||||
PrivacyExceptionsBoxController(Fn<QString()> titleFactory, const std::vector<not_null<UserData*>> &selected);
|
||||
PrivacyExceptionsBoxController(Fn<QString()> titleFactory, const std::vector<not_null<PeerData*>> &selected);
|
||||
void rowClicked(not_null<PeerListRow*> row) override;
|
||||
|
||||
std::vector<not_null<UserData*>> getResult() const;
|
||||
std::vector<not_null<PeerData*>> getResult() const;
|
||||
|
||||
protected:
|
||||
void prepareViewHook() override;
|
||||
@@ -40,11 +43,13 @@ protected:
|
||||
|
||||
private:
|
||||
Fn<QString()> _titleFactory;
|
||||
std::vector<not_null<UserData*>> _selected;
|
||||
std::vector<not_null<PeerData*>> _selected;
|
||||
|
||||
};
|
||||
|
||||
PrivacyExceptionsBoxController::PrivacyExceptionsBoxController(Fn<QString()> titleFactory, const std::vector<not_null<UserData*>> &selected)
|
||||
PrivacyExceptionsBoxController::PrivacyExceptionsBoxController(
|
||||
Fn<QString()> titleFactory,
|
||||
const std::vector<not_null<PeerData*>> &selected)
|
||||
: _titleFactory(std::move(titleFactory))
|
||||
, _selected(selected) {
|
||||
}
|
||||
@@ -54,32 +59,43 @@ void PrivacyExceptionsBoxController::prepareViewHook() {
|
||||
delegate()->peerListAddSelectedRows(_selected);
|
||||
}
|
||||
|
||||
std::vector<not_null<UserData*>> PrivacyExceptionsBoxController::getResult() const {
|
||||
auto peers = delegate()->peerListCollectSelectedRows();
|
||||
auto users = std::vector<not_null<UserData*>>();
|
||||
if (!peers.empty()) {
|
||||
users.reserve(peers.size());
|
||||
for_const (auto peer, peers) {
|
||||
auto user = peer->asUser();
|
||||
Assert(user != nullptr);
|
||||
users.push_back(user);
|
||||
}
|
||||
}
|
||||
return users;
|
||||
std::vector<not_null<PeerData*>> PrivacyExceptionsBoxController::getResult() const {
|
||||
return delegate()->peerListCollectSelectedRows();
|
||||
}
|
||||
|
||||
void PrivacyExceptionsBoxController::rowClicked(not_null<PeerListRow*> row) {
|
||||
delegate()->peerListSetRowChecked(row, !row->checked());
|
||||
if (const auto channel = row->peer()->asChannel()) {
|
||||
if (!channel->membersCountKnown()) {
|
||||
channel->updateFull();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
std::unique_ptr<PrivacyExceptionsBoxController::Row> PrivacyExceptionsBoxController::createRow(not_null<History*> history) {
|
||||
if (history->peer->isSelf()) {
|
||||
return nullptr;
|
||||
} else if (!history->peer->isUser()
|
||||
&& !history->peer->isChat()
|
||||
&& !history->peer->isMegagroup()) {
|
||||
return nullptr;
|
||||
}
|
||||
if (auto user = history->peer->asUser()) {
|
||||
return std::make_unique<Row>(history);
|
||||
auto result = std::make_unique<Row>(history);
|
||||
const auto count = [&] {
|
||||
if (const auto chat = history->peer->asChat()) {
|
||||
return chat->count;
|
||||
} else if (const auto channel = history->peer->asChannel()) {
|
||||
return channel->membersCountKnown()
|
||||
? channel->membersCount()
|
||||
: 0;
|
||||
}
|
||||
return 0;
|
||||
}();
|
||||
if (count > 0) {
|
||||
result->setCustomStatus(
|
||||
lng_chat_status_members(lt_count_decimal, count));
|
||||
}
|
||||
return nullptr;
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
@@ -107,29 +123,30 @@ void EditPrivacyBox::prepare() {
|
||||
setupContent();
|
||||
}
|
||||
|
||||
void EditPrivacyBox::editExceptionUsers(
|
||||
void EditPrivacyBox::editExceptions(
|
||||
Exception exception,
|
||||
Fn<void()> done) {
|
||||
auto controller = std::make_unique<PrivacyExceptionsBoxController>(
|
||||
crl::guard(this, [=] {
|
||||
return _controller->exceptionBoxTitle(exception);
|
||||
}),
|
||||
exceptionUsers(exception));
|
||||
exceptions(exception));
|
||||
auto initBox = [=, controller = controller.get()](
|
||||
not_null<PeerListBox*> box) {
|
||||
box->addButton(langFactory(lng_settings_save), crl::guard(this, [=] {
|
||||
exceptionUsers(exception) = controller->getResult();
|
||||
const auto removeFrom = ([=] {
|
||||
exceptions(exception) = controller->getResult();
|
||||
const auto type = [&] {
|
||||
switch (exception) {
|
||||
case Exception::Always: return Exception::Never;
|
||||
case Exception::Never: return Exception::Always;
|
||||
}
|
||||
Unexpected("Invalid exception value.");
|
||||
})();
|
||||
auto &removeFromUsers = exceptionUsers(removeFrom);
|
||||
for (const auto user : exceptionUsers(exception)) {
|
||||
const auto from = ranges::remove(removeFromUsers, user);
|
||||
removeFromUsers.erase(from, end(removeFromUsers));
|
||||
}();
|
||||
auto &removeFrom = exceptions(type);
|
||||
for (const auto peer : exceptions(exception)) {
|
||||
removeFrom.erase(
|
||||
ranges::remove(removeFrom, peer),
|
||||
end(removeFrom));
|
||||
}
|
||||
done();
|
||||
box->closeBox();
|
||||
@@ -142,19 +159,23 @@ void EditPrivacyBox::editExceptionUsers(
|
||||
}
|
||||
|
||||
QVector<MTPInputPrivacyRule> EditPrivacyBox::collectResult() {
|
||||
const auto collectInputUsers = [](const auto &users) {
|
||||
const auto collectInputUsers = [](const auto &peers) {
|
||||
auto result = QVector<MTPInputUser>();
|
||||
result.reserve(users.size());
|
||||
for (const auto user : users) {
|
||||
result.push_back(user->inputUser);
|
||||
result.reserve(peers.size());
|
||||
for (const auto peer : peers) {
|
||||
if (const auto user = peer->asUser()) {
|
||||
result.push_back(user->inputUser);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
const auto collectInputChats = [](const auto & chats) {
|
||||
const auto collectInputChats = [](const auto &peers) {
|
||||
auto result = QVector<MTPint>();
|
||||
result.reserve(chats.size());
|
||||
for (const auto peer : chats) {
|
||||
result.push_back(MTP_int(peer->bareId()));
|
||||
result.reserve(peers.size());
|
||||
for (const auto peer : peers) {
|
||||
if (!peer->isUser()) {
|
||||
result.push_back(MTP_int(peer->bareId()));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
@@ -163,19 +184,23 @@ QVector<MTPInputPrivacyRule> EditPrivacyBox::collectResult() {
|
||||
auto result = QVector<MTPInputPrivacyRule>();
|
||||
result.reserve(kMaxRules);
|
||||
if (showExceptionLink(Exception::Always)) {
|
||||
if (!_value.alwaysUsers.empty()) {
|
||||
result.push_back(MTP_inputPrivacyValueAllowUsers(MTP_vector<MTPInputUser>(collectInputUsers(_value.alwaysUsers))));
|
||||
const auto users = collectInputUsers(_value.always);
|
||||
const auto chats = collectInputChats(_value.always);
|
||||
if (!users.empty()) {
|
||||
result.push_back(MTP_inputPrivacyValueAllowUsers(MTP_vector<MTPInputUser>(users)));
|
||||
}
|
||||
if (!_value.alwaysChats.empty()) {
|
||||
result.push_back(MTP_inputPrivacyValueAllowChatParticipants(MTP_vector<MTPint>(collectInputChats(_value.alwaysChats))));
|
||||
if (!chats.empty()) {
|
||||
result.push_back(MTP_inputPrivacyValueAllowChatParticipants(MTP_vector<MTPint>(chats)));
|
||||
}
|
||||
}
|
||||
if (showExceptionLink(Exception::Never)) {
|
||||
if (!_value.neverUsers.empty()) {
|
||||
result.push_back(MTP_inputPrivacyValueDisallowUsers(MTP_vector<MTPInputUser>(collectInputUsers(_value.neverUsers))));
|
||||
const auto users = collectInputUsers(_value.never);
|
||||
const auto chats = collectInputChats(_value.never);
|
||||
if (!users.empty()) {
|
||||
result.push_back(MTP_inputPrivacyValueDisallowUsers(MTP_vector<MTPInputUser>(users)));
|
||||
}
|
||||
if (!_value.neverChats.empty()) {
|
||||
result.push_back(MTP_inputPrivacyValueDisallowChatParticipants(MTP_vector<MTPint>(collectInputChats(_value.neverChats))));
|
||||
if (!chats.empty()) {
|
||||
result.push_back(MTP_inputPrivacyValueDisallowChatParticipants(MTP_vector<MTPint>(chats)));
|
||||
}
|
||||
}
|
||||
result.push_back([&] {
|
||||
@@ -190,11 +215,10 @@ QVector<MTPInputPrivacyRule> EditPrivacyBox::collectResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
// #TODO privacy
|
||||
std::vector<not_null<UserData*>> &EditPrivacyBox::exceptionUsers(Exception exception) {
|
||||
std::vector<not_null<PeerData*>> &EditPrivacyBox::exceptions(Exception exception) {
|
||||
switch (exception) {
|
||||
case Exception::Always: return _value.alwaysUsers;
|
||||
case Exception::Never: return _value.neverUsers;
|
||||
case Exception::Always: return _value.always;
|
||||
case Exception::Never: return _value.never;
|
||||
}
|
||||
Unexpected("Invalid exception value.");
|
||||
}
|
||||
@@ -275,7 +299,7 @@ void EditPrivacyBox::setupContent() {
|
||||
auto label = update->events_starting_with(
|
||||
rpl::empty_value()
|
||||
) | rpl::map([=] {
|
||||
return exceptionUsers(exception).size();
|
||||
return Settings::ExceptionUsersCount(exceptions(exception));
|
||||
}) | rpl::map([](int count) {
|
||||
return count
|
||||
? lng_edit_privacy_exceptions_count(lt_count, count)
|
||||
@@ -299,7 +323,7 @@ void EditPrivacyBox::setupContent() {
|
||||
) | rpl::map([=] {
|
||||
return showExceptionLink(exception);
|
||||
}))->entity()->addClickHandler([=] {
|
||||
editExceptionUsers(exception, [=] { update->fire({}); });
|
||||
editExceptions(exception, [=] { update->fire({}); });
|
||||
});
|
||||
return button;
|
||||
};
|
||||
@@ -328,8 +352,7 @@ void EditPrivacyBox::setupContent() {
|
||||
|
||||
addButton(langFactory(lng_settings_save), [=] {
|
||||
const auto someAreDisallowed = (_value.option != Option::Everyone)
|
||||
|| !_value.neverUsers.empty()
|
||||
|| !_value.neverChats.empty();
|
||||
|| !_value.never.empty();
|
||||
_controller->confirmSave(someAreDisallowed, crl::guard(this, [=] {
|
||||
Auth().api().savePrivacy(
|
||||
_controller->apiKey(),
|
||||
|
Reference in New Issue
Block a user