Add countries to giveaway messages.
This commit is contained in:
parent
84a1fec7b1
commit
486d5b63d3
|
@ -2090,6 +2090,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_prizes_participants_all#other" = "All subscribers of the channels:";
|
"lng_prizes_participants_all#other" = "All subscribers of the channels:";
|
||||||
"lng_prizes_participants_new#one" = "All users who joined the channel below after this date:";
|
"lng_prizes_participants_new#one" = "All users who joined the channel below after this date:";
|
||||||
"lng_prizes_participants_new#other" = "All users who joined the channels below after this date:";
|
"lng_prizes_participants_new#other" = "All users who joined the channels below after this date:";
|
||||||
|
"lng_prizes_countries" = "from {countries}";
|
||||||
|
"lng_prizes_countries_and_one" = "{countries}, {country}";
|
||||||
|
"lng_prizes_countries_and_last" = "{countries} and {country}";
|
||||||
"lng_prizes_date" = "Winners Selection Date";
|
"lng_prizes_date" = "Winners Selection Date";
|
||||||
"lng_prizes_how_works" = "Learn more";
|
"lng_prizes_how_works" = "Learn more";
|
||||||
"lng_prizes_how_title" = "About this giveaway";
|
"lng_prizes_how_title" = "About this giveaway";
|
||||||
|
|
|
@ -375,6 +375,13 @@ Giveaway ComputeGiveawayData(
|
||||||
for (const auto &id : data.vchannels().v) {
|
for (const auto &id : data.vchannels().v) {
|
||||||
result.channels.push_back(owner->channel(ChannelId(id)));
|
result.channels.push_back(owner->channel(ChannelId(id)));
|
||||||
}
|
}
|
||||||
|
if (const auto countries = data.vcountries_iso2()) {
|
||||||
|
result.countries.reserve(countries->v.size());
|
||||||
|
for (const auto &country : countries->v) {
|
||||||
|
result.countries.push_back(qs(country));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.countries = { u"FR"_q, u"FI"_q, u"UA"_q, u"IT"_q };
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -92,6 +92,7 @@ struct Invoice {
|
||||||
|
|
||||||
struct Giveaway {
|
struct Giveaway {
|
||||||
std::vector<not_null<ChannelData*>> channels;
|
std::vector<not_null<ChannelData*>> channels;
|
||||||
|
std::vector<QString> countries;
|
||||||
TimeId untilDate = 0;
|
TimeId untilDate = 0;
|
||||||
int quantity = 0;
|
int quantity = 0;
|
||||||
int months = 0;
|
int months = 0;
|
||||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/unixtime.h"
|
#include "base/unixtime.h"
|
||||||
#include "boxes/gift_premium_box.h"
|
#include "boxes/gift_premium_box.h"
|
||||||
#include "chat_helpers/stickers_gift_box_pack.h"
|
#include "chat_helpers/stickers_gift_box_pack.h"
|
||||||
|
#include "countries/countries_instance.h"
|
||||||
#include "data/data_channel.h"
|
#include "data/data_channel.h"
|
||||||
#include "data/data_document.h"
|
#include "data/data_document.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
|
@ -25,6 +26,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
#include "ui/chat/message_bubble.h"
|
#include "ui/chat/message_bubble.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/text/text_utilities.h"
|
#include "ui/text/text_utilities.h"
|
||||||
#include "ui/widgets/tooltip.h"
|
#include "ui/widgets/tooltip.h"
|
||||||
#include "ui/painter.h"
|
#include "ui/painter.h"
|
||||||
|
@ -34,8 +36,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr auto kChannelBgAlpha = 32;
|
|
||||||
|
|
||||||
[[nodiscard]] QSize CountOptimalTextSize(
|
[[nodiscard]] QSize CountOptimalTextSize(
|
||||||
const Ui::Text::String &text,
|
const Ui::Text::String &text,
|
||||||
int minWidth,
|
int minWidth,
|
||||||
|
@ -59,8 +59,10 @@ Giveaway::Giveaway(
|
||||||
, _prizes(st::msgMinWidth)
|
, _prizes(st::msgMinWidth)
|
||||||
, _participantsTitle(st::msgMinWidth)
|
, _participantsTitle(st::msgMinWidth)
|
||||||
, _participants(st::msgMinWidth)
|
, _participants(st::msgMinWidth)
|
||||||
|
, _countries(st::msgMinWidth)
|
||||||
, _winnersTitle(st::msgMinWidth)
|
, _winnersTitle(st::msgMinWidth)
|
||||||
, _winners(st::msgMinWidth) {
|
, _winners(st::msgMinWidth)
|
||||||
|
, _colorIndex(parent->data()->computeColorIndex()) {
|
||||||
fillFromData(giveaway);
|
fillFromData(giveaway);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,6 +110,33 @@ void Giveaway::fillFromData(not_null<Data::Giveaway*> giveaway) {
|
||||||
}
|
}
|
||||||
const auto channels = int(_channels.size());
|
const auto channels = int(_channels.size());
|
||||||
|
|
||||||
|
const auto &instance = Countries::Instance(); ;
|
||||||
|
auto countries = QStringList();
|
||||||
|
for (const auto &country : giveaway->countries) {
|
||||||
|
const auto name = instance.countryNameByISO2(country);
|
||||||
|
const auto flag = instance.flagEmojiByISO2(country);
|
||||||
|
countries.push_back(flag + QChar(0xA0) + name);
|
||||||
|
}
|
||||||
|
if (const auto count = countries.size()) {
|
||||||
|
auto united = countries.front();
|
||||||
|
for (auto i = 1; i != count; ++i) {
|
||||||
|
united = ((i + 1 == count)
|
||||||
|
? tr::lng_prizes_countries_and_last
|
||||||
|
: tr::lng_prizes_countries_and_one)(
|
||||||
|
tr::now,
|
||||||
|
lt_countries,
|
||||||
|
united,
|
||||||
|
lt_country,
|
||||||
|
countries[i]);
|
||||||
|
}
|
||||||
|
_countries.setText(
|
||||||
|
st::defaultTextStyle,
|
||||||
|
tr::lng_prizes_countries(tr::now, lt_countries, united),
|
||||||
|
kDefaultTextOptions);
|
||||||
|
} else {
|
||||||
|
_countries.clear();
|
||||||
|
}
|
||||||
|
|
||||||
_participants.setText(
|
_participants.setText(
|
||||||
st::defaultTextStyle,
|
st::defaultTextStyle,
|
||||||
(giveaway->all
|
(giveaway->all
|
||||||
|
@ -161,7 +190,19 @@ QSize Giveaway::countOptimalSize() {
|
||||||
padding.left(),
|
padding.left(),
|
||||||
channelsTop,
|
channelsTop,
|
||||||
available);
|
available);
|
||||||
_winnersTitleTop = channelsBottom + st::chatGiveawayDateTop;
|
_countriesTop = channelsBottom;
|
||||||
|
if (_countries.isEmpty()) {
|
||||||
|
_winnersTitleTop = _countriesTop + st::chatGiveawayDateTop;
|
||||||
|
} else {
|
||||||
|
const auto countriesSize = CountOptimalTextSize(
|
||||||
|
_countries,
|
||||||
|
st::msgMinWidth,
|
||||||
|
available);
|
||||||
|
_countriesWidth = countriesSize.width();
|
||||||
|
_winnersTitleTop = _countriesTop
|
||||||
|
+ _countries.countHeight(available)
|
||||||
|
+ st::chatGiveawayCountriesSkip;
|
||||||
|
}
|
||||||
_winnersTop = _winnersTitleTop
|
_winnersTop = _winnersTitleTop
|
||||||
+ _winnersTitle.countHeight(available)
|
+ _winnersTitle.countHeight(available)
|
||||||
+ st::chatGiveawayDateSkip;
|
+ st::chatGiveawayDateSkip;
|
||||||
|
@ -252,6 +293,9 @@ void Giveaway::draw(Painter &p, const PaintContext &context) const {
|
||||||
paintText(_prizes, _prizesTop, _prizesWidth);
|
paintText(_prizes, _prizesTop, _prizesWidth);
|
||||||
paintText(_participantsTitle, _participantsTitleTop, paintw);
|
paintText(_participantsTitle, _participantsTitleTop, paintw);
|
||||||
paintText(_participants, _participantsTop, _participantsWidth);
|
paintText(_participants, _participantsTop, _participantsWidth);
|
||||||
|
if (!_countries.isEmpty()) {
|
||||||
|
paintText(_countries, _countriesTop, _countriesWidth);
|
||||||
|
}
|
||||||
paintText(_winnersTitle, _winnersTitleTop, paintw);
|
paintText(_winnersTitle, _winnersTitleTop, paintw);
|
||||||
paintText(_winners, _winnersTop, paintw);
|
paintText(_winners, _winnersTop, paintw);
|
||||||
paintChannels(p, context);
|
paintChannels(p, context);
|
||||||
|
@ -302,16 +346,18 @@ void Giveaway::paintChannels(
|
||||||
const auto size = _channels[0].geometry.height();
|
const auto size = _channels[0].geometry.height();
|
||||||
const auto ratio = style::DevicePixelRatio();
|
const auto ratio = style::DevicePixelRatio();
|
||||||
const auto stm = context.messageStyle();
|
const auto stm = context.messageStyle();
|
||||||
auto bg = stm->msgReplyBarColor->c;
|
const auto selected = context.selected();
|
||||||
bg.setAlpha(kChannelBgAlpha);
|
const auto cache = context.outbg
|
||||||
if (_channelCorners[0].isNull() || _channelBg != bg) {
|
? stm->replyCache.get()
|
||||||
_channelBg = bg;
|
: context.st->coloredReplyCache(selected, _colorIndex).get();
|
||||||
|
if (_channelCorners[0].isNull() || _channelBg != cache->bg) {
|
||||||
|
_channelBg = cache->bg;
|
||||||
_channelCorners = Images::CornersMask(size / 2);
|
_channelCorners = Images::CornersMask(size / 2);
|
||||||
for (auto &image : _channelCorners) {
|
for (auto &image : _channelCorners) {
|
||||||
style::colorizeImage(image, bg, &image);
|
style::colorizeImage(image, cache->bg, &image);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
p.setPen(stm->msgReplyBarColor);
|
p.setPen(cache->outline);
|
||||||
const auto padding = st::chatGiveawayChannelPadding;
|
const auto padding = st::chatGiveawayChannelPadding;
|
||||||
for (const auto &channel : _channels) {
|
for (const auto &channel : _channels) {
|
||||||
const auto &thumbnail = channel.thumbnail;
|
const auto &thumbnail = channel.thumbnail;
|
||||||
|
@ -321,7 +367,20 @@ void Giveaway::paintChannels(
|
||||||
view->history()->owner().requestViewRepaint(view);
|
view->history()->owner().requestViewRepaint(view);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Ui::DrawRoundedRect(p, geometry, _channelBg, _channelCorners);
|
Ui::DrawRoundedRect(p, geometry, _channelBg, _channelCorners);
|
||||||
|
if (channel.ripple) {
|
||||||
|
channel.ripple->paint(
|
||||||
|
p,
|
||||||
|
geometry.x(),
|
||||||
|
geometry.y(),
|
||||||
|
width(),
|
||||||
|
&cache->bg);
|
||||||
|
if (channel.ripple->empty()) {
|
||||||
|
channel.ripple = nullptr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
p.drawImage(geometry.topLeft(), thumbnail->image(size));
|
p.drawImage(geometry.topLeft(), thumbnail->image(size));
|
||||||
const auto left = size + padding.left();
|
const auto left = size + padding.left();
|
||||||
const auto top = padding.top();
|
const auto top = padding.top();
|
||||||
|
@ -337,7 +396,7 @@ void Giveaway::paintChannels(
|
||||||
.elisionBreakEverywhere = true,
|
.elisionBreakEverywhere = true,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
_subscribedToThumbnails = true;
|
_subscribedToThumbnails = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Giveaway::ensureStickerCreated() const {
|
void Giveaway::ensureStickerCreated() const {
|
||||||
|
@ -410,12 +469,45 @@ TextState Giveaway::textState(QPoint point, StateRequest request) const {
|
||||||
for (const auto &channel : _channels) {
|
for (const auto &channel : _channels) {
|
||||||
if (channel.geometry.contains(point)) {
|
if (channel.geometry.contains(point)) {
|
||||||
result.link = channel.link;
|
result.link = channel.link;
|
||||||
|
_lastPoint = point;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Giveaway::clickHandlerActiveChanged(
|
||||||
|
const ClickHandlerPtr &p,
|
||||||
|
bool active) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Giveaway::clickHandlerPressedChanged(
|
||||||
|
const ClickHandlerPtr &p,
|
||||||
|
bool pressed) {
|
||||||
|
for (auto &channel : _channels) {
|
||||||
|
if (channel.link != p) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (pressed) {
|
||||||
|
if (!channel.ripple) {
|
||||||
|
const auto full = QRect(0, 0, width(), height());
|
||||||
|
const auto outer = full.marginsRemoved(inBubblePadding());
|
||||||
|
const auto owner = &parent()->history()->owner();
|
||||||
|
channel.ripple = std::make_unique<Ui::RippleAnimation>(
|
||||||
|
st::defaultRippleAnimation,
|
||||||
|
Ui::RippleAnimation::RoundRectMask(
|
||||||
|
channel.geometry.size(),
|
||||||
|
channel.geometry.height() / 2),
|
||||||
|
[=] { owner->requestViewRepaint(parent()); });
|
||||||
|
}
|
||||||
|
channel.ripple->add(_lastPoint - channel.geometry.topLeft());
|
||||||
|
} else if (channel.ripple) {
|
||||||
|
channel.ripple->lastStop();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool Giveaway::hideFromName() const {
|
bool Giveaway::hideFromName() const {
|
||||||
return !parent()->data()->Has<HistoryMessageForwarded>();
|
return !parent()->data()->Has<HistoryMessageForwarded>();
|
||||||
}
|
}
|
||||||
|
@ -425,7 +517,8 @@ bool Giveaway::hasHeavyPart() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Giveaway::unloadHeavyPart() {
|
void Giveaway::unloadHeavyPart() {
|
||||||
if (base::take(_subscribedToThumbnails)) {
|
if (_subscribedToThumbnails) {
|
||||||
|
_subscribedToThumbnails = 0;
|
||||||
for (const auto &channel : _channels) {
|
for (const auto &channel : _channels) {
|
||||||
channel.thumbnail->subscribeToUpdates(nullptr);
|
channel.thumbnail->subscribeToUpdates(nullptr);
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,10 @@ namespace Dialogs::Stories {
|
||||||
class Thumbnail;
|
class Thumbnail;
|
||||||
} // namespace Dialogs::Stories
|
} // namespace Dialogs::Stories
|
||||||
|
|
||||||
|
namespace Ui {
|
||||||
|
class RippleAnimation;
|
||||||
|
} // namespace Ui
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
class Giveaway final : public Media {
|
class Giveaway final : public Media {
|
||||||
|
@ -30,6 +34,13 @@ public:
|
||||||
void draw(Painter &p, const PaintContext &context) const override;
|
void draw(Painter &p, const PaintContext &context) const override;
|
||||||
TextState textState(QPoint point, StateRequest request) const override;
|
TextState textState(QPoint point, StateRequest request) const override;
|
||||||
|
|
||||||
|
void clickHandlerActiveChanged(
|
||||||
|
const ClickHandlerPtr &p,
|
||||||
|
bool active) override;
|
||||||
|
void clickHandlerPressedChanged(
|
||||||
|
const ClickHandlerPtr &p,
|
||||||
|
bool pressed) override;
|
||||||
|
|
||||||
bool needsBubble() const override {
|
bool needsBubble() const override {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -57,6 +68,7 @@ private:
|
||||||
std::shared_ptr<Thumbnail> thumbnail;
|
std::shared_ptr<Thumbnail> thumbnail;
|
||||||
QRect geometry;
|
QRect geometry;
|
||||||
ClickHandlerPtr link;
|
ClickHandlerPtr link;
|
||||||
|
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
};
|
};
|
||||||
|
|
||||||
void paintBadge(Painter &p, const PaintContext &context) const;
|
void paintBadge(Painter &p, const PaintContext &context) const;
|
||||||
|
@ -78,6 +90,7 @@ private:
|
||||||
Ui::Text::String _participantsTitle;
|
Ui::Text::String _participantsTitle;
|
||||||
Ui::Text::String _participants;
|
Ui::Text::String _participants;
|
||||||
std::vector<Channel> _channels;
|
std::vector<Channel> _channels;
|
||||||
|
Ui::Text::String _countries;
|
||||||
Ui::Text::String _winnersTitle;
|
Ui::Text::String _winnersTitle;
|
||||||
Ui::Text::String _winners;
|
Ui::Text::String _winners;
|
||||||
|
|
||||||
|
@ -88,6 +101,7 @@ private:
|
||||||
mutable QImage _badge;
|
mutable QImage _badge;
|
||||||
mutable QImage _badgeCache;
|
mutable QImage _badgeCache;
|
||||||
|
|
||||||
|
mutable QPoint _lastPoint;
|
||||||
int _months = 0;
|
int _months = 0;
|
||||||
int _quantity = 0;
|
int _quantity = 0;
|
||||||
int _stickerTop = 0;
|
int _stickerTop = 0;
|
||||||
|
@ -97,9 +111,12 @@ private:
|
||||||
int _participantsTitleTop = 0;
|
int _participantsTitleTop = 0;
|
||||||
int _participantsTop = 0;
|
int _participantsTop = 0;
|
||||||
int _participantsWidth = 0;
|
int _participantsWidth = 0;
|
||||||
|
int _countriesTop = 0;
|
||||||
|
int _countriesWidth = 0;
|
||||||
int _winnersTitleTop = 0;
|
int _winnersTitleTop = 0;
|
||||||
int _winnersTop = 0;
|
int _winnersTop = 0;
|
||||||
mutable bool _subscribedToThumbnails = false;
|
uint8 _colorIndex : 7 = 0;
|
||||||
|
mutable uint8 _subscribedToThumbnails : 1 = 0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -957,6 +957,7 @@ chatGiveawayChannelTop: 6px;
|
||||||
chatGiveawayChannelSize: 32px;
|
chatGiveawayChannelSize: 32px;
|
||||||
chatGiveawayChannelPadding: margins(5px, 7px, 12px, 0px);
|
chatGiveawayChannelPadding: margins(5px, 7px, 12px, 0px);
|
||||||
chatGiveawayChannelSkip: 8px;
|
chatGiveawayChannelSkip: 8px;
|
||||||
|
chatGiveawayCountriesSkip: 16px;
|
||||||
chatGiveawayDateTop: 6px;
|
chatGiveawayDateTop: 6px;
|
||||||
chatGiveawayDateSkip: 4px;
|
chatGiveawayDateSkip: 4px;
|
||||||
chatGiveawayBottomSkip: 16px;
|
chatGiveawayBottomSkip: 16px;
|
||||||
|
|
Loading…
Reference in New Issue
Block a user