mirror of
https://github.com/kotatogram/kotatogram-desktop
synced 2025-08-31 14:45:14 +00:00
Implement full theming of attachments in stories.
This commit is contained in:
@@ -76,7 +76,7 @@ bool operator==(const Descriptor &a, const Descriptor &b) {
|
||||
struct Preload {
|
||||
Descriptor descriptor;
|
||||
std::shared_ptr<Data::DocumentMedia> media;
|
||||
base::weak_ptr<Window::SessionController> controller;
|
||||
std::weak_ptr<ChatHelpers::Show> show;
|
||||
};
|
||||
|
||||
[[nodiscard]] std::vector<Preload> &Preloads() {
|
||||
@@ -168,7 +168,7 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> StickerPreview(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const std::shared_ptr<Data::DocumentMedia> &media,
|
||||
Fn<void()> readyCallback = nullptr) {
|
||||
using namespace HistoryView;
|
||||
@@ -194,6 +194,8 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||
struct State {
|
||||
std::unique_ptr<Lottie::SinglePlayer> lottie;
|
||||
std::unique_ptr<Lottie::SinglePlayer> effect;
|
||||
style::owned_color pathFg = style::owned_color(
|
||||
QColor(255, 255, 255, 64));
|
||||
std::unique_ptr<Ui::PathShiftGradient> pathGradient;
|
||||
bool readyInvoked = false;
|
||||
};
|
||||
@@ -239,15 +241,17 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||
};
|
||||
createLottieIfReady();
|
||||
if (!state->lottie || !state->effect) {
|
||||
controller->session().downloaderTaskFinished(
|
||||
show->session().downloaderTaskFinished(
|
||||
) | rpl::take_while([=] {
|
||||
createLottieIfReady();
|
||||
return !state->lottie || !state->effect;
|
||||
}) | rpl::start(result->lifetime());
|
||||
}
|
||||
state->pathGradient = MakePathShiftGradient(
|
||||
controller->chatStyle(),
|
||||
[=] { result->update(); });
|
||||
state->pathGradient = std::make_unique<Ui::PathShiftGradient>(
|
||||
st::shadowFg,
|
||||
state->pathFg.color(),
|
||||
[=] { result->update(); },
|
||||
rpl::never<>());
|
||||
|
||||
result->paintRequest(
|
||||
) | rpl::start_with_next([=] {
|
||||
@@ -262,7 +266,7 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||
if (!state->lottie
|
||||
|| !state->lottie->ready()
|
||||
|| !state->effect->ready()) {
|
||||
p.setBrush(controller->chatStyle()->msgServiceBg());
|
||||
p.setBrush(st::shadowFg);
|
||||
ChatHelpers::PaintStickerThumbnailPath(
|
||||
p,
|
||||
media.get(),
|
||||
@@ -302,7 +306,7 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> StickersPreview(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
Fn<void()> readyCallback) {
|
||||
const auto result = Ui::CreateChild<Ui::RpWidget>(parent.get());
|
||||
result->show();
|
||||
@@ -327,7 +331,7 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||
bool nextReady = false;
|
||||
int index = 0;
|
||||
};
|
||||
const auto premium = &controller->session().api().premium();
|
||||
const auto premium = &show->session().api().premium();
|
||||
const auto state = lifetime.make_state<State>();
|
||||
const auto create = [=](std::shared_ptr<Data::DocumentMedia> media) {
|
||||
const auto outer = Ui::CreateChild<Ui::RpWidget>(result);
|
||||
@@ -340,7 +344,7 @@ void PreloadSticker(const std::shared_ptr<Data::DocumentMedia> &media) {
|
||||
|
||||
[[maybe_unused]] const auto sticker = StickerPreview(
|
||||
outer,
|
||||
controller,
|
||||
show,
|
||||
media,
|
||||
state->singleReadyCallback);
|
||||
|
||||
@@ -520,7 +524,7 @@ struct VideoPreviewDocument {
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> VideoPreview(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
not_null<DocumentData*> document,
|
||||
bool alignToBottom,
|
||||
Fn<void()> readyCallback) {
|
||||
@@ -683,7 +687,7 @@ struct VideoPreviewDocument {
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> GenericPreview(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
PremiumPreview section,
|
||||
Fn<void()> readyCallback) {
|
||||
const auto result = Ui::CreateChild<Ui::RpWidget>(parent.get());
|
||||
@@ -699,7 +703,7 @@ struct VideoPreviewDocument {
|
||||
std::vector<std::shared_ptr<Data::DocumentMedia>> medias;
|
||||
Ui::RpWidget *single = nullptr;
|
||||
};
|
||||
const auto session = &controller->session();
|
||||
const auto session = &show->session();
|
||||
const auto state = lifetime.make_state<State>();
|
||||
const auto create = [=] {
|
||||
const auto document = LookupVideo(session, section);
|
||||
@@ -708,7 +712,7 @@ struct VideoPreviewDocument {
|
||||
}
|
||||
state->single = VideoPreview(
|
||||
result,
|
||||
controller,
|
||||
show,
|
||||
document,
|
||||
!VideoAlignToTop(section),
|
||||
readyCallback);
|
||||
@@ -724,14 +728,18 @@ struct VideoPreviewDocument {
|
||||
|
||||
[[nodiscard]] not_null<Ui::RpWidget*> GenerateDefaultPreview(
|
||||
not_null<Ui::RpWidget*> parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
PremiumPreview section,
|
||||
Fn<void()> readyCallback) {
|
||||
switch (section) {
|
||||
case PremiumPreview::Stickers:
|
||||
return StickersPreview(parent, controller, readyCallback);
|
||||
return StickersPreview(parent, std::move(show), readyCallback);
|
||||
default:
|
||||
return GenericPreview(parent, controller, section, readyCallback);
|
||||
return GenericPreview(
|
||||
parent,
|
||||
std::move(show),
|
||||
section,
|
||||
readyCallback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -792,7 +800,7 @@ struct VideoPreviewDocument {
|
||||
|
||||
void PreviewBox(
|
||||
not_null<Ui::GenericBox*> box,
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const Descriptor &descriptor,
|
||||
const std::shared_ptr<Data::DocumentMedia> &media,
|
||||
const QImage &back) {
|
||||
@@ -825,7 +833,7 @@ void PreviewBox(
|
||||
};
|
||||
const auto state = outer->lifetime().make_state<State>();
|
||||
state->selected = descriptor.section;
|
||||
state->order = Settings::PremiumPreviewOrder(&controller->session());
|
||||
state->order = Settings::PremiumPreviewOrder(&show->session());
|
||||
|
||||
const auto index = [=](PremiumPreview section) {
|
||||
const auto it = ranges::find(state->order, section);
|
||||
@@ -880,7 +888,7 @@ void PreviewBox(
|
||||
};
|
||||
state->stickersPreload = GenerateDefaultPreview(
|
||||
outer,
|
||||
controller,
|
||||
show,
|
||||
PremiumPreview::Stickers,
|
||||
ready);
|
||||
state->stickersPreload->hide();
|
||||
@@ -890,13 +898,13 @@ void PreviewBox(
|
||||
switch (descriptor.section) {
|
||||
case PremiumPreview::Stickers:
|
||||
state->content = media
|
||||
? StickerPreview(outer, controller, media, state->preload)
|
||||
: StickersPreview(outer, controller, state->preload);
|
||||
? StickerPreview(outer, show, media, state->preload)
|
||||
: StickersPreview(outer, show, state->preload);
|
||||
break;
|
||||
default:
|
||||
state->content = GenericPreview(
|
||||
outer,
|
||||
controller,
|
||||
show,
|
||||
descriptor.section,
|
||||
state->preload);
|
||||
break;
|
||||
@@ -955,7 +963,7 @@ void PreviewBox(
|
||||
} else {
|
||||
state->content = GenerateDefaultPreview(
|
||||
outer,
|
||||
controller,
|
||||
show,
|
||||
now,
|
||||
state->preload);
|
||||
}
|
||||
@@ -1003,7 +1011,7 @@ void PreviewBox(
|
||||
state->preload();
|
||||
}
|
||||
};
|
||||
if (descriptor.fromSettings && controller->session().premium()) {
|
||||
if (descriptor.fromSettings && show->session().premium()) {
|
||||
box->setShowFinishedCallback(showFinished);
|
||||
box->addButton(tr::lng_close(), [=] { box->closeBox(); });
|
||||
} else {
|
||||
@@ -1030,16 +1038,21 @@ void PreviewBox(
|
||||
auto button = descriptor.fromSettings
|
||||
? object_ptr<Ui::GradientButton>::fromRaw(
|
||||
Settings::CreateSubscribeButton({
|
||||
controller,
|
||||
box,
|
||||
computeRef,
|
||||
.parent = box,
|
||||
.computeRef = computeRef,
|
||||
.show = show,
|
||||
}))
|
||||
: CreateUnlockButton(box, std::move(unlock));
|
||||
button->resizeToWidth(width);
|
||||
if (!descriptor.fromSettings) {
|
||||
button->setClickedCallback([=] {
|
||||
const auto window = show->resolveWindow(
|
||||
ChatHelpers::WindowUsage::PremiumPromo);
|
||||
if (!window) {
|
||||
return;
|
||||
}
|
||||
Settings::ShowPremium(
|
||||
controller,
|
||||
window,
|
||||
Settings::LookupPremiumRef(state->selected.current()));
|
||||
});
|
||||
}
|
||||
@@ -1052,7 +1065,7 @@ void PreviewBox(
|
||||
|
||||
if (descriptor.fromSettings) {
|
||||
Data::AmPremiumValue(
|
||||
&controller->session()
|
||||
&show->session()
|
||||
) | rpl::skip(1) | rpl::start_with_next([=] {
|
||||
box->closeBox();
|
||||
}, box->lifetime());
|
||||
@@ -1076,25 +1089,26 @@ void PreviewBox(
|
||||
}
|
||||
|
||||
void Show(
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
const Descriptor &descriptor,
|
||||
const std::shared_ptr<Data::DocumentMedia> &media,
|
||||
QImage back) {
|
||||
const auto box = controller->show(
|
||||
Box(PreviewBox, controller, descriptor, media, back));
|
||||
auto box = Box(PreviewBox, show, descriptor, media, back);
|
||||
const auto raw = box.data();
|
||||
show->showBox(std::move(box));
|
||||
if (descriptor.shownCallback) {
|
||||
descriptor.shownCallback(box);
|
||||
descriptor.shownCallback(raw);
|
||||
}
|
||||
}
|
||||
|
||||
void Show(not_null<Window::SessionController*> controller, QImage back) {
|
||||
void Show(std::shared_ptr<ChatHelpers::Show> show, QImage back) {
|
||||
auto &list = Preloads();
|
||||
for (auto i = begin(list); i != end(list);) {
|
||||
const auto already = i->controller.get();
|
||||
const auto already = i->show.lock();
|
||||
if (!already) {
|
||||
i = list.erase(i);
|
||||
} else if (already == controller) {
|
||||
Show(controller, i->descriptor, i->media, back);
|
||||
} else if (already == show) {
|
||||
Show(std::move(show), i->descriptor, i->media, back);
|
||||
i = list.erase(i);
|
||||
return;
|
||||
} else {
|
||||
@@ -1104,21 +1118,23 @@ void Show(not_null<Window::SessionController*> controller, QImage back) {
|
||||
}
|
||||
|
||||
void Show(
|
||||
not_null<Window::SessionController*> controller,
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
Descriptor &&descriptor) {
|
||||
if (!controller->session().premiumPossible()) {
|
||||
const auto box = controller->show(Box(PremiumUnavailableBox));
|
||||
if (!show->session().premiumPossible()) {
|
||||
auto box = Box(PremiumUnavailableBox);
|
||||
const auto raw = box.data();
|
||||
show->showBox(std::move(box));
|
||||
if (descriptor.shownCallback) {
|
||||
descriptor.shownCallback(box);
|
||||
descriptor.shownCallback(raw);
|
||||
}
|
||||
return;
|
||||
}
|
||||
auto &list = Preloads();
|
||||
for (auto i = begin(list); i != end(list);) {
|
||||
const auto already = i->controller.get();
|
||||
const auto already = i->show.lock();
|
||||
if (!already) {
|
||||
i = list.erase(i);
|
||||
} else if (already == controller) {
|
||||
} else if (already == show) {
|
||||
if (i->descriptor == descriptor) {
|
||||
return;
|
||||
}
|
||||
@@ -1135,13 +1151,13 @@ void Show(
|
||||
}
|
||||
}
|
||||
|
||||
const auto weak = base::make_weak(controller);
|
||||
const auto weak = std::weak_ptr(show);
|
||||
list.push_back({
|
||||
.descriptor = descriptor,
|
||||
.media = (descriptor.requestedSticker
|
||||
? descriptor.requestedSticker->createMediaView()
|
||||
: nullptr),
|
||||
.controller = weak,
|
||||
.show = weak,
|
||||
});
|
||||
if (const auto &media = list.back().media) {
|
||||
PreloadSticker(media);
|
||||
@@ -1166,8 +1182,8 @@ void Show(
|
||||
Images::CornersMask(st::boxRadius),
|
||||
RectPart::TopLeft | RectPart::TopRight);
|
||||
crl::on_main([=] {
|
||||
if (const auto strong = weak.get()) {
|
||||
Show(strong, result);
|
||||
if (auto strong = weak.lock()) {
|
||||
Show(std::move(strong), result);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1178,7 +1194,7 @@ void Show(
|
||||
void ShowStickerPreviewBox(
|
||||
not_null<Window::SessionController*> controller,
|
||||
not_null<DocumentData*> document) {
|
||||
Show(controller, Descriptor{
|
||||
Show(controller->uiShow(), Descriptor{
|
||||
.section = PremiumPreview::Stickers,
|
||||
.requestedSticker = document,
|
||||
});
|
||||
@@ -1188,7 +1204,14 @@ void ShowPremiumPreviewBox(
|
||||
not_null<Window::SessionController*> controller,
|
||||
PremiumPreview section,
|
||||
Fn<void(not_null<Ui::BoxContent*>)> shown) {
|
||||
Show(controller, Descriptor{
|
||||
ShowPremiumPreviewBox(controller->uiShow(), section, std::move(shown));
|
||||
}
|
||||
|
||||
void ShowPremiumPreviewBox(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
PremiumPreview section,
|
||||
Fn<void(not_null<Ui::BoxContent*>)> shown) {
|
||||
Show(std::move(show), Descriptor{
|
||||
.section = section,
|
||||
.shownCallback = std::move(shown),
|
||||
});
|
||||
@@ -1198,7 +1221,7 @@ void ShowPremiumPreviewToBuy(
|
||||
not_null<Window::SessionController*> controller,
|
||||
PremiumPreview section,
|
||||
Fn<void()> hiddenCallback) {
|
||||
Show(controller, Descriptor{
|
||||
Show(controller->uiShow(), Descriptor{
|
||||
.section = section,
|
||||
.fromSettings = true,
|
||||
.hiddenCallback = std::move(hiddenCallback),
|
||||
@@ -1337,7 +1360,10 @@ void DoubledLimitsPreviewBox(
|
||||
Main::Domain::kPremiumMaxAccounts,
|
||||
till,
|
||||
});
|
||||
Ui::Premium::ShowListBox(box, std::move(entries));
|
||||
Ui::Premium::ShowListBox(
|
||||
box,
|
||||
st::defaultPremiumLimits,
|
||||
std::move(entries));
|
||||
}
|
||||
|
||||
object_ptr<Ui::GradientButton> CreateUnlockButton(
|
||||
|
Reference in New Issue
Block a user