Merge tag 'v6.1.3' into dev

This commit is contained in:
AlexeyZavar
2025-10-04 17:24:42 +03:00
598 changed files with 20578 additions and 6423 deletions
+72 -13
View File
@@ -40,13 +40,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Window {
namespace {
[[nodiscard]] rpl::producer<QString> PeerThemeEmojiValue(
[[nodiscard]] rpl::producer<QString> PeerThemeTokenValue(
not_null<PeerData*> peer) {
return peer->session().changes().peerFlagsValue(
peer,
Data::PeerUpdate::Flag::ChatThemeEmoji
Data::PeerUpdate::Flag::ChatThemeToken
) | rpl::map([=] {
return peer->themeEmoji();
return peer->themeToken();
});
}
@@ -100,11 +100,11 @@ struct ResolvedPaper {
[[nodiscard]] auto MaybeChatThemeDataValueFromPeer(
not_null<PeerData*> peer)
-> rpl::producer<std::optional<Data::CloudTheme>> {
return PeerThemeEmojiValue(
return PeerThemeTokenValue(
peer
) | rpl::map([=](const QString &emoji)
) | rpl::map([=](const QString &token)
-> rpl::producer<std::optional<Data::CloudTheme>> {
return peer->owner().cloudThemes().themeForEmojiValue(emoji);
return peer->owner().cloudThemes().themeForTokenValue(token);
}) | rpl::flatten_latest();
}
@@ -268,7 +268,7 @@ void SectionWidget::setGeometryWithTopMoved(
_topDelta = topDelta;
bool willBeResized = (size() != newGeometry.size());
if (geometry() != newGeometry) {
auto weak = Ui::MakeWeak(this);
auto weak = base::make_weak(this);
setGeometry(newGeometry);
if (!weak) {
return;
@@ -329,12 +329,33 @@ void SectionWidget::PaintBackground(
not_null<Ui::ChatTheme*> theme,
not_null<QWidget*> widget,
QRect clip) {
if (const auto id = theme->background().giftId) {
const auto fillHeight = controller->content()->height();
const auto fill = QSize(widget->width(), fillHeight);
const auto &state = theme->backgroundState(fill);
const auto make = [&] {
return std::make_unique<Ui::Text::LimitedLoopsEmoji>(
controller->session().data().customEmojiManager().create(
id,
crl::guard(widget, [=] { widget->update(); }),
Data::CustomEmojiSizeTag::Isolated),
1);
};
if (!state.was.gift) {
state.was.gift = make();
}
if (!state.now.gift) {
state.now.gift = make();
}
}
PaintBackground(
theme,
widget,
controller->content()->height(),
controller->content()->backgroundFromY(),
clip);
clip,
controller->isGifPausedAtLeastFor(GifPauseReason::Any));
}
void SectionWidget::PaintBackground(
@@ -342,37 +363,68 @@ void SectionWidget::PaintBackground(
not_null<QWidget*> widget,
int fillHeight,
int fromy,
QRect clip) {
QRect clip,
bool paused) {
auto p = QPainter(widget);
if (fromy) {
p.translate(0, fromy);
clip = clip.translated(0, -fromy);
}
PaintBackground(p, theme, QSize(widget->width(), fillHeight), clip);
const auto fill = QSize(widget->width(), fillHeight);
PaintBackground(p, theme, fill, clip, paused);
}
void SectionWidget::PaintBackground(
QPainter &p,
not_null<Ui::ChatTheme*> theme,
QSize fill,
QRect clip) {
QRect clip,
bool paused) {
const auto &background = theme->background();
if (background.colorForFill) {
p.fillRect(clip, *background.colorForFill);
return;
}
const auto &gradient = background.gradientForFill;
auto state = theme->backgroundState(fill);
const auto &state = theme->backgroundState(fill);
const auto paintCache = [&](const Ui::CachedBackground &cache) {
const auto to = QRect(
QPoint(cache.x, cache.y),
cache.pixmap.size() / style::DevicePixelRatio());
const auto paintGift = [&](QRect area) {
if (!cache.gift) {
return;
}
auto hq = PainterHighQualityEnabler(p);
const auto center = area.center();
const auto size = Data::FrameSizeFromTag(
Data::CustomEmojiSizeTag::Isolated
) / style::DevicePixelRatio();
p.save();
p.translate(center);
p.rotate(cache.giftRotation);
p.translate(-center);
p.setOpacity(0.5);
cache.gift->paint(p, {
.textColor = st::windowFg->c,
.size = QSize(size, size),
.now = crl::now(),
.scale = (area.width() / float64(size)),
.position = area.topLeft(),
.paused = paused,
.scaled = true,
});
p.restore();
};
if (cache.waitingForNegativePattern) {
// While we wait for pattern being loaded we paint just gradient.
// But in case of negative patter opacity we just fill-black.
p.fillRect(to, Qt::black);
} else if (cache.area == fill) {
p.drawPixmap(to, cache.pixmap);
if (background.giftId && !cache.giftArea.isEmpty()) {
paintGift(cache.giftArea.translated(to.topLeft()));
}
} else {
const auto sx = fill.width() / float64(cache.area.width());
const auto sy = fill.height() / float64(cache.area.height());
@@ -388,6 +440,13 @@ void SectionWidget::PaintBackground(
round((to.x() + to.width()) * sx) - sto.x(),
round((to.y() + to.height()) * sy) - sto.y(),
cache.pixmap);
if (background.giftId && !cache.giftArea.isEmpty()) {
paintGift(QRect(
(to.x() + cache.giftArea.x()) * sx,
(to.y() + cache.giftArea.y()) * sy,
cache.giftArea.width() * sx,
cache.giftArea.height() * sy));
}
}
};
const auto hasNow = !state.now.pixmap.isNull();
@@ -517,7 +576,7 @@ auto ChatThemeValueFromPeer(
std::shared_ptr<Ui::ChatTheme> &&cloud,
PeerThemeOverride &&overriden) {
return (overriden.peer == peer.get()
&& Ui::Emoji::Find(peer->themeEmoji()) != overriden.emoji)
&& peer->themeToken() != overriden.token)
? std::move(overriden.theme)
: std::move(cloud);
});