mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Added badge and loading state to confirm button in giveaway box.
This commit is contained in:
parent
4150cdff86
commit
43aa8825a5
4 changed files with 166 additions and 4 deletions
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "countries/countries_instance.h"
|
#include "countries/countries_instance.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
|
#include "info/boosts/giveaway/boost_badge.h"
|
||||||
#include "info/boosts/giveaway/giveaway_list_controllers.h"
|
#include "info/boosts/giveaway/giveaway_list_controllers.h"
|
||||||
#include "info/boosts/giveaway/giveaway_type_row.h"
|
#include "info/boosts/giveaway/giveaway_type_row.h"
|
||||||
#include "info/boosts/giveaway/select_countries_box.h"
|
#include "info/boosts/giveaway/select_countries_box.h"
|
||||||
|
@ -253,7 +254,7 @@ void CreateGiveawayBox(
|
||||||
rpl::variable<TimeId> dateValue;
|
rpl::variable<TimeId> dateValue;
|
||||||
rpl::variable<std::vector<QString>> countriesValue;
|
rpl::variable<std::vector<QString>> countriesValue;
|
||||||
|
|
||||||
bool confirmButtonBusy = false;
|
rpl::variable<bool> confirmButtonBusy = true;
|
||||||
};
|
};
|
||||||
const auto state = box->lifetime().make_state<State>(peer);
|
const auto state = box->lifetime().make_state<State>(peer);
|
||||||
const auto typeGroup = std::make_shared<GiveawayGroup>();
|
const auto typeGroup = std::make_shared<GiveawayGroup>();
|
||||||
|
@ -726,17 +727,41 @@ void CreateGiveawayBox(
|
||||||
}, box->lifetime());
|
}, box->lifetime());
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
// TODO mini-icon.
|
using namespace Info::Statistics;
|
||||||
const auto &stButton = st::startGiveawayBox;
|
const auto &stButton = st::startGiveawayBox;
|
||||||
box->setStyle(stButton);
|
box->setStyle(stButton);
|
||||||
auto button = object_ptr<Ui::RoundButton>(
|
auto button = object_ptr<Ui::RoundButton>(
|
||||||
box,
|
box,
|
||||||
|
rpl::never<QString>(),
|
||||||
|
st::giveawayGiftCodeStartButton);
|
||||||
|
|
||||||
|
AddLabelWithBadgeToButton(
|
||||||
|
button,
|
||||||
rpl::conditional(
|
rpl::conditional(
|
||||||
state->typeValue.value(
|
state->typeValue.value(
|
||||||
) | rpl::map(rpl::mappers::_1 == GiveawayType::Random),
|
) | rpl::map(rpl::mappers::_1 == GiveawayType::Random),
|
||||||
tr::lng_giveaway_start(),
|
tr::lng_giveaway_start(),
|
||||||
tr::lng_giveaway_award()),
|
tr::lng_giveaway_award()),
|
||||||
st::giveawayGiftCodeStartButton);
|
state->sliderValue.value(
|
||||||
|
) | rpl::map([=](int v) -> int {
|
||||||
|
return state->apiOptions.giveawayBoostsPerPremium() * v;
|
||||||
|
}),
|
||||||
|
state->confirmButtonBusy.value() | rpl::map(!rpl::mappers::_1));
|
||||||
|
|
||||||
|
{
|
||||||
|
const auto loadingAnimation = InfiniteRadialAnimationWidget(
|
||||||
|
button,
|
||||||
|
st::giveawayGiftCodeStartButton.height / 2);
|
||||||
|
button->sizeValue(
|
||||||
|
) | rpl::start_with_next([=](const QSize &s) {
|
||||||
|
const auto size = loadingAnimation->size();
|
||||||
|
loadingAnimation->moveToLeft(
|
||||||
|
(s.width() - size.width()) / 2,
|
||||||
|
(s.height() - size.height()) / 2);
|
||||||
|
}, loadingAnimation->lifetime());
|
||||||
|
loadingAnimation->showOn(state->confirmButtonBusy.value());
|
||||||
|
}
|
||||||
|
|
||||||
button->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
button->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||||
state->typeValue.value(
|
state->typeValue.value(
|
||||||
) | rpl::start_with_next([=, raw = button.data()] {
|
) | rpl::start_with_next([=, raw = button.data()] {
|
||||||
|
@ -745,7 +770,7 @@ void CreateGiveawayBox(
|
||||||
- stButton.buttonPadding.right());
|
- stButton.buttonPadding.right());
|
||||||
}, button->lifetime());
|
}, button->lifetime());
|
||||||
button->setClickedCallback([=] {
|
button->setClickedCallback([=] {
|
||||||
if (state->confirmButtonBusy) {
|
if (state->confirmButtonBusy.current()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const auto type = typeGroup->value();
|
const auto type = typeGroup->value();
|
||||||
|
@ -847,6 +872,7 @@ void CreateGiveawayBox(
|
||||||
}, [=] {
|
}, [=] {
|
||||||
state->lifetimeApi.destroy();
|
state->lifetimeApi.destroy();
|
||||||
loading->toggle(false, anim::type::instant);
|
loading->toggle(false, anim::type::instant);
|
||||||
|
state->confirmButtonBusy = false;
|
||||||
fillSliderContainer();
|
fillSliderContainer();
|
||||||
rebuildListOptions(1);
|
rebuildListOptions(1);
|
||||||
contentWrap->toggle(true, anim::type::instant);
|
contentWrap->toggle(true, anim::type::instant);
|
||||||
|
|
|
@ -7,11 +7,51 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "info/boosts/giveaway/boost_badge.h"
|
#include "info/boosts/giveaway/boost_badge.h"
|
||||||
|
|
||||||
|
#include "ui/effects/radial_animation.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
#include "ui/rect.h"
|
#include "ui/rect.h"
|
||||||
|
#include "ui/rp_widget.h"
|
||||||
|
#include "ui/widgets/labels.h"
|
||||||
|
#include "styles/style_giveaway.h"
|
||||||
|
#include "styles/style_statistics.h"
|
||||||
|
#include "styles/style_widgets.h"
|
||||||
|
|
||||||
namespace Info::Statistics {
|
namespace Info::Statistics {
|
||||||
|
|
||||||
|
not_null<Ui::RpWidget*> InfiniteRadialAnimationWidget(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
int size) {
|
||||||
|
class Widget final : public Ui::RpWidget {
|
||||||
|
public:
|
||||||
|
Widget(not_null<Ui::RpWidget*> p, int size)
|
||||||
|
: Ui::RpWidget(p)
|
||||||
|
, _animation([=] { update(); }, st::startGiveawayButtonLoading) {
|
||||||
|
resize(size, size);
|
||||||
|
shownValue() | rpl::start_with_next([=](bool v) {
|
||||||
|
return v
|
||||||
|
? _animation.start()
|
||||||
|
: _animation.stop(anim::type::instant);
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintEvent(QPaintEvent *e) override {
|
||||||
|
auto p = QPainter(this);
|
||||||
|
p.setPen(st::activeButtonFg);
|
||||||
|
p.setBrush(st::activeButtonFg);
|
||||||
|
const auto r = rect()
|
||||||
|
- Margins(st::startGiveawayButtonLoading.thickness);
|
||||||
|
_animation.draw(p, r.topLeft(), r.size(), width());
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
Ui::InfiniteRadialAnimation _animation;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ui::CreateChild<Widget>(parent.get(), size);
|
||||||
|
}
|
||||||
|
|
||||||
QImage CreateBadge(
|
QImage CreateBadge(
|
||||||
const style::TextStyle &textStyle,
|
const style::TextStyle &textStyle,
|
||||||
const QString &text,
|
const QString &text,
|
||||||
|
@ -64,4 +104,70 @@ QImage CreateBadge(
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AddLabelWithBadgeToButton(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
rpl::producer<QString> text,
|
||||||
|
rpl::producer<int> number,
|
||||||
|
rpl::producer<bool> shown) {
|
||||||
|
struct State {
|
||||||
|
QImage badge;
|
||||||
|
};
|
||||||
|
const auto state = parent->lifetime().make_state<State>();
|
||||||
|
const auto label = Ui::CreateChild<Ui::LabelSimple>(
|
||||||
|
parent.get(),
|
||||||
|
st::startGiveawayButtonLabelSimple);
|
||||||
|
std::move(
|
||||||
|
text
|
||||||
|
) | rpl::start_with_next([=](const QString &s) {
|
||||||
|
label->setText(s);
|
||||||
|
}, label->lifetime());
|
||||||
|
const auto count = Ui::CreateChild<Ui::RpWidget>(parent.get());
|
||||||
|
count->paintRequest(
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
auto p = QPainter(count);
|
||||||
|
p.drawImage(0, 0, state->badge);
|
||||||
|
}, count->lifetime());
|
||||||
|
std::move(
|
||||||
|
number
|
||||||
|
) | rpl::start_with_next([=](int c) {
|
||||||
|
state->badge = Info::Statistics::CreateBadge(
|
||||||
|
st::startGiveawayButtonTextStyle,
|
||||||
|
QString::number(c),
|
||||||
|
st::boostsListBadgeHeight,
|
||||||
|
st::startGiveawayButtonBadgeTextPadding,
|
||||||
|
st::activeButtonFg,
|
||||||
|
st::activeButtonBg,
|
||||||
|
1.,
|
||||||
|
st::boostsListMiniIconPadding,
|
||||||
|
st::startGiveawayButtonMiniIcon);
|
||||||
|
count->resize(state->badge.size() / style::DevicePixelRatio());
|
||||||
|
count->update();
|
||||||
|
}, count->lifetime());
|
||||||
|
|
||||||
|
std::move(
|
||||||
|
shown
|
||||||
|
) | rpl::start_with_next([=](bool shown) {
|
||||||
|
count->setVisible(shown);
|
||||||
|
label->setVisible(shown);
|
||||||
|
}, count->lifetime());
|
||||||
|
|
||||||
|
rpl::combine(
|
||||||
|
parent->sizeValue(),
|
||||||
|
label->sizeValue(),
|
||||||
|
count->sizeValue()
|
||||||
|
) | rpl::start_with_next([=](
|
||||||
|
const QSize &s,
|
||||||
|
const QSize &s1,
|
||||||
|
const QSize &s2) {
|
||||||
|
const auto sum = st::startGiveawayButtonMiniIconSkip
|
||||||
|
+ s1.width()
|
||||||
|
+ s2.width();
|
||||||
|
const auto contentLeft = (s.width() - sum) / 2;
|
||||||
|
label->moveToLeft(contentLeft, (s.height() - s1.height()) / 2);
|
||||||
|
count->moveToLeft(
|
||||||
|
contentLeft + sum - s2.width(),
|
||||||
|
(s.height() - s2.height()) / 2 + st::boostsListMiniIconSkip);
|
||||||
|
}, parent->lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Info::Statistics
|
} // namespace Info::Statistics
|
||||||
|
|
|
@ -11,6 +11,10 @@ namespace style {
|
||||||
struct TextStyle;
|
struct TextStyle;
|
||||||
} // namespace style
|
} // namespace style
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RpWidget;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace Info::Statistics {
|
namespace Info::Statistics {
|
||||||
|
|
||||||
[[nodiscard]] QImage CreateBadge(
|
[[nodiscard]] QImage CreateBadge(
|
||||||
|
@ -24,4 +28,14 @@ namespace Info::Statistics {
|
||||||
const style::margins &iconPadding,
|
const style::margins &iconPadding,
|
||||||
const style::icon &icon);
|
const style::icon &icon);
|
||||||
|
|
||||||
|
[[nodiscard]] not_null<Ui::RpWidget*> InfiniteRadialAnimationWidget(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
int size);
|
||||||
|
|
||||||
|
void AddLabelWithBadgeToButton(
|
||||||
|
not_null<Ui::RpWidget*> parent,
|
||||||
|
rpl::producer<QString> text,
|
||||||
|
rpl::producer<int> number,
|
||||||
|
rpl::producer<bool> shown);
|
||||||
|
|
||||||
} // namespace Info::Statistics
|
} // namespace Info::Statistics
|
||||||
|
|
|
@ -178,3 +178,19 @@ startGiveawayCover: PremiumCover(giveawayGiftCodeCover) {
|
||||||
bg: boxDividerBg;
|
bg: boxDividerBg;
|
||||||
additionalShadowForDarkThemes: false;
|
additionalShadowForDarkThemes: false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
startGiveawayButtonLabelSimple: LabelSimple {
|
||||||
|
font: semiboldFont;
|
||||||
|
textFg: activeButtonFg;
|
||||||
|
}
|
||||||
|
startGiveawayButtonMiniIcon: icon{{ "boosts/boost_mini2", activeButtonBg }};
|
||||||
|
startGiveawayButtonMiniIconSkip: 5px;
|
||||||
|
startGiveawayButtonBadgeTextPadding: margins(16px, -1px, 6px, 0px);
|
||||||
|
startGiveawayButtonTextStyle: TextStyle(defaultTextStyle) {
|
||||||
|
font: semiboldFont;
|
||||||
|
}
|
||||||
|
|
||||||
|
startGiveawayButtonLoading: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
|
||||||
|
color: activeButtonFg;
|
||||||
|
thickness: 2px;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue