mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 06:35:14 +00:00
Show a new "Battery and Animations" settings item.
This commit is contained in:
@@ -297,7 +297,7 @@ void EditAdminBox::prepare() {
|
||||
& (filterByMyRights ? channel->adminRights() : ~Flag(0)));
|
||||
|
||||
const auto disabledMessages = [&] {
|
||||
auto result = std::map<Flags, QString>();
|
||||
auto result = base::flat_map<Flags, QString>();
|
||||
if (!canSave()) {
|
||||
result.emplace(
|
||||
~Flags(0),
|
||||
@@ -725,7 +725,7 @@ void EditRestrictedBox::prepare() {
|
||||
? (Flag::ChangeInfo | Flag::PinMessages)
|
||||
: Flags(0)));
|
||||
const auto disabledMessages = [&] {
|
||||
auto result = std::map<Flags, QString>();
|
||||
auto result = base::flat_map<Flags, QString>();
|
||||
if (!canSave()) {
|
||||
result.emplace(
|
||||
~Flags(0),
|
||||
|
@@ -48,18 +48,12 @@ constexpr auto kSuggestGigagroupThreshold = 199000;
|
||||
return {};
|
||||
}
|
||||
|
||||
struct NestedRestrictionLabels {
|
||||
std::optional<rpl::producer<QString>> nestedLabel;
|
||||
std::vector<RestrictionLabel> restrictionLabels;
|
||||
};
|
||||
|
||||
[[nodiscard]] auto NestedRestrictionLabelsList(
|
||||
Data::RestrictionsSetOptions options) {
|
||||
using Flag = ChatRestriction;
|
||||
|
||||
auto first = std::vector<RestrictionLabel>{
|
||||
{ Flag::SendOther, tr::lng_rights_chat_send_text(tr::now) },
|
||||
// { Flag::SendMedia, tr::lng_rights_chat_send_media(tr::now) },
|
||||
};
|
||||
auto inner = std::vector<RestrictionLabel>{
|
||||
{ Flag::SendPhotos, tr::lng_rights_chat_photos(tr::now) },
|
||||
@@ -89,7 +83,7 @@ struct NestedRestrictionLabels {
|
||||
&RestrictionLabel::flags),
|
||||
end(second));
|
||||
}
|
||||
return std::vector<NestedRestrictionLabels>{
|
||||
return std::vector<NestedEditFlagsLabels<ChatRestrictions>>{
|
||||
{ std::nullopt, std::move(first) },
|
||||
{ tr::lng_rights_chat_send_media(), std::move(inner) },
|
||||
{ std::nullopt, std::move(second) },
|
||||
@@ -267,19 +261,24 @@ ChatRestrictions DisabledByAdminRights(not_null<PeerData*> peer) {
|
||||
|
||||
not_null<Ui::RpWidget*> AddInnerToggle(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
const style::SettingsButton &st,
|
||||
std::vector<not_null<Ui::AbstractCheckView*>> innerCheckViews,
|
||||
not_null<Ui::SlideWrap<>*> wrap,
|
||||
rpl::producer<QString> buttonLabel,
|
||||
std::optional<QString> locked) {
|
||||
const auto &stButton = st::rightsButton;
|
||||
std::optional<QString> locked,
|
||||
Settings::IconDescriptor &&icon) {
|
||||
const auto button = container->add(object_ptr<Ui::SettingsButton>(
|
||||
container,
|
||||
nullptr,
|
||||
stButton));
|
||||
st));
|
||||
if (icon) {
|
||||
Settings::AddButtonIcon(button, st, std::move(icon));
|
||||
}
|
||||
|
||||
const auto toggleButton = Ui::CreateChild<Ui::SettingsButton>(
|
||||
container.get(),
|
||||
nullptr,
|
||||
stButton);
|
||||
st);
|
||||
|
||||
struct State final {
|
||||
State(const style::Toggle &st, Fn<void()> c)
|
||||
@@ -291,7 +290,7 @@ not_null<Ui::RpWidget*> AddInnerToggle(
|
||||
std::vector<not_null<Ui::AbstractCheckView*>> innerChecks;
|
||||
};
|
||||
const auto state = button->lifetime().make_state<State>(
|
||||
stButton.toggle,
|
||||
st.toggle,
|
||||
[=] { toggleButton->update(); });
|
||||
state->innerChecks = std::move(innerCheckViews);
|
||||
const auto countChecked = [=] {
|
||||
@@ -309,12 +308,12 @@ not_null<Ui::RpWidget*> AddInnerToggle(
|
||||
{
|
||||
const auto separator = Ui::CreateChild<Ui::RpWidget>(container.get());
|
||||
separator->paintRequest(
|
||||
) | rpl::start_with_next([=, bg = stButton.textBgOver] {
|
||||
) | rpl::start_with_next([=, bg = st.textBgOver] {
|
||||
auto p = QPainter(separator);
|
||||
p.fillRect(separator->rect(), bg);
|
||||
}, separator->lifetime());
|
||||
const auto separatorHeight = 2 * stButton.toggle.border
|
||||
+ stButton.toggle.diameter;
|
||||
const auto separatorHeight = 2 * st.toggle.border
|
||||
+ st.toggle.diameter;
|
||||
button->geometryValue(
|
||||
) | rpl::start_with_next([=](const QRect &r) {
|
||||
const auto w = st::rightsButtonToggleWidth;
|
||||
@@ -341,7 +340,7 @@ not_null<Ui::RpWidget*> AddInnerToggle(
|
||||
toggleButton->sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &s) {
|
||||
checkWidget->moveToRight(
|
||||
stButton.toggleSkip,
|
||||
st.toggleSkip,
|
||||
(s.height() - checkWidget->height()) / 2);
|
||||
}, toggleButton->lifetime());
|
||||
}
|
||||
@@ -392,8 +391,8 @@ not_null<Ui::RpWidget*> AddInnerToggle(
|
||||
}, arrow->lifetime());
|
||||
}
|
||||
button->sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &s) {
|
||||
const auto labelLeft = stButton.padding.left();
|
||||
) | rpl::start_with_next([=, &st](const QSize &s) {
|
||||
const auto labelLeft = st.padding.left();
|
||||
const auto labelRight = s.width() - toggleButton->width();
|
||||
|
||||
label->resizeToWidth(labelRight - labelLeft - arrow->width());
|
||||
@@ -446,22 +445,18 @@ not_null<Ui::RpWidget*> AddInnerToggle(
|
||||
return button;
|
||||
}
|
||||
|
||||
template <
|
||||
typename Flags,
|
||||
typename DisabledMessagePairs,
|
||||
typename FlagLabelPairs>
|
||||
[[nodiscard]] EditFlagsControl<Flags, Ui::RpWidget> CreateEditFlags(
|
||||
template <typename Flags>
|
||||
[[nodiscard]] EditFlagsControl<Flags> CreateEditFlags(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
rpl::producer<QString> header,
|
||||
Flags checked,
|
||||
const DisabledMessagePairs &disabledMessagePairs,
|
||||
const FlagLabelPairs &flagLabelPairsNested) {
|
||||
EditFlagsDescriptor<Flags> &&descriptor) {
|
||||
struct State final {
|
||||
std::map<Flags, not_null<Ui::AbstractCheckView*>> checkViews;
|
||||
rpl::event_stream<> anyChanges;
|
||||
};
|
||||
const auto state = container->lifetime().make_state<State>();
|
||||
|
||||
const auto &st = descriptor.st ? *descriptor.st : st::rightsButton;
|
||||
const auto value = [=] {
|
||||
auto result = Flags(0);
|
||||
for (const auto &[flags, checkView] : state->checkViews) {
|
||||
@@ -478,23 +473,23 @@ template <
|
||||
ApplyDependencies(state->checkViews, dependencies, view);
|
||||
};
|
||||
|
||||
if (header) {
|
||||
if (descriptor.header) {
|
||||
container->add(
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
container,
|
||||
std::move(header),
|
||||
std::move(descriptor.header),
|
||||
st::rightsHeaderLabel),
|
||||
st::rightsHeaderMargin);
|
||||
}
|
||||
const auto addCheckbox = [&](
|
||||
not_null<Ui::VerticalLayout*> verticalLayout,
|
||||
bool isInner,
|
||||
Flags flags,
|
||||
const QString &text) {
|
||||
const EditFlagsLabel<Flags> &entry) {
|
||||
const auto flags = entry.flags;
|
||||
const auto lockedIt = ranges::find_if(
|
||||
disabledMessagePairs,
|
||||
descriptor.disabledMessages,
|
||||
[&](const auto &pair) { return (pair.first & flags) != 0; });
|
||||
const auto locked = (lockedIt != end(disabledMessagePairs))
|
||||
const auto locked = (lockedIt != end(descriptor.disabledMessages))
|
||||
? std::make_optional(lockedIt->second)
|
||||
: std::nullopt;
|
||||
const auto toggled = ((checked & flags) != 0);
|
||||
@@ -504,10 +499,10 @@ template <
|
||||
const auto checkbox = verticalLayout->add(
|
||||
object_ptr<Ui::Checkbox>(
|
||||
verticalLayout,
|
||||
text,
|
||||
entry.label,
|
||||
toggled,
|
||||
st::settingsCheckbox),
|
||||
st::rightsButton.padding);
|
||||
st.padding);
|
||||
const auto button = Ui::CreateChild<Ui::RippleButton>(
|
||||
verticalLayout.get(),
|
||||
st::defaultRippleAnimation);
|
||||
@@ -530,13 +525,14 @@ template <
|
||||
} else {
|
||||
const auto button = Settings::AddButton(
|
||||
verticalLayout,
|
||||
rpl::single(text),
|
||||
st::rightsButton);
|
||||
rpl::single(entry.label),
|
||||
st,
|
||||
{ entry.icon });
|
||||
const auto toggle = Ui::CreateChild<Ui::RpWidget>(
|
||||
button.get());
|
||||
auto &lifetime = toggle->lifetime();
|
||||
const auto checkView = lifetime.make_state<Ui::ToggleView>(
|
||||
st::rightsButton.toggle,
|
||||
st.toggle,
|
||||
toggled,
|
||||
[=] { toggle->update(); });
|
||||
toggle->resize(checkView->getSize());
|
||||
@@ -548,7 +544,7 @@ template <
|
||||
button->sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &s) {
|
||||
toggle->moveToRight(
|
||||
st::rightsButton.toggleSkip,
|
||||
st.toggleSkip,
|
||||
(s.height() - toggle->height()) / 2);
|
||||
}, toggle->lifetime());
|
||||
button->setClickedCallback([=] {
|
||||
@@ -581,8 +577,10 @@ template <
|
||||
|
||||
return checkView;
|
||||
};
|
||||
for (const auto &[nestedLabel, flagLabelPairs] : flagLabelPairsNested) {
|
||||
const auto isInner = nestedLabel.has_value();
|
||||
for (const auto &nestedWithLabel : descriptor.labels) {
|
||||
Assert(!nestedWithLabel.nested.empty());
|
||||
|
||||
const auto isInner = nestedWithLabel.nestingLabel.has_value();
|
||||
auto wrap = isInner
|
||||
? object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>(
|
||||
container,
|
||||
@@ -590,8 +588,8 @@ template <
|
||||
: object_ptr<Ui::SlideWrap<Ui::VerticalLayout>>{ nullptr };
|
||||
const auto verticalLayout = wrap ? wrap->entity() : container.get();
|
||||
auto innerChecks = std::vector<not_null<Ui::AbstractCheckView*>>();
|
||||
for (const auto &[flags, label] : flagLabelPairs) {
|
||||
const auto c = addCheckbox(verticalLayout, isInner, flags, label);
|
||||
for (const auto &entry : nestedWithLabel.nested) {
|
||||
const auto c = addCheckbox(verticalLayout, isInner, entry);
|
||||
if (isInner) {
|
||||
innerChecks.push_back(c);
|
||||
}
|
||||
@@ -601,10 +599,12 @@ template <
|
||||
raw->hide(anim::type::instant);
|
||||
AddInnerToggle(
|
||||
container,
|
||||
st,
|
||||
innerChecks,
|
||||
raw,
|
||||
*nestedLabel,
|
||||
std::nullopt);
|
||||
*nestedWithLabel.nestingLabel,
|
||||
std::nullopt,
|
||||
{ nestedWithLabel.nested.front().icon });
|
||||
container->add(std::move(wrap));
|
||||
container->widthValue(
|
||||
) | rpl::start_with_next([=](int w) {
|
||||
@@ -857,10 +857,10 @@ void ShowEditPeerPermissionsBox(
|
||||
Unexpected("User in EditPeerPermissionsBox.");
|
||||
}());
|
||||
const auto disabledMessages = [&] {
|
||||
auto result = std::map<Flags, QString>();
|
||||
result.emplace(
|
||||
disabledByAdminRights,
|
||||
tr::lng_rights_permission_cant_edit(tr::now));
|
||||
auto result = base::flat_map<Flags, QString>();
|
||||
result.emplace(
|
||||
disabledByAdminRights,
|
||||
tr::lng_rights_permission_cant_edit(tr::now));
|
||||
if (const auto channel = peer->asChannel()) {
|
||||
if (channel->isPublic()
|
||||
|| (channel->isMegagroup() && channel->linkedChat())) {
|
||||
@@ -1026,19 +1026,21 @@ std::vector<AdminRightLabel> AdminRightLabels(
|
||||
}
|
||||
}
|
||||
|
||||
EditFlagsControl<ChatRestrictions, Ui::RpWidget> CreateEditRestrictions(
|
||||
EditFlagsControl<ChatRestrictions> CreateEditRestrictions(
|
||||
QWidget *parent,
|
||||
rpl::producer<QString> header,
|
||||
ChatRestrictions restrictions,
|
||||
std::map<ChatRestrictions, QString> disabledMessages,
|
||||
base::flat_map<ChatRestrictions, QString> disabledMessages,
|
||||
Data::RestrictionsSetOptions options) {
|
||||
auto widget = object_ptr<Ui::VerticalLayout>(parent);
|
||||
auto result = CreateEditFlags(
|
||||
widget.data(),
|
||||
header,
|
||||
NegateRestrictions(restrictions),
|
||||
disabledMessages,
|
||||
NestedRestrictionLabelsList(options));
|
||||
{
|
||||
.header = std::move(header),
|
||||
.labels = NestedRestrictionLabelsList(options),
|
||||
.disabledMessages = std::move(disabledMessages),
|
||||
});
|
||||
result.widget = std::move(widget);
|
||||
result.value = [original = std::move(result.value)]{
|
||||
return NegateRestrictions(original());
|
||||
@@ -1050,22 +1052,21 @@ EditFlagsControl<ChatRestrictions, Ui::RpWidget> CreateEditRestrictions(
|
||||
return result;
|
||||
}
|
||||
|
||||
EditFlagsControl<ChatAdminRights, Ui::RpWidget> CreateEditAdminRights(
|
||||
EditFlagsControl<ChatAdminRights> CreateEditAdminRights(
|
||||
QWidget *parent,
|
||||
rpl::producer<QString> header,
|
||||
ChatAdminRights rights,
|
||||
std::map<ChatAdminRights, QString> disabledMessages,
|
||||
base::flat_map<ChatAdminRights, QString> disabledMessages,
|
||||
Data::AdminRightsSetOptions options) {
|
||||
using String = std::optional<rpl::producer<QString>>;
|
||||
using Labels = std::pair<String, std::vector<AdminRightLabel>>;
|
||||
|
||||
auto widget = object_ptr<Ui::VerticalLayout>(parent);
|
||||
auto result = CreateEditFlags(
|
||||
widget.data(),
|
||||
header,
|
||||
rights,
|
||||
disabledMessages,
|
||||
std::vector<Labels>{ { std::nullopt, AdminRightLabels(options) } });
|
||||
{
|
||||
.header = std::move(header),
|
||||
.labels = { { std::nullopt, AdminRightLabels(options) } },
|
||||
.disabledMessages = std::move(disabledMessages),
|
||||
});
|
||||
result.widget = std::move(widget);
|
||||
|
||||
return result;
|
||||
@@ -1130,24 +1131,22 @@ ChatRestrictions FixDependentRestrictions(ChatRestrictions restrictions) {
|
||||
ChatAdminRights AdminRightsForOwnershipTransfer(
|
||||
Data::AdminRightsSetOptions options) {
|
||||
auto result = ChatAdminRights();
|
||||
for (const auto &[flag, label] : AdminRightLabels(options)) {
|
||||
if (!(flag & ChatAdminRight::Anonymous)) {
|
||||
result |= flag;
|
||||
for (const auto &entry : AdminRightLabels(options)) {
|
||||
if (!(entry.flags & ChatAdminRight::Anonymous)) {
|
||||
result |= entry.flags;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
EditFlagsControl<PowerSaving::Flags, Ui::RpWidget> CreateEditPowerSaving(
|
||||
EditFlagsControl<PowerSaving::Flags> CreateEditPowerSaving(
|
||||
QWidget *parent,
|
||||
PowerSaving::Flags flags) {
|
||||
auto widget = object_ptr<Ui::VerticalLayout>(parent);
|
||||
auto result = CreateEditFlags(
|
||||
widget.data(),
|
||||
nullptr,
|
||||
flags,
|
||||
std::map<PowerSaving::Flags, QString>{},
|
||||
Settings::PowerSavingLabelsList());
|
||||
Settings::PowerSavingLabels());
|
||||
result.widget = std::move(widget);
|
||||
|
||||
return result;
|
||||
|
@@ -9,6 +9,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "data/data_chat_participant_status.h"
|
||||
|
||||
namespace style {
|
||||
struct SettingsButton;
|
||||
} // namespace style
|
||||
|
||||
namespace Ui {
|
||||
class GenericBox;
|
||||
class RoundButton;
|
||||
@@ -44,42 +48,57 @@ void ShowEditPeerPermissionsBox(
|
||||
not_null<ChannelData*> channel,
|
||||
not_null<Window::SessionController*> controller);
|
||||
|
||||
struct RestrictionLabel {
|
||||
ChatRestrictions flags;
|
||||
template <typename Flags>
|
||||
struct EditFlagsLabel {
|
||||
Flags flags;
|
||||
QString label;
|
||||
const style::icon *icon = nullptr;
|
||||
};
|
||||
[[nodiscard]] std::vector<RestrictionLabel> RestrictionLabels(
|
||||
Data::RestrictionsSetOptions options);
|
||||
|
||||
struct AdminRightLabel {
|
||||
ChatAdminRights flags;
|
||||
QString label;
|
||||
};
|
||||
[[nodiscard]] std::vector<AdminRightLabel> AdminRightLabels(
|
||||
Data::AdminRightsSetOptions options);
|
||||
|
||||
template <typename Flags, typename Widget>
|
||||
template <typename Flags>
|
||||
struct EditFlagsControl {
|
||||
object_ptr<Widget> widget;
|
||||
object_ptr<Ui::RpWidget> widget;
|
||||
Fn<Flags()> value;
|
||||
rpl::producer<Flags> changes;
|
||||
};
|
||||
|
||||
template <typename Flags>
|
||||
struct NestedEditFlagsLabels {
|
||||
std::optional<rpl::producer<QString>> nestingLabel;
|
||||
std::vector<EditFlagsLabel<Flags>> nested;
|
||||
};
|
||||
|
||||
template <typename Flags>
|
||||
struct EditFlagsDescriptor {
|
||||
rpl::producer<QString> header;
|
||||
std::vector<NestedEditFlagsLabels<Flags>> labels;
|
||||
base::flat_map<Flags, QString> disabledMessages;
|
||||
const style::SettingsButton *st = nullptr;
|
||||
};
|
||||
|
||||
using RestrictionLabel = EditFlagsLabel<ChatRestrictions>;
|
||||
[[nodiscard]] std::vector<RestrictionLabel> RestrictionLabels(
|
||||
Data::RestrictionsSetOptions options);
|
||||
|
||||
using AdminRightLabel = EditFlagsLabel<ChatAdminRights>;
|
||||
[[nodiscard]] std::vector<AdminRightLabel> AdminRightLabels(
|
||||
Data::AdminRightsSetOptions options);
|
||||
|
||||
[[nodiscard]] auto CreateEditRestrictions(
|
||||
QWidget *parent,
|
||||
rpl::producer<QString> header,
|
||||
ChatRestrictions restrictions,
|
||||
std::map<ChatRestrictions, QString> disabledMessages,
|
||||
base::flat_map<ChatRestrictions, QString> disabledMessages,
|
||||
Data::RestrictionsSetOptions options)
|
||||
-> EditFlagsControl<ChatRestrictions, Ui::RpWidget>;
|
||||
-> EditFlagsControl<ChatRestrictions>;
|
||||
|
||||
[[nodiscard]] auto CreateEditAdminRights(
|
||||
QWidget *parent,
|
||||
rpl::producer<QString> header,
|
||||
ChatAdminRights rights,
|
||||
std::map<ChatAdminRights, QString> disabledMessages,
|
||||
base::flat_map<ChatAdminRights, QString> disabledMessages,
|
||||
Data::AdminRightsSetOptions options)
|
||||
-> EditFlagsControl<ChatAdminRights, Ui::RpWidget>;
|
||||
-> EditFlagsControl<ChatAdminRights>;
|
||||
|
||||
[[nodiscard]] ChatAdminRights DisabledByDefaultRestrictions(
|
||||
not_null<PeerData*> peer);
|
||||
@@ -91,4 +110,4 @@ struct EditFlagsControl {
|
||||
[[nodiscard]] auto CreateEditPowerSaving(
|
||||
QWidget *parent,
|
||||
PowerSaving::Flags flags
|
||||
) -> EditFlagsControl<PowerSaving::Flags, Ui::RpWidget>;
|
||||
) -> EditFlagsControl<PowerSaving::Flags>;
|
||||
|
Reference in New Issue
Block a user