Add IV icon to the button.

This commit is contained in:
John Preston 2024-03-12 17:56:42 +04:00
parent 7b4adc2e60
commit d43f0be0da
9 changed files with 95 additions and 29 deletions

View file

@ -4561,6 +4561,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_view_button_external_link" = "Open link"; "lng_view_button_external_link" = "Open link";
"lng_view_button_boost" = "Boost"; "lng_view_button_boost" = "Boost";
"lng_view_button_giftcode" = "Open"; "lng_view_button_giftcode" = "Open";
"lng_view_button_iv" = "Instant View";
"lng_sponsored_hide_ads" = "Hide"; "lng_sponsored_hide_ads" = "Hide";
"lng_sponsored_title" = "What are sponsored messages?"; "lng_sponsored_title" = "What are sponsored messages?";

View file

@ -3544,9 +3544,13 @@ void Session::webpageApplyFields(
process(block, process); process(block, process);
} }
} }
const auto type = story ? WebPageType::Story : ParseWebPageType(data);
auto iv = (data.vcached_page() && !IgnoreIv(type))
? std::make_unique<Iv::Data>(data, *data.vcached_page())
: nullptr;
webpageApplyFields( webpageApplyFields(
page, page,
(story ? WebPageType::Story : ParseWebPageType(data)), type,
qs(data.vurl()), qs(data.vurl()),
qs(data.vdisplay_url()), qs(data.vdisplay_url()),
siteName, siteName,
@ -3564,9 +3568,7 @@ void Session::webpageApplyFields(
? processDocument(*document).get() ? processDocument(*document).get()
: lookupThemeDocument()), : lookupThemeDocument()),
WebPageCollage(this, data), WebPageCollage(this, data),
(data.vcached_page() std::move(iv),
? std::make_unique<Iv::Data>(data, *data.vcached_page())
: nullptr),
data.vduration().value_or_empty(), data.vduration().value_or_empty(),
qs(data.vauthor().value_or_empty()), qs(data.vauthor().value_or_empty()),
data.is_has_large_media(), data.is_has_large_media(),

View file

@ -171,6 +171,10 @@ WebPageType ParseWebPageType(
} }
} }
bool IgnoreIv(WebPageType type) {
return (type == WebPageType::Message);
}
WebPageType ParseWebPageType(const MTPDwebPage &page) { WebPageType ParseWebPageType(const MTPDwebPage &page) {
return ParseWebPageType( return ParseWebPageType(
qs(page.vtype().value_or_empty()), qs(page.vtype().value_or_empty()),

View file

@ -53,6 +53,7 @@ enum class WebPageType : uint8 {
Livestream, Livestream,
}; };
[[nodiscard]] WebPageType ParseWebPageType(const MTPDwebPage &type); [[nodiscard]] WebPageType ParseWebPageType(const MTPDwebPage &type);
[[nodiscard]] bool IgnoreIv(WebPageType type);
struct WebPageCollage { struct WebPageCollage {
using Item = std::variant<PhotoData*, DocumentData*>; using Item = std::variant<PhotoData*, DocumentData*>;

View file

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "iv/iv_instance.h" #include "iv/iv_instance.h"
#include "core/click_handler_types.h" #include "core/click_handler_types.h"
#include "core/ui_integration.h" #include "core/ui_integration.h"
#include "data/stickers/data_custom_emoji.h"
#include "data/data_file_click_handler.h" #include "data/data_file_click_handler.h"
#include "data/data_photo_media.h" #include "data/data_photo_media.h"
#include "data/data_session.h" #include "data/data_session.h"
@ -135,12 +136,11 @@ constexpr auto kMaxOriginalEntryLines = 8192;
}); });
} }
[[nodiscard]] QString PageToPhrase(not_null<WebPageData*> webpage) { [[nodiscard]] TextWithEntities PageToPhrase(not_null<WebPageData*> page) {
if (webpage->iv) { const auto type = page->type;
return u"Instant View"_q; const auto text = Ui::Text::Upper(page->iv
} ? tr::lng_view_button_iv(tr::now)
const auto type = webpage->type; : (type == WebPageType::Theme)
return Ui::Text::Upper((type == WebPageType::Theme)
? tr::lng_view_button_theme(tr::now) ? tr::lng_view_button_theme(tr::now)
: (type == WebPageType::Story) : (type == WebPageType::Story)
? tr::lng_view_button_story(tr::now) ? tr::lng_view_button_story(tr::now)
@ -170,6 +170,15 @@ constexpr auto kMaxOriginalEntryLines = 8192;
: (type == WebPageType::BotApp) : (type == WebPageType::BotApp)
? tr::lng_view_button_bot_app(tr::now) ? tr::lng_view_button_bot_app(tr::now)
: QString()); : QString());
if (page->iv) {
const auto manager = &page->owner().customEmojiManager();
const auto &icon = st::historyIvIcon;
const auto padding = st::historyIvIconPadding;
return Ui::Text::SingleCustomEmoji(
manager->registerInternalEmoji(icon, padding)
).append(text);
}
return { text };
} }
[[nodiscard]] bool HasButton(not_null<WebPageData*> webpage) { [[nodiscard]] bool HasButton(not_null<WebPageData*> webpage) {
@ -238,15 +247,23 @@ QSize WebPage::countOptimalSize() {
} }
// Detect _openButtonWidth before counting paddings. // Detect _openButtonWidth before counting paddings.
_openButton = QString(); _openButton = Ui::Text::String();
_openButtonWidth = 0;
if (HasButton(_data)) { if (HasButton(_data)) {
_openButton = PageToPhrase(_data); const auto context = Core::MarkedTextContext{
_openButtonWidth = st::semiboldFont->width(_openButton); .session = &_data->session(),
.customEmojiRepaint = [] {},
.customEmojiLoopLimit = 1,
};
_openButton.setMarkedText(
st::semiboldTextStyle,
PageToPhrase(_data),
kMarkupTextOptions,
context);
} else if (_sponsoredData) { } else if (_sponsoredData) {
if (!_sponsoredData->buttonText.isEmpty()) { if (!_sponsoredData->buttonText.isEmpty()) {
_openButton = Ui::Text::Upper(_sponsoredData->buttonText); _openButton.setText(
_openButtonWidth = st::semiboldFont->width(_openButton); st::semiboldTextStyle,
Ui::Text::Upper(_sponsoredData->buttonText));
} }
} }
@ -453,9 +470,9 @@ QSize WebPage::countOptimalSize() {
_duration = Ui::FormatDurationText(_data->duration); _duration = Ui::FormatDurationText(_data->duration);
_durationWidth = st::msgDateFont->width(_duration); _durationWidth = st::msgDateFont->width(_duration);
} }
if (_openButtonWidth) { if (!_openButton.isEmpty()) {
maxWidth += rect::m::sum::h(st::historyPageButtonPadding) maxWidth += rect::m::sum::h(st::historyPageButtonPadding)
+ _openButtonWidth; + _openButton.maxWidth();
} }
maxWidth += rect::m::sum::h(padding); maxWidth += rect::m::sum::h(padding);
minHeight += rect::m::sum::v(padding); minHeight += rect::m::sum::v(padding);
@ -910,7 +927,7 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
} }
} }
if (_openButtonWidth) { if (!_openButton.isEmpty()) {
p.setFont(st::semiboldFont); p.setFont(st::semiboldFont);
p.setPen(cache->icon); p.setPen(cache->icon);
const auto end = inner.y() + inner.height() + _st.padding.bottom(); const auto end = inner.y() + inner.height() + _st.padding.bottom();
@ -918,11 +935,13 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
auto color = cache->icon; auto color = cache->icon;
color.setAlphaF(color.alphaF() * 0.3); color.setAlphaF(color.alphaF() * 0.3);
p.fillRect(inner.x(), end, inner.width(), line, color); p.fillRect(inner.x(), end, inner.width(), line, color);
const auto top = end + st::historyPageButtonPadding.top(); _openButton.draw(p, {
p.drawText( .position = QPoint(
inner.x() + (inner.width() - _openButtonWidth) / 2, inner.x() + (inner.width() - _openButton.maxWidth()) / 2,
top + st::semiboldFont->ascent, end + st::historyPageButtonPadding.top()),
_openButton); .availableWidth = paintw,
.now = context.now,
});
} }
} }
@ -1225,7 +1244,9 @@ QMargins WebPage::inBubblePadding() const {
} }
QMargins WebPage::innerMargin() const { QMargins WebPage::innerMargin() const {
const auto button = _openButtonWidth ? st::historyPageButtonHeight : 0; const auto button = _openButton.isEmpty()
? 0
: st::historyPageButtonHeight;
return _st.padding + QMargins(0, 0, 0, button); return _st.padding + QMargins(0, 0, 0, button);
} }

