Full upgradable variants preview.

This commit is contained in:
John Preston
2025-12-02 17:25:38 +04:00
parent 65b3a36984
commit 0b67fa65f2
30 changed files with 1719 additions and 72 deletions
+2
View File
@@ -337,6 +337,8 @@ PRIVATE
boxes/star_gift_auction_box.h
boxes/star_gift_box.cpp
boxes/star_gift_box.h
boxes/star_gift_preview_box.cpp
boxes/star_gift_preview_box.h
boxes/star_gift_resale_box.cpp
boxes/star_gift_resale_box.h
boxes/sticker_set_box.cpp
+3
View File
@@ -4180,12 +4180,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_auction_preview_model" = "model";
"lng_auction_preview_models#one" = "This collectible features **{count}** unique model.";
"lng_auction_preview_models#other" = "This collectible features **{count}** unique models.";
"lng_auction_preview_models_button" = "Models";
"lng_auction_preview_backdrop" = "backdrop";
"lng_auction_preview_backdrops#one" = "This collectible features **{count}** unique backdrop.";
"lng_auction_preview_backdrops#other" = "This collectible features **{count}** unique backdrops.";
"lng_auction_preview_backdrops_button" = "Backdrops";
"lng_auction_preview_symbol" = "symbol";
"lng_auction_preview_symbols#one" = "This collectible features **{count}** unique symbol.";
"lng_auction_preview_symbols#other" = "This collectible features **{count}** unique symbols.";
"lng_auction_preview_symbols_button" = "Symbols";
"lng_auction_preview_wear" = "More about wearing gifts {arrow}";
"lng_auction_preview_free_upgrade" = "You can upgrade your gift for free, sell it on the market, or set it as your profile cover.";
@@ -24,7 +24,7 @@ void ToggleExistingMedia(
Data::FileOrigin origin,
ToggleRequestCallback toggleRequest,
DoneCallback &&done) {
const auto api = &document->owner().session().api();
const auto api = &document->session().api();
auto performRequest = [=](const auto &repeatRequest) -> void {
const auto usedFileReference = document->fileReference();
@@ -121,7 +121,7 @@ namespace {
return true;
};
if (!updateThumbnail()) {
document->owner().session().downloaderTaskFinished(
document->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (updateThumbnail()) {
state->loadingLifetime.destroy();
+2 -2
View File
@@ -1731,14 +1731,14 @@ ShareBox::SubmitCallback ShareBox::DefaultForwardCallback(
}
return result;
};
auto &api = history->owner().session().api();
auto &api = history->session().api();
auto &histories = history->owner().histories();
const auto donePhraseArgs = CreateForwardedMessagePhraseArgs(
result,
msgIds);
const auto showRecentForwardsToSelf = result.size() == 1
&& result.front()->peer()->isSelf()
&& history->owner().session().premium();
&& history->session().premium();
const auto requestType = Data::Histories::RequestType::Send;
for (const auto thread : result) {
if (!comment.text.isEmpty()) {
@@ -16,6 +16,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "boxes/send_credits_box.h" // CreditsEmojiSmall
#include "boxes/share_box.h"
#include "boxes/star_gift_box.h"
#include "boxes/star_gift_preview_box.h"
#include "boxes/star_gift_resale_box.h"
#include "calls/group/calls_group_common.h"
#include "core/application.h"
@@ -1190,11 +1191,14 @@ void AuctionGotGiftsBox(
}
}
[[nodiscard]] rpl::producer<Data::UniqueGift> MakePreviewAuctionStream(
[[nodiscard]] rpl::producer<UniqueGiftCover> MakePreviewAuctionStream(
const Data::StarGift &info,
rpl::producer<Data::UniqueGiftAttributes> attributes) {
Expects(attributes);
const auto cover = [](Data::UniqueGift gift) {
return UniqueGiftCover{ std::move(gift) };
};
auto initial = Data::UniqueGift{
.title = info.resellTitle,
.model = Data::UniqueGiftModel{
@@ -1207,14 +1211,14 @@ void AuctionGotGiftsBox(
? info.background->backdrop()
: Data::UniqueGiftBackdrop()),
};
return rpl::single(initial) | rpl::then(std::move(
return rpl::single(cover(initial)) | rpl::then(std::move(
attributes
) | rpl::map([=](const Data::UniqueGiftAttributes &values)
-> rpl::producer<Data::UniqueGift> {
-> rpl::producer<UniqueGiftCover> {
if (values.backdrops.empty()
|| values.models.empty()
|| values.patterns.empty()) {
return rpl::never<Data::UniqueGift>();
return rpl::never<UniqueGiftCover>();
}
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
@@ -1256,12 +1260,12 @@ void AuctionGotGiftsBox(
auto &models = state->data.models;
auto &patterns = state->data.patterns;
auto &backdrops = state->data.backdrops;
consumer.put_next(Data::UniqueGift{
consumer.put_next(cover({
.title = info.resellTitle,
.model = models[index(state->modelIndices, models)],
.pattern = patterns[index(state->patternIndices, patterns)],
.backdrop = backdrops[index(state->backdropIndices, backdrops)],
});
}));
};
put();
@@ -1520,18 +1524,7 @@ void AuctionInfoBox(
st::boxRowPadding + st::uniqueGiftValueAvailableMargin,
style::al_top
)->setClickHandlerFilter([=](const auto &...) {
//if (state->previewRequested) {
// return false;
//}
//state->previewRequested = true;
//const auto &value = state->value.current();
//const auto &gift = *value.gift;
//state->previewLifetime = ShowStarGiftResale(
// window,
// peer,
// gift.id,
// gift.resellTitle,
// [=] { state->previewRequested = false; });
show->show(Box(StarGiftPreviewBox, window, *now.gift, list));
return false;
});
}, box->lifetime());
+169 -25
View File
@@ -2798,7 +2798,7 @@ void SetupResalePriceButton(
void AddUniqueGiftCover(
not_null<VerticalLayout*> container,
rpl::producer<Data::UniqueGift> data,
rpl::producer<UniqueGiftCover> data,
UniqueGiftCoverArgs &&args) {
const auto cover = container->add(object_ptr<RpWidget>(container));
@@ -2812,16 +2812,18 @@ void AddUniqueGiftCover(
style::FlatLabel st;
PeerData *by = nullptr;
QColor bg;
QColor fg;
};
const auto released = cover->lifetime().make_state<Released>();
released->st = st::uniqueGiftReleasedBy;
released->st.palette.linkFg = released->link.color();
const auto repaintedHook = args.repaintedHook;
if (args.resalePrice) {
auto background = rpl::duplicate(
data
) | rpl::map([=](const Data::UniqueGift &unique) {
auto result = unique.backdrop.patternColor;
) | rpl::map([=](const UniqueGiftCover &cover) {
auto result = cover.values.backdrop.patternColor;
result.setAlphaF(kGradientButtonBgOpacity * result.alphaF());
return result;
});
@@ -2870,12 +2872,15 @@ void AddUniqueGiftCover(
cover,
rpl::duplicate(
data
) | rpl::map([](const Data::UniqueGift &now) { return now.title; }),
) | rpl::map([](const UniqueGiftCover &now) {
return now.values.title;
}),
st::uniqueGiftTitle);
title->setTextColorOverride(QColor(255, 255, 255));
released->subtitleText = args.subtitle
? std::move(args.subtitle)
: rpl::duplicate(data) | rpl::map([=](const Data::UniqueGift &gift) {
: rpl::duplicate(data) | rpl::map([=](const UniqueGiftCover &cover) {
const auto &gift = cover.values;
released->by = gift.releasedBy;
return gift.releasedBy
? tr::lng_gift_unique_number_by(
@@ -2940,6 +2945,7 @@ void AddUniqueGiftCover(
std::unique_ptr<Lottie::SinglePlayer> lottie;
std::unique_ptr<Text::CustomEmoji> emoji;
base::flat_map<float64, QImage> emojis;
bool forced = false;
rpl::lifetime lifetime;
};
struct State {
@@ -2947,11 +2953,23 @@ void AddUniqueGiftCover(
GiftView next;
Animations::Simple crossfade;
bool animating = false;
bool updateAttributesPending = false;
};
const auto state = cover->lifetime().make_state<State>();
const auto lottieSize = st::creditsHistoryEntryStarGiftSize;
const auto updateLinkFg = args.subtitleLinkColored;
const auto updateColors = [=](float64 progress) {
if (repaintedHook) {
repaintedHook(state->now.gift, state->next.gift, progress);
}
released->bg = (progress == 0.)
? state->now.gift->backdrop.patternColor
: (progress == 1.)
? state->next.gift->backdrop.patternColor
: anim::color(
state->now.gift->backdrop.patternColor,
state->next.gift->backdrop.patternColor,
progress);
const auto color = (progress == 0.)
? state->now.gift->backdrop.textColor
: (progress == 1.)
@@ -2963,22 +2981,16 @@ void AddUniqueGiftCover(
if (updateLinkFg) {
released->link.update(color);
}
released->fg = color;
subtitle->setTextColorOverride(color);
released->bg = (progress == 0.)
? state->now.gift->backdrop.patternColor
: (progress == 1.)
? state->next.gift->backdrop.patternColor
: anim::color(
state->now.gift->backdrop.patternColor,
state->next.gift->backdrop.patternColor,
progress);
};
std::move(
rpl::duplicate(
data
) | rpl::start_with_next([=](const Data::UniqueGift &gift) {
) | rpl::start_with_next([=](const UniqueGiftCover &now) {
const auto setup = [&](GiftView &to) {
to.gift = gift;
const auto document = gift.model.document;
to.gift = now.values;
to.forced = now.force;
const auto document = now.values.model.document;
to.media = document->createMediaView();
to.media->automaticLoad({}, nullptr);
rpl::single() | rpl::then(
@@ -3003,7 +3015,7 @@ void AddUniqueGiftCover(
}, to.lifetime);
}, to.lifetime);
to.emoji = document->owner().customEmojiManager().create(
gift.pattern.document,
now.values.pattern.document,
[=] { cover->update(); },
Data::CustomEmojiSizeTag::Large);
[[maybe_unused]] const auto preload = to.emoji->ready();
@@ -3013,11 +3025,122 @@ void AddUniqueGiftCover(
setup(state->now);
cover->update();
updateColors(0.);
} else if (!state->next.gift) {
} else if (!state->next.gift || now.force) {
setup(state->next);
}
}, cover->lifetime());
const auto attrs = args.attributesInfo
? CreateChild<RpWidget>(cover)
: nullptr;
auto updateAttrs = Fn<void(const Data::UniqueGift &)>([](const auto &) {
});
if (attrs) {
struct AttributeState {
Ui::Text::String name;
Ui::Text::String type;
Ui::Text::String percent;
};
struct AttributesState {
AttributeState model;
AttributeState pattern;
AttributeState backdrop;
};
const auto astate = cover->lifetime().make_state<AttributesState>();
const auto setType = [&](AttributeState &state, tr::phrase<> text) {
state.type = Ui::Text::String(
st::uniqueAttributeType,
text(tr::now));
};
setType(astate->model, tr::lng_auction_preview_model);
setType(astate->pattern, tr::lng_auction_preview_symbol);
setType(astate->backdrop, tr::lng_auction_preview_backdrop);
updateAttrs = [=](const Data::UniqueGift &gift) {
const auto set = [&](
AttributeState &state,
const Data::UniqueGiftAttribute &value) {
state.name = Ui::Text::String(
st::uniqueAttributeName,
value.name);
state.percent = Ui::Text::String(
st::uniqueAttributePercent,
QString::number(value.rarityPermille / 10.) + '%');
};
set(astate->model, gift.model);
set(astate->pattern, gift.pattern);
set(astate->backdrop, gift.backdrop);
attrs->update();
};
const auto height = st::uniqueAttributeTop
+ st::uniqueAttributePadding.top()
+ st::uniqueAttributeName.font->height
+ st::uniqueAttributeType.font->height
+ st::uniqueAttributePadding.bottom();
attrs->resize(attrs->width(), height);
attrs->paintOn([=](QPainter &p) {
const auto skip = st::giftBoxGiftSkip.x();
const auto available = attrs->width() - 2 * skip;
const auto single = available / 3;
if (single <= 0) {
return;
}
auto hq = PainterHighQualityEnabler(p);
auto bg = released->bg;
bg.setAlphaF(kGradientButtonBgOpacity * bg.alphaF());
const auto innert = st::uniqueAttributeTop;
const auto innerh = height - innert;
const auto radius = innerh / 3.;
const auto paint = [&](int x, const AttributeState &state) {
p.setPen(Qt::NoPen);
p.setBrush(bg);
p.drawRoundedRect(x, innert, single, innerh, radius, radius);
p.setPen(QColor(255, 255, 255));
const auto padding = st::uniqueAttributePadding;
const auto inner = single - padding.left() - padding.right();
const auto namew = std::min(inner, state.name.maxWidth());
state.name.draw(p, {
.position = QPoint(
x + (single - namew) / 2,
innert + padding.top()),
.availableWidth = namew,
.elisionLines = 1,
});
p.setPen(released->fg);
const auto typew = std::min(inner, state.type.maxWidth());
state.type.draw(p, {
.position = QPoint(
x + (single - typew) / 2,
innert + padding.top() + state.name.minHeight()),
.availableWidth = typew,
});
p.setPen(Qt::NoPen);
p.setBrush(anim::color(released->bg, released->fg, 0.3));
const auto r = st::uniqueAttributePercent.font->height / 2.;
const auto left = x + single - state.percent.maxWidth();
const auto top = st::uniqueAttributePercentPadding.top();
const auto percent = QRect(
left,
top,
state.percent.maxWidth(),
st::uniqueAttributeType.font->height);
p.drawRoundedRect(
percent.marginsAdded(st::uniqueAttributePercentPadding),
r,
r);
p.setPen(QColor(255, 255, 255));
state.percent.draw(p, {
.position = percent.topLeft(),
});
};
auto left = 0;
paint(left, astate->model);
paint(left + single + skip, astate->backdrop);
paint(attrs->width() - single - left, astate->pattern);
});
}
updateAttrs(*state->now.gift);
cover->widthValue() | rpl::start_with_next([=](int width) {
const auto skip = st::uniqueGiftBottom;
if (width <= 3 * skip) {
@@ -3043,14 +3166,32 @@ void AddUniqueGiftCover(
}
subtitle->moveToLeft(skip, top);
top += subtitle->height() + skip;
cover->resize(width, subtitle->y() + subtitle->height() + skip);
if (attrs) {
attrs->resizeToWidth(width
- st::giftBoxPadding.left()
- st::giftBoxPadding.right());
attrs->moveToLeft(st::giftBoxPadding.left(), top);
top += attrs->height() + (skip / 2);
}
cover->resize(width, top);
}, cover->lifetime());
cover->paintRequest() | rpl::start_with_next([=] {
auto p = QPainter(cover);
auto progress = state->crossfade.value(state->animating ? 1. : 0.);
if (state->updateAttributesPending && progress >= 0.5) {
state->updateAttributesPending = false;
updateAttrs(*state->next.gift);
} else if (state->updateAttributesPending
&& !state->animating
&& !state->crossfade.animating()) {
state->updateAttributesPending = false;
updateAttrs(*state->now.gift);
}
if (state->animating) {
updateColors(progress);
}
@@ -3105,10 +3246,13 @@ void AddUniqueGiftCover(
};
if (progress < 1.) {
const auto finished = paint(state->now, 1. - progress);
const auto finished = paint(state->now, 1. - progress)
|| (state->next.forced
&& (!state->animating || !state->crossfade.animating()));
const auto next = finished ? state->next.lottie.get() : nullptr;
if (next && next->ready()) {
state->animating = true;
state->updateAttributesPending = true;
state->crossfade.start([=] {
cover->update();
}, 0., 1., kCrossfadeDuration);
@@ -3803,12 +3947,12 @@ struct UpgradeArgs : StarGiftUpgradeArgs {
std::vector<UpgradePrice> nextPrices;
};
[[nodiscard]] rpl::producer<Data::UniqueGift> MakeUpgradeGiftStream(
[[nodiscard]] rpl::producer<UniqueGiftCover> MakeUpgradeGiftStream(
const UpgradeArgs &args) {
if (args.models.empty()
|| args.patterns.empty()
|| args.backdrops.empty()) {
return rpl::never<Data::UniqueGift>();
return rpl::never<UniqueGiftCover>();
}
return [=](auto consumer) {
auto lifetime = rpl::lifetime();
@@ -3846,14 +3990,14 @@ struct UpgradeArgs : StarGiftUpgradeArgs {
auto &models = state->data.models;
auto &patterns = state->data.patterns;
auto &backdrops = state->data.backdrops;
consumer.put_next(Data::UniqueGift{
consumer.put_next(UniqueGiftCover{ Data::UniqueGift{
.title = (state->data.savedId
? tr::lng_gift_upgrade_title(tr::now)
: tr::lng_gift_upgrade_preview_title(tr::now)),
.model = models[index(state->modelIndices, models)],
.pattern = patterns[index(state->patternIndices, patterns)],
.backdrop = backdrops[index(state->backdropIndices, backdrops)],
});
} });
};
put();
+10 -1
View File
@@ -72,11 +72,20 @@ struct UniqueGiftCoverArgs {
bool subtitleLinkColored = false;
rpl::producer<CreditsAmount> resalePrice;
Fn<void()> resaleClick;
bool attributesInfo = false;
Fn<void(
std::optional<Data::UniqueGift> now,
std::optional<Data::UniqueGift> next,
float64 progress)> repaintedHook;
};
struct UniqueGiftCover {
Data::UniqueGift values;
bool force = false;
};
void AddUniqueGiftCover(
not_null<VerticalLayout*> container,
rpl::producer<Data::UniqueGift> data,
rpl::producer<UniqueGiftCover> data,
UniqueGiftCoverArgs &&args);
void AddWearGiftCover(
not_null<VerticalLayout*> container,
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,29 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
namespace Data {
struct StarGift;
struct UniqueGiftAttributes;
} // namespace Data
namespace Window {
class SessionController;
} // namespace Window
namespace Ui {
class GenericBox;
void StarGiftPreviewBox(
not_null<GenericBox*> box,
not_null<Window::SessionController*> controller,
const Data::StarGift &gift,
const Data::UniqueGiftAttributes &attributes);
} // namespace Ui
@@ -1548,7 +1548,7 @@ void StickerSetBox::Inner::fillDeleteStickerBox(
const auto buttonWidth = state->saveButton
? state->saveButton->width()
: 0;
state->requestId = document->owner().session().api().request(
state->requestId = document->session().api().request(
MTPstickers_RemoveStickerFromSet(document->mtpInput()
)).done([=](const TLStickerSet &result) {
result.match([&](const MTPDmessages_stickerSet &d) {
@@ -1590,7 +1590,7 @@ void StickerSetBox::Inner::fillDeleteStickerBox(
state->requestId.value() | rpl::map(rpl::mappers::_1 > 0));
}
box->addButton(tr::lng_close(), [=] {
document->owner().session().api().request(
document->session().api().request(
state->requestId.current()).cancel();
box->closeBox();
});
@@ -1742,7 +1742,7 @@ void StickersListWidget::showStickerSetBox(
}
lifetime->destroy();
}, *lifetime);
document->owner().session().api().requestSpecialStickersForce(
document->session().api().requestSpecialStickersForce(
setId == Data::Stickers::FavedSetId,
setId == Data::Stickers::RecentSetId,
false);
@@ -431,7 +431,7 @@ void DocumentMedia::GenerateGoodThumbnail(
document->setGoodThumbnailChecked(false);
return;
}
const auto guard = base::make_weak(&document->owner().session());
const auto guard = base::make_weak(&document->session());
crl::async([=, location = std::move(location)] {
const auto filepath = (location && location->accessEnable())
? location->name()
@@ -20,14 +20,26 @@ namespace Data {
struct UniqueGiftAttribute {
QString name;
int rarityPermille = 0;
friend inline bool operator==(
const UniqueGiftAttribute &,
const UniqueGiftAttribute &) = default;
};
struct UniqueGiftModel : UniqueGiftAttribute {
not_null<DocumentData*> document;
friend inline bool operator==(
const UniqueGiftModel &,
const UniqueGiftModel &) = default;
};
struct UniqueGiftPattern : UniqueGiftAttribute {
not_null<DocumentData*> document;
friend inline bool operator==(
const UniqueGiftPattern &,
const UniqueGiftPattern &) = default;
};
struct UniqueGiftBackdrop : UniqueGiftAttribute {
@@ -36,6 +48,10 @@ struct UniqueGiftBackdrop : UniqueGiftAttribute {
QColor patternColor;
QColor textColor;
int id = 0;
friend inline bool operator==(
const UniqueGiftBackdrop &,
const UniqueGiftBackdrop &) = default;
};
struct UniqueGiftAttributes {
+1 -1
View File
@@ -727,7 +727,7 @@ void Story::applyFields(
auto caption = TextWithEntities{
data.vcaption().value_or_empty(),
Api::EntitiesFromMTP(
&owner().session(),
&session(),
data.ventities().value_or_empty()),
};
if (const auto user = _peer->asUser()) {
@@ -84,7 +84,7 @@ ItemSticker::ItemSticker(
return true;
};
if (!updateThumbnail()) {
_document->owner().session().downloaderTaskFinished(
_document->session().downloaderTaskFinished(
) | rpl::start_with_next([=] {
if (updateThumbnail()) {
_loadingLifetime.destroy();
@@ -161,7 +161,7 @@ ListController::ListController(not_null<History*> history)
}
Main::Session &ListController::session() const {
return _history->owner().session();
return _history->session();
}
void ListController::prepare() {
@@ -381,7 +381,7 @@ void GiftButton::setDocument(not_null<DocumentData*> document) {
const auto destroyed = base::take(_player);
_playerDocument = nullptr;
_mediaLifetime = rpl::single() | rpl::then(
document->owner().session().downloaderTaskFinished()
document->session().downloaderTaskFinished()
) | rpl::filter([=] {
return media->loaded();
}) | rpl::start_with_next([=] {
@@ -168,7 +168,7 @@ void TopicIconView::setupPlayer(not_null<Data::ForumTopic*> topic) {
media->goodThumbnailWanted();
return rpl::single() | rpl::then(
document->owner().session().downloaderTaskFinished()
document->session().downloaderTaskFinished()
) | rpl::filter([=] {
return media->loaded();
}) | rpl::take(1) | rpl::map([=] {
@@ -748,7 +748,7 @@ void TopBar::setupActions(not_null<Window::SessionController*> controller) {
tr::lng_profile_action_short_join(tr::now),
st::infoProfileTopBarActionJoin);
join->setClickedCallback([=] {
channel->owner().session().api().joinChannel(channel);
channel->session().api().joinChannel(channel);
});
buttons.push_back(join);
_actions->add(join);
@@ -76,7 +76,7 @@ void PreviewPainter::setDocument(
}
rpl::single() | rpl::then(
document->owner().session().downloaderTaskFinished()
document->session().downloaderTaskFinished()
) | rpl::start_with_next([=] {
if (!_media->loaded()) {
return;
@@ -171,7 +171,7 @@ EmojiUserpic::EmojiUserpic(
void EmojiUserpic::setDocument(not_null<DocumentData*> document) {
if (!_playOnce.has_value()) {
const auto &c = document->owner().session().appConfig();
const auto &c = document->session().appConfig();
_playOnce = !c.get<bool>(u"upload_markup_video"_q, false);
}
_painter.setDocument(document, [=] { update(); });
@@ -656,7 +656,7 @@ void WeatherView::setStickerFrom(not_null<DocumentData*> document) {
media->goodThumbnailWanted();
rpl::single() | rpl::then(
document->owner().session().downloaderTaskFinished()
document->session().downloaderTaskFinished()
) | rpl::filter([=] {
return media->loaded();
}) | rpl::take(1) | rpl::start_with_next([=] {
@@ -132,7 +132,7 @@ namespace Media::Stories {
return;
}
const auto api = &story->owner().session().api();
const auto api = &story->session().api();
auto &histories = story->owner().histories();
for (const auto thread : result) {
const auto action = Api::SendAction(thread, options);
@@ -28,7 +28,7 @@ namespace Menu {
Fn<void(bool)> RateTranscribeCallbackFactory(
not_null<HistoryItem*> item) {
return [item](bool good) {
item->history()->peer->owner().session().api().transcribes().rate(
item->history()->peer->session().api().transcribes().rate(
item,
good);
};
@@ -36,9 +36,9 @@ Fn<void(bool)> RateTranscribeCallbackFactory(
bool HasRateTranscribeItem(not_null<HistoryItem*> item) {
const auto &peer = item->history()->peer;
if (!peer->owner().session().api().transcribes().entry(
if (!peer->session().api().transcribes().entry(
item).result.isEmpty()) {
return !peer->owner().session().api().transcribes().isRated(item);
return !peer->session().api().transcribes().isRated(item);
}
return false;
}
@@ -175,7 +175,7 @@ rpl::producer<std::shared_ptr<StickerPlayer>> IconPlayerValue(
media->goodThumbnailWanted();
return rpl::single() | rpl::then(
sticker->owner().session().downloaderTaskFinished()
sticker->session().downloaderTaskFinished()
) | rpl::filter([=] {
return media->loaded();
}) | rpl::take(1) | rpl::map([=] {
@@ -1342,7 +1342,8 @@ void GenericCreditsEntryBox(
style);
};
const auto canResell = CanResellGift(session, e);
AddUniqueGiftCover(content, rpl::single(*uniqueGift), {
const auto cover = Ui::UniqueGiftCover{ *uniqueGift };
AddUniqueGiftCover(content, rpl::single(cover), {
.resalePrice = std::move(price),
.resaleClick = canResell ? std::move(change) : Fn<void()>(),
});
+45 -1
View File
@@ -320,6 +320,50 @@ uniqueMenuButton: IconButton(uniqueCloseButton) {
color: shadowFg;
}
}
uniqueAttributeTop: 10px;
uniqueAttributeSkip: 8px;
uniqueAttributePadding: margins(6px, 8px, 6px, 8px);
uniqueAttributeName: TextStyle(semiboldTextStyle) {
font: font(12px semibold);
}
uniqueAttributeType: TextStyle(defaultTextStyle) {
font: font(12px);
}
uniqueAttributePercent: uniqueAttributeType;
uniqueAttributePercentPadding: margins(4px, 0px, 4px, 0px);
uniqueAttributeModel: RoundButton(defaultLightButton) {
textFg: windowBoldFg;
textFgOver: windowBoldFg;
textBg: windowBgOver;
textBgOver: windowBgOver;
ripple: defaultRippleAnimation;
radius: 8px;
width: 107px;
height: 34px;
textTop: 7px;
style: defaultBoxButtonTextStyle;
icon: icon {{ "menu/unique", windowBoldFg }};
iconOver: icon {{ "menu/unique", windowBoldFg }};
iconPosition: point(-1px, 4px);
}
uniqueAttributeModelActive: icon{{ "menu/unique", activeButtonFg }};
uniqueAttributeBackdrop: RoundButton(uniqueAttributeModel) {
icon: icon {{ "menu/palette", windowBoldFg }};
iconOver: icon {{ "menu/palette", windowBoldFg }};
}
uniqueAttributeBackdropActive: icon{{ "menu/palette", activeButtonFg }};
uniqueAttributeSymbol: RoundButton(uniqueAttributeModel) {
icon: icon {{ "menu/all_media", windowBoldFg }};
iconOver: icon {{ "menu/all_media", windowBoldFg }};
}
uniqueAttributeSymbolActive: icon{{ "menu/all_media", activeButtonFg }};
uniqueAttributesBox: Box(giftBox) {
buttonWide: false;
buttonHeight: 34px;
buttonPadding: margins(10px, 10px, 11px, 10px);
}
uniqueAttributeStickerSize: size(64px, 64px);
upgradeGiftBox: Box(giftBox) {
buttonPadding: margins(22px, 3px, 22px, 22px);
}
@@ -341,7 +385,7 @@ darkUpgradeGiftBox: Box(upgradeGiftBox) {
titleAdditionalFg: groupCallMemberNotJoinedStatus;
}
darkUpgradeGiftRadiant: icon{{ "menu/unique", groupCallMembersFg }};
darkUpgradeGiftProfile: icon{{ "menu/profile", groupCallMembersFg }};
darkUpgradeGiftProfile: icon{{ "settings/premium/features/feature_profile_cover", groupCallMembersFg }};
darkUpgradeGiftProof: icon{{ "menu/factcheck", groupCallMembersFg }};
darkUpgradeGiftInfoTitle: FlatLabel(defaultFlatLabel) {
textFg: groupCallMembersFg;
@@ -341,7 +341,7 @@ PaintRoundImageCallback GenerateCreditsPaintEntryCallback(
photo->load(Data::PhotoSize::Large, {});
rpl::single(rpl::empty_value()) | rpl::then(
photo->owner().session().downloaderTaskFinished()
photo->session().downloaderTaskFinished()
) | rpl::start_with_next([=] {
using Size = Data::PhotoSize;
if (const auto large = state->view->image(Size::Large)) {
@@ -391,7 +391,7 @@ PaintRoundImageCallback GenerateCreditsPaintEntryCallback(
video->loadThumbnail({});
rpl::single(rpl::empty_value()) | rpl::then(
video->owner().session().downloaderTaskFinished()
video->session().downloaderTaskFinished()
) | rpl::start_with_next([=] {
if (const auto thumbnail = state->view->thumbnail()) {
state->imagePtr = thumbnail;
@@ -60,6 +60,6 @@ void PaintBgPoints(
not_null<Ui::Text::CustomEmoji*> emoji,
const QColor &patternColor,
const QRect &rect,
float64 shown);
float64 shown = 1.);
} // namespace Ui