diff --git a/Telegram/Resources/animations/palette.tgs b/Telegram/Resources/animations/palette.tgs
new file mode 100644
index 00000000000000..cc4887f9471607
Binary files /dev/null and b/Telegram/Resources/animations/palette.tgs differ
diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings
index 9e3f181e320bf5..6369098637d0b2 100644
--- a/Telegram/Resources/langs/lang.strings
+++ b/Telegram/Resources/langs/lang.strings
@@ -2157,6 +2157,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_boost_channel_button" = "Boost Channel";
"lng_boost_group_button" = "Boost Group";
"lng_boost_again_button" = "Boost Again";
+"lng_boost_group_about" = "Boost your group to unlock additional\nappearance settings.";
"lng_boost_level#one" = "Level {count}";
"lng_boost_level#other" = "Level {count}";
"lng_boost_level_unlocks#one" = "Level {count} Unlocks:";
diff --git a/Telegram/Resources/qrc/telegram/animations.qrc b/Telegram/Resources/qrc/telegram/animations.qrc
index 76ea1ef4a3c293..a129237ca0b3d7 100644
--- a/Telegram/Resources/qrc/telegram/animations.qrc
+++ b/Telegram/Resources/qrc/telegram/animations.qrc
@@ -13,5 +13,6 @@
../../animations/stats.tgs
../../animations/voice_ttl_idle.tgs
../../animations/voice_ttl_start.tgs
+ ../../animations/palette.tgs
diff --git a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp
index 15700114b353aa..752c492fe0d4c3 100644
--- a/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp
+++ b/Telegram/SourceFiles/boxes/peers/edit_peer_color_box.cpp
@@ -29,6 +29,7 @@ For license and copyright information please follow this link:
#include "info/profile/info_profile_emoji_status_panel.h"
#include "info/info_memento.h"
#include "lang/lang_keys.h"
+#include "lottie/lottie_icon.h"
#include "main/main_account.h"
#include "main/main_app_config.h"
#include "main/main_session.h"
@@ -686,7 +687,7 @@ int ColorSelector::resizeGetHeight(int newWidth) {
rpl::producer colorIndexValue,
rpl::producer emojiIdValue,
Fn emojiIdChosen) {
- const auto &basicSt = st::settingsButtonNoIcon;
+ const auto &basicSt = st::peerAppearanceButton;
const auto ratio = style::DevicePixelRatio();
const auto added = st::normalFont->spacew;
const auto emojiSize = Data::FrameSizeFromTag({}) / ratio;
@@ -698,10 +699,11 @@ int ColorSelector::resizeGetHeight(int newWidth) {
const auto st = parent->lifetime().make_state(
basicSt);
st->padding.setRight(rightPadding);
- auto result = object_ptr(
+ auto result = Settings::CreateButtonWithIcon(
parent,
tr::lng_settings_color_emoji(),
- *st);
+ *st,
+ { &st::menuBlueIconColorNames });
const auto raw = result.data();
const auto right = Ui::CreateChild(raw);
@@ -802,7 +804,7 @@ int ColorSelector::resizeGetHeight(int newWidth) {
rpl::producer statusIdValue,
Fn statusIdChosen,
bool group) {
- const auto &basicSt = st::settingsButtonNoIcon;
+ const auto &basicSt = st::peerAppearanceButton;
const auto ratio = style::DevicePixelRatio();
const auto added = st::normalFont->spacew;
const auto emojiSize = Data::FrameSizeFromTag({}) / ratio;
@@ -814,12 +816,13 @@ int ColorSelector::resizeGetHeight(int newWidth) {
const auto st = parent->lifetime().make_state(
basicSt);
st->padding.setRight(rightPadding);
- auto result = object_ptr(
+ auto result = Settings::CreateButtonWithIcon(
parent,
(group
? tr::lng_edit_channel_status_group()
: tr::lng_edit_channel_status()),
- *st);
+ *st,
+ { &st::menuBlueIconEmojiStatus });
const auto raw = result.data();
const auto right = Ui::CreateChild(raw);
@@ -931,7 +934,38 @@ void EditPeerColorBox(
state->emojiId = peer->backgroundEmojiId();
state->statusId = peer->emojiStatusId();
- if (!group) {
+ if (group) {
+ const auto divider = Ui::CreateChild(
+ box.get());
+ const auto verticalLayout = box->verticalLayout()->add(
+ object_ptr(box.get()));
+
+ auto icon = CreateLottieIcon(
+ verticalLayout,
+ {
+ .name = u"palette"_q,
+ .sizeOverride = {
+ st::settingsCloudPasswordIconSize,
+ st::settingsCloudPasswordIconSize,
+ },
+ },
+ st::peerAppearanceIconPadding);
+ box->setShowFinishedCallback([animate = std::move(icon.animate)] {
+ animate(anim::repeat::once);
+ });
+ verticalLayout->add(std::move(icon.widget));
+ verticalLayout->add(
+ object_ptr(
+ verticalLayout,
+ tr::lng_boost_group_about(),
+ st::peerAppearanceCoverLabel),
+ st::peerAppearanceCoverLabelMargin);
+
+ verticalLayout->geometryValue(
+ ) | rpl::start_with_next([=](const QRect &r) {
+ divider->setGeometry(r);
+ }, divider->lifetime());
+ } else {
box->addRow(object_ptr(
box,
style,
@@ -953,9 +987,12 @@ void EditPeerColorBox(
[=](uint8 index) { state->index = index; }),
{ margin, skip, margin, skip });
- Ui::AddDividerText(container, peer->isSelf()
- ? tr::lng_settings_color_about()
- : tr::lng_settings_color_about_channel());
+ Ui::AddDividerText(
+ container,
+ (peer->isSelf()
+ ? tr::lng_settings_color_about()
+ : tr::lng_settings_color_about_channel()),
+ st::peerAppearanceDividerTextMargin);
Ui::AddSkip(container, st::settingsColorSampleSkip);
@@ -968,19 +1005,23 @@ void EditPeerColorBox(
[=](DocumentId id) { state->emojiId = id; }));
Ui::AddSkip(container, st::settingsColorSampleSkip);
- Ui::AddDividerText(container, peer->isSelf()
- ? tr::lng_settings_color_emoji_about()
- : tr::lng_settings_color_emoji_about_channel());
+ Ui::AddDividerText(
+ container,
+ (peer->isSelf()
+ ? tr::lng_settings_color_emoji_about()
+ : tr::lng_settings_color_emoji_about_channel()),
+ st::peerAppearanceDividerTextMargin);
}
if (const auto channel = peer->asChannel()) {
Ui::AddSkip(container, st::settingsColorSampleSkip);
- container->add(object_ptr(
+ Settings::AddButtonWithIcon(
container,
(group
? tr::lng_edit_channel_wallpaper_group()
: tr::lng_edit_channel_wallpaper()),
- st::settingsButtonNoIcon)
+ st::peerAppearanceButton,
+ { &st::menuBlueIconWallpaper }
)->setClickedCallback([=] {
const auto usage = ChatHelpers::WindowUsage::PremiumPromo;
if (const auto strong = show->resolveWindow(usage)) {
@@ -989,24 +1030,31 @@ void EditPeerColorBox(
});
Ui::AddSkip(container, st::settingsColorSampleSkip);
- Ui::AddDividerText(container, group
- ? tr::lng_edit_channel_wallpaper_about_group()
- : tr::lng_edit_channel_wallpaper_about());
+ Ui::AddDividerText(
+ container,
+ (group
+ ? tr::lng_edit_channel_wallpaper_about_group()
+ : tr::lng_edit_channel_wallpaper_about()),
+ st::peerAppearanceDividerTextMargin);
if (group) {
Ui::AddSkip(container, st::settingsColorSampleSkip);
- container->add(object_ptr(
+ Settings::AddButtonWithIcon(
container,
tr::lng_group_emoji(),
- st::settingsButtonNoIcon)
+ st::peerAppearanceButton,
+ { &st::menuBlueIconEmojiPack }
)->setClickedCallback([=] {
const auto isEmoji = true;
show->showBox(Box(show, channel, isEmoji));
});
Ui::AddSkip(container, st::settingsColorSampleSkip);
- Ui::AddDividerText(container, tr::lng_group_emoji_description());
+ Ui::AddDividerText(
+ container,
+ tr::lng_group_emoji_description(),
+ st::peerAppearanceDividerTextMargin);
}
// Preload exceptions list.
@@ -1032,9 +1080,12 @@ void EditPeerColorBox(
group));
Ui::AddSkip(container, st::settingsColorSampleSkip);
- Ui::AddDividerText(container, group
- ? tr::lng_edit_channel_status_about_group()
- : tr::lng_edit_channel_status_about());
+ Ui::AddDividerText(
+ container,
+ (group
+ ? tr::lng_edit_channel_status_about_group()
+ : tr::lng_edit_channel_status_about()),
+ st::peerAppearanceDividerTextMargin);
}
box->addButton(tr::lng_settings_apply(), [=] {
diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp
index b85703cf0922fc..270aedf97ad040 100644
--- a/Telegram/SourceFiles/history/history_inner_widget.cpp
+++ b/Telegram/SourceFiles/history/history_inner_widget.cpp
@@ -84,6 +84,8 @@ For license and copyright information please follow this link:
#include "styles/style_chat.h"
#include "styles/style_menu_icons.h"
+#include "chat_helpers/stickers_emoji_pack.h"
+
#include
#include
#include
@@ -2320,6 +2322,19 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
? reinterpret_cast(
link->property(kDocumentLinkMediaProperty).toULongLong())
: nullptr;
+ if (const auto media = _dragStateItem->media()) {
+ if (const auto document = media->document()) {
+ addDocumentActions(document, _dragStateItem);
+ }
+ }
+ if (_dragStateItem) {
+ if (const auto emoji = _dragStateItem->mainView()->isolatedEmoji()) {
+ const auto emojiStickers = &_dragStateItem->history()->session().emojiStickersPack();
+ if (const auto sticker = emojiStickers->stickerForEmoji(emoji)) {
+ addDocumentActions(sticker.document, _dragStateItem);
+ }
+ }
+ }
if (lnkPhoto || lnkDocument) {
const auto item = _dragStateItem;
const auto itemId = item ? item->fullId() : FullMsgId();
diff --git a/Telegram/SourceFiles/settings/settings.style b/Telegram/SourceFiles/settings/settings.style
index 0df986eb0f5f83..f45d68c0b42d77 100644
--- a/Telegram/SourceFiles/settings/settings.style
+++ b/Telegram/SourceFiles/settings/settings.style
@@ -574,3 +574,14 @@ messagePrivacySubscribe: SettingsButton(settingsButtonLight) {
iconLeft: 20px;
}
messagePrivacyLock: icon {{ "info/info_rights_lock", checkboxFg }};
+
+peerAppearanceButton: SettingsButton(settingsButtonLight) {
+ padding: margins(60px, 8px, 22px, 8px);
+ iconLeft: 20px;
+}
+peerAppearanceCoverLabel: FlatLabel(boxDividerLabel) {
+ align: align(top);
+}
+peerAppearanceCoverLabelMargin: margins(22px, 0px, 22px, 17px);
+peerAppearanceIconPadding: margins(0px, 15px, 0px, 5px);
+peerAppearanceDividerTextMargin: margins(22px, 8px, 22px, 11px);
diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style
index dc870d4980cea2..b0e0dda134c7b8 100644
--- a/Telegram/SourceFiles/ui/menu_icons.style
+++ b/Telegram/SourceFiles/ui/menu_icons.style
@@ -160,6 +160,10 @@ menuIconMuteForAnyTextFont: font(8px semibold);
menuBlueIconPhotoSet: icon {{ "menu/photo_set", lightButtonFg }};
menuBlueIconPremium: icon{{ "menu/premium", lightButtonFg }};
+menuBlueIconColorNames: icon{{ "settings/premium/features/feature_color_names", lightButtonFg }};
+menuBlueIconWallpaper: icon{{ "settings/premium/features/feature_wallpaper", lightButtonFg }};
+menuBlueIconEmojiStatus: icon{{ "settings/premium/features/feature_status", lightButtonFg }};
+menuBlueIconEmojiPack: icon{{ "settings/premium/features/feature_emoji_pack", lightButtonFg }};
mediaMenuIconStickers: icon {{ "menu/stickers", mediaviewMenuFg }};
mediaMenuIconCancel: icon {{ "menu/cancel", mediaviewMenuFg }};
diff --git a/Telegram/SourceFiles/ui/vertical_list.cpp b/Telegram/SourceFiles/ui/vertical_list.cpp
index 34c6c0916bae16..b1acce232c034e 100644
--- a/Telegram/SourceFiles/ui/vertical_list.cpp
+++ b/Telegram/SourceFiles/ui/vertical_list.cpp
@@ -30,20 +30,25 @@ void AddDivider(not_null container) {
void AddDividerText(
not_null container,
- rpl::producer text) {
- AddDividerText(container, std::move(text) | Ui::Text::ToWithEntities());
+ rpl::producer text,
+ const style::margins &margins) {
+ AddDividerText(
+ container,
+ std::move(text) | Ui::Text::ToWithEntities(),
+ margins);
}
void AddDividerText(
not_null container,
- rpl::producer text) {
+ rpl::producer text,
+ const style::margins &margins) {
container->add(object_ptr(
container,
object_ptr(
container,
std::move(text),
st::boxDividerLabel),
- st::defaultBoxDividerLabelPadding));
+ margins));
}
not_null AddSubsectionTitle(
diff --git a/Telegram/SourceFiles/ui/vertical_list.h b/Telegram/SourceFiles/ui/vertical_list.h
index 970e73f4c0784a..87deef1786b51e 100644
--- a/Telegram/SourceFiles/ui/vertical_list.h
+++ b/Telegram/SourceFiles/ui/vertical_list.h
@@ -11,6 +11,10 @@ namespace style {
struct FlatLabel;
} // namespace style
+namespace st {
+extern const style::margins &defaultBoxDividerLabelPadding;
+} // namespace st
+
namespace Ui {
class FlatLabel;
@@ -21,10 +25,12 @@ void AddSkip(not_null container, int skip);
void AddDivider(not_null container);
void AddDividerText(
not_null container,
- rpl::producer text);
+ rpl::producer text,
+ const style::margins &margins = st::defaultBoxDividerLabelPadding);
void AddDividerText(
not_null container,
- rpl::producer text);
+ rpl::producer text,
+ const style::margins &margins = st::defaultBoxDividerLabelPadding);
not_null AddSubsectionTitle(
not_null container,
rpl::producer text,