mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Display reply/link area style from collectibles.
This commit is contained in:
@@ -88,6 +88,28 @@ using UpdateFlag = Data::PeerUpdate::Flag;
|
||||
return (month > 0 && month <= 12) ? month : 0;
|
||||
}
|
||||
|
||||
[[nodiscard]] Ui::ColorCollectible ParseColorCollectible(
|
||||
const MTPDpeerColorCollectible &data) {
|
||||
return {
|
||||
.giftEmojiId = data.vgift_emoji_id().v,
|
||||
.accentColor = Ui::ColorFromSerialized(data.vaccent_color()),
|
||||
.strip = ranges::views::all(
|
||||
data.vcolors().v
|
||||
) | ranges::views::transform(
|
||||
&Ui::ColorFromSerialized
|
||||
) | ranges::to_vector,
|
||||
.darkAccentColor = Ui::MaybeColorFromSerialized(
|
||||
data.vdark_accent_color()).value_or(QColor(0, 0, 0, 0)),
|
||||
.darkStrip = (data.vdark_colors()
|
||||
? ranges::views::all(
|
||||
data.vdark_colors()->v
|
||||
) | ranges::views::transform(
|
||||
&Ui::ColorFromSerialized
|
||||
) | ranges::to_vector
|
||||
: std::vector<QColor>()),
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace Data {
|
||||
@@ -998,13 +1020,6 @@ TimeId PeerData::photoChangeDate() const {
|
||||
return _barDetails ? _barDetails->photoChangeDate : 0;
|
||||
}
|
||||
|
||||
bool PeerData::changeColorIndex(
|
||||
const tl::conditional<MTPint> &cloudColorIndex) {
|
||||
return cloudColorIndex
|
||||
? changeColorIndex(cloudColorIndex->v)
|
||||
: clearColorIndex();
|
||||
}
|
||||
|
||||
bool PeerData::changeBackgroundEmojiId(
|
||||
const tl::conditional<MTPlong> &cloudBackgroundEmoji) {
|
||||
return changeBackgroundEmojiId(cloudBackgroundEmoji
|
||||
@@ -1012,6 +1027,36 @@ bool PeerData::changeBackgroundEmojiId(
|
||||
: DocumentId());
|
||||
}
|
||||
|
||||
bool PeerData::changeColorCollectible(
|
||||
const tl::conditional<MTPPeerColor> &cloudColor) {
|
||||
const auto clear = [&] {
|
||||
if (_colorCollectible) {
|
||||
_colorCollectible = nullptr;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
if (!cloudColor) {
|
||||
return clear();
|
||||
}
|
||||
return cloudColor->match([&](const MTPDpeerColorCollectible &data) {
|
||||
auto parsed = ParseColorCollectible(data);
|
||||
if (!_colorCollectible) {
|
||||
_colorCollectible = std::make_shared<Ui::ColorCollectible>(
|
||||
std::move(parsed));
|
||||
return true;
|
||||
} else if (*_colorCollectible != parsed) {
|
||||
*_colorCollectible = std::move(parsed);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}, [&](const MTPDpeerColor &) {
|
||||
return clear();
|
||||
}, [&](const MTPDinputPeerColorCollectible &) {
|
||||
return clear();
|
||||
});
|
||||
}
|
||||
|
||||
bool PeerData::changeColor(
|
||||
const tl::conditional<MTPPeerColor> &cloudColor) {
|
||||
const auto changed1 = cloudColor
|
||||
@@ -1019,7 +1064,8 @@ bool PeerData::changeColor(
|
||||
: clearColorIndex();
|
||||
const auto changed2 = changeBackgroundEmojiId(
|
||||
Data::BackgroundEmojiIdFromColor(cloudColor));
|
||||
return changed1 || changed2;
|
||||
const auto changed3 = changeColorCollectible(cloudColor);
|
||||
return changed1 || changed2 || changed3;
|
||||
}
|
||||
|
||||
void PeerData::fillNames() {
|
||||
@@ -1344,6 +1390,7 @@ bool PeerData::clearColorIndex() {
|
||||
}
|
||||
_colorIndexCloud = 0;
|
||||
_colorIndex = Data::DecideColorIndex(id);
|
||||
_colorCollectible = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -2036,7 +2083,7 @@ uint8 ColorIndexFromColor(const MTPPeerColor *color) {
|
||||
return color->match([](const MTPDpeerColor &data) -> uint8 {
|
||||
return data.vcolor().value_or_empty();
|
||||
}, [](const MTPDpeerColorCollectible &data) -> uint8 {
|
||||
return 0; // themes
|
||||
return 0;
|
||||
}, [](const MTPDinputPeerColorCollectible &) -> uint8 {
|
||||
return 0;
|
||||
});
|
||||
|
||||
@@ -25,6 +25,7 @@ enum class ChatRestriction;
|
||||
namespace Ui {
|
||||
class EmptyUserpic;
|
||||
struct BotVerifyDetails;
|
||||
struct ColorCollectible;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Main {
|
||||
@@ -214,6 +215,10 @@ public:
|
||||
[[nodiscard]] uint8 colorIndex() const {
|
||||
return _colorIndex;
|
||||
}
|
||||
[[nodiscard]] auto colorCollectible() const
|
||||
-> const std::shared_ptr<Ui::ColorCollectible> & {
|
||||
return _colorCollectible;
|
||||
}
|
||||
bool changeColorIndex(uint8 index);
|
||||
bool clearColorIndex();
|
||||
[[nodiscard]] DocumentId backgroundEmojiId() const;
|
||||
@@ -489,9 +494,10 @@ public:
|
||||
void saveTranslationDisabled(bool disabled);
|
||||
|
||||
void setBarSettings(const MTPPeerSettings &data);
|
||||
bool changeColorIndex(const tl::conditional<MTPint> &cloudColorIndex);
|
||||
bool changeBackgroundEmojiId(
|
||||
const tl::conditional<MTPlong> &cloudBackgroundEmoji);
|
||||
bool changeColorCollectible(
|
||||
const tl::conditional<MTPPeerColor> &cloudColor);
|
||||
bool changeColor(const tl::conditional<MTPPeerColor> &cloudColor);
|
||||
|
||||
enum class BlockStatus : char {
|
||||
@@ -609,6 +615,7 @@ private:
|
||||
|
||||
BarSettings _barSettings = PeerBarSettings(PeerBarSetting::Unknown);
|
||||
std::unique_ptr<PeerBarDetails> _barDetails;
|
||||
std::shared_ptr<Ui::ColorCollectible> _colorCollectible;
|
||||
|
||||
BlockStatus _blockStatus = BlockStatus::Unknown;
|
||||
LoadedStatus _loadedStatus = LoadedStatus::Not;
|
||||
|
||||
@@ -699,14 +699,24 @@ void Reply::paint(
|
||||
const auto colorIndexPlusOne = _colorPeer
|
||||
? (_colorPeer->colorIndex() + 1)
|
||||
: _hiddenSenderColorIndexPlusOne;
|
||||
const auto &colorCollectible = _colorPeer
|
||||
? _colorPeer->colorCollectible()
|
||||
: nullptr;
|
||||
const auto useColorCollectible = colorCollectible && !context.outbg;
|
||||
const auto useColorIndex = colorIndexPlusOne && !context.outbg;
|
||||
const auto colorPattern = colorIndexPlusOne
|
||||
const auto colorPattern = colorCollectible
|
||||
? 2
|
||||
: colorIndexPlusOne
|
||||
? st->colorPatternIndex(colorIndexPlusOne - 1)
|
||||
: 0;
|
||||
const auto cache = !inBubble
|
||||
? (_hasQuoteIcon
|
||||
? st->serviceQuoteCache(colorPattern)
|
||||
: st->serviceReplyCache(colorPattern)).get()
|
||||
: useColorCollectible
|
||||
? (_hasQuoteIcon
|
||||
? st->collectibleQuoteCache(selected, colorCollectible)
|
||||
: st->collectibleReplyCache(selected, colorCollectible)).get()
|
||||
: useColorIndex
|
||||
? (_hasQuoteIcon
|
||||
? st->coloredQuoteCache(selected, colorIndexPlusOne - 1)
|
||||
@@ -832,6 +842,8 @@ void Reply::paint(
|
||||
if (namew > 0) {
|
||||
p.setPen(!inBubble
|
||||
? st->msgImgReplyBarColor()->c
|
||||
: useColorCollectible
|
||||
? cache->icon
|
||||
: useColorIndex
|
||||
? FromNameFg(context, colorIndexPlusOne - 1)
|
||||
: stm->msgServiceFg->c);
|
||||
@@ -849,6 +861,8 @@ void Reply::paint(
|
||||
view->prepareCustomEmojiPaint(p, context, _text);
|
||||
auto replyToTextPalette = &(!inBubble
|
||||
? st->imgReplyTextPalette()
|
||||
: useColorCollectible
|
||||
? st->collectibleTextPalette(selected, colorCollectible)
|
||||
: useColorIndex
|
||||
? st->coloredTextPalette(selected, colorIndexPlusOne - 1)
|
||||
: stm->replyTextPalette);
|
||||
|
||||
@@ -871,6 +871,13 @@ const ColorIndexValues &ChatStyle::coloredValues(
|
||||
return *result;
|
||||
}
|
||||
|
||||
QColor ChatStyle::collectibleNameColor(
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const {
|
||||
return (_dark && collectible->darkAccentColor.alpha() > 0)
|
||||
? collectible->darkAccentColor
|
||||
: collectible->accentColor;
|
||||
}
|
||||
|
||||
const style::TextPalette &ChatStyle::coloredTextPalette(
|
||||
bool selected,
|
||||
uint8 colorIndex) const {
|
||||
@@ -891,6 +898,24 @@ const style::TextPalette &ChatStyle::coloredTextPalette(
|
||||
return result.data;
|
||||
}
|
||||
|
||||
const style::TextPalette &ChatStyle::collectibleTextPalette(
|
||||
bool selected,
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const {
|
||||
auto &entry = resolveCollectibleCaches(collectible);
|
||||
auto &result = selected ? entry.paletteSelected : entry.palette;
|
||||
if (!result.linkFg) {
|
||||
result.linkFg.emplace(collectibleNameColor(collectible));
|
||||
make(
|
||||
result.data,
|
||||
(selected
|
||||
? st::inReplyTextPaletteSelected
|
||||
: st::inReplyTextPalette));
|
||||
result.data.linkFg = result.linkFg->color();
|
||||
result.data.selectLinkFg = result.data.linkFg;
|
||||
}
|
||||
return result.data;
|
||||
}
|
||||
|
||||
not_null<BackgroundEmojiData*> ChatStyle::backgroundEmojiData(
|
||||
uint64 id) const {
|
||||
return &_backgroundEmojis[id];
|
||||
@@ -908,6 +933,24 @@ not_null<Text::QuotePaintCache*> ChatStyle::coloredReplyCache(
|
||||
return coloredCache(_coloredReplyCaches, selected, colorIndex);
|
||||
}
|
||||
|
||||
not_null<Text::QuotePaintCache*> ChatStyle::collectibleQuoteCache(
|
||||
bool selected,
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const {
|
||||
auto &entry = resolveCollectibleCaches(collectible);
|
||||
return collectibleCache(
|
||||
selected ? entry.quoteSelected : entry.quote,
|
||||
collectible);
|
||||
}
|
||||
|
||||
not_null<Text::QuotePaintCache*> ChatStyle::collectibleReplyCache(
|
||||
bool selected,
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const {
|
||||
auto &entry = resolveCollectibleCaches(collectible);
|
||||
return collectibleCache(
|
||||
selected ? entry.replySelected : entry.reply,
|
||||
collectible);
|
||||
}
|
||||
|
||||
not_null<Text::QuotePaintCache*> ChatStyle::coloredCache(
|
||||
ColoredQuotePaintCaches &caches,
|
||||
bool selected,
|
||||
@@ -922,6 +965,46 @@ not_null<Text::QuotePaintCache*> ChatStyle::coloredCache(
|
||||
return cache.get();
|
||||
}
|
||||
|
||||
not_null<Text::QuotePaintCache*> ChatStyle::collectibleCache(
|
||||
std::unique_ptr<Text::QuotePaintCache> &cache,
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const {
|
||||
EnsureBlockquoteCache(cache, [&] {
|
||||
const auto name = collectibleNameColor(collectible);
|
||||
auto bg = name;
|
||||
bg.setAlpha(kDefaultBgOpacity * 255);
|
||||
|
||||
const auto &strip = (_dark && !collectible->darkStrip.empty())
|
||||
? collectible->darkStrip
|
||||
: collectible->strip;
|
||||
return ColorIndexValues{
|
||||
.outlines = {
|
||||
strip.empty() ? name : strip[0],
|
||||
(strip.size() < 2) ? QColor(0, 0, 0, 0) : strip[1],
|
||||
(strip.size() < 3) ? QColor(0, 0, 0, 0) : strip[2],
|
||||
},
|
||||
.name = name,
|
||||
.bg = bg,
|
||||
};
|
||||
});
|
||||
return cache.get();
|
||||
}
|
||||
|
||||
ChatStyle::CollectibleColors &ChatStyle::resolveCollectibleCaches(
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const {
|
||||
const auto i = _collectibleCaches.find(collectible);
|
||||
if (i != end(_collectibleCaches)) {
|
||||
return i->second;
|
||||
}
|
||||
for (auto i = begin(_collectibleCaches); i != end(_collectibleCaches);) {
|
||||
if (i->first.expired()) {
|
||||
i = _collectibleCaches.erase(i);
|
||||
} else {
|
||||
++i;
|
||||
}
|
||||
}
|
||||
return _collectibleCaches.emplace(collectible).first->second;
|
||||
}
|
||||
|
||||
const CornersPixmaps &ChatStyle::msgBotKbOverBgAddCornersSmall() const {
|
||||
EnsureCorners(
|
||||
_msgBotKbOverBgAddCornersSmall,
|
||||
|
||||
@@ -267,6 +267,26 @@ struct ColorIndexValues {
|
||||
QColor color,
|
||||
int patternIndex);
|
||||
|
||||
struct ColorCollectible {
|
||||
uint64 giftEmojiId = 0;
|
||||
QColor accentColor;
|
||||
std::vector<QColor> strip;
|
||||
QColor darkAccentColor;
|
||||
std::vector<QColor> darkStrip;
|
||||
|
||||
friend inline bool operator==(
|
||||
const ColorCollectible &,
|
||||
const ColorCollectible &) = default;
|
||||
};
|
||||
|
||||
struct ColorCollectiblePtrCompare {
|
||||
bool operator()(
|
||||
const std::weak_ptr<ColorCollectible> &a,
|
||||
const std::weak_ptr<ColorCollectible> &b) const {
|
||||
return a.owner_before(b);
|
||||
}
|
||||
};
|
||||
|
||||
class ChatStyle final : public style::palette {
|
||||
public:
|
||||
explicit ChatStyle(rpl::producer<ColorIndicesCompressed> colorIndices);
|
||||
@@ -325,16 +345,27 @@ public:
|
||||
[[nodiscard]] const ColorIndexValues &coloredValues(
|
||||
bool selected,
|
||||
uint8 colorIndex) const;
|
||||
[[nodiscard]] QColor collectibleNameColor(
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const;
|
||||
[[nodiscard]] not_null<Text::QuotePaintCache*> coloredQuoteCache(
|
||||
bool selected,
|
||||
uint8 colorIndex) const;
|
||||
[[nodiscard]] not_null<Text::QuotePaintCache*> coloredReplyCache(
|
||||
bool selected,
|
||||
uint8 colorIndex) const;
|
||||
[[nodiscard]] not_null<Text::QuotePaintCache*> collectibleQuoteCache(
|
||||
bool selected,
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const;
|
||||
[[nodiscard]] not_null<Text::QuotePaintCache*> collectibleReplyCache(
|
||||
bool selected,
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const;
|
||||
|
||||
[[nodiscard]] const style::TextPalette &coloredTextPalette(
|
||||
bool selected,
|
||||
uint8 colorIndex) const;
|
||||
[[nodiscard]] const style::TextPalette &collectibleTextPalette(
|
||||
bool selected,
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const;
|
||||
|
||||
[[nodiscard]] not_null<BackgroundEmojiData*> backgroundEmojiData(
|
||||
uint64 id) const;
|
||||
@@ -448,6 +479,15 @@ private:
|
||||
style::TextPalette data;
|
||||
};
|
||||
|
||||
struct CollectibleColors {
|
||||
std::unique_ptr<Text::QuotePaintCache> quote;
|
||||
std::unique_ptr<Text::QuotePaintCache> quoteSelected;
|
||||
std::unique_ptr<Text::QuotePaintCache> reply;
|
||||
std::unique_ptr<Text::QuotePaintCache> replySelected;
|
||||
ColoredPalette palette;
|
||||
ColoredPalette paletteSelected;
|
||||
};
|
||||
|
||||
void assignPalette(not_null<const style::palette*> palette);
|
||||
void clearColorIndexCaches();
|
||||
void updateDarkValue();
|
||||
@@ -456,6 +496,11 @@ private:
|
||||
ColoredQuotePaintCaches &caches,
|
||||
bool selected,
|
||||
uint8 colorIndex) const;
|
||||
[[nodiscard]] not_null<Text::QuotePaintCache*> collectibleCache(
|
||||
std::unique_ptr<Text::QuotePaintCache> &cache,
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const;
|
||||
[[nodiscard]] CollectibleColors &resolveCollectibleCaches(
|
||||
const std::shared_ptr<ColorCollectible> &collectible) const;
|
||||
|
||||
void make(style::color &my, const style::color &original) const;
|
||||
void make(style::icon &my, const style::icon &original) const;
|
||||
@@ -521,6 +566,10 @@ private:
|
||||
mutable std::array<
|
||||
ColoredPalette,
|
||||
2 * kColorIndexCount> _coloredTextPalettes;
|
||||
mutable base::flat_map<
|
||||
std::weak_ptr<ColorCollectible>,
|
||||
CollectibleColors,
|
||||
ColorCollectiblePtrCompare> _collectibleCaches;
|
||||
mutable base::flat_map<uint64, BackgroundEmojiData> _backgroundEmojis;
|
||||
|
||||
style::TextPalette _historyPsaForwardPalette;
|
||||
|
||||
Reference in New Issue
Block a user