mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-30 15:30:20 +00:00
Improve unacessible permissions design.
This commit is contained in:
parent
6066265717
commit
6d706fd222
Telegram
BIN
Telegram/Resources/icons/info_rights_lock.png
Normal file
BIN
Telegram/Resources/icons/info_rights_lock.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 280 B |
BIN
Telegram/Resources/icons/info_rights_lock@2x.png
Normal file
BIN
Telegram/Resources/icons/info_rights_lock@2x.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 519 B |
BIN
Telegram/Resources/icons/info_rights_lock@3x.png
Normal file
BIN
Telegram/Resources/icons/info_rights_lock@3x.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 721 B |
@ -1489,7 +1489,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_rights_edit_admin_header" = "What can this admin do?";
|
||||
"lng_rights_about_add_admins_yes" = "This admin will be able to add new admins with the same (or more limited) permissions.";
|
||||
"lng_rights_about_add_admins_no" = "This admin will not be able to add new admins.";
|
||||
"lng_rights_about_admin_cant_edit" = "You cannot edit rights of this admin.";
|
||||
|
||||
"lng_rights_about_admin_cant_edit" = "You are not allowed to edit the rights of this admin.";
|
||||
"lng_rights_about_restriction_cant_edit" = "You cannot change the restrictions for this user.";
|
||||
"lng_rights_restriction_for_all" = "This option is disabled for all members in Group Permissions. You can either enable the permission for everyone or make this user an admin.";
|
||||
"lng_rights_permission_for_all" = "This option is enabled for all members in Group Permissions.";
|
||||
"lng_rights_permission_unavailable" = "This permission is not available in public groups.";
|
||||
"lng_rights_permission_cant_edit" = "You cannot edit this permission.";
|
||||
"lng_rights_user_restrictions" = "User restrictions";
|
||||
"lng_rights_user_restrictions_header" = "What can this member do?";
|
||||
"lng_rights_default_restrictions_header" = "What can members of this group do?";
|
||||
|
@ -692,6 +692,7 @@ rightsCheckbox: Checkbox(defaultBoxCheckbox) {
|
||||
rightsToggle: Toggle(defaultToggle) {
|
||||
toggledFg: windowBgActive;
|
||||
untoggledFg: attentionButtonFg;
|
||||
lockIcon: icon {{ "info_rights_lock", windowBgActive }};
|
||||
xsize: 8px;
|
||||
vsize: 5px;
|
||||
vshift: 1px;
|
||||
|
@ -221,12 +221,26 @@ void EditAdminBox::prepare() {
|
||||
| (prepareRights.c_chatAdminRights().vflags.v
|
||||
& (filterByMyRights ? channel->adminRights() : ~Flag(0)));
|
||||
|
||||
const auto disabledFlags = canSave()
|
||||
? (disabledByDefaults
|
||||
| ((!channel || channel->amCreator())
|
||||
? Flags(0)
|
||||
: ~channel->adminRights()))
|
||||
: ~Flags(0);
|
||||
const auto disabledMessages = [&] {
|
||||
auto result = std::map<Flags, QString>();
|
||||
if (!canSave()) {
|
||||
result.emplace(
|
||||
~Flags(0),
|
||||
lang(lng_rights_about_admin_cant_edit));
|
||||
} else {
|
||||
result.emplace(
|
||||
disabledByDefaults,
|
||||
lang(lng_rights_permission_for_all));
|
||||
if (const auto channel = peer()->asChannel()) {
|
||||
if (!channel->amCreator()) {
|
||||
result.emplace(
|
||||
~channel->adminRights(),
|
||||
lang(lng_rights_permission_cant_edit));
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}();
|
||||
|
||||
const auto anyoneCanAddMembers = chat
|
||||
? chat->anyoneCanAddMembers()
|
||||
@ -235,7 +249,7 @@ void EditAdminBox::prepare() {
|
||||
this,
|
||||
lng_rights_edit_admin_header,
|
||||
prepareFlags,
|
||||
disabledFlags,
|
||||
disabledMessages,
|
||||
peer()->isChat() || peer()->isMegagroup(),
|
||||
anyoneCanAddMembers);
|
||||
addControl(std::move(checkboxes), QMargins());
|
||||
@ -316,18 +330,29 @@ void EditRestrictedBox::prepare() {
|
||||
| ((channel && channel->isPublic())
|
||||
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||
: Flags(0));
|
||||
const auto disabledFlags = canSave()
|
||||
? (defaultRestrictions
|
||||
| ((channel && channel->isPublic())
|
||||
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||
: Flags(0)))
|
||||
: ~Flags(0);
|
||||
const auto disabledMessages = [&] {
|
||||
auto result = std::map<Flags, QString>();
|
||||
if (!canSave()) {
|
||||
result.emplace(
|
||||
~Flags(0),
|
||||
lang(lng_rights_about_restriction_cant_edit));
|
||||
} else {
|
||||
const auto disabled = defaultRestrictions
|
||||
| ((channel && channel->isPublic())
|
||||
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||
: Flags(0));
|
||||
result.emplace(
|
||||
disabled,
|
||||
lang(lng_rights_restriction_for_all));
|
||||
}
|
||||
return result;
|
||||
}();
|
||||
|
||||
auto [checkboxes, getRestrictions, changes] = CreateEditRestrictions(
|
||||
this,
|
||||
lng_rights_user_restrictions_header,
|
||||
prepareFlags,
|
||||
disabledFlags);
|
||||
disabledMessages);
|
||||
addControl(std::move(checkboxes), QMargins());
|
||||
|
||||
_until = prepareRights.c_chatBannedRights().vuntil_date.v;
|
||||
@ -424,7 +449,7 @@ void EditRestrictedBox::createUntilVariants() {
|
||||
if (!canSave() && _untilGroup->value() != value) {
|
||||
return;
|
||||
}
|
||||
_untilVariants.push_back(base::unique_qptr<Ui::Radiobutton>(
|
||||
_untilVariants.emplace_back(
|
||||
addControl(
|
||||
object_ptr<Ui::Radiobutton>(
|
||||
this,
|
||||
@ -432,7 +457,7 @@ void EditRestrictedBox::createUntilVariants() {
|
||||
value,
|
||||
text,
|
||||
st::defaultBoxCheckbox),
|
||||
st::rightsToggleMargin)));
|
||||
st::rightsToggleMargin));
|
||||
if (!canSave()) {
|
||||
_untilVariants.back()->setDisabled(true);
|
||||
}
|
||||
|
@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "ui/wrap/vertical_layout.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/widgets/checkbox.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "info/profile/info_profile_button.h"
|
||||
#include "info/profile/info_profile_icon.h"
|
||||
#include "info/profile/info_profile_values.h"
|
||||
@ -280,24 +281,26 @@ void EditPeerPermissionsBox::prepare() {
|
||||
}
|
||||
Unexpected("User in EditPeerPermissionsBox.");
|
||||
}();
|
||||
const auto disabledFlags = [&] {
|
||||
if (const auto chat = _peer->asChat()) {
|
||||
return Flags(0)
|
||||
| disabledByAdminRights;
|
||||
} else if (const auto channel = _peer->asChannel()) {
|
||||
return (channel->isPublic()
|
||||
? (Flag::f_change_info | Flag::f_pin_messages)
|
||||
: Flags(0))
|
||||
| disabledByAdminRights;
|
||||
const auto disabledMessages = [&] {
|
||||
auto result = std::map<Flags, QString>();
|
||||
result.emplace(
|
||||
disabledByAdminRights,
|
||||
lang(lng_rights_permission_cant_edit));
|
||||
if (const auto channel = _peer->asChannel()) {
|
||||
if (channel->isPublic()) {
|
||||
result.emplace(
|
||||
Flag::f_change_info | Flag::f_pin_messages,
|
||||
lang(lng_rights_permission_unavailable));
|
||||
}
|
||||
}
|
||||
Unexpected("User in EditPeerPermissionsBox.");
|
||||
return result;
|
||||
}();
|
||||
|
||||
auto [checkboxes, getRestrictions, changes] = CreateEditRestrictions(
|
||||
this,
|
||||
lng_rights_default_restrictions_header,
|
||||
restrictions,
|
||||
disabledFlags);
|
||||
disabledMessages);
|
||||
|
||||
inner->add(std::move(checkboxes));
|
||||
|
||||
@ -353,12 +356,15 @@ void EditPeerPermissionsBox::addBannedButtons(
|
||||
}
|
||||
}
|
||||
|
||||
template <typename Flags, typename FlagLabelPairs>
|
||||
template <
|
||||
typename Flags,
|
||||
typename DisabledMessagePairs,
|
||||
typename FlagLabelPairs>
|
||||
EditFlagsControl<Flags> CreateEditFlags(
|
||||
QWidget *parent,
|
||||
LangKey header,
|
||||
Flags checked,
|
||||
Flags disabled,
|
||||
const DisabledMessagePairs &disabledMessagePairs,
|
||||
const FlagLabelPairs &flagLabelPairs) {
|
||||
auto widget = object_ptr<Ui::VerticalLayout>(parent);
|
||||
const auto container = widget.data();
|
||||
@ -394,24 +400,38 @@ EditFlagsControl<Flags> CreateEditFlags(
|
||||
st::rightsHeaderMargin);
|
||||
|
||||
auto addCheckbox = [&](Flags flags, const QString &text) {
|
||||
const auto lockedIt = ranges::find_if(
|
||||
disabledMessagePairs,
|
||||
[&](const auto &pair) { return (pair.first & flags) != 0; });
|
||||
const auto locked = (lockedIt != end(disabledMessagePairs))
|
||||
? std::make_optional(lockedIt->second)
|
||||
: std::nullopt;
|
||||
const auto toggled = ((checked & flags) != 0);
|
||||
auto toggle = std::make_unique<Ui::ToggleView>(
|
||||
st::rightsToggle,
|
||||
toggled);
|
||||
toggle->setLocked(locked.has_value());
|
||||
const auto control = container->add(
|
||||
object_ptr<Ui::Checkbox>(
|
||||
container,
|
||||
text,
|
||||
(checked & flags) != 0,
|
||||
st::rightsCheckbox,
|
||||
st::rightsToggle),
|
||||
std::move(toggle)),
|
||||
st::rightsToggleMargin);
|
||||
control->checkedChanges(
|
||||
) | rpl::start_with_next([=](bool checked) {
|
||||
InvokeQueued(control, [=] {
|
||||
applyDependencies(control);
|
||||
changes->fire({});
|
||||
});
|
||||
if (locked.has_value()) {
|
||||
if (checked != toggled) {
|
||||
Ui::Toast::Show(*locked);
|
||||
control->setChecked(toggled);
|
||||
}
|
||||
} else {
|
||||
InvokeQueued(control, [=] {
|
||||
applyDependencies(control);
|
||||
changes->fire({});
|
||||
});
|
||||
}
|
||||
}, control->lifetime());
|
||||
if ((disabled & flags) != 0) {
|
||||
control->setDisabled(true);
|
||||
}
|
||||
checkboxes->emplace(flags, control);
|
||||
};
|
||||
for (const auto &[flags, label] : flagLabelPairs) {
|
||||
@ -434,12 +454,12 @@ EditFlagsControl<MTPDchatBannedRights::Flags> CreateEditRestrictions(
|
||||
QWidget *parent,
|
||||
LangKey header,
|
||||
MTPDchatBannedRights::Flags restrictions,
|
||||
MTPDchatBannedRights::Flags disabled) {
|
||||
std::map<MTPDchatBannedRights::Flags, QString> disabledMessages) {
|
||||
auto result = CreateEditFlags(
|
||||
parent,
|
||||
header,
|
||||
NegateRestrictions(restrictions),
|
||||
disabled,
|
||||
disabledMessages,
|
||||
RestrictionLabels());
|
||||
result.value = [original = std::move(result.value)]{
|
||||
return NegateRestrictions(original());
|
||||
@ -455,13 +475,13 @@ EditFlagsControl<MTPDchatAdminRights::Flags> CreateEditAdminRights(
|
||||
QWidget *parent,
|
||||
LangKey header,
|
||||
MTPDchatAdminRights::Flags rights,
|
||||
MTPDchatAdminRights::Flags disabled,
|
||||
std::map<MTPDchatAdminRights::Flags, QString> disabledMessages,
|
||||
bool isGroup,
|
||||
bool anyoneCanAddMembers) {
|
||||
return CreateEditFlags(
|
||||
parent,
|
||||
header,
|
||||
rights,
|
||||
disabled,
|
||||
disabledMessages,
|
||||
AdminRightLabels(isGroup, anyoneCanAddMembers));
|
||||
}
|
||||
|
@ -46,13 +46,13 @@ EditFlagsControl<MTPDchatBannedRights::Flags> CreateEditRestrictions(
|
||||
QWidget *parent,
|
||||
LangKey header,
|
||||
MTPDchatBannedRights::Flags restrictions,
|
||||
MTPDchatBannedRights::Flags disabled);
|
||||
std::map<MTPDchatBannedRights::Flags, QString> disabledMessages);
|
||||
|
||||
EditFlagsControl<MTPDchatAdminRights::Flags> CreateEditAdminRights(
|
||||
QWidget *parent,
|
||||
LangKey header,
|
||||
MTPDchatAdminRights::Flags rights,
|
||||
MTPDchatAdminRights::Flags disabled,
|
||||
std::map<MTPDchatAdminRights::Flags, QString> disabledMessages,
|
||||
bool isGroup,
|
||||
bool anyoneCanAddMembers);
|
||||
|
||||
|
@ -22,7 +22,7 @@ bool ValidateFont(const QString &familyName, int flags = 0) {
|
||||
checkFont.setStyleStrategy(QFont::PreferQuality);
|
||||
auto realFamily = QFontInfo(checkFont).family();
|
||||
if (realFamily.trimmed().compare(familyName, Qt::CaseInsensitive)) {
|
||||
LOG(("Font Error: could not resolve '%1' font, got '%2' after feeding '%3'.").arg(familyName).arg(realFamily));
|
||||
LOG(("Font Error: could not resolve '%1' font, got '%2'.").arg(familyName).arg(realFamily));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -115,20 +115,28 @@ void ToggleView::paint(Painter &p, int left, int top, int outerWidth, TimeMs ms)
|
||||
p.drawEllipse(fgRect);
|
||||
|
||||
if (_st->xsize > 0) {
|
||||
paintXV(p, toggleLeft, top, outerWidth, toggled, fgBrush);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(fgBrush);
|
||||
if (_locked) {
|
||||
const auto color = anim::color(_st->untoggledFg, _st->toggledFg, toggled);
|
||||
_st->lockIcon.paint(p, toggleLeft, top, outerWidth, color);
|
||||
} else {
|
||||
paintXV(p, toggleLeft, top, outerWidth, toggled, fgBrush);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ToggleView::paintXV(Painter &p, int left, int top, int outerWidth, float64 toggled, const QBrush &brush) {
|
||||
Assert(_st->vsize > 0);
|
||||
Assert(_st->stroke > 0);
|
||||
Expects(_st->vsize > 0);
|
||||
Expects(_st->stroke > 0);
|
||||
|
||||
static const auto sqrt2 = sqrt(2.);
|
||||
auto stroke = (0. + _st->stroke) / sqrt2;
|
||||
const auto stroke = (0. + _st->stroke) / sqrt2;
|
||||
if (toggled < 1) {
|
||||
// Just X or X->V.
|
||||
auto xSize = 0. + _st->xsize;
|
||||
auto xLeft = left + (_st->diameter - xSize) / 2.;
|
||||
auto xTop = top + (_st->diameter - xSize) / 2.;
|
||||
const auto xSize = 0. + _st->xsize;
|
||||
const auto xLeft = left + (_st->diameter - xSize) / 2.;
|
||||
const auto xTop = top + (_st->diameter - xSize) / 2.;
|
||||
QPointF pathX[] = {
|
||||
{ xLeft, xTop + stroke },
|
||||
{ xLeft + stroke, xTop },
|
||||
@ -148,10 +156,10 @@ void ToggleView::paintXV(Painter &p, int left, int top, int outerWidth, float64
|
||||
}
|
||||
if (toggled > 0) {
|
||||
// X->V.
|
||||
auto vSize = 0. + _st->vsize;
|
||||
auto fSize = (xSize + vSize - 2. * stroke);
|
||||
auto vLeft = left + (_st->diameter - fSize) / 2.;
|
||||
auto vTop = 0. + xTop + _st->vshift;
|
||||
const auto vSize = 0. + _st->vsize;
|
||||
const auto fSize = (xSize + vSize - 2. * stroke);
|
||||
const auto vLeft = left + (_st->diameter - fSize) / 2.;
|
||||
const auto vTop = 0. + xTop + _st->vshift;
|
||||
QPointF pathV[] = {
|
||||
{ vLeft, vTop + xSize - vSize + stroke },
|
||||
{ vLeft + stroke, vTop + xSize - vSize },
|
||||
@ -176,12 +184,12 @@ void ToggleView::paintXV(Painter &p, int left, int top, int outerWidth, float64
|
||||
}
|
||||
} else {
|
||||
// Just V.
|
||||
auto xSize = 0. + _st->xsize;
|
||||
auto xTop = top + (_st->diameter - xSize) / 2.;
|
||||
auto vSize = 0. + _st->vsize;
|
||||
auto fSize = (xSize + vSize - 2. * stroke);
|
||||
auto vLeft = left + (_st->diameter - (_st->xsize + _st->vsize - 2. * stroke)) / 2.;
|
||||
auto vTop = 0. + xTop + _st->vshift;
|
||||
const auto xSize = 0. + _st->xsize;
|
||||
const auto xTop = top + (_st->diameter - xSize) / 2.;
|
||||
const auto vSize = 0. + _st->vsize;
|
||||
const auto fSize = (xSize + vSize - 2. * stroke);
|
||||
const auto vLeft = left + (_st->diameter - (_st->xsize + _st->vsize - 2. * stroke)) / 2.;
|
||||
const auto vTop = 0. + xTop + _st->vshift;
|
||||
QPointF pathV[] = {
|
||||
{ vLeft, vTop + xSize - vSize + stroke },
|
||||
{ vLeft + stroke, vTop + xSize - vSize },
|
||||
@ -214,6 +222,13 @@ bool ToggleView::checkRippleStartPosition(QPoint position) const {
|
||||
return QRect(QPoint(0, 0), rippleSize()).contains(position);
|
||||
}
|
||||
|
||||
void ToggleView::setLocked(bool locked) {
|
||||
if (_locked != locked) {
|
||||
_locked = locked;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
CheckView::CheckView(const style::Check &st, bool checked, Fn<void()> updateCallback) : AbstractCheckView(st.duration, checked, std::move(updateCallback))
|
||||
, _st(&st) {
|
||||
}
|
||||
|
@ -126,12 +126,14 @@ public:
|
||||
void paint(Painter &p, int left, int top, int outerWidth, TimeMs ms) override;
|
||||
QImage prepareRippleMask() const override;
|
||||
bool checkRippleStartPosition(QPoint position) const override;
|
||||
void setLocked(bool locked);
|
||||
|
||||
private:
|
||||
void paintXV(Painter &p, int left, int top, int outerWidth, float64 toggled, const QBrush &brush);
|
||||
QSize rippleSize() const;
|
||||
|
||||
not_null<const style::Toggle*> _st;
|
||||
bool _locked = false;
|
||||
|
||||
};
|
||||
|
||||
|
@ -115,6 +115,7 @@ Toggle {
|
||||
vsize: pixels;
|
||||
vshift: pixels;
|
||||
stroke: pixels;
|
||||
lockIcon: icon;
|
||||
rippleAreaPadding: pixels;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user