Update API scheme. HistoryView::Giveaway->MediaInBubble.

This commit is contained in:
John Preston 2023-12-09 23:40:08 +04:00
parent e854f0b60c
commit 62f9f3c94b
12 changed files with 690 additions and 490 deletions

View file

@ -1682,7 +1682,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_giveaway_started" = "{from} just started a giveaway of Telegram Premium subscriptions to its followers.";
"lng_action_giveaway_results#one" = "{count} winner of the giveaway was randomly selected by Telegram and received private messages with giftcodes.";
"lng_action_giveaway_results#other" = "{count} winners of the giveaway were randomly selected by Telegram and received private messages with giftcodes.";
"lng_action_giveaway_results_some" = "Some winners of the giveaway was randomly selected by Telegram and received private messages with giftcodes.";
"lng_action_giveaway_results_some" = "Some winners of the giveaway were randomly selected by Telegram and received private messages with giftcodes.";
"lng_action_giveaway_results_none" = "No winners of the giveaway could be selected.";
"lng_similar_channels_title" = "Similar channels";

View file

@ -2285,7 +2285,9 @@ std::unique_ptr<HistoryView::Media> MediaGiveaway::createView(
not_null<HistoryView::Element*> message,
not_null<HistoryItem*> realParent,
HistoryView::Element *replacing) {
return std::make_unique<HistoryView::Giveaway>(message, &_giveaway);
return std::make_unique<HistoryView::MediaInBubble>(
message,
HistoryView::GenerateGiveawayStart(message, &_giveaway));
}
} // namespace Data

View file

@ -1196,6 +1196,8 @@ Media ParseMedia(
// #TODO export stories
}, [&](const MTPDmessageMediaGiveaway &data) {
result.content = ParseGiveaway(data);
}, [&](const MTPDmessageMediaGiveawayResults &data) {
// #TODO export giveaway
}, [](const MTPDmessageMediaEmpty &data) {});
return result;
}

View file

@ -314,6 +314,10 @@ std::unique_ptr<Data::Media> HistoryItem::CreateMedia(
return std::make_unique<Data::MediaGiveaway>(
item,
Data::ComputeGiveawayData(item, media));
}, [&](const MTPDmessageMediaGiveawayResults &media) -> Result {
return nullptr;/* std::make_unique<Data::MediaGiveaway>(
item,
Data::ComputeGiveawayData(item, media));*/
}, [](const MTPDmessageMediaEmpty &) -> Result {
return nullptr;
}, [](const MTPDmessageMediaUnsupported &) -> Result {

View file

@ -498,6 +498,8 @@ MediaCheckResult CheckMessageMedia(const MTPMessageMedia &media) {
: Result::Good;
}, [](const MTPDmessageMediaGiveaway &) {
return Result::Good;
}, [](const MTPDmessageMediaGiveawayResults &) {
return Result::Good;
}, [](const MTPDmessageMediaUnsupported &) {
return Result::Unsupported;
});

View file

@ -1389,6 +1389,14 @@ bool Element::allowTextSelectionByHandler(
return false;
}
bool Element::usesBubblePattern(const PaintContext &context) const {
return (context.selection != FullSelection)
&& hasOutLayout()
&& context.bubblesPattern
&& !context.viewport.isEmpty()
&& !context.bubblesPattern->pixmap.size().isEmpty();
}
bool Element::hasVisibleText() const {
return false;
}

View file

