mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-06 23:24:01 +02:00
Allow buying resold gifts.
This commit is contained in:
parent
0a92e12a62
commit
18f14b828c
11 changed files with 122 additions and 63 deletions
|
@ -528,8 +528,12 @@ void EditCreditsSubscription(
|
|||
)).done(done).fail([=](const MTP::Error &e) { fail(e.type()); }).send();
|
||||
}
|
||||
|
||||
MTPInputSavedStarGift InputSavedStarGiftId(const Data::SavedStarGiftId &id) {
|
||||
return id.isUser()
|
||||
MTPInputSavedStarGift InputSavedStarGiftId(
|
||||
const Data::SavedStarGiftId &id,
|
||||
const std::shared_ptr<Data::UniqueGift> &unique) {
|
||||
return (!id && unique)
|
||||
? MTP_inputSavedStarGiftSlug(MTP_string(unique->slug))
|
||||
: id.isUser()
|
||||
? MTP_inputSavedStarGiftUser(MTP_int(id.userMessageId().bare))
|
||||
: MTP_inputSavedStarGiftChat(
|
||||
id.chat()->input,
|
||||
|
|
|
@ -122,6 +122,7 @@ void EditCreditsSubscription(
|
|||
Fn<void(QString)> fail);
|
||||
|
||||
[[nodiscard]] MTPInputSavedStarGift InputSavedStarGiftId(
|
||||
const Data::SavedStarGiftId &id);
|
||||
const Data::SavedStarGiftId &id,
|
||||
const std::shared_ptr<Data::UniqueGift> &unique = nullptr);
|
||||
|
||||
} // namespace Api
|
||||
|
|
|
@ -3069,10 +3069,12 @@ void GiftResaleBox(
|
|||
state->updated.events()
|
||||
) | rpl::map([=] {
|
||||
auto result = GiftsDescriptor();
|
||||
const auto selfId = window->session().userPeerId();
|
||||
for (const auto &gift : state->data.list) {
|
||||
result.list.push_back(GiftTypeStars{
|
||||
.info = gift,
|
||||
.resale = true,
|
||||
.mine = (gift.unique->ownerId == selfId),
|
||||
});
|
||||
}
|
||||
return result;
|
||||
|
@ -4061,15 +4063,40 @@ void ShowUniqueGiftWearBox(
|
|||
}));
|
||||
}
|
||||
|
||||
void UpdateGiftSellPrice(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
std::shared_ptr<Data::UniqueGift> unique,
|
||||
Data::SavedStarGiftId savedId,
|
||||
int price) {
|
||||
const auto session = &show->session();
|
||||
session->api().request(MTPpayments_UpdateStarGiftPrice(
|
||||
Api::InputSavedStarGiftId(savedId, unique),
|
||||
MTP_long(price)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
session->api().applyUpdates(result);
|
||||
show->showToast(tr::lng_gift_sell_toast(
|
||||
tr::now,
|
||||
lt_name,
|
||||
Data::UniqueGiftName(*unique)));
|
||||
|
||||
unique->starsForResale = price;
|
||||
session->data().notifyGiftUpdate({
|
||||
.id = savedId,
|
||||
.slug = unique->slug,
|
||||
.action = Data::GiftUpdate::Action::ResaleChange,
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
show->showToast(error.type());
|
||||
}).send();
|
||||
|
||||
}
|
||||
|
||||
void ShowUniqueGiftSellBox(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
const Data::UniqueGift &gift,
|
||||
std::shared_ptr<Data::UniqueGift> unique,
|
||||
Data::SavedStarGiftId savedId,
|
||||
Settings::GiftWearBoxStyleOverride st) {
|
||||
const auto priceNow = gift.starsForResale;
|
||||
const auto name = Data::UniqueGiftName(gift);
|
||||
const auto slug = gift.slug;
|
||||
show->show(Box([=](not_null<Ui::GenericBox*> box) {
|
||||
box->setTitle(tr::lng_gift_sell_title());
|
||||
box->setStyle(st.box ? *st.box : st::upgradeGiftBox);
|
||||
|
@ -4078,6 +4105,9 @@ void ShowUniqueGiftSellBox(
|
|||
box->addTopButton(st.close ? *st.close : st::boxTitleClose, [=] {
|
||||
box->closeBox();
|
||||
});
|
||||
const auto priceNow = unique->starsForResale;
|
||||
const auto name = Data::UniqueGiftName(*unique);
|
||||
const auto slug = unique->slug;
|
||||
|
||||
const auto session = &show->session();
|
||||
AddSubsectionTitle(
|
||||
|
@ -4171,24 +4201,7 @@ void ShowUniqueGiftSellBox(
|
|||
return;
|
||||
}
|
||||
box->closeBox();
|
||||
session->api().request(MTPpayments_UpdateStarGiftPrice(
|
||||
(savedId
|
||||
? Api::InputSavedStarGiftId(savedId)
|
||||
: MTP_inputSavedStarGiftSlug(MTP_string(slug))),
|
||||
MTP_long(count)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
session->api().applyUpdates(result);
|
||||
show->showToast(tr::lng_gift_sell_toast(
|
||||
tr::now,
|
||||
lt_name,
|
||||
name));
|
||||
session->data().notifyGiftUpdate({
|
||||
|
||||
});
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
show->showToast(error.type());
|
||||
}).send();
|
||||
|
||||
UpdateGiftSellPrice(show, unique, savedId, count);
|
||||
});
|
||||
rpl::combine(
|
||||
box->widthValue(),
|
||||
|
|
|
@ -69,10 +69,15 @@ void ShowUniqueGiftWearBox(
|
|||
const Data::UniqueGift &gift,
|
||||
Settings::GiftWearBoxStyleOverride st);
|
||||
|
||||
void UpdateGiftSellPrice(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
std::shared_ptr<Data::UniqueGift> unique,
|
||||
Data::SavedStarGiftId savedId,
|
||||
int price);
|
||||
void ShowUniqueGiftSellBox(
|
||||
std::shared_ptr<ChatHelpers::Show> show,
|
||||
not_null<PeerData*> peer,
|
||||
const Data::UniqueGift &gift,
|
||||
std::shared_ptr<Data::UniqueGift> unique,
|
||||
Data::SavedStarGiftId savedId,
|
||||
Settings::GiftWearBoxStyleOverride st);
|
||||
|
||||
|
|
|
@ -443,7 +443,7 @@ void TransferGift(
|
|||
};
|
||||
if (gift->starsForTransfer <= 0) {
|
||||
session->api().request(MTPpayments_TransferStarGift(
|
||||
Api::InputSavedStarGiftId(savedId),
|
||||
Api::InputSavedStarGiftId(savedId, gift),
|
||||
to->input
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
session->api().applyUpdates(result);
|
||||
|
@ -459,7 +459,7 @@ void TransferGift(
|
|||
Ui::RequestStarsFormAndSubmit(
|
||||
window->uiShow(),
|
||||
MTP_inputInvoiceStarGiftTransfer(
|
||||
Api::InputSavedStarGiftId(savedId),
|
||||
Api::InputSavedStarGiftId(savedId, gift),
|
||||
to->input),
|
||||
std::move(formDone));
|
||||
}
|
||||
|
|
|
@ -89,9 +89,11 @@ struct GiftUpdate {
|
|||
Delete,
|
||||
Pin,
|
||||
Unpin,
|
||||
ResaleChange,
|
||||
};
|
||||
|
||||
Data::SavedStarGiftId id;
|
||||
QString slug;
|
||||
Action action = {};
|
||||
};
|
||||
|
||||
|
|
|
@ -55,10 +55,14 @@ std::strong_ordering operator<=>(const GiftBadge &a, const GiftBadge &b) {
|
|||
if (result3 != std::strong_ordering::equal) {
|
||||
return result3;
|
||||
}
|
||||
const auto result4 = (a.fg.rgb() <=> b.fg.rgb());
|
||||
const auto result4 = (a.border.rgb() <=> b.border.rgb());
|
||||
if (result4 != std::strong_ordering::equal) {
|
||||
return result4;
|
||||
}
|
||||
const auto result5 = (a.fg.rgb() <=> b.fg.rgb());
|
||||
if (result5 != std::strong_ordering::equal) {
|
||||
return result5;
|
||||
}
|
||||
return a.gradient <=> b.gradient;
|
||||
}
|
||||
|
||||
|
@ -80,14 +84,22 @@ void GiftButton::unsubscribe() {
|
|||
}
|
||||
|
||||
void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
|
||||
if (_descriptor == descriptor) {
|
||||
const auto unique = v::is<GiftTypeStars>(descriptor)
|
||||
? v::get<GiftTypeStars>(descriptor).info.unique.get()
|
||||
: nullptr;
|
||||
const auto resalePrice = unique ? unique->starsForResale : 0;
|
||||
if (_descriptor == descriptor && _resalePrice == resalePrice) {
|
||||
return;
|
||||
}
|
||||
auto player = base::take(_player);
|
||||
const auto starsType = Ui::Premium::MiniStars::Type::SlowStars;
|
||||
_mediaLifetime.destroy();
|
||||
_descriptor = descriptor;
|
||||
unsubscribe();
|
||||
|
||||
_descriptor = descriptor;
|
||||
_resalePrice = resalePrice;
|
||||
const auto resale = (_resalePrice > 0);
|
||||
_small = (mode != Mode::Full);
|
||||
v::match(descriptor, [&](const GiftTypePremium &data) {
|
||||
const auto months = data.months;
|
||||
_text = Ui::Text::String(st::giftBoxGiftHeight / 4);
|
||||
|
@ -125,7 +137,6 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
|
|||
{ 1., st::windowActiveTextFg->c },
|
||||
});
|
||||
}, [&](const GiftTypeStars &data) {
|
||||
const auto unique = data.info.unique.get();
|
||||
const auto soldOut = data.info.limitedCount
|
||||
&& !data.userpic
|
||||
&& !data.info.limitedLeft;
|
||||
|
@ -134,7 +145,7 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
|
|||
: data.from
|
||||
? Ui::MakeUserpicThumbnail(data.from)
|
||||
: Ui::MakeHiddenAuthorThumbnail();
|
||||
if (mode == Mode::Minimal) {
|
||||
if (_small && !resale) {
|
||||
_price = {};
|
||||
_stars.reset();
|
||||
return;
|
||||
|
@ -149,6 +160,9 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
|
|||
? unique->starsForResale
|
||||
: data.info.starsResellMin)
|
||||
).append(data.info.resellCount > 1 ? "+" : "")
|
||||
: (_small && unique && unique->starsForResale)
|
||||
? _delegate->monostar().append(' ').append(
|
||||
Lang::FormatCountDecimal(unique->starsForResale))
|
||||
: unique
|
||||
? tr::lng_gift_transfer_button(
|
||||
tr::now,
|
||||
|
@ -186,9 +200,8 @@ void GiftButton::setDescriptor(const GiftDescriptor &descriptor, Mode mode) {
|
|||
_uniquePatternEmoji = nullptr;
|
||||
_uniquePatternCache.clear();
|
||||
|
||||
if (mode != Mode::Full) {
|
||||
if (_small && !resale) {
|
||||
_button = QRect();
|
||||
_small = true;
|
||||
return;
|
||||
}
|
||||
const auto buttonw = _price.maxWidth();
|
||||
|
@ -403,6 +416,7 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
const auto unique = v::is<GiftTypeStars>(_descriptor)
|
||||
? v::get<GiftTypeStars>(_descriptor).info.unique.get()
|
||||
: nullptr;
|
||||
const auto onsale = (unique && unique->starsForResale && _small);
|
||||
const auto hidden = v::is<GiftTypeStars>(_descriptor)
|
||||
&& v::get<GiftTypeStars>(_descriptor).hidden;;
|
||||
const auto extend = currentExtend();
|
||||
|
@ -502,7 +516,7 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
&& !data.userpic
|
||||
&& !data.info.limitedLeft;
|
||||
return GiftBadge{
|
||||
.text = ((unique && data.resale && _small)
|
||||
.text = (onsale
|
||||
? tr::lng_gift_stars_on_sale(tr::now)
|
||||
: (unique && (data.resale || pinned))
|
||||
? ('#' + QString::number(unique->number))
|
||||
|
@ -520,7 +534,7 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
(((count % 1000) && (count < 10'000))
|
||||
? Lang::FormatCountDecimal(count)
|
||||
: Lang::FormatCountToShort(count).string))),
|
||||
.bg1 = ((unique && data.resale && _small)
|
||||
.bg1 = (onsale
|
||||
? st::boxTextFgGood->c
|
||||
: unique
|
||||
? unique->backdrop.edgeColor
|
||||
|
@ -529,12 +543,15 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
: soldOut
|
||||
? st::attentionButtonFg->c
|
||||
: st::windowActiveTextFg->c),
|
||||
.bg2 = ((unique && data.resale && _small)
|
||||
.bg2 = (onsale
|
||||
? QColor(0, 0, 0, 0)
|
||||
: unique
|
||||
? unique->backdrop.patternColor
|
||||
: QColor(0, 0, 0, 0)),
|
||||
.fg = ((unique && data.resale && _small)
|
||||
.border = (onsale
|
||||
? QColor(255, 255, 255)
|
||||
: QColor(0, 0, 0, 0)),
|
||||
.fg = (onsale
|
||||
? st::windowBg->c
|
||||
: unique
|
||||
? QColor(255, 255, 255)
|
||||
|
@ -577,7 +594,9 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
});
|
||||
|
||||
if (!_button.isEmpty()) {
|
||||
p.setBrush(unique
|
||||
p.setBrush(onsale
|
||||
? QBrush(unique->backdrop.patternColor)
|
||||
: unique
|
||||
? QBrush(QColor(255, 255, 255, .2 * 255))
|
||||
: premium
|
||||
? st::lightButtonBgOver
|
||||
|
@ -585,11 +604,13 @@ void GiftButton::paintEvent(QPaintEvent *e) {
|
|||
p.setPen(Qt::NoPen);
|
||||
if (!unique && !premium) {
|
||||
p.setOpacity(0.12);
|
||||
} else if (onsale) {
|
||||
p.setOpacity(0.8);
|
||||
}
|
||||
const auto geometry = _button;
|
||||
const auto radius = geometry.height() / 2.;
|
||||
p.drawRoundedRect(geometry, radius, radius);
|
||||
if (!premium) {
|
||||
if (!premium || onsale) {
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
if (_stars) {
|
||||
|
@ -816,6 +837,7 @@ QImage ValidateRotatedBadge(const GiftBadge &badge, int added) {
|
|||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto multiplier = ratio * 3;
|
||||
const auto size = (twidth + font->height * 2);
|
||||
const auto height = font->height + st::lineWidth;
|
||||
const auto textpos = QPoint(size - skip, added);
|
||||
auto image = QImage(
|
||||
QSize(size, size) * multiplier,
|
||||
|
@ -846,12 +868,16 @@ QImage ValidateRotatedBadge(const GiftBadge &badge, int added) {
|
|||
{
|
||||
auto p = QPainter(&result);
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
||||
p.save();
|
||||
p.translate(textpos);
|
||||
p.rotate(45.);
|
||||
const auto rect = QRect(-5 * twidth, 0, twidth * 12, font->height);
|
||||
const auto rect = QRect(-5 * twidth, 0, twidth * 12, height);
|
||||
if (badge.border.alpha() > 0) {
|
||||
p.setPen(badge.border);
|
||||
} else {
|
||||
p.setPen(Qt::NoPen);
|
||||
}
|
||||
if (badge.gradient) {
|
||||
const auto skip = font->height / M_SQRT2;
|
||||
auto gradient = QLinearGradient(
|
||||
|
|
|
@ -88,6 +88,7 @@ struct GiftBadge {
|
|||
QString text;
|
||||
QColor bg1;
|
||||
QColor bg2 = QColor(0, 0, 0, 0);
|
||||
QColor border = QColor(0, 0, 0, 0);
|
||||
QColor fg;
|
||||
bool gradient = false;
|
||||
bool small = false;
|
||||
|
@ -174,6 +175,7 @@ private:
|
|||
base::flat_map<float64, QImage> _uniquePatternCache;
|
||||
std::optional<Ui::Premium::ColoredMiniStars> _stars;
|
||||
Ui::Animations::Simple _selectedAnimation;
|
||||
int _resalePrice = 0;
|
||||
bool _subscribed = false;
|
||||
bool _patterned = false;
|
||||
bool _selected = false;
|
||||
|
|
|
@ -181,7 +181,14 @@ void InnerWidget::subscribeToUpdates() {
|
|||
const auto savedId = [](const Entry &entry) {
|
||||
return entry.gift.manageId;
|
||||
};
|
||||
const auto i = ranges::find(_entries, update.id, savedId);
|
||||
const auto bySlug = [](const Entry &entry) {
|
||||
return entry.gift.info.unique
|
||||
? entry.gift.info.unique->slug
|
||||
: QString();
|
||||
};
|
||||
const auto i = update.id
|
||||
? ranges::find(_entries, update.id, savedId)
|
||||
: ranges::find(_entries, update.slug, bySlug);
|
||||
if (i == end(_entries)) {
|
||||
return;
|
||||
}
|
||||
|
@ -224,6 +231,13 @@ void InnerWidget::subscribeToUpdates() {
|
|||
} else {
|
||||
markUnpinned(i);
|
||||
}
|
||||
} else if (update.action == Action::ResaleChange) {
|
||||
for (auto &view : _views) {
|
||||
if (view.index == index) {
|
||||
view.index = -1;
|
||||
view.manageId = {};
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1052,21 +1052,7 @@ void FillUniqueGiftMenu(
|
|||
const auto name = UniqueGiftName(*unique);
|
||||
const auto confirm = [=](Fn<void()> close) {
|
||||
close();
|
||||
session->api().request(MTPpayments_UpdateStarGiftPrice(
|
||||
(savedId
|
||||
? Api::InputSavedStarGiftId(savedId)
|
||||
: MTP_inputSavedStarGiftSlug(
|
||||
MTP_string(unique->slug))),
|
||||
MTP_long(0)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
session->api().applyUpdates(result);
|
||||
show->showToast(tr::lng_gift_sell_removed(
|
||||
tr::now,
|
||||
lt_name,
|
||||
name));
|
||||
}).fail([=](const MTP::Error &error) {
|
||||
show->showToast(error.type());
|
||||
}).send();
|
||||
Ui::UpdateGiftSellPrice(show, unique, savedId, 0);
|
||||
};
|
||||
show->show(Ui::MakeConfirmBox({
|
||||
.text = tr::lng_gift_sell_unlist_sure(),
|
||||
|
@ -1082,7 +1068,7 @@ void FillUniqueGiftMenu(
|
|||
const auto style = st.giftWearBox
|
||||
? *st.giftWearBox
|
||||
: GiftWearBoxStyleOverride();
|
||||
ShowUniqueGiftSellBox(show, owner, *unique, savedId, style);
|
||||
ShowUniqueGiftSellBox(show, owner, unique, savedId, style);
|
||||
}, st.resell ? st.resell : &st::menuIconTagSell);
|
||||
}
|
||||
}
|
||||
|
@ -1177,6 +1163,8 @@ void GenericCreditsEntryBox(
|
|||
&& !e.converted
|
||||
&& starGiftSender;
|
||||
const auto canConvert = forConvert && !timeExceeded;
|
||||
const auto inResale = uniqueGift && (uniqueGift->starsForResale > 0);
|
||||
const auto canBuyResold = inResale && (e.bareGiftOwnerId != selfPeerId);
|
||||
|
||||
if (auto savedId = EntryToSavedStarGiftId(session, e)) {
|
||||
session->data().giftUpdates(
|
||||
|
@ -1219,6 +1207,8 @@ void GenericCreditsEntryBox(
|
|||
if (uniqueGift) {
|
||||
box->setNoContentMargin(true);
|
||||
|
||||
//const auto canEditResale = (e.bareGiftOwnerId == selfPeerId);
|
||||
//auto starsResale = rpl
|
||||
AddUniqueGiftCover(content, rpl::single(*uniqueGift));
|
||||
|
||||
AddSkip(content, st::defaultVerticalListSkip * 2);
|
||||
|
@ -1970,7 +1960,7 @@ void GenericCreditsEntryBox(
|
|||
if (willBusy) {
|
||||
state->confirmButtonBusy = true;
|
||||
send();
|
||||
} else if (uniqueGift && uniqueGift->starsForResale && !giftToSelf) {
|
||||
} else if (canBuyResold) {
|
||||
const auto to = e.bareGiftResaleRecipientId
|
||||
? show->session().data().peer(
|
||||
PeerId(e.bareGiftResaleRecipientId))
|
||||
|
@ -1988,7 +1978,7 @@ void GenericCreditsEntryBox(
|
|||
box->closeBox();
|
||||
}
|
||||
});
|
||||
if (uniqueGift && uniqueGift->starsForResale && !giftToSelf) {
|
||||
if (canBuyResold) {
|
||||
button->setText(tr::lng_gift_buy_resale_button(
|
||||
lt_cost,
|
||||
rpl::single(
|
||||
|
|
|
@ -58,7 +58,9 @@ void ConfirmBox(not_null<Ui::GenericBox*> box, ConfirmBoxArgs &&args) {
|
|||
};
|
||||
|
||||
const auto &defaultButtonStyle = box->getDelegate()->style().button;
|
||||
const auto confirmTextPlain = v::text::is_plain(args.confirmText);
|
||||
const auto confirmTextPlain = v::is_null(args.confirmText)
|
||||
|| v::is<rpl::producer<QString>>(args.confirmText)
|
||||
|| v::is<QString>(args.confirmText);
|
||||
const auto confirmButton = box->addButton(
|
||||
(confirmTextPlain
|
||||
? v::text::take_plain(
|
||||
|
|
Loading…
Add table
Reference in a new issue