2017-06-07 12:59:45 +00:00
|
|
|
/*
|
|
|
|
This file is part of Telegram Desktop,
|
|
|
|
the official desktop version of Telegram messaging app, see https://telegram.org
|
|
|
|
|
|
|
|
Telegram Desktop is free software: you can redistribute it and/or modify
|
|
|
|
it under the terms of the GNU General Public License as published by
|
|
|
|
the Free Software Foundation, either version 3 of the License, or
|
|
|
|
(at your option) any later version.
|
|
|
|
|
|
|
|
It is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
GNU General Public License for more details.
|
|
|
|
|
|
|
|
In addition, as a special exception, the copyright holders give permission
|
|
|
|
to link the code of portions of this program with the OpenSSL library.
|
|
|
|
|
|
|
|
Full license: https://github.com/telegramdesktop/tdesktop/blob/master/LICENSE
|
|
|
|
Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
|
|
|
*/
|
|
|
|
#include "boxes/edit_participant_box.h"
|
|
|
|
|
|
|
|
#include "lang/lang_keys.h"
|
|
|
|
#include "ui/widgets/checkbox.h"
|
|
|
|
#include "ui/widgets/labels.h"
|
2017-06-09 16:12:02 +00:00
|
|
|
#include "ui/widgets/buttons.h"
|
2017-06-07 12:59:45 +00:00
|
|
|
#include "styles/style_boxes.h"
|
2017-07-10 12:43:30 +00:00
|
|
|
#include "ui/special_buttons.h"
|
2017-06-09 16:12:02 +00:00
|
|
|
#include "boxes/calendar_box.h"
|
2017-06-07 12:59:45 +00:00
|
|
|
|
2017-06-09 16:12:02 +00:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
constexpr auto kMaxRestrictDelayDays = 366;
|
2017-07-10 10:43:25 +00:00
|
|
|
constexpr auto kSecondsInDay = 24 * 60 * 60;
|
|
|
|
constexpr auto kSecondsInWeek = 7 * kSecondsInDay;
|
2017-06-09 16:12:02 +00:00
|
|
|
|
|
|
|
template <typename CheckboxesMap, typename DependenciesMap>
|
|
|
|
void ApplyDependencies(CheckboxesMap &checkboxes, DependenciesMap &dependencies, QPointer<Ui::Checkbox> changed) {
|
|
|
|
auto checkAndApply = [&checkboxes](auto &¤t, auto dependency, bool isChecked) {
|
|
|
|
for (auto &&checkbox : checkboxes) {
|
|
|
|
if ((checkbox.first & dependency) && (checkbox.second->checked() == isChecked)) {
|
|
|
|
current->setChecked(isChecked);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
};
|
|
|
|
auto applySomeDependency = [&checkboxes, &dependencies, &changed, checkAndApply] {
|
|
|
|
auto result = false;
|
|
|
|
for (auto &&entry : checkboxes) {
|
|
|
|
if (entry.second == changed) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
auto isChecked = entry.second->checked();
|
|
|
|
for (auto &&dependency : dependencies) {
|
|
|
|
if (entry.first & (isChecked ? dependency.first : dependency.second)) {
|
|
|
|
if (checkAndApply(entry.second, (isChecked ? dependency.second : dependency.first), !isChecked)) {
|
|
|
|
result = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
};
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
if (!applySomeDependency()) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
2017-06-07 12:59:45 +00:00
|
|
|
}
|
|
|
|
|
2017-06-09 16:12:02 +00:00
|
|
|
} // namespace
|
|
|
|
|
2017-07-10 10:43:25 +00:00
|
|
|
class EditParticipantBox::Inner : public TWidget {
|
|
|
|
public:
|
2017-08-17 08:31:24 +00:00
|
|
|
Inner(QWidget *parent, not_null<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights);
|
2017-07-10 10:43:25 +00:00
|
|
|
|
2017-06-09 16:12:02 +00:00
|
|
|
template <typename Widget>
|
2017-07-10 10:43:25 +00:00
|
|
|
QPointer<Widget> addControl(object_ptr<Widget> widget, QMargins margin) {
|
|
|
|
doAddControl(std::move(widget), margin);
|
|
|
|
return static_cast<Widget*>(_rows.back().widget.data());
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|
|
|
|
|
2017-07-10 10:43:25 +00:00
|
|
|
void removeControl(QPointer<TWidget> widget);
|
|
|
|
|
2017-06-09 16:12:02 +00:00
|
|
|
protected:
|
|
|
|
int resizeGetHeight(int newWidth) override;
|
|
|
|
void paintEvent(QPaintEvent *e) override;
|
|
|
|
|
|
|
|
private:
|
2017-07-10 10:43:25 +00:00
|
|
|
void doAddControl(object_ptr<TWidget> widget, QMargins margin);
|
|
|
|
|
2017-08-17 08:31:24 +00:00
|
|
|
not_null<ChannelData*> _channel;
|
|
|
|
not_null<UserData*> _user;
|
2017-07-10 12:43:30 +00:00
|
|
|
object_ptr<Ui::PeerAvatarButton> _userPhoto;
|
2017-07-10 10:43:25 +00:00
|
|
|
Text _userName;
|
2017-06-17 19:51:23 +00:00
|
|
|
bool _hasAdminRights = false;
|
2017-07-10 10:43:25 +00:00
|
|
|
struct Control {
|
|
|
|
object_ptr<TWidget> widget;
|
|
|
|
QMargins margin;
|
|
|
|
};
|
|
|
|
std::vector<Control> _rows;
|
2017-06-09 16:12:02 +00:00
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-08-17 08:31:24 +00:00
|
|
|
EditParticipantBox::Inner::Inner(QWidget *parent, not_null<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights) : TWidget(parent)
|
2017-07-10 10:43:25 +00:00
|
|
|
, _channel(channel)
|
|
|
|
, _user(user)
|
2017-07-10 12:43:30 +00:00
|
|
|
, _userPhoto(this, _user, st::rightsPhotoButton)
|
2017-07-10 10:43:25 +00:00
|
|
|
, _hasAdminRights(hasAdminRights) {
|
|
|
|
_userName.setText(st::rightsNameStyle, App::peerName(_user), _textNameOptions);
|
2017-07-10 12:43:30 +00:00
|
|
|
_userPhoto->setClickedCallback([this] { Ui::showPeerProfile(_user); });
|
2017-06-07 12:59:45 +00:00
|
|
|
}
|
|
|
|
|
2017-07-10 10:43:25 +00:00
|
|
|
void EditParticipantBox::Inner::removeControl(QPointer<TWidget> widget) {
|
|
|
|
auto row = std::find_if(_rows.begin(), _rows.end(), [widget](auto &&row) {
|
|
|
|
return (row.widget == widget);
|
|
|
|
});
|
2017-08-17 09:06:26 +00:00
|
|
|
Assert(row != _rows.end());
|
2017-07-10 10:43:25 +00:00
|
|
|
row->widget.destroy();
|
|
|
|
_rows.erase(row);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditParticipantBox::Inner::doAddControl(object_ptr<TWidget> widget, QMargins margin) {
|
|
|
|
widget->setParent(this);
|
|
|
|
_rows.push_back({ std::move(widget), margin });
|
|
|
|
_rows.back().widget->show();
|
|
|
|
}
|
|
|
|
|
|
|
|
int EditParticipantBox::Inner::resizeGetHeight(int newWidth) {
|
2017-07-10 12:43:30 +00:00
|
|
|
_userPhoto->moveToLeft(st::rightsPhotoMargin.left(), st::rightsPhotoMargin.top());
|
|
|
|
auto newHeight = st::rightsPhotoMargin.top() + st::rightsPhotoButton.size + st::rightsPhotoMargin.bottom();
|
2017-06-07 12:59:45 +00:00
|
|
|
for (auto &&row : _rows) {
|
2017-07-10 10:43:25 +00:00
|
|
|
auto rowWidth = newWidth - row.margin.left() - row.margin.right();
|
|
|
|
newHeight += row.margin.top();
|
|
|
|
row.widget->resizeToNaturalWidth(rowWidth);
|
|
|
|
row.widget->moveToLeft(row.margin.left(), newHeight);
|
|
|
|
newHeight += row.widget->heightNoMargins() + row.margin.bottom();
|
2017-06-07 12:59:45 +00:00
|
|
|
}
|
2017-07-10 10:43:25 +00:00
|
|
|
return newHeight;
|
2017-06-07 12:59:45 +00:00
|
|
|
}
|
|
|
|
|
2017-06-09 16:12:02 +00:00
|
|
|
void EditParticipantBox::Inner::paintEvent(QPaintEvent *e) {
|
2017-06-07 12:59:45 +00:00
|
|
|
Painter p(this);
|
|
|
|
|
|
|
|
p.fillRect(e->rect(), st::boxBg);
|
2017-06-09 16:12:02 +00:00
|
|
|
|
|
|
|
p.setPen(st::contactsNameFg);
|
2017-07-10 12:43:30 +00:00
|
|
|
auto namex = st::rightsPhotoMargin.left() + st::rightsPhotoButton.size + st::rightsPhotoMargin.right();
|
2017-07-10 10:43:25 +00:00
|
|
|
auto namew = width() - namex - st::rightsPhotoMargin.right();
|
|
|
|
_userName.drawLeftElided(p, namex, st::rightsPhotoMargin.top() + st::rightsNameTop, namew, width());
|
2017-06-09 16:12:02 +00:00
|
|
|
auto statusText = [this] {
|
|
|
|
if (_user->botInfo) {
|
2017-06-17 19:51:23 +00:00
|
|
|
auto seesAllMessages = (_user->botInfo->readsAllHistory || _hasAdminRights);
|
2017-06-09 16:12:02 +00:00
|
|
|
return lang(seesAllMessages ? lng_status_bot_reads_all : lng_status_bot_not_reads_all);
|
|
|
|
}
|
|
|
|
return App::onlineText(_user->onlineTill, unixtime());
|
|
|
|
};
|
|
|
|
p.setFont(st::contactsStatusFont);
|
|
|
|
p.setPen(st::contactsStatusFg);
|
2017-07-10 10:43:25 +00:00
|
|
|
p.drawTextLeft(namex, st::rightsPhotoMargin.top() + st::rightsStatusTop, width(), statusText());
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|
|
|
|
|
2017-08-17 08:31:24 +00:00
|
|
|
EditParticipantBox::EditParticipantBox(QWidget*, not_null<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights) : BoxContent()
|
2017-06-09 16:12:02 +00:00
|
|
|
, _channel(channel)
|
2017-06-17 19:51:23 +00:00
|
|
|
, _user(user)
|
|
|
|
, _hasAdminRights(hasAdminRights) {
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditParticipantBox::prepare() {
|
2017-06-17 19:51:23 +00:00
|
|
|
_inner = setInnerWidget(object_ptr<Inner>(this, _channel, _user, hasAdminRights()));
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <typename Widget>
|
2017-07-10 10:43:25 +00:00
|
|
|
QPointer<Widget> EditParticipantBox::addControl(object_ptr<Widget> widget, QMargins margin) {
|
2017-06-09 16:12:02 +00:00
|
|
|
Expects(_inner != nullptr);
|
2017-07-10 10:43:25 +00:00
|
|
|
return _inner->addControl(std::move(widget), margin);
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditParticipantBox::removeControl(QPointer<TWidget> widget) {
|
|
|
|
Expects(_inner != nullptr);
|
|
|
|
return _inner->removeControl(widget);
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditParticipantBox::resizeToContent() {
|
|
|
|
_inner->resizeToWidth(st::boxWideWidth);
|
2017-07-10 10:43:25 +00:00
|
|
|
setDimensions(_inner->width(), qMin(_inner->height(), st::boxMaxListHeight));
|
2017-06-07 12:59:45 +00:00
|
|
|
}
|
|
|
|
|
2017-08-17 08:31:24 +00:00
|
|
|
EditAdminBox::EditAdminBox(QWidget*, not_null<ChannelData*> channel, not_null<UserData*> user, const MTPChannelAdminRights &rights) : EditParticipantBox(nullptr, channel, user, (rights.c_channelAdminRights().vflags.v != 0))
|
2017-07-10 12:29:55 +00:00
|
|
|
, _oldRights(rights) {
|
2017-06-09 16:12:02 +00:00
|
|
|
auto dependency = [this](Flag dependent, Flag dependency) {
|
|
|
|
_dependencies.push_back(std::make_pair(dependent, dependency));
|
|
|
|
};
|
|
|
|
dependency(Flag::f_invite_link, Flag::f_invite_users); // invite_link <-> invite_users
|
|
|
|
dependency(Flag::f_invite_users, Flag::f_invite_link);
|
|
|
|
}
|
|
|
|
|
2017-08-17 08:31:24 +00:00
|
|
|
MTPChannelAdminRights EditAdminBox::DefaultRights(not_null<ChannelData*> channel) {
|
2017-06-09 16:12:02 +00:00
|
|
|
auto defaultRights = channel->isMegagroup()
|
|
|
|
? (Flag::f_change_info | Flag::f_delete_messages | Flag::f_ban_users | Flag::f_invite_users | Flag::f_invite_link | Flag::f_pin_messages)
|
2017-07-05 21:11:49 +00:00
|
|
|
: (Flag::f_change_info | Flag::f_post_messages | Flag::f_edit_messages | Flag::f_delete_messages | Flag::f_invite_users | Flag::f_invite_link);
|
2017-06-09 16:12:02 +00:00
|
|
|
return MTP_channelAdminRights(MTP_flags(defaultRights));
|
2017-06-07 12:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditAdminBox::prepare() {
|
2017-06-09 16:12:02 +00:00
|
|
|
EditParticipantBox::prepare();
|
|
|
|
|
2017-07-19 08:18:20 +00:00
|
|
|
auto hadRights = _oldRights.c_channelAdminRights().vflags.v;
|
|
|
|
setTitle(langFactory(hadRights ? lng_rights_edit_admin : lng_channel_add_admin));
|
2017-06-07 12:59:45 +00:00
|
|
|
|
2017-08-05 20:01:20 +00:00
|
|
|
addControl(object_ptr<BoxContentDivider>(this), QMargins());
|
2017-07-10 10:43:25 +00:00
|
|
|
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_edit_admin_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
|
2017-06-07 12:59:45 +00:00
|
|
|
|
2017-07-19 08:18:20 +00:00
|
|
|
auto prepareRights = (hadRights ? _oldRights : DefaultRights(channel()));
|
2017-07-05 21:11:49 +00:00
|
|
|
auto addCheckbox = [this, &prepareRights](Flags flags, const QString &text) {
|
|
|
|
auto checked = (prepareRights.c_channelAdminRights().vflags.v & flags) != 0;
|
2017-07-10 10:43:25 +00:00
|
|
|
auto control = addControl(object_ptr<Ui::Checkbox>(this, text, checked, st::rightsCheckbox, st::rightsToggle), st::rightsToggleMargin);
|
2017-07-07 11:16:37 +00:00
|
|
|
subscribe(control->checkedChanged, [this, control](bool checked) {
|
|
|
|
InvokeQueued(this, [this, control] { applyDependencies(control); });
|
|
|
|
});
|
2017-07-09 15:06:27 +00:00
|
|
|
if (!channel()->amCreator()) {
|
|
|
|
if (!(channel()->adminRights().vflags.v & flags)) {
|
|
|
|
control->setDisabled(true); // Grey out options that we don't have ourselves.
|
|
|
|
}
|
|
|
|
}
|
2017-07-10 12:29:55 +00:00
|
|
|
if (!canSave()) {
|
|
|
|
control->setDisabled(true);
|
|
|
|
}
|
2017-06-14 10:58:54 +00:00
|
|
|
_checkboxes.emplace(flags, control);
|
2017-06-07 12:59:45 +00:00
|
|
|
};
|
|
|
|
if (channel()->isMegagroup()) {
|
|
|
|
addCheckbox(Flag::f_change_info, lang(lng_rights_group_info));
|
2017-06-09 16:12:02 +00:00
|
|
|
addCheckbox(Flag::f_delete_messages, lang(lng_rights_group_delete));
|
2017-06-07 12:59:45 +00:00
|
|
|
addCheckbox(Flag::f_ban_users, lang(lng_rights_group_ban));
|
2017-06-14 10:58:54 +00:00
|
|
|
addCheckbox(Flag::f_invite_users | Flag::f_invite_link, lang(channel()->anyoneCanAddMembers() ? lng_rights_group_invite_link : lng_rights_group_invite));
|
2017-06-07 12:59:45 +00:00
|
|
|
addCheckbox(Flag::f_pin_messages, lang(lng_rights_group_pin));
|
|
|
|
addCheckbox(Flag::f_add_admins, lang(lng_rights_add_admins));
|
|
|
|
} else {
|
|
|
|
addCheckbox(Flag::f_change_info, lang(lng_rights_channel_info));
|
|
|
|
addCheckbox(Flag::f_post_messages, lang(lng_rights_channel_post));
|
|
|
|
addCheckbox(Flag::f_edit_messages, lang(lng_rights_channel_edit));
|
2017-06-09 16:12:02 +00:00
|
|
|
addCheckbox(Flag::f_delete_messages, lang(lng_rights_channel_delete));
|
2017-06-28 07:07:49 +00:00
|
|
|
addCheckbox(Flag::f_invite_users | Flag::f_invite_link, lang(lng_rights_group_invite));
|
2017-06-07 12:59:45 +00:00
|
|
|
addCheckbox(Flag::f_add_admins, lang(lng_rights_add_admins));
|
|
|
|
}
|
|
|
|
|
|
|
|
auto addAdmins = _checkboxes.find(Flag::f_add_admins);
|
2017-07-02 19:23:41 +00:00
|
|
|
if (addAdmins != _checkboxes.end()) {
|
2017-07-10 10:43:25 +00:00
|
|
|
_aboutAddAdmins = addControl(object_ptr<Ui::FlatLabel>(this, st::boxLabel), st::rightsAboutMargin);
|
2017-08-17 09:06:26 +00:00
|
|
|
Assert(addAdmins != _checkboxes.end());
|
2017-07-07 11:16:37 +00:00
|
|
|
subscribe(addAdmins->second->checkedChanged, [this](bool checked) {
|
2017-07-02 19:23:41 +00:00
|
|
|
refreshAboutAddAdminsText();
|
|
|
|
});
|
2017-06-07 12:59:45 +00:00
|
|
|
refreshAboutAddAdminsText();
|
2017-07-02 19:23:41 +00:00
|
|
|
}
|
2017-06-07 12:59:45 +00:00
|
|
|
|
2017-07-10 12:29:55 +00:00
|
|
|
if (canSave()) {
|
|
|
|
addButton(langFactory(lng_settings_save), [this] {
|
|
|
|
if (!_saveCallback) {
|
|
|
|
return;
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|
2017-07-10 12:29:55 +00:00
|
|
|
auto newFlags = MTPDchannelAdminRights::Flags(0);
|
|
|
|
for (auto &&checkbox : _checkboxes) {
|
|
|
|
if (checkbox.second->checked()) {
|
|
|
|
newFlags |= checkbox.first;
|
|
|
|
} else {
|
|
|
|
newFlags &= ~checkbox.first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!channel()->amCreator()) {
|
|
|
|
// Leave only rights that we have so we could save them.
|
|
|
|
newFlags &= channel()->adminRights().vflags.v;
|
|
|
|
}
|
|
|
|
_saveCallback(_oldRights, MTP_channelAdminRights(MTP_flags(newFlags)));
|
|
|
|
});
|
|
|
|
addButton(langFactory(lng_cancel), [this] { closeBox(); });
|
|
|
|
} else {
|
|
|
|
addButton(langFactory(lng_box_ok), [this] { closeBox(); });
|
|
|
|
}
|
2017-06-09 16:12:02 +00:00
|
|
|
|
|
|
|
applyDependencies(nullptr);
|
|
|
|
for (auto &&checkbox : _checkboxes) {
|
|
|
|
checkbox.second->finishAnimations();
|
|
|
|
}
|
|
|
|
|
2017-06-07 12:59:45 +00:00
|
|
|
resizeToContent();
|
|
|
|
}
|
|
|
|
|
2017-06-09 16:12:02 +00:00
|
|
|
void EditAdminBox::applyDependencies(QPointer<Ui::Checkbox> changed) {
|
|
|
|
ApplyDependencies(_checkboxes, _dependencies, changed);
|
|
|
|
}
|
|
|
|
|
2017-06-07 12:59:45 +00:00
|
|
|
void EditAdminBox::refreshAboutAddAdminsText() {
|
|
|
|
auto addAdmins = _checkboxes.find(Flag::f_add_admins);
|
2017-08-17 09:06:26 +00:00
|
|
|
Assert(addAdmins != _checkboxes.end());
|
2017-07-10 12:29:55 +00:00
|
|
|
auto text = [this, addAdmins] {
|
|
|
|
if (!canSave()) {
|
|
|
|
return lang(lng_rights_about_admin_cant_edit);
|
|
|
|
} else if (addAdmins->second->checked()) {
|
|
|
|
return lang(lng_rights_about_add_admins_yes);
|
|
|
|
}
|
|
|
|
return lang(lng_rights_about_add_admins_no);
|
|
|
|
};
|
|
|
|
_aboutAddAdmins->setText(text());
|
2017-06-07 12:59:45 +00:00
|
|
|
resizeToContent();
|
|
|
|
}
|
|
|
|
|
2017-08-17 08:31:24 +00:00
|
|
|
EditRestrictedBox::EditRestrictedBox(QWidget*, not_null<ChannelData*> channel, not_null<UserData*> user, bool hasAdminRights, const MTPChannelBannedRights &rights) : EditParticipantBox(nullptr, channel, user, hasAdminRights)
|
2017-07-10 12:29:55 +00:00
|
|
|
, _oldRights(rights) {
|
2017-06-09 16:12:02 +00:00
|
|
|
auto dependency = [this](Flag dependent, Flag dependency) {
|
|
|
|
_dependencies.push_back(std::make_pair(dependent, dependency));
|
|
|
|
};
|
|
|
|
dependency(Flag::f_send_gifs, Flag::f_send_stickers); // stickers <-> gifs
|
|
|
|
dependency(Flag::f_send_stickers, Flag::f_send_gifs);
|
|
|
|
dependency(Flag::f_send_games, Flag::f_send_stickers); // stickers <-> games
|
|
|
|
dependency(Flag::f_send_stickers, Flag::f_send_games);
|
|
|
|
dependency(Flag::f_send_inline, Flag::f_send_stickers); // stickers <-> inline
|
|
|
|
dependency(Flag::f_send_stickers, Flag::f_send_inline);
|
|
|
|
dependency(Flag::f_send_stickers, Flag::f_send_media); // stickers -> send_media
|
|
|
|
dependency(Flag::f_embed_links, Flag::f_send_media); // embed_links -> send_media
|
|
|
|
dependency(Flag::f_send_media, Flag::f_send_messages); // send_media- > send_messages
|
|
|
|
dependency(Flag::f_send_messages, Flag::f_view_messages); // send_messages -> view_messages
|
2017-06-07 12:59:45 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void EditRestrictedBox::prepare() {
|
2017-06-09 16:12:02 +00:00
|
|
|
EditParticipantBox::prepare();
|
|
|
|
|
2017-06-07 12:59:45 +00:00
|
|
|
setTitle(langFactory(lng_rights_user_restrictions));
|
|
|
|
|
2017-08-05 20:01:20 +00:00
|
|
|
addControl(object_ptr<BoxContentDivider>(this), QMargins());
|
2017-07-10 10:43:25 +00:00
|
|
|
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_user_restrictions_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
|
2017-06-07 12:59:45 +00:00
|
|
|
|
2017-07-05 21:11:49 +00:00
|
|
|
auto prepareRights = (_oldRights.c_channelBannedRights().vflags.v ? _oldRights : DefaultRights(channel()));
|
|
|
|
_until = prepareRights.c_channelBannedRights().vuntil_date.v;
|
|
|
|
|
|
|
|
auto addCheckbox = [this, &prepareRights](Flags flags, const QString &text) {
|
|
|
|
auto checked = (prepareRights.c_channelBannedRights().vflags.v & flags) == 0;
|
2017-07-10 10:43:25 +00:00
|
|
|
auto control = addControl(object_ptr<Ui::Checkbox>(this, text, checked, st::rightsCheckbox, st::rightsToggle), st::rightsToggleMargin);
|
2017-07-07 11:16:37 +00:00
|
|
|
subscribe(control->checkedChanged, [this, control](bool checked) {
|
|
|
|
InvokeQueued(this, [this, control] { applyDependencies(control); });
|
|
|
|
});
|
2017-07-10 12:29:55 +00:00
|
|
|
if (!canSave()) {
|
|
|
|
control->setDisabled(true);
|
|
|
|
}
|
2017-06-09 16:12:02 +00:00
|
|
|
_checkboxes.emplace(flags, control);
|
2017-06-07 12:59:45 +00:00
|
|
|
};
|
|
|
|
addCheckbox(Flag::f_view_messages, lang(lng_rights_chat_read));
|
|
|
|
addCheckbox(Flag::f_send_messages, lang(lng_rights_chat_send_text));
|
|
|
|
addCheckbox(Flag::f_send_media, lang(lng_rights_chat_send_media));
|
2017-06-09 16:12:02 +00:00
|
|
|
addCheckbox(Flag::f_send_stickers | Flag::f_send_gifs | Flag::f_send_games | Flag::f_send_inline, lang(lng_rights_chat_send_stickers));
|
2017-06-07 12:59:45 +00:00
|
|
|
addCheckbox(Flag::f_embed_links, lang(lng_rights_chat_send_links));
|
2017-06-09 16:12:02 +00:00
|
|
|
|
2017-08-05 20:01:20 +00:00
|
|
|
addControl(object_ptr<BoxContentDivider>(this), st::rightsUntilMargin);
|
2017-07-10 10:43:25 +00:00
|
|
|
addControl(object_ptr<Ui::FlatLabel>(this, lang(lng_rights_chat_banned_until_header), Ui::FlatLabel::InitType::Simple, st::rightsHeaderLabel), st::rightsHeaderMargin);
|
2017-06-09 16:12:02 +00:00
|
|
|
setRestrictUntil(_until);
|
|
|
|
|
|
|
|
//addControl(object_ptr<Ui::LinkButton>(this, lang(lng_rights_chat_banned_block), st::boxLinkButton));
|
|
|
|
|
2017-07-10 12:29:55 +00:00
|
|
|
if (canSave()) {
|
|
|
|
addButton(langFactory(lng_settings_save), [this] {
|
|
|
|
if (!_saveCallback) {
|
|
|
|
return;
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|
2017-07-10 12:29:55 +00:00
|
|
|
auto newFlags = MTPDchannelBannedRights::Flags(0);
|
|
|
|
for (auto &&checkbox : _checkboxes) {
|
|
|
|
if (checkbox.second->checked()) {
|
|
|
|
newFlags &= ~checkbox.first;
|
|
|
|
} else {
|
|
|
|
newFlags |= checkbox.first;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_saveCallback(_oldRights, MTP_channelBannedRights(MTP_flags(newFlags), MTP_int(getRealUntilValue())));
|
|
|
|
});
|
|
|
|
addButton(langFactory(lng_cancel), [this] { closeBox(); });
|
|
|
|
} else {
|
|
|
|
addButton(langFactory(lng_box_ok), [this] { closeBox(); });
|
|
|
|
}
|
2017-06-09 16:12:02 +00:00
|
|
|
|
|
|
|
applyDependencies(nullptr);
|
|
|
|
for (auto &&checkbox : _checkboxes) {
|
|
|
|
checkbox.second->finishAnimations();
|
|
|
|
}
|
|
|
|
|
2017-06-07 12:59:45 +00:00
|
|
|
resizeToContent();
|
|
|
|
}
|
2017-06-09 16:12:02 +00:00
|
|
|
|
|
|
|
void EditRestrictedBox::applyDependencies(QPointer<Ui::Checkbox> changed) {
|
|
|
|
ApplyDependencies(_checkboxes, _dependencies, changed);
|
|
|
|
}
|
|
|
|
|
2017-08-17 08:31:24 +00:00
|
|
|
MTPChannelBannedRights EditRestrictedBox::DefaultRights(not_null<ChannelData*> channel) {
|
2017-06-09 16:12:02 +00:00
|
|
|
auto defaultRights = Flag::f_send_messages | Flag::f_send_media | Flag::f_embed_links | Flag::f_send_stickers | Flag::f_send_gifs | Flag::f_send_games | Flag::f_send_inline;
|
|
|
|
return MTP_channelBannedRights(MTP_flags(defaultRights), MTP_int(0));
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditRestrictedBox::showRestrictUntil() {
|
|
|
|
auto tomorrow = QDate::currentDate().addDays(1);
|
2017-07-10 10:43:25 +00:00
|
|
|
auto highlighted = isUntilForever() ? tomorrow : date(getRealUntilValue()).date();
|
2017-06-09 16:12:02 +00:00
|
|
|
auto month = highlighted;
|
|
|
|
_restrictUntilBox = Ui::show(Box<CalendarBox>(month, highlighted, [this](const QDate &date) { setRestrictUntil(static_cast<int>(QDateTime(date).toTime_t())); }), KeepOtherLayers);
|
|
|
|
_restrictUntilBox->setMaxDate(QDate::currentDate().addDays(kMaxRestrictDelayDays));
|
|
|
|
_restrictUntilBox->setMinDate(tomorrow);
|
|
|
|
_restrictUntilBox->addLeftButton(langFactory(lng_rights_chat_banned_forever), [this] { setRestrictUntil(0); });
|
|
|
|
}
|
|
|
|
|
2017-07-10 10:43:25 +00:00
|
|
|
void EditRestrictedBox::setRestrictUntil(TimeId until) {
|
2017-06-09 16:12:02 +00:00
|
|
|
_until = until;
|
|
|
|
if (_restrictUntilBox) {
|
|
|
|
_restrictUntilBox->closeBox();
|
|
|
|
}
|
2017-07-10 10:43:25 +00:00
|
|
|
clearVariants();
|
|
|
|
createUntilGroup();
|
|
|
|
createUntilVariants();
|
|
|
|
resizeToContent();
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditRestrictedBox::clearVariants() {
|
|
|
|
for (auto &&widget : base::take(_untilVariants)) {
|
|
|
|
removeControl(widget.data());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditRestrictedBox::createUntilGroup() {
|
|
|
|
_untilGroup = std::make_shared<Ui::RadiobuttonGroup>(isUntilForever() ? 0 : _until);
|
|
|
|
_untilGroup->setChangedCallback([this](int value) {
|
|
|
|
if (value == kUntilCustom) {
|
|
|
|
_untilGroup->setValue(_until);
|
|
|
|
showRestrictUntil();
|
|
|
|
} else if (_until != value) {
|
|
|
|
_until = value;
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
void EditRestrictedBox::createUntilVariants() {
|
|
|
|
auto addVariant = [this](int value, const QString &text) {
|
2017-07-10 12:29:55 +00:00
|
|
|
if (!canSave() && _untilGroup->value() != value) {
|
|
|
|
return;
|
|
|
|
}
|
2017-07-10 10:43:25 +00:00
|
|
|
_untilVariants.push_back(addControl(object_ptr<Ui::Radiobutton>(this, _untilGroup, value, text, st::defaultBoxCheckbox), st::rightsToggleMargin));
|
2017-07-10 12:29:55 +00:00
|
|
|
if (!canSave()) {
|
|
|
|
_untilVariants.back()->setDisabled(true);
|
|
|
|
}
|
2017-07-10 10:43:25 +00:00
|
|
|
};
|
|
|
|
auto addCustomVariant = [this, addVariant](TimeId until, TimeId from, TimeId to) {
|
|
|
|
if (!ChannelData::IsRestrictedForever(until) && until > from && until <= to) {
|
|
|
|
addVariant(until, lng_rights_chat_banned_custom_date(lt_date, langDayOfMonthFull(date(until).date())));
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|
|
|
|
};
|
2017-07-10 10:43:25 +00:00
|
|
|
auto addCurrentVariant = [this, addCustomVariant](TimeId from, TimeId to) {
|
|
|
|
auto oldUntil = _oldRights.c_channelBannedRights().vuntil_date.v;
|
|
|
|
if (oldUntil < _until) {
|
|
|
|
addCustomVariant(oldUntil, from, to);
|
|
|
|
}
|
|
|
|
addCustomVariant(_until, from, to);
|
|
|
|
if (oldUntil > _until) {
|
|
|
|
addCustomVariant(oldUntil, from, to);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
addVariant(0, lang(lng_rights_chat_banned_forever));
|
|
|
|
|
|
|
|
auto now = unixtime();
|
|
|
|
auto nextDay = now + kSecondsInDay;
|
|
|
|
auto nextWeek = now + kSecondsInWeek;
|
|
|
|
addCurrentVariant(0, nextDay);
|
|
|
|
addVariant(kUntilOneDay, lng_rights_chat_banned_day(lt_count, 1));
|
|
|
|
addCurrentVariant(nextDay, nextWeek);
|
|
|
|
addVariant(kUntilOneWeek, lng_rights_chat_banned_week(lt_count, 1));
|
|
|
|
addCurrentVariant(nextWeek, INT_MAX);
|
|
|
|
addVariant(kUntilCustom, lang(lng_rights_chat_banned_custom));
|
|
|
|
}
|
|
|
|
|
|
|
|
TimeId EditRestrictedBox::getRealUntilValue() const {
|
|
|
|
Expects(_until != kUntilCustom);
|
|
|
|
if (_until == kUntilOneDay) {
|
|
|
|
return unixtime() + kSecondsInDay;
|
|
|
|
} else if (_until == kUntilOneWeek) {
|
|
|
|
return unixtime() + kSecondsInWeek;
|
|
|
|
}
|
2017-08-17 09:06:26 +00:00
|
|
|
Assert(_until >= 0);
|
2017-07-10 10:43:25 +00:00
|
|
|
return _until;
|
2017-06-09 16:12:02 +00:00
|
|
|
}
|