View file

@ -147,10 +147,9 @@ private:
Ui::Text::String _siteName; Ui::Text::String _siteName;
Ui::Text::String _title; Ui::Text::String _title;
Ui::Text::String _description; Ui::Text::String _description;
Ui::Text::String _openButton;
QString _openButton;
QString _duration; QString _duration;
int _openButtonWidth = 0;
int _durationWidth = 0; int _durationWidth = 0;
mutable QPoint _lastPoint; mutable QPoint _lastPoint;

View file

@ -31,6 +31,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
namespace Settings { namespace Settings {
namespace { namespace {
constexpr auto kShortcutLimit = 32;
class QuickReplies : public BusinessSection<QuickReplies> { class QuickReplies : public BusinessSection<QuickReplies> {
public: public:
QuickReplies( QuickReplies(
@ -162,7 +164,7 @@ void QuickReplies::setupContent(
} }
[[nodiscard]] bool ValidShortcutName(const QString &name) { [[nodiscard]] bool ValidShortcutName(const QString &name) {
if (name.isEmpty() || name.size() > 32) { if (name.isEmpty() || name.size() > kShortcutLimit) {
return false; return false;
} }
for (const auto &ch : name) { for (const auto &ch : name) {
@ -207,6 +209,39 @@ void EditShortcutNameBox(
field->setFocusFast(); field->setFocusFast();
}); });
field->selectAll(); field->selectAll();
field->setMaxLength(kShortcutLimit * 2);
struct State {
rpl::variable<int> length;
};
const auto state = field->lifetime().make_state<State>();
state->length = rpl::single(
int(name.size())
) | rpl::then(field->changes() | rpl::map([=] {
return int(field->getLastText().size());
}));
const auto warning = Ui::CreateChild<Ui::FlatLabel>(
field,
state->length.value() | rpl::map([](int count) {
return (count > kShortcutLimit * 3 / 4)
? QString::number(kShortcutLimit - count)
: QString();
}),
st::editTagLimit);
state->length.value() | rpl::map(
rpl::mappers::_1 > kShortcutLimit
) | rpl::start_with_next([=](bool exceeded) {
warning->setTextColorOverride(exceeded
? st::attentionButtonFg->c
: std::optional<QColor>());
}, warning->lifetime());
rpl::combine(
field->sizeValue(),
warning->sizeValue()
) | rpl::start_with_next([=] {
warning->moveToRight(0, 0);
}, warning->lifetime());
warning->setAttribute(Qt::WA_TransparentForMouseEvents);
const auto callback = [=] { const auto callback = [=] {
const auto name = field->getLastText().trimmed(); const auto name = field->getLastText().trimmed();

View file

@ -622,7 +622,7 @@ settingsAddReplyLabel: FlatLabel(defaultFlatLabel) {
} }
settingsAddReplyField: InputField(defaultInputField) { settingsAddReplyField: InputField(defaultInputField) {
textBg: transparent; textBg: transparent;
textMargins: margins(0px, 10px, 0px, 2px); textMargins: margins(0px, 10px, 32px, 2px);
placeholderFg: placeholderFg; placeholderFg: placeholderFg;
placeholderFgActive: placeholderFgActive; placeholderFgActive: placeholderFgActive;

View file

@ -1058,3 +1058,6 @@ boostMessageIcon: icon {{ "stories/boost_mini", windowFg }};
boostMessageIconPadding: margins(0px, 2px, 0px, 0px); boostMessageIconPadding: margins(0px, 2px, 0px, 0px);
boostsMessageIcon: icon {{ "stories/boosts_mini", windowFg }}; boostsMessageIcon: icon {{ "stories/boosts_mini", windowFg }};
boostsMessageIconPadding: margins(0px, 2px, 0px, 0px); boostsMessageIconPadding: margins(0px, 2px, 0px, 0px);
historyIvIcon: icon{{ "boosts/boost_mini2", windowFg }};
historyIvIconPadding: margins(2px, 3px, 2px, 0px);