mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Allow setting channel wallpaper.
This commit is contained in:
parent
941126ad69
commit
fd64718502
10 changed files with 420 additions and 164 deletions
|
@ -591,6 +591,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_settings_section_background" = "Chat background";
|
"lng_settings_section_background" = "Chat background";
|
||||||
"lng_settings_bg_from_gallery" = "Choose from gallery";
|
"lng_settings_bg_from_gallery" = "Choose from gallery";
|
||||||
"lng_settings_bg_from_file" = "Choose from file";
|
"lng_settings_bg_from_file" = "Choose from file";
|
||||||
|
"lng_settings_bg_remove" = "Remove wallpaper";
|
||||||
"lng_settings_bg_theme_edit" = "Edit theme";
|
"lng_settings_bg_theme_edit" = "Edit theme";
|
||||||
"lng_settings_bg_theme_create" = "Create new theme";
|
"lng_settings_bg_theme_create" = "Create new theme";
|
||||||
"lng_settings_bg_cloud_themes" = "Custom themes";
|
"lng_settings_bg_cloud_themes" = "Custom themes";
|
||||||
|
@ -838,6 +839,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_background_blur" = "Blurred";
|
"lng_background_blur" = "Blurred";
|
||||||
"lng_background_sure_delete" = "Are you sure you want to delete this background?";
|
"lng_background_sure_delete" = "Are you sure you want to delete this background?";
|
||||||
"lng_background_other_info" = "{user} will be able to apply this wallpaper";
|
"lng_background_other_info" = "{user} will be able to apply this wallpaper";
|
||||||
|
"lng_background_other_channel" = "All subscribers will see this wallpaper";
|
||||||
"lng_background_apply1" = "Apply the wallpaper in this chat.";
|
"lng_background_apply1" = "Apply the wallpaper in this chat.";
|
||||||
"lng_background_apply2" = "Enjoy the view.";
|
"lng_background_apply2" = "Enjoy the view.";
|
||||||
"lng_background_apply_button" = "Apply For This Chat";
|
"lng_background_apply_button" = "Apply For This Chat";
|
||||||
|
@ -846,6 +848,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_background_reset_default" = "Reset";
|
"lng_background_reset_default" = "Reset";
|
||||||
"lng_background_apply_me" = "Apply for me";
|
"lng_background_apply_me" = "Apply for me";
|
||||||
"lng_background_apply_both" = "Apply for me and {user}";
|
"lng_background_apply_both" = "Apply for me and {user}";
|
||||||
|
"lng_background_apply_channel" = "Apply For Channel";
|
||||||
|
|
||||||
"lng_download_path_ask" = "Ask download path for each file";
|
"lng_download_path_ask" = "Ask download path for each file";
|
||||||
"lng_download_path" = "Download path";
|
"lng_download_path" = "Download path";
|
||||||
|
|
|
@ -129,6 +129,8 @@ private:
|
||||||
int row) const;
|
int row) const;
|
||||||
void validatePaperThumbnail(const Paper &paper) const;
|
void validatePaperThumbnail(const Paper &paper) const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool forChannel() const;
|
||||||
|
|
||||||
const not_null<Main::Session*> _session;
|
const not_null<Main::Session*> _session;
|
||||||
PeerData * const _forPeer = nullptr;
|
PeerData * const _forPeer = nullptr;
|
||||||
|
|
||||||
|
@ -176,6 +178,23 @@ void BackgroundBox::prepare() {
|
||||||
st::infoIconMediaPhoto,
|
st::infoIconMediaPhoto,
|
||||||
st::infoSharedMediaButtonIconPosition);
|
st::infoSharedMediaButtonIconPosition);
|
||||||
|
|
||||||
|
if (forChannel() && _forPeer->wallPaper()) {
|
||||||
|
const auto remove = container->add(object_ptr<Ui::SettingsButton>(
|
||||||
|
container,
|
||||||
|
tr::lng_settings_bg_remove(),
|
||||||
|
st::infoBlockButton));
|
||||||
|
object_ptr<Info::Profile::FloatingIcon>(
|
||||||
|
remove,
|
||||||
|
st::infoIconDeleteRed,
|
||||||
|
st::infoSharedMediaButtonIconPosition);
|
||||||
|
|
||||||
|
remove->setClickedCallback([=] {
|
||||||
|
if (const auto resolved = _inner->resolveResetCustomPaper()) {
|
||||||
|
chosen(*resolved);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
button->setClickedCallback([=] {
|
button->setClickedCallback([=] {
|
||||||
chooseFromFile();
|
chooseFromFile();
|
||||||
});
|
});
|
||||||
|
@ -290,6 +309,23 @@ void BackgroundBox::chosen(const Data::WallPaper &paper) {
|
||||||
closeBox();
|
closeBox();
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
} else if (forChannel()) {
|
||||||
|
if (_forPeer->wallPaper() && _forPeer->wallPaper()->equals(paper)) {
|
||||||
|
closeBox();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto &themes = _forPeer->owner().cloudThemes();
|
||||||
|
for (const auto &theme : themes.chatThemes()) {
|
||||||
|
for (const auto &[type, themed] : theme.settings) {
|
||||||
|
if (themed.paper && themed.paper->equals(paper)) {
|
||||||
|
_controller->show(Box<BackgroundPreviewBox>(
|
||||||
|
_controller,
|
||||||
|
Data::WallPaper::FromEmojiId(theme.emoticon),
|
||||||
|
BackgroundPreviewArgs{ _forPeer }));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_controller->show(Box<BackgroundPreviewBox>(
|
_controller->show(Box<BackgroundPreviewBox>(
|
||||||
_controller,
|
_controller,
|
||||||
|
@ -316,6 +352,10 @@ void BackgroundBox::resetForPeer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BackgroundBox::forChannel() const {
|
||||||
|
return _forPeer && _forPeer->isChannel();
|
||||||
|
}
|
||||||
|
|
||||||
void BackgroundBox::removePaper(const Data::WallPaper &paper) {
|
void BackgroundBox::removePaper(const Data::WallPaper &paper) {
|
||||||
const auto session = &_controller->session();
|
const auto session = &_controller->session();
|
||||||
const auto remove = [=, weak = Ui::MakeWeak(this)](Fn<void()> &&close) {
|
const auto remove = [=, weak = Ui::MakeWeak(this)](Fn<void()> &&close) {
|
||||||
|
@ -345,9 +385,16 @@ BackgroundBox::Inner::Inner(
|
||||||
, _session(session)
|
, _session(session)
|
||||||
, _forPeer(forPeer)
|
, _forPeer(forPeer)
|
||||||
, _api(&_session->mtp())
|
, _api(&_session->mtp())
|
||||||
, _check(std::make_unique<Ui::RoundCheckbox>(st::overviewCheck, [=] { update(); })) {
|
, _check(
|
||||||
|
std::make_unique<Ui::RoundCheckbox>(
|
||||||
|
st::overviewCheck,
|
||||||
|
[=] { update(); })) {
|
||||||
_check->setChecked(true, anim::type::instant);
|
_check->setChecked(true, anim::type::instant);
|
||||||
resize(st::boxWideWidth, 2 * (st::backgroundSize.height() + st::backgroundPadding) + st::backgroundPadding);
|
resize(
|
||||||
|
st::boxWideWidth,
|
||||||
|
(2 * (st::backgroundSize.height() + st::backgroundPadding)
|
||||||
|
+ st::backgroundPadding));
|
||||||
|
|
||||||
Window::Theme::IsNightModeValue(
|
Window::Theme::IsNightModeValue(
|
||||||
) | rpl::start_with_next([=] {
|
) | rpl::start_with_next([=] {
|
||||||
updatePapers();
|
updatePapers();
|
||||||
|
@ -364,21 +411,31 @@ BackgroundBox::Inner::Inner(
|
||||||
_check->invalidateCache();
|
_check->invalidateCache();
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
using Update = Window::Theme::BackgroundUpdate;
|
if (forChannel()) {
|
||||||
Window::Theme::Background()->updates(
|
_session->data().cloudThemes().chatThemesUpdated(
|
||||||
) | rpl::start_with_next([=](const Update &update) {
|
) | rpl::start_with_next([=] {
|
||||||
if (update.type == Update::Type::New) {
|
updatePapers();
|
||||||
sortPapers();
|
}, lifetime());
|
||||||
requestPapers();
|
} else {
|
||||||
this->update();
|
using Update = Window::Theme::BackgroundUpdate;
|
||||||
}
|
Window::Theme::Background()->updates(
|
||||||
}, lifetime());
|
) | rpl::start_with_next([=](const Update &update) {
|
||||||
|
if (update.type == Update::Type::New) {
|
||||||
|
sortPapers();
|
||||||
|
requestPapers();
|
||||||
|
this->update();
|
||||||
|
}
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
setMouseTracking(true);
|
setMouseTracking(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundBox::Inner::requestPapers() {
|
void BackgroundBox::Inner::requestPapers() {
|
||||||
|
if (forChannel()) {
|
||||||
|
_session->data().cloudThemes().refreshChatThemes();
|
||||||
|
return;
|
||||||
|
}
|
||||||
_api.request(MTPaccount_GetWallPapers(
|
_api.request(MTPaccount_GetWallPapers(
|
||||||
MTP_long(_session->data().wallpapersHash())
|
MTP_long(_session->data().wallpapersHash())
|
||||||
)).done([=](const MTPaccount_WallPapers &result) {
|
)).done([=](const MTPaccount_WallPapers &result) {
|
||||||
|
@ -395,7 +452,7 @@ auto BackgroundBox::Inner::resolveResetCustomPaper() const
|
||||||
}
|
}
|
||||||
const auto nonCustom = Window::Theme::Background()->paper();
|
const auto nonCustom = Window::Theme::Background()->paper();
|
||||||
const auto themeEmoji = _forPeer->themeEmoji();
|
const auto themeEmoji = _forPeer->themeEmoji();
|
||||||
if (themeEmoji.isEmpty()) {
|
if (forChannel() || themeEmoji.isEmpty()) {
|
||||||
return nonCustom;
|
return nonCustom;
|
||||||
}
|
}
|
||||||
const auto &themes = _forPeer->owner().cloudThemes();
|
const auto &themes = _forPeer->owner().cloudThemes();
|
||||||
|
@ -443,6 +500,8 @@ void BackgroundBox::Inner::pushCustomPapers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundBox::Inner::sortPapers() {
|
void BackgroundBox::Inner::sortPapers() {
|
||||||
|
Expects(!forChannel());
|
||||||
|
|
||||||
const auto currentCustom = _forPeer ? _forPeer->wallPaper() : nullptr;
|
const auto currentCustom = _forPeer ? _forPeer->wallPaper() : nullptr;
|
||||||
_currentId = currentCustom
|
_currentId = currentCustom
|
||||||
? currentCustom->id()
|
? currentCustom->id()
|
||||||
|
@ -472,23 +531,60 @@ void BackgroundBox::Inner::sortPapers() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundBox::Inner::updatePapers() {
|
void BackgroundBox::Inner::updatePapers() {
|
||||||
if (_session->data().wallpapers().empty()) {
|
if (forChannel()) {
|
||||||
return;
|
if (_session->data().cloudThemes().chatThemes().empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (_session->data().wallpapers().empty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
_over = _overDown = Selection();
|
_over = _overDown = Selection();
|
||||||
|
|
||||||
_papers = _session->data().wallpapers(
|
const auto was = base::take(_papers);
|
||||||
) | ranges::views::filter([&](const Data::WallPaper &paper) {
|
if (forChannel()) {
|
||||||
return (!paper.isPattern() || !paper.backgroundColors().empty())
|
const auto now = _forPeer->wallPaper();
|
||||||
&& (!_forPeer
|
const auto &list = _session->data().cloudThemes().chatThemes();
|
||||||
|| (!Data::IsDefaultWallPaper(paper)
|
if (list.empty()) {
|
||||||
&& (Data::IsCloudWallPaper(paper)
|
return;
|
||||||
|| Data::IsCustomWallPaper(paper))));
|
}
|
||||||
}) | ranges::views::transform([](const Data::WallPaper &paper) {
|
using Type = Data::CloudThemeType;
|
||||||
return Paper{ paper };
|
const auto type = Window::Theme::IsNightMode()
|
||||||
}) | ranges::to_vector;
|
? Type::Dark
|
||||||
pushCustomPapers();
|
: Type::Light;
|
||||||
sortPapers();
|
_papers.reserve(list.size() + 1);
|
||||||
|
const auto nowEmojiId = now ? now->emojiId() : QString();
|
||||||
|
if (!now || !now->emojiId().isEmpty()) {
|
||||||
|
_papers.push_back({ Window::Theme::Background()->paper() });
|
||||||
|
_currentId = _papers.back().data.id();
|
||||||
|
} else {
|
||||||
|
_papers.push_back({ *now });
|
||||||
|
_currentId = now->id();
|
||||||
|
}
|
||||||
|
for (const auto &theme : list) {
|
||||||
|
const auto i = theme.settings.find(type);
|
||||||
|
if (i != end(theme.settings) && i->second.paper) {
|
||||||
|
_papers.push_back({ *i->second.paper });
|
||||||
|
if (nowEmojiId == theme.emoticon) {
|
||||||
|
_currentId = _papers.back().data.id();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_papers = _session->data().wallpapers(
|
||||||
|
) | ranges::views::filter([&](const Data::WallPaper &paper) {
|
||||||
|
return (!paper.isPattern() || !paper.backgroundColors().empty())
|
||||||
|
&& (!_forPeer
|
||||||
|
|| (!Data::IsDefaultWallPaper(paper)
|
||||||
|
&& (Data::IsCloudWallPaper(paper)
|
||||||
|
|| Data::IsCustomWallPaper(paper))));
|
||||||
|
}) | ranges::views::transform([](const Data::WallPaper &paper) {
|
||||||
|
return Paper{ paper };
|
||||||
|
}) | ranges::to_vector;
|
||||||
|
pushCustomPapers();
|
||||||
|
sortPapers();
|
||||||
|
}
|
||||||
resizeToContentAndPreload();
|
resizeToContentAndPreload();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,6 +683,10 @@ void BackgroundBox::Inner::validatePaperThumbnail(
|
||||||
paper.thumbnail.setDevicePixelRatio(cRetinaFactor());
|
paper.thumbnail.setDevicePixelRatio(cRetinaFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BackgroundBox::Inner::forChannel() const {
|
||||||
|
return _forPeer && _forPeer->isChannel();
|
||||||
|
}
|
||||||
|
|
||||||
void BackgroundBox::Inner::paintPaper(
|
void BackgroundBox::Inner::paintPaper(
|
||||||
QPainter &p,
|
QPainter &p,
|
||||||
const Paper &paper,
|
const Paper &paper,
|
||||||
|
@ -604,7 +704,8 @@ void BackgroundBox::Inner::paintPaper(
|
||||||
const auto checkLeft = x + st::backgroundSize.width() - st::overviewCheckSkip - st::overviewCheck.size;
|
const auto checkLeft = x + st::backgroundSize.width() - st::overviewCheckSkip - st::overviewCheck.size;
|
||||||
const auto checkTop = y + st::backgroundSize.height() - st::overviewCheckSkip - st::overviewCheck.size;
|
const auto checkTop = y + st::backgroundSize.height() - st::overviewCheckSkip - st::overviewCheck.size;
|
||||||
_check->paint(p, checkLeft, checkTop, width());
|
_check->paint(p, checkLeft, checkTop, width());
|
||||||
} else if (Data::IsCloudWallPaper(paper.data)
|
} else if (!forChannel()
|
||||||
|
&& Data::IsCloudWallPaper(paper.data)
|
||||||
&& !Data::IsDefaultWallPaper(paper.data)
|
&& !Data::IsDefaultWallPaper(paper.data)
|
||||||
&& !Data::IsLegacy2DefaultWallPaper(paper.data)
|
&& !Data::IsLegacy2DefaultWallPaper(paper.data)
|
||||||
&& !Data::IsLegacy3DefaultWallPaper(paper.data)
|
&& !Data::IsLegacy3DefaultWallPaper(paper.data)
|
||||||
|
@ -642,7 +743,8 @@ void BackgroundBox::Inner::mouseMoveEvent(QMouseEvent *e) {
|
||||||
- st::stickerPanDeleteIconBg.width();
|
- st::stickerPanDeleteIconBg.width();
|
||||||
const auto deleteBottom = row * (height + skip) + skip
|
const auto deleteBottom = row * (height + skip) + skip
|
||||||
+ st::stickerPanDeleteIconBg.height();
|
+ st::stickerPanDeleteIconBg.height();
|
||||||
const auto inDelete = (x >= deleteLeft)
|
const auto inDelete = !forChannel()
|
||||||
|
&& (x >= deleteLeft)
|
||||||
&& (y < deleteBottom)
|
&& (y < deleteBottom)
|
||||||
&& Data::IsCloudWallPaper(data)
|
&& Data::IsCloudWallPaper(data)
|
||||||
&& !Data::IsDefaultWallPaper(data)
|
&& !Data::IsDefaultWallPaper(data)
|
||||||
|
|
|
@ -38,6 +38,7 @@ private:
|
||||||
const Data::WallPaper &paper) const;
|
const Data::WallPaper &paper) const;
|
||||||
void removePaper(const Data::WallPaper &paper);
|
void removePaper(const Data::WallPaper &paper);
|
||||||
void resetForPeer();
|
void resetForPeer();
|
||||||
|
[[nodiscard]] bool forChannel() const;
|
||||||
|
|
||||||
void chooseFromFile();
|
void chooseFromFile();
|
||||||
|
|
||||||
|
|
|
@ -8,11 +8,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "boxes/background_preview_box.h"
|
#include "boxes/background_preview_box.h"
|
||||||
|
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
|
#include "boxes/peers/edit_peer_color_box.h"
|
||||||
#include "boxes/premium_preview_box.h"
|
#include "boxes/premium_preview_box.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "mainwidget.h"
|
#include "mainwidget.h"
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
#include "ui/boxes/confirm_box.h"
|
#include "ui/boxes/confirm_box.h"
|
||||||
|
#include "ui/boxes/boost_box.h"
|
||||||
#include "ui/controls/chat_service_checkbox.h"
|
#include "ui/controls/chat_service_checkbox.h"
|
||||||
#include "ui/chat/chat_theme.h"
|
#include "ui/chat/chat_theme.h"
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
|
@ -29,6 +31,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history_item.h"
|
#include "history/history_item.h"
|
||||||
#include "history/history_item_helpers.h"
|
#include "history/history_item_helpers.h"
|
||||||
#include "history/view/history_view_message.h"
|
#include "history/view/history_view_message.h"
|
||||||
|
#include "main/main_account.h"
|
||||||
|
#include "main/main_app_config.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
|
@ -159,6 +163,25 @@ constexpr auto kDefaultDimming = 50;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] Data::WallPaper Resolve(
|
||||||
|
not_null<Main::Session*> session,
|
||||||
|
const Data::WallPaper &paper,
|
||||||
|
bool dark) {
|
||||||
|
if (paper.emojiId().isEmpty()) {
|
||||||
|
return paper;
|
||||||
|
}
|
||||||
|
const auto &themes = session->data().cloudThemes();
|
||||||
|
if (const auto theme = themes.themeForEmoji(paper.emojiId())) {
|
||||||
|
using Type = Data::CloudThemeType;
|
||||||
|
const auto type = dark ? Type::Dark : Type::Light;
|
||||||
|
const auto i = theme->settings.find(type);
|
||||||
|
if (i != end(theme->settings) && i->second.paper) {
|
||||||
|
return *i->second.paper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return paper;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct BackgroundPreviewBox::OverridenStyle {
|
struct BackgroundPreviewBox::OverridenStyle {
|
||||||
|
@ -196,15 +219,17 @@ BackgroundPreviewBox::BackgroundPreviewBox(
|
||||||
? tr::lng_background_apply2(tr::now)
|
? tr::lng_background_apply2(tr::now)
|
||||||
: tr::lng_background_text2(tr::now)),
|
: tr::lng_background_text2(tr::now)),
|
||||||
true))
|
true))
|
||||||
, _paper(paper)
|
, _paperEmojiId(paper.emojiId())
|
||||||
|
, _paper(
|
||||||
|
Resolve(&controller->session(), paper, Window::Theme::IsNightMode()))
|
||||||
, _media(_paper.document() ? _paper.document()->createMediaView() : nullptr)
|
, _media(_paper.document() ? _paper.document()->createMediaView() : nullptr)
|
||||||
, _radial([=](crl::time now) { radialAnimationCallback(now); })
|
, _radial([=](crl::time now) { radialAnimationCallback(now); })
|
||||||
, _appNightMode(Window::Theme::IsNightModeValue())
|
, _appNightMode(Window::Theme::IsNightModeValue())
|
||||||
, _boxDarkMode(_appNightMode.current())
|
, _boxDarkMode(_appNightMode.current())
|
||||||
, _dimmingIntensity(std::clamp(paper.patternIntensity(), 0, 100))
|
, _dimmingIntensity(std::clamp(_paper.patternIntensity(), 0, 100))
|
||||||
, _dimmed(_forPeer
|
, _dimmed(_forPeer
|
||||||
&& (paper.document() || paper.localThumbnail())
|
&& (_paper.document() || _paper.localThumbnail())
|
||||||
&& !paper.isPattern()) {
|
&& !_paper.isPattern()) {
|
||||||
if (_media) {
|
if (_media) {
|
||||||
_media->thumbnailWanted(_paper.fileOrigin());
|
_media->thumbnailWanted(_paper.fileOrigin());
|
||||||
}
|
}
|
||||||
|
@ -244,7 +269,36 @@ BackgroundPreviewBox::BackgroundPreviewBox(
|
||||||
|
|
||||||
BackgroundPreviewBox::~BackgroundPreviewBox() = default;
|
BackgroundPreviewBox::~BackgroundPreviewBox() = default;
|
||||||
|
|
||||||
|
void BackgroundPreviewBox::recreate(bool dark) {
|
||||||
|
_paper = Resolve(
|
||||||
|
&_controller->session(),
|
||||||
|
Data::WallPaper::FromEmojiId(_paperEmojiId),
|
||||||
|
dark);
|
||||||
|
_media = _paper.document()
|
||||||
|
? _paper.document()->createMediaView()
|
||||||
|
: nullptr;
|
||||||
|
if (_media) {
|
||||||
|
_media->thumbnailWanted(_paper.fileOrigin());
|
||||||
|
}
|
||||||
|
_full = QImage();
|
||||||
|
_generated = _scaled = _blurred = _fadeOutThumbnail = QPixmap();
|
||||||
|
_generating = {};
|
||||||
|
generateBackground();
|
||||||
|
_paper.loadDocument();
|
||||||
|
if (const auto document = _paper.document()) {
|
||||||
|
if (document->loading()) {
|
||||||
|
_radial.start(_media->progress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
checkLoadedDocument();
|
||||||
|
updateServiceBg(_paper.backgroundColors());
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
|
||||||
void BackgroundPreviewBox::applyDarkMode(bool dark) {
|
void BackgroundPreviewBox::applyDarkMode(bool dark) {
|
||||||
|
if (!_paperEmojiId.isEmpty()) {
|
||||||
|
recreate(dark);
|
||||||
|
}
|
||||||
const auto equals = (dark == Window::Theme::IsNightMode());
|
const auto equals = (dark == Window::Theme::IsNightMode());
|
||||||
const auto &palette = (dark ? _darkPalette : _lightPalette);
|
const auto &palette = (dark ? _darkPalette : _lightPalette);
|
||||||
if (!equals && !palette) {
|
if (!equals && !palette) {
|
||||||
|
@ -410,6 +464,10 @@ auto BackgroundPreviewBox::prepareOverridenStyle(bool dark)
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BackgroundPreviewBox::forChannel() const {
|
||||||
|
return _forPeer && _forPeer->isChannel();
|
||||||
|
}
|
||||||
|
|
||||||
void BackgroundPreviewBox::generateBackground() {
|
void BackgroundPreviewBox::generateBackground() {
|
||||||
if (_paper.backgroundColors().empty()) {
|
if (_paper.backgroundColors().empty()) {
|
||||||
return;
|
return;
|
||||||
|
@ -435,7 +493,9 @@ void BackgroundPreviewBox::resetTitle() {
|
||||||
|
|
||||||
void BackgroundPreviewBox::rebuildButtons(bool dark) {
|
void BackgroundPreviewBox::rebuildButtons(bool dark) {
|
||||||
clearButtons();
|
clearButtons();
|
||||||
addButton(_forPeer
|
addButton(forChannel()
|
||||||
|
? tr::lng_background_apply_channel()
|
||||||
|
: _forPeer
|
||||||
? tr::lng_background_apply_button()
|
? tr::lng_background_apply_button()
|
||||||
: tr::lng_settings_apply(), [=] { apply(); });
|
: tr::lng_settings_apply(), [=] { apply(); });
|
||||||
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
addButton(tr::lng_cancel(), [=] { closeBox(); });
|
||||||
|
@ -624,6 +684,36 @@ void BackgroundPreviewBox::setExistingForPeer(
|
||||||
_controller->finishChatThemeEdit(_forPeer);
|
_controller->finishChatThemeEdit(_forPeer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BackgroundPreviewBox::checkLevelForChannel() {
|
||||||
|
Expects(forChannel());
|
||||||
|
|
||||||
|
const auto show = _controller->uiShow();
|
||||||
|
_forPeerLevelCheck = true;
|
||||||
|
const auto weak = Ui::MakeWeak(this);
|
||||||
|
CheckBoostLevel(show, _forPeer, [=](int level) {
|
||||||
|
if (!weak) {
|
||||||
|
return std::optional<Ui::AskBoostReason>();
|
||||||
|
}
|
||||||
|
const auto appConfig = &_forPeer->session().account().appConfig();
|
||||||
|
const auto defaultRequired = appConfig->get<int>(
|
||||||
|
"channel_wallpaper_level_min",
|
||||||
|
9);
|
||||||
|
const auto customRequired = appConfig->get<int>(
|
||||||
|
"channel_custom_wallpaper_level_min",
|
||||||
|
10);
|
||||||
|
const auto required = _paperEmojiId.isEmpty()
|
||||||
|
? customRequired
|
||||||
|
: defaultRequired;
|
||||||
|
if (level >= required) {
|
||||||
|
applyForPeer(false);
|
||||||
|
return std::optional<Ui::AskBoostReason>();
|
||||||
|
}
|
||||||
|
return std::make_optional(Ui::AskBoostReason{
|
||||||
|
Ui::AskBoostWallpaper{ required }
|
||||||
|
});
|
||||||
|
}, [=] { _forPeerLevelCheck = false; });
|
||||||
|
}
|
||||||
|
|
||||||
void BackgroundPreviewBox::applyForPeer() {
|
void BackgroundPreviewBox::applyForPeer() {
|
||||||
Expects(_forPeer != nullptr);
|
Expects(_forPeer != nullptr);
|
||||||
|
|
||||||
|
@ -636,105 +726,110 @@ void BackgroundPreviewBox::applyForPeer() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_fromMessageId && _forPeer->session().premiumPossible()) {
|
if (forChannel()) {
|
||||||
if (_forBothOverlay) {
|
checkLevelForChannel();
|
||||||
return;
|
return;
|
||||||
}
|
} else if (_fromMessageId || !_forPeer->session().premiumPossible()) {
|
||||||
const auto size = this->size() * style::DevicePixelRatio();
|
|
||||||
const auto bg = Images::DitherImage(
|
|
||||||
Images::BlurLargeImage(
|
|
||||||
Ui::GrabWidgetToImage(this).scaled(
|
|
||||||
size / style::ConvertScale(4),
|
|
||||||
Qt::IgnoreAspectRatio,
|
|
||||||
Qt::SmoothTransformation),
|
|
||||||
24).scaled(
|
|
||||||
size,
|
|
||||||
Qt::IgnoreAspectRatio,
|
|
||||||
Qt::SmoothTransformation));
|
|
||||||
|
|
||||||
_forBothOverlay = std::make_unique<Ui::FadeWrap<>>(
|
|
||||||
this,
|
|
||||||
object_ptr<Ui::RpWidget>(this));
|
|
||||||
const auto overlay = _forBothOverlay->entity();
|
|
||||||
|
|
||||||
sizeValue() | rpl::start_with_next([=](QSize size) {
|
|
||||||
_forBothOverlay->setGeometry({ QPoint(), size });
|
|
||||||
overlay->setGeometry({ QPoint(), size });
|
|
||||||
}, _forBothOverlay->lifetime());
|
|
||||||
|
|
||||||
overlay->paintRequest(
|
|
||||||
) | rpl::start_with_next([=](QRect clip) {
|
|
||||||
auto p = QPainter(overlay);
|
|
||||||
p.drawImage(0, 0, bg);
|
|
||||||
p.fillRect(clip, QColor(0, 0, 0, 64));
|
|
||||||
}, overlay->lifetime());
|
|
||||||
|
|
||||||
using namespace Ui;
|
|
||||||
const auto forMe = CreateChild<RoundButton>(
|
|
||||||
overlay,
|
|
||||||
tr::lng_background_apply_me(),
|
|
||||||
st::backgroundConfirm);
|
|
||||||
forMe->setClickedCallback([=] {
|
|
||||||
applyForPeer(false);
|
|
||||||
});
|
|
||||||
using namespace rpl::mappers;
|
|
||||||
const auto forBoth = ::Settings::CreateLockedButton(
|
|
||||||
overlay,
|
|
||||||
tr::lng_background_apply_both(
|
|
||||||
lt_user,
|
|
||||||
rpl::single(_forPeer->shortName())),
|
|
||||||
st::backgroundConfirm,
|
|
||||||
Data::AmPremiumValue(&_forPeer->session()) | rpl::map(!_1));
|
|
||||||
forBoth->setClickedCallback([=] {
|
|
||||||
if (_forPeer->session().premium()) {
|
|
||||||
applyForPeer(true);
|
|
||||||
} else {
|
|
||||||
ShowPremiumPreviewBox(
|
|
||||||
_controller->uiShow(),
|
|
||||||
PremiumPreview::Wallpapers);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
const auto cancel = CreateChild<RoundButton>(
|
|
||||||
overlay,
|
|
||||||
tr::lng_cancel(),
|
|
||||||
st::backgroundConfirmCancel);
|
|
||||||
cancel->setClickedCallback([=] {
|
|
||||||
const auto raw = _forBothOverlay.release();
|
|
||||||
raw->shownValue() | rpl::filter(
|
|
||||||
!rpl::mappers::_1
|
|
||||||
) | rpl::take(1) | rpl::start_with_next(crl::guard(raw, [=] {
|
|
||||||
delete raw;
|
|
||||||
}), raw->lifetime());
|
|
||||||
raw->toggle(false, anim::type::normal);
|
|
||||||
});
|
|
||||||
forMe->setTextTransform(RoundButton::TextTransform::NoTransform);
|
|
||||||
forBoth->setTextTransform(RoundButton::TextTransform::NoTransform);
|
|
||||||
cancel->setTextTransform(RoundButton::TextTransform::NoTransform);
|
|
||||||
|
|
||||||
overlay->sizeValue(
|
|
||||||
) | rpl::start_with_next([=](QSize size) {
|
|
||||||
const auto padding = st::backgroundConfirmPadding;
|
|
||||||
const auto width = size.width()
|
|
||||||
- padding.left()
|
|
||||||
- padding.right();
|
|
||||||
const auto height = cancel->height();
|
|
||||||
auto top = size.height() - padding.bottom() - height;
|
|
||||||
cancel->setGeometry(padding.left(), top, width, height);
|
|
||||||
top -= height + padding.top();
|
|
||||||
forBoth->setGeometry(padding.left(), top, width, height);
|
|
||||||
top -= height + padding.top();
|
|
||||||
forMe->setGeometry(padding.left(), top, width, height);
|
|
||||||
}, _forBothOverlay->lifetime());
|
|
||||||
|
|
||||||
_forBothOverlay->hide(anim::type::instant);
|
|
||||||
_forBothOverlay->show(anim::type::normal);
|
|
||||||
} else {
|
|
||||||
applyForPeer(false);
|
applyForPeer(false);
|
||||||
|
return;
|
||||||
|
} else if (_forBothOverlay) {
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
const auto size = this->size() * style::DevicePixelRatio();
|
||||||
|
const auto bg = Images::DitherImage(
|
||||||
|
Images::BlurLargeImage(
|
||||||
|
Ui::GrabWidgetToImage(this).scaled(
|
||||||
|
size / style::ConvertScale(4),
|
||||||
|
Qt::IgnoreAspectRatio,
|
||||||
|
Qt::SmoothTransformation),
|
||||||
|
24).scaled(
|
||||||
|
size,
|
||||||
|
Qt::IgnoreAspectRatio,
|
||||||
|
Qt::SmoothTransformation));
|
||||||
|
|
||||||
|
_forBothOverlay = std::make_unique<Ui::FadeWrap<>>(
|
||||||
|
this,
|
||||||
|
object_ptr<Ui::RpWidget>(this));
|
||||||
|
const auto overlay = _forBothOverlay->entity();
|
||||||
|
|
||||||
|
sizeValue() | rpl::start_with_next([=](QSize size) {
|
||||||
|
_forBothOverlay->setGeometry({ QPoint(), size });
|
||||||
|
overlay->setGeometry({ QPoint(), size });
|
||||||
|
}, _forBothOverlay->lifetime());
|
||||||
|
|
||||||
|
overlay->paintRequest(
|
||||||
|
) | rpl::start_with_next([=](QRect clip) {
|
||||||
|
auto p = QPainter(overlay);
|
||||||
|
p.drawImage(0, 0, bg);
|
||||||
|
p.fillRect(clip, QColor(0, 0, 0, 64));
|
||||||
|
}, overlay->lifetime());
|
||||||
|
|
||||||
|
using namespace Ui;
|
||||||
|
const auto forMe = CreateChild<RoundButton>(
|
||||||
|
overlay,
|
||||||
|
tr::lng_background_apply_me(),
|
||||||
|
st::backgroundConfirm);
|
||||||
|
forMe->setClickedCallback([=] {
|
||||||
|
applyForPeer(false);
|
||||||
|
});
|
||||||
|
using namespace rpl::mappers;
|
||||||
|
const auto forBoth = ::Settings::CreateLockedButton(
|
||||||
|
overlay,
|
||||||
|
tr::lng_background_apply_both(
|
||||||
|
lt_user,
|
||||||
|
rpl::single(_forPeer->shortName())),
|
||||||
|
st::backgroundConfirm,
|
||||||
|
Data::AmPremiumValue(&_forPeer->session()) | rpl::map(!_1));
|
||||||
|
forBoth->setClickedCallback([=] {
|
||||||
|
if (_forPeer->session().premium()) {
|
||||||
|
applyForPeer(true);
|
||||||
|
} else {
|
||||||
|
ShowPremiumPreviewBox(
|
||||||
|
_controller->uiShow(),
|
||||||
|
PremiumPreview::Wallpapers);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const auto cancel = CreateChild<RoundButton>(
|
||||||
|
overlay,
|
||||||
|
tr::lng_cancel(),
|
||||||
|
st::backgroundConfirmCancel);
|
||||||
|
cancel->setClickedCallback([=] {
|
||||||
|
const auto raw = _forBothOverlay.release();
|
||||||
|
raw->shownValue() | rpl::filter(
|
||||||
|
!rpl::mappers::_1
|
||||||
|
) | rpl::take(1) | rpl::start_with_next(crl::guard(raw, [=] {
|
||||||
|
delete raw;
|
||||||
|
}), raw->lifetime());
|
||||||
|
raw->toggle(false, anim::type::normal);
|
||||||
|
});
|
||||||
|
forMe->setTextTransform(RoundButton::TextTransform::NoTransform);
|
||||||
|
forBoth->setTextTransform(RoundButton::TextTransform::NoTransform);
|
||||||
|
cancel->setTextTransform(RoundButton::TextTransform::NoTransform);
|
||||||
|
|
||||||
|
overlay->sizeValue(
|
||||||
|
) | rpl::start_with_next([=](QSize size) {
|
||||||
|
const auto padding = st::backgroundConfirmPadding;
|
||||||
|
const auto width = size.width()
|
||||||
|
- padding.left()
|
||||||
|
- padding.right();
|
||||||
|
const auto height = cancel->height();
|
||||||
|
auto top = size.height() - padding.bottom() - height;
|
||||||
|
cancel->setGeometry(padding.left(), top, width, height);
|
||||||
|
top -= height + padding.top();
|
||||||
|
forBoth->setGeometry(padding.left(), top, width, height);
|
||||||
|
top -= height + padding.top();
|
||||||
|
forMe->setGeometry(padding.left(), top, width, height);
|
||||||
|
}, _forBothOverlay->lifetime());
|
||||||
|
|
||||||
|
_forBothOverlay->hide(anim::type::instant);
|
||||||
|
_forBothOverlay->show(anim::type::normal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundPreviewBox::applyForPeer(bool both) {
|
void BackgroundPreviewBox::applyForPeer(bool both) {
|
||||||
if (Data::IsCustomWallPaper(_paper)) {
|
using namespace Data;
|
||||||
|
if (forChannel() && !_paperEmojiId.isEmpty()) {
|
||||||
|
setExistingForPeer(WallPaper::FromEmojiId(_paperEmojiId), both);
|
||||||
|
} else if (IsCustomWallPaper(_paper)) {
|
||||||
uploadForPeer(both);
|
uploadForPeer(both);
|
||||||
} else {
|
} else {
|
||||||
setExistingForPeer(_paper, both);
|
setExistingForPeer(_paper, both);
|
||||||
|
@ -855,7 +950,7 @@ int BackgroundPreviewBox::textsTop() const {
|
||||||
- st::historyPaddingBottom
|
- st::historyPaddingBottom
|
||||||
- (_service ? _service->height() : 0)
|
- (_service ? _service->height() : 0)
|
||||||
- _text1->height()
|
- _text1->height()
|
||||||
- _text2->height();
|
- (forChannel() ? _text2->height() : 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect BackgroundPreviewBox::radialRect() const {
|
QRect BackgroundPreviewBox::radialRect() const {
|
||||||
|
@ -885,10 +980,11 @@ void BackgroundPreviewBox::paintTexts(Painter &p, crl::time ms) {
|
||||||
context.outbg = _text1->hasOutLayout();
|
context.outbg = _text1->hasOutLayout();
|
||||||
_text1->draw(p, context);
|
_text1->draw(p, context);
|
||||||
p.translate(0, height1);
|
p.translate(0, height1);
|
||||||
|
if (!forChannel()) {
|
||||||
context.outbg = _text2->hasOutLayout();
|
context.outbg = _text2->hasOutLayout();
|
||||||
_text2->draw(p, context);
|
_text2->draw(p, context);
|
||||||
p.translate(0, height2);
|
p.translate(0, height2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BackgroundPreviewBox::radialAnimationCallback(crl::time now) {
|
void BackgroundPreviewBox::radialAnimationCallback(crl::time now) {
|
||||||
|
@ -988,7 +1084,9 @@ void BackgroundPreviewBox::updateServiceBg(const std::vector<QColor> &bg) {
|
||||||
_service = GenerateServiceItem(
|
_service = GenerateServiceItem(
|
||||||
delegate(),
|
delegate(),
|
||||||
_serviceHistory,
|
_serviceHistory,
|
||||||
((_forPeer && !_fromMessageId)
|
(forChannel()
|
||||||
|
? tr::lng_background_other_channel(tr::now)
|
||||||
|
: (_forPeer && !_fromMessageId)
|
||||||
? tr::lng_background_other_info(
|
? tr::lng_background_other_info(
|
||||||
tr::now,
|
tr::now,
|
||||||
lt_user,
|
lt_user,
|
||||||
|
|
|
@ -94,18 +94,24 @@ private:
|
||||||
void applyDarkMode(bool dark);
|
void applyDarkMode(bool dark);
|
||||||
[[nodiscard]] OverridenStyle prepareOverridenStyle(bool dark);
|
[[nodiscard]] OverridenStyle prepareOverridenStyle(bool dark);
|
||||||
|
|
||||||
|
[[nodiscard]] bool forChannel() const;
|
||||||
|
void checkLevelForChannel();
|
||||||
|
|
||||||
|
void recreate(bool dark);
|
||||||
void resetTitle();
|
void resetTitle();
|
||||||
void rebuildButtons(bool dark);
|
void rebuildButtons(bool dark);
|
||||||
void createDimmingSlider(bool dark);
|
void createDimmingSlider(bool dark);
|
||||||
|
|
||||||
const not_null<Window::SessionController*> _controller;
|
const not_null<Window::SessionController*> _controller;
|
||||||
PeerData * const _forPeer = nullptr;
|
PeerData * const _forPeer = nullptr;
|
||||||
|
bool _forPeerLevelCheck = false;
|
||||||
FullMsgId _fromMessageId;
|
FullMsgId _fromMessageId;
|
||||||
std::unique_ptr<Ui::ChatStyle> _chatStyle;
|
std::unique_ptr<Ui::ChatStyle> _chatStyle;
|
||||||
const not_null<History*> _serviceHistory;
|
const not_null<History*> _serviceHistory;
|
||||||
AdminLog::OwnedItem _service;
|
AdminLog::OwnedItem _service;
|
||||||
AdminLog::OwnedItem _text1;
|
AdminLog::OwnedItem _text1;
|
||||||
AdminLog::OwnedItem _text2;
|
AdminLog::OwnedItem _text2;
|
||||||
|
QString _paperEmojiId;
|
||||||
Data::WallPaper _paper;
|
Data::WallPaper _paper;
|
||||||
std::shared_ptr<Data::DocumentMedia> _media;
|
std::shared_ptr<Data::DocumentMedia> _media;
|
||||||
QImage _full;
|
QImage _full;
|
||||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "api/api_peer_photo.h"
|
#include "api/api_peer_photo.h"
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "boxes/peers/replace_boost_box.h"
|
#include "boxes/peers/replace_boost_box.h"
|
||||||
|
#include "boxes/background_box.h"
|
||||||
#include "chat_helpers/compose/compose_show.h"
|
#include "chat_helpers/compose/compose_show.h"
|
||||||
#include "data/data_changes.h"
|
#include "data/data_changes.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
|
@ -524,13 +525,7 @@ void Apply(
|
||||||
Set(show, peer, values);
|
Set(show, peer, values);
|
||||||
close();
|
close();
|
||||||
} else {
|
} else {
|
||||||
session->api().request(MTPpremium_GetBoostsStatus(
|
CheckBoostLevel(show, peer, [=](int level) {
|
||||||
peer->input
|
|
||||||
)).done([=](const MTPpremium_BoostsStatus &result) {
|
|
||||||
const auto &data = result.data();
|
|
||||||
if (const auto channel = peer->asChannel()) {
|
|
||||||
channel->updateLevelHint(data.vlevel().v);
|
|
||||||
}
|
|
||||||
const auto peerColors = &peer->session().api().peerColors();
|
const auto peerColors = &peer->session().api().peerColors();
|
||||||
const auto colorRequired = peerColors->requiredLevelFor(
|
const auto colorRequired = peerColors->requiredLevelFor(
|
||||||
peer->id,
|
peer->id,
|
||||||
|
@ -551,38 +546,21 @@ void Apply(
|
||||||
iconRequired,
|
iconRequired,
|
||||||
statusRequired,
|
statusRequired,
|
||||||
});
|
});
|
||||||
const auto current = data.vlevel().v;
|
if (level >= required) {
|
||||||
if (current >= required) {
|
|
||||||
Set(show, peer, values);
|
Set(show, peer, values);
|
||||||
close();
|
close();
|
||||||
return;
|
return std::optional<Ui::AskBoostReason>();
|
||||||
}
|
}
|
||||||
const auto openStatistics = [=] {
|
|
||||||
if (const auto controller = show->resolveWindow(
|
|
||||||
ChatHelpers::WindowUsage::PremiumPromo)) {
|
|
||||||
controller->showSection(Info::Boosts::Make(peer));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
auto counters = ParseBoostCounters(result);
|
|
||||||
counters.mine = 0; // Don't show current level as just-reached.
|
|
||||||
const auto reason = [&]() -> Ui::AskBoostReason {
|
const auto reason = [&]() -> Ui::AskBoostReason {
|
||||||
if (current < statusRequired) {
|
if (level < statusRequired) {
|
||||||
return { Ui::AskBoostEmojiStatus{ statusRequired } };
|
return { Ui::AskBoostEmojiStatus{ statusRequired } };
|
||||||
} else if (current < iconRequired) {
|
} else if (level < iconRequired) {
|
||||||
return { Ui::AskBoostChannelColor{ iconRequired } };
|
return { Ui::AskBoostChannelColor{ iconRequired } };
|
||||||
}
|
}
|
||||||
return { Ui::AskBoostChannelColor{ colorRequired } };
|
return { Ui::AskBoostChannelColor{ colorRequired } };
|
||||||
}();
|
}();
|
||||||
show->show(Box(Ui::AskBoostBox, Ui::AskBoostBoxData{
|
return std::make_optional(reason);
|
||||||
.link = qs(data.vboost_url()),
|
}, cancel);
|
||||||
.boost = counters,
|
|
||||||
.reason = reason,
|
|
||||||
}, openStatistics, nullptr));
|
|
||||||
cancel();
|
|
||||||
}).fail([=](const MTP::Error &error) {
|
|
||||||
show->showToast(error.type());
|
|
||||||
cancel();
|
|
||||||
}).send();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -978,6 +956,23 @@ void EditPeerColorBox(
|
||||||
: tr::lng_settings_color_emoji_about_channel());
|
: tr::lng_settings_color_emoji_about_channel());
|
||||||
|
|
||||||
if (const auto channel = peer->asChannel()) {
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
Ui::AddSkip(container, st::settingsColorSampleSkip);
|
||||||
|
container->add(object_ptr<Ui::SettingsButton>(
|
||||||
|
container,
|
||||||
|
tr::lng_edit_channel_wallpaper(),
|
||||||
|
st::settingsButtonNoIcon)
|
||||||
|
)->setClickedCallback([=] {
|
||||||
|
const auto usage = ChatHelpers::WindowUsage::PremiumPromo;
|
||||||
|
if (const auto strong = show->resolveWindow(usage)) {
|
||||||
|
show->show(Box<BackgroundBox>(strong, channel));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Ui::AddSkip(container, st::settingsColorSampleSkip);
|
||||||
|
Ui::AddDividerText(
|
||||||
|
container,
|
||||||
|
tr::lng_edit_channel_wallpaper_about());
|
||||||
|
|
||||||
// Preload exceptions list.
|
// Preload exceptions list.
|
||||||
const auto peerPhoto = &channel->session().api().peerPhoto();
|
const auto peerPhoto = &channel->session().api().peerPhoto();
|
||||||
[[maybe_unused]] auto list = peerPhoto->emojiListValue(
|
[[maybe_unused]] auto list = peerPhoto->emojiListValue(
|
||||||
|
@ -1110,3 +1105,39 @@ void AddPeerColorButton(
|
||||||
show->show(Box(EditPeerColorBox, show, peer, style, theme));
|
show->show(Box(EditPeerColorBox, show, peer, style, theme));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckBoostLevel(
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Fn<std::optional<Ui::AskBoostReason>(int level)> askMore,
|
||||||
|
Fn<void()> cancel) {
|
||||||
|
peer->session().api().request(MTPpremium_GetBoostsStatus(
|
||||||
|
peer->input
|
||||||
|
)).done([=](const MTPpremium_BoostsStatus &result) {
|
||||||
|
const auto &data = result.data();
|
||||||
|
if (const auto channel = peer->asChannel()) {
|
||||||
|
channel->updateLevelHint(data.vlevel().v);
|
||||||
|
}
|
||||||
|
const auto reason = askMore(data.vlevel().v);
|
||||||
|
if (!reason) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto openStatistics = [=] {
|
||||||
|
if (const auto controller = show->resolveWindow(
|
||||||
|
ChatHelpers::WindowUsage::PremiumPromo)) {
|
||||||
|
controller->showSection(Info::Boosts::Make(peer));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
auto counters = ParseBoostCounters(result);
|
||||||
|
counters.mine = 0; // Don't show current level as just-reached.
|
||||||
|
show->show(Box(Ui::AskBoostBox, Ui::AskBoostBoxData{
|
||||||
|
.link = qs(data.vboost_url()),
|
||||||
|
.boost = counters,
|
||||||
|
.reason = *reason,
|
||||||
|
}, openStatistics, nullptr));
|
||||||
|
cancel();
|
||||||
|
}).fail([=](const MTP::Error &error) {
|
||||||
|
show->showToast(error.type());
|
||||||
|
cancel();
|
||||||
|
}).send();
|
||||||
|
}
|
||||||
|
|
|
@ -16,6 +16,7 @@ class GenericBox;
|
||||||
class ChatStyle;
|
class ChatStyle;
|
||||||
class ChatTheme;
|
class ChatTheme;
|
||||||
class VerticalLayout;
|
class VerticalLayout;
|
||||||
|
struct AskBoostReason;
|
||||||
} // namespace Ui
|
} // namespace Ui
|
||||||
|
|
||||||
void EditPeerColorBox(
|
void EditPeerColorBox(
|
||||||
|
@ -29,3 +30,9 @@ void AddPeerColorButton(
|
||||||
not_null<Ui::VerticalLayout*> container,
|
not_null<Ui::VerticalLayout*> container,
|
||||||
std::shared_ptr<ChatHelpers::Show> show,
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
not_null<PeerData*> peer);
|
not_null<PeerData*> peer);
|
||||||
|
|
||||||
|
void CheckBoostLevel(
|
||||||
|
std::shared_ptr<ChatHelpers::Show> show,
|
||||||
|
not_null<PeerData*> peer,
|
||||||
|
Fn<std::optional<Ui::AskBoostReason>(int level)> askMore,
|
||||||
|
Fn<void()> cancel);
|
||||||
|
|
|
@ -698,6 +698,12 @@ std::optional<WallPaper> WallPaper::FromColorsSlug(const QString &slug) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
WallPaper WallPaper::FromEmojiId(const QString &emojiId) {
|
||||||
|
auto result = WallPaper(0);
|
||||||
|
result._emojiId = emojiId;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
WallPaper WallPaper::ConstructDefault() {
|
WallPaper WallPaper::ConstructDefault() {
|
||||||
auto result = WallPaper(
|
auto result = WallPaper(
|
||||||
kDefaultBackground
|
kDefaultBackground
|
||||||
|
|
|
@ -103,6 +103,7 @@ public:
|
||||||
qint32 legacyId);
|
qint32 legacyId);
|
||||||
[[nodiscard]] static std::optional<WallPaper> FromColorsSlug(
|
[[nodiscard]] static std::optional<WallPaper> FromColorsSlug(
|
||||||
const QString &slug);
|
const QString &slug);
|
||||||
|
[[nodiscard]] static WallPaper FromEmojiId(const QString &emojiId);
|
||||||
[[nodiscard]] static WallPaper ConstructDefault();
|
[[nodiscard]] static WallPaper ConstructDefault();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -404,6 +404,7 @@ infoIconMediaStoriesRecent: icon {{ "info/info_stories_recent", infoIconFg }};
|
||||||
infoIconShare: icon {{ "info/info_share", infoIconFg }};
|
infoIconShare: icon {{ "info/info_share", infoIconFg }};
|
||||||
infoIconEdit: icon {{ "info/info_edit", infoIconFg }};
|
infoIconEdit: icon {{ "info/info_edit", infoIconFg }};
|
||||||
infoIconDelete: icon {{ "info/info_delete", infoIconFg }};
|
infoIconDelete: icon {{ "info/info_delete", infoIconFg }};
|
||||||
|
infoIconDeleteRed: icon {{ "info/info_delete", attentionButtonFg }};
|
||||||
infoIconReport: icon {{ "info/info_report", attentionButtonFg }};
|
infoIconReport: icon {{ "info/info_report", attentionButtonFg }};
|
||||||
infoIconLeave: icon {{ "info/info_leave", infoIconFg }};
|
infoIconLeave: icon {{ "info/info_leave", infoIconFg }};
|
||||||
infoIconBlock: icon {{ "info/info_block", attentionButtonFg }};
|
infoIconBlock: icon {{ "info/info_block", attentionButtonFg }};
|
||||||
|
|
Loading…
Add table
Reference in a new issue