@ -465,6 +465,8 @@ public:
[[nodiscard]] virtual bool allowTextSelectionByHandler(
const ClickHandlerPtr &handler) const;
[[nodiscard]] bool usesBubblePattern(const PaintContext &context) const;
struct VerticalRepaintRange {
int top = 0;
int height = 0;

View file

@ -24,12 +24,30 @@ class RippleAnimation;
namespace HistoryView {
class Giveaway final : public Media {
class MediaInBubble final : public Media {
public:
Giveaway(
class Part : public Object {
public:
virtual ~Part() = default;
virtual void draw(
Painter &p,
const PaintContext &context,
int outerWidth) const = 0;
[[nodiscard]] virtual TextState textState(
QPoint point,
StateRequest request) const;
virtual void clickHandlerPressedChanged(
const ClickHandlerPtr &p,
bool pressed);
[[nodiscard]] virtual bool hasHeavyPart();
virtual void unloadHeavyPart();
};
MediaInBubble(
not_null<Element*> parent,
not_null<Data::Giveaway*> giveaway);
~Giveaway();
Fn<void(Fn<void(std::unique_ptr<Part>)>)> generate);
~MediaInBubble();
void draw(Painter &p, const PaintContext &context) const override;
TextState textState(QPoint point, StateRequest request) const override;
@ -49,7 +67,7 @@ public:
}
bool toggleSelectionByHandlerClick(
const ClickHandlerPtr &p) const override {
const ClickHandlerPtr &p) const override {
return true;
}
bool dragItemByHandler(const ClickHandlerPtr &p) const override {
@ -62,8 +80,113 @@ public:
bool hasHeavyPart() const override;
private:
struct Entry {
std::unique_ptr<Part> object;
int top = 0;
};
QSize countOptimalSize() override;
QSize countCurrentSize(int newWidth) override;
[[nodiscard]] QMargins inBubblePadding() const;
std::vector<Entry> _entries;
};
class TextMediaInBubblePart final : public MediaInBubble::Part {
public:
TextMediaInBubblePart(TextWithEntities text, QMargins margins);
void draw(
Painter &p,
const PaintContext &context,
int outerWidth) const override;
QSize countOptimalSize() override;
QSize countCurrentSize(int newWidth) override;
private:
Ui::Text::String _text;
QMargins _margins;
};
class TextDelimeterPart final : public MediaInBubble::Part {
public:
TextDelimeterPart(const QString &text, QMargins margins);
void draw(
Painter &p,
const PaintContext &context,
int outerWidth) const override;
QSize countOptimalSize() override;
QSize countCurrentSize(int newWidth) override;
private:
Ui::Text::String _text;
QMargins _margins;
};
class StickerWithBadgePart final : public MediaInBubble::Part {
public:
StickerWithBadgePart(
not_null<Element*> parent,
Fn<DocumentData*()> lookup,
QString badge);
void draw(
Painter &p,
const PaintContext &context,
int outerWidth) const override;
bool hasHeavyPart() override;
void unloadHeavyPart() override;
QSize countOptimalSize() override;
QSize countCurrentSize(int newWidth) override;
private:
void ensureCreated() const;
void validateBadge(const PaintContext &context) const;
void paintBadge(Painter &p, const PaintContext &context) const;
const not_null<Element*> _parent;
Fn<DocumentData*()> _lookup;
QString _badgeText;
mutable std::optional<Sticker> _sticker;
mutable QColor _badgeFg;
mutable QColor _badgeBorder;
mutable QImage _badge;
mutable QImage _badgeCache;
};
class PeerBubbleListPart final : public MediaInBubble::Part {
public:
PeerBubbleListPart(
not_null<Element*> parent,
const std::vector<not_null<PeerData*>> &list);
void draw(
Painter &p,
const PaintContext &context,
int outerWidth) const override;
void clickHandlerPressedChanged(
const ClickHandlerPtr &p,
bool pressed) override;
bool hasHeavyPart() override;
void unloadHeavyPart() override;
QSize countOptimalSize() override;
QSize countCurrentSize(int newWidth) override;
private:
int layout(int x, int y, int available);
using Thumbnail = Dialogs::Stories::Thumbnail;
struct Channel {
struct Peer {
Ui::Text::String name;
std::shared_ptr<Thumbnail> thumbnail;
QRect geometry;
@ -74,55 +197,15 @@ private:
uint8 colorIndex = 0;
};
void paintBadge(Painter &p, const PaintContext &context) const;
void paintChannels(Painter &p, const PaintContext &context) const;
int layoutChannels(int x, int y, int available);
QSize countOptimalSize() override;
QSize countCurrentSize(int newWidth) override;
void fillFromData(not_null<Data::Giveaway*> giveaway);
void ensureStickerCreated() const;
void validateBadge(const PaintContext &context) const;
[[nodiscard]] QMargins inBubblePadding() const;
mutable std::optional<Sticker> _sticker;
Ui::Text::String _prizesTitle;
Ui::Text::String _additional;
Ui::Text::String _with;
Ui::Text::String _prizes;
Ui::Text::String _participantsTitle;
Ui::Text::String _participants;
std::vector<Channel> _channels;
Ui::Text::String _countries;
Ui::Text::String _winnersTitle;
Ui::Text::String _winners;
mutable QColor _badgeFg;
mutable QColor _badgeBorder;
mutable QImage _badge;
mutable QImage _badgeCache;
mutable QPoint _lastPoint;
int _months = 0;
int _quantity = 0;
int _stickerTop = 0;
int _prizesTitleTop = 0;
int _additionalTop = 0;
int _additionalWidth = 0;
int _withTop = 0;
int _prizesTop = 0;
int _prizesWidth = 0;
int _participantsTitleTop = 0;
int _participantsTop = 0;
int _participantsWidth = 0;
int _countriesTop = 0;
int _countriesWidth = 0;
int _winnersTitleTop = 0;
int _winnersTop = 0;
mutable uint8 _subscribedToThumbnails : 1 = 0;
const not_null<Element*> _parent;
std::vector<Peer> _peers;
mutable bool _subscribed = false;
};
[[nodiscard]] auto GenerateGiveawayStart(
not_null<Element*> parent,
not_null<Data::Giveaway*> giveaway)
-> Fn<void(Fn<void(std::unique_ptr<MediaInBubble::Part>)>)>;
} // namespace HistoryView

View file

@ -341,11 +341,7 @@ auto Media::getBubbleSelectionIntervals(
}
bool Media::usesBubblePattern(const PaintContext &context) const {
return (context.selection != FullSelection)
&& _parent->hasOutLayout()
&& context.bubblesPattern
&& !context.viewport.isEmpty()
&& !context.bubblesPattern->pixmap.size().isEmpty();
return _parent->usesBubblePattern(context);
}
PointState Media::pointState(QPoint point) const {

View file

@ -132,6 +132,7 @@ messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
messageMediaStory#68cb6283 flags:# via_mention:flags.1?true peer:Peer id:int story:flags.0?StoryItem = MessageMedia;
messageMediaGiveaway#daad85b0 flags:# only_new_subscribers:flags.0?true winners_are_visible:flags.2?true channels:Vector<long> countries_iso2:flags.1?Vector<string> prize_description:flags.3?string quantity:int months:int until_date:int = MessageMedia;
messageMediaGiveawayResults#b11ff5a1 flags:# refunded:flags.0?true channel_id:long launch_msg_id:int winners_count:int unclaimed_count:int winners:Vector<long> months:int prize_description:flags.1?string = MessageMedia;
messageActionEmpty#b6aef7b0 = MessageAction;
messageActionChatCreate#bd47cbad title:string users:Vector<long> = MessageAction;
@ -1583,7 +1584,7 @@ premiumGiftCodeOption#257e962b flags:# users:int months:int store_product:flags.
payments.checkedGiftCode#b722f158 flags:# via_giveaway:flags.2?true from_id:Peer giveaway_msg_id:flags.3?int to_id:flags.0?long date:int months:int used_date:flags.1?int chats:Vector<Chat> users:Vector<User> = payments.CheckedGiftCode;
payments.giveawayInfo#4367daa0 flags:# participating:flags.0?true preparing_results:flags.3?true start_date:int joined_too_early_date:flags.1?int admin_disallowed_chat_id:flags.2?long disallowed_country:flags.4?string = payments.GiveawayInfo;
payments.giveawayInfoResults#8ac7e167 flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int winners:flags.2?Vector<User> = payments.GiveawayInfo;
payments.giveawayInfoResults#cd5570 flags:# winner:flags.0?true refunded:flags.1?true start_date:int gift_code_slug:flags.0?string finish_date:int winners_count:int activated_count:int = payments.GiveawayInfo;
prepaidGiveaway#b2539d54 id:long months:int quantity:int date:int = PrepaidGiveaway;
@ -1620,6 +1621,7 @@ help.peerColorsNotModified#2ba1f5ce = help.PeerColors;
help.peerColors#f8ed08 hash:int colors:Vector<help.PeerColorOption> = help.PeerColors;
storyPeerReaction#7decc433 peer_id:Peer date:int reaction:Reaction = StoryPeerReaction;
storyPeerPublicRepost#f7fbc17d peer_id:Peer story:StoryItem = StoryPeerReaction;
stories.storyReactionsList#d86c162a flags:# count:int reactions:Vector<StoryPeerReaction> chats:Vector<Chat> users:Vector<User> next_offset:flags.0?string = stories.StoryReactionsList;
@ -2198,7 +2200,7 @@ stories.getAllReadPeerStories#9b5ae7f9 = Updates;
stories.getPeerMaxIDs#535983c3 id:Vector<InputPeer> = Vector<int>;
stories.getChatsToSend#a56a8b60 = messages.Chats;
stories.togglePeerStoriesHidden#bd0415c4 peer:InputPeer hidden:Bool = Bool;
stories.getStoryReactionsList#b9b2881f flags:# peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = stories.StoryReactionsList;
stories.getStoryReactionsList#b9b2881f flags:# reposts_first:flags.2?true peer:InputPeer id:int reaction:flags.0?Reaction offset:flags.1?string limit:int = stories.StoryReactionsList;
premium.getBoostsList#60f67660 flags:# gifts:flags.0?true peer:InputPeer offset:string limit:int = premium.BoostsList;
premium.getMyBoosts#be77b4a = premium.MyBoosts;

View file

@ -978,20 +978,17 @@ chatGiveawayBadgeFont: font(12px bold);
chatGiveawayBadgeTop: 106px;
chatGiveawayBadgePadding: margins(7px, 1px, 5px, 3px);
chatGiveawayBadgeStroke: 2px;
chatGiveawayPrizesTop: 16px;
chatGiveawayPrizesSkip: 4px;
chatGiveawayPrizesWithPadding: margins(22px, 2px, 8px, 2px);
chatGiveawayPrizesWithTop: 9px;
chatGiveawayParticipantsTop: 16px;
chatGiveawayParticipantsSkip: 4px;
chatGiveawayChannelTop: 6px;
chatGiveawayChannelSize: 32px;
chatGiveawayChannelPadding: margins(5px, 7px, 12px, 0px);
chatGiveawayChannelSkip: 8px;
chatGiveawayCountriesSkip: 16px;
chatGiveawayDateTop: 6px;
chatGiveawayDateSkip: 4px;
chatGiveawayBottomSkip: 16px;
chatGiveawayPrizesTitleMargin: margins(11px, 16px, 11px, 4px);
chatGiveawayPrizesMargin: margins(11px, 0px, 11px, 0px);
chatGiveawayPrizesWithPadding: margins(22px, 2px, 22px, 2px);
chatGiveawayPrizesWithSkip: 8px;
chatGiveawayPrizesWithLineTop: 9px;
chatGiveawayParticipantsMargin: margins(11px, 0px, 11px, 6px);
chatGiveawayNoCountriesTitleMargin: margins(11px, 6px, 11px, 4px);
chatGiveawayEndDateMargin: margins(11px, 0px, 11px, 16px);
chatGiveawayPeerSize: 32px;
chatGiveawayPeerPadding: margins(5px, 7px, 12px, 0px);
chatGiveawayPeerSkip: 8px;
chatSimilarRadius: 12px;
chatSimilarArrowSize: 6px;