Added view button to webpages.
This commit is contained in:
parent
1613495425
commit
6163e922b3
|
@ -2893,6 +2893,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
"lng_view_button_bot" = "View bot";
|
"lng_view_button_bot" = "View bot";
|
||||||
"lng_view_button_group" = "View group";
|
"lng_view_button_group" = "View group";
|
||||||
"lng_view_button_channel" = "View channel";
|
"lng_view_button_channel" = "View channel";
|
||||||
|
"lng_view_button_background" = "View background";
|
||||||
|
"lng_view_button_theme" = "View theme";
|
||||||
|
"lng_view_button_message" = "View message";
|
||||||
|
"lng_view_button_voice_chat" = "Voice chat";
|
||||||
|
"lng_view_button_voice_chat_channel" = "Live stream";
|
||||||
|
|
||||||
"lng_sponsored_title" = "What are sponsored messages?";
|
"lng_sponsored_title" = "What are sponsored messages?";
|
||||||
"lng_sponsored_info_description1" = "Unlike other apps, Telegram never uses your private data to target ads. Sponsored messages on Telegram are based solely on the topic of the public channels in which they are shown. This means that no user data is mined or analyzed to display ads, and every user viewing a channel on Telegram sees the same sponsored messages.\n\nUnlike other apps, Telegram doesn't track whether you tapped on a sponsored message and doesn't profile you based on your activity. We also prevent external links in sponsored messages to ensure that third parties can’t spy on our users. We believe that everyone has the right to privacy, and technological platforms should respect that.\n\nTelegram offers a free and unlimited service to hundreds of millions of users, which involves significant server and traffic costs. In order to remain independent and stay true to its values, Telegram developed a paid tool to promote messages with user privacy in mind. We welcome responsible advertisers at:";
|
"lng_sponsored_info_description1" = "Unlike other apps, Telegram never uses your private data to target ads. Sponsored messages on Telegram are based solely on the topic of the public channels in which they are shown. This means that no user data is mined or analyzed to display ads, and every user viewing a channel on Telegram sees the same sponsored messages.\n\nUnlike other apps, Telegram doesn't track whether you tapped on a sponsored message and doesn't profile you based on your activity. We also prevent external links in sponsored messages to ensure that third parties can’t spy on our users. We believe that everyone has the right to privacy, and technological platforms should respect that.\n\nTelegram offers a free and unlimited service to hundreds of millions of users, which involves significant server and traffic costs. In order to remain independent and stay true to its values, Telegram developed a paid tool to promote messages with user privacy in mind. We welcome responsible advertisers at:";
|
||||||
|
|
|
@ -146,6 +146,20 @@ WebPageType ParseWebPageType(const MTPDwebPage &page) {
|
||||||
return WebPageType::WallPaper;
|
return WebPageType::WallPaper;
|
||||||
} else if (type == qstr("telegram_theme")) {
|
} else if (type == qstr("telegram_theme")) {
|
||||||
return WebPageType::Theme;
|
return WebPageType::Theme;
|
||||||
|
} else if (type == qstr("telegram_channel")) {
|
||||||
|
return WebPageType::Channel;
|
||||||
|
} else if (type == qstr("telegram_message")) {
|
||||||
|
return WebPageType::Message;
|
||||||
|
} else if (type == qstr("telegram_bot")) {
|
||||||
|
return WebPageType::Bot;
|
||||||
|
} else if (type == qstr("telegram_megagroup")) {
|
||||||
|
return WebPageType::Group;
|
||||||
|
} else if (type == qstr("telegram_voicechat")) {
|
||||||
|
return WebPageType::VoiceChat;
|
||||||
|
} else if (type == qstr("telegram_livestream")) {
|
||||||
|
return WebPageType::Livestream;
|
||||||
|
} else if (type == qstr("telegram_user")) {
|
||||||
|
return WebPageType::User;
|
||||||
} else if (page.vcached_page()) {
|
} else if (page.vcached_page()) {
|
||||||
return WebPageType::ArticleWithIV;
|
return WebPageType::ArticleWithIV;
|
||||||
} else {
|
} else {
|
||||||
|
@ -302,4 +316,4 @@ void WebPageData::ApplyChanges(
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
session->data().sendWebPageGamePollNotifications();
|
session->data().sendWebPageGamePollNotifications();
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,13 +17,26 @@ class Session;
|
||||||
} // namespace Data
|
} // namespace Data
|
||||||
|
|
||||||
enum class WebPageType {
|
enum class WebPageType {
|
||||||
|
Message,
|
||||||
|
|
||||||
|
Group,
|
||||||
|
Channel,
|
||||||
|
|
||||||
Photo,
|
Photo,
|
||||||
Video,
|
Video,
|
||||||
|
|
||||||
|
User,
|
||||||
|
Bot,
|
||||||
Profile,
|
Profile,
|
||||||
|
|
||||||
WallPaper,
|
WallPaper,
|
||||||
Theme,
|
Theme,
|
||||||
|
|
||||||
Article,
|
Article,
|
||||||
ArticleWithIV,
|
ArticleWithIV,
|
||||||
|
|
||||||
|
VoiceChat,
|
||||||
|
Livestream,
|
||||||
};
|
};
|
||||||
|
|
||||||
WebPageType ParseWebPageType(const MTPDwebPage &type);
|
WebPageType ParseWebPageType(const MTPDwebPage &type);
|
||||||
|
|
|
@ -243,12 +243,6 @@ Message::Message(
|
||||||
: Element(delegate, data, replacing) {
|
: Element(delegate, data, replacing) {
|
||||||
initLogEntryOriginal();
|
initLogEntryOriginal();
|
||||||
initPsa();
|
initPsa();
|
||||||
|
|
||||||
if (data->isSponsored()) {
|
|
||||||
_viewButton = std::make_unique<ViewButton>(
|
|
||||||
data->displayFrom(),
|
|
||||||
[=] { history()->owner().requestViewRepaint(this); });
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Message::~Message() {
|
Message::~Message() {
|
||||||
|
@ -611,16 +605,18 @@ void Message::draw(Painter &p, const PaintContext &context) const {
|
||||||
|
|
||||||
auto inner = g;
|
auto inner = g;
|
||||||
paintCommentsButton(p, inner, context);
|
paintCommentsButton(p, inner, context);
|
||||||
if (_viewButton) {
|
if (ensureViewButton()) {
|
||||||
_viewButton->draw(
|
_viewButton->draw(
|
||||||
p,
|
p,
|
||||||
_viewButton->countSponsoredRect(inner),
|
_viewButton->countRect(inner),
|
||||||
context);
|
context);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto trect = inner.marginsRemoved(st::msgPadding);
|
auto trect = inner.marginsRemoved(st::msgPadding);
|
||||||
if (mediaOnBottom) {
|
if (mediaOnBottom) {
|
||||||
trect.setHeight(trect.height() + st::msgPadding.bottom());
|
trect.setHeight(trect.height()
|
||||||
|
+ st::msgPadding.bottom()
|
||||||
|
- viewButtonHeight());
|
||||||
}
|
}
|
||||||
if (mediaOnTop) {
|
if (mediaOnTop) {
|
||||||
trect.setY(trect.y() - st::msgPadding.top());
|
trect.setY(trect.y() - st::msgPadding.top());
|
||||||
|
@ -1208,14 +1204,16 @@ TextState Message::textState(
|
||||||
if (_viewButton
|
if (_viewButton
|
||||||
&& _viewButton->getState(
|
&& _viewButton->getState(
|
||||||
point,
|
point,
|
||||||
_viewButton->countSponsoredRect(bubble),
|
_viewButton->countRect(bubble),
|
||||||
&result)) {
|
&result)) {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto trect = bubble.marginsRemoved(st::msgPadding);
|
auto trect = bubble.marginsRemoved(st::msgPadding);
|
||||||
if (mediaOnBottom) {
|
if (mediaOnBottom) {
|
||||||
trect.setHeight(trect.height() + st::msgPadding.bottom());
|
trect.setHeight(trect.height()
|
||||||
|
+ st::msgPadding.bottom()
|
||||||
|
- viewButtonHeight());
|
||||||
}
|
}
|
||||||
if (mediaOnTop) {
|
if (mediaOnTop) {
|
||||||
trect.setY(trect.y() - st::msgPadding.top());
|
trect.setY(trect.y() - st::msgPadding.top());
|
||||||
|
@ -1754,7 +1752,7 @@ void Message::drawInfo(
|
||||||
; msgsigned && !msgsigned->isAnonymousRank) {
|
; msgsigned && !msgsigned->isAnonymousRank) {
|
||||||
msgsigned->signature.drawElided(p, dateX, dateY, item->_timeWidth);
|
msgsigned->signature.drawElided(p, dateX, dateY, item->_timeWidth);
|
||||||
} else if (const auto sponsored = displayedSponsorBadge()) {
|
} else if (const auto sponsored = displayedSponsorBadge()) {
|
||||||
const auto skipY = _viewButton ? _viewButton->height() : 0;
|
const auto skipY = viewButtonHeight();
|
||||||
sponsored->text.drawElided(p, dateX, dateY - skipY, item->_timeWidth);
|
sponsored->text.drawElided(p, dateX, dateY - skipY, item->_timeWidth);
|
||||||
} else if (const auto edited = displayedEditBadge()) {
|
} else if (const auto edited = displayedEditBadge()) {
|
||||||
edited->text.drawElided(p, dateX, dateY, item->_timeWidth);
|
edited->text.drawElided(p, dateX, dateY, item->_timeWidth);
|
||||||
|
@ -1958,6 +1956,33 @@ int Message::monospaceMaxWidth() const {
|
||||||
+ st::msgPadding.right();
|
+ st::msgPadding.right();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Message::viewButtonHeight() const {
|
||||||
|
return _viewButton ? _viewButton->height() : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Message::ensureViewButton() const {
|
||||||
|
if (data()->isSponsored()
|
||||||
|
|| (data()->media()
|
||||||
|
&& ViewButton::MediaHasViewButton(data()->media()))) {
|
||||||
|
if (_viewButton) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
auto callback = [=] { history()->owner().requestViewRepaint(this); };
|
||||||
|
_viewButton = data()->isSponsored()
|
||||||
|
? std::make_unique<ViewButton>(
|
||||||
|
data()->displayFrom(),
|
||||||
|
std::move(callback))
|
||||||
|
: std::make_unique<ViewButton>(
|
||||||
|
data()->media(),
|
||||||
|
std::move(callback));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (_viewButton) {
|
||||||
|
_viewButton.reset(nullptr);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void Message::initLogEntryOriginal() {
|
void Message::initLogEntryOriginal() {
|
||||||
if (const auto log = message()->Get<HistoryMessageLogEntryOriginal>()) {
|
if (const auto log = message()->Get<HistoryMessageLogEntryOriginal>()) {
|
||||||
AddComponents(LogEntryOriginal::Bit());
|
AddComponents(LogEntryOriginal::Bit());
|
||||||
|
@ -2618,8 +2643,8 @@ int Message::resizeContentGetHeight(int newWidth) {
|
||||||
if (item->repliesAreComments() || item->externalReply()) {
|
if (item->repliesAreComments() || item->externalReply()) {
|
||||||
newHeight += st::historyCommentsButtonHeight;
|
newHeight += st::historyCommentsButtonHeight;
|
||||||
}
|
}
|
||||||
if (_viewButton) {
|
if (ensureViewButton()) {
|
||||||
newHeight += _viewButton->height();
|
newHeight += viewButtonHeight();
|
||||||
}
|
}
|
||||||
} else if (mediaDisplayed) {
|
} else if (mediaDisplayed) {
|
||||||
newHeight = media->height();
|
newHeight = media->height();
|
||||||
|
|
|
@ -213,6 +213,9 @@ private:
|
||||||
[[nodiscard]] int plainMaxWidth() const;
|
[[nodiscard]] int plainMaxWidth() const;
|
||||||
[[nodiscard]] int monospaceMaxWidth() const;
|
[[nodiscard]] int monospaceMaxWidth() const;
|
||||||
|
|
||||||
|
[[nodiscard]] bool ensureViewButton() const;
|
||||||
|
[[nodiscard]] int viewButtonHeight() const;
|
||||||
|
|
||||||
WebPage *logEntryOriginal() const;
|
WebPage *logEntryOriginal() const;
|
||||||
|
|
||||||
[[nodiscard]] ClickHandlerPtr createGoToCommentsLink() const;
|
[[nodiscard]] ClickHandlerPtr createGoToCommentsLink() const;
|
||||||
|
@ -224,7 +227,7 @@ private:
|
||||||
mutable ClickHandlerPtr _rightActionLink;
|
mutable ClickHandlerPtr _rightActionLink;
|
||||||
mutable ClickHandlerPtr _fastReplyLink;
|
mutable ClickHandlerPtr _fastReplyLink;
|
||||||
mutable std::unique_ptr<CommentsButton> _comments;
|
mutable std::unique_ptr<CommentsButton> _comments;
|
||||||
std::unique_ptr<ViewButton> _viewButton;
|
mutable std::unique_ptr<ViewButton> _viewButton;
|
||||||
|
|
||||||
Ui::Text::String _rightBadge;
|
Ui::Text::String _rightBadge;
|
||||||
int _bubbleWidthLimit = 0;
|
int _bubbleWidthLimit = 0;
|
||||||
|
|
|
@ -7,10 +7,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
*/
|
*/
|
||||||
#include "history/view/history_view_view_button.h"
|
#include "history/view/history_view_view_button.h"
|
||||||
|
|
||||||
|
#include "core/application.h"
|
||||||
#include "core/click_handler_types.h"
|
#include "core/click_handler_types.h"
|
||||||
|
#include "data/data_cloud_themes.h"
|
||||||
#include "data/data_session.h"
|
#include "data/data_session.h"
|
||||||
#include "data/data_sponsored_messages.h"
|
#include "data/data_sponsored_messages.h"
|
||||||
#include "data/data_user.h"
|
#include "data/data_user.h"
|
||||||
|
#include "data/data_web_page.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
#include "history/view/history_view_cursor_state.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
#include "main/main_session.h"
|
#include "main/main_session.h"
|
||||||
|
@ -42,22 +45,71 @@ inline auto PeerToPhrase(not_null<PeerData*> peer) {
|
||||||
return Ui::Text::Upper(phrase);
|
return Ui::Text::Upper(phrase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline auto WebPageToPhrase(not_null<WebPageData*> webpage) {
|
||||||
|
const auto type = webpage->type;
|
||||||
|
return Ui::Text::Upper((type == WebPageType::Theme)
|
||||||
|
? tr::lng_view_button_theme(tr::now)
|
||||||
|
: (type == WebPageType::Message)
|
||||||
|
? tr::lng_view_button_message(tr::now)
|
||||||
|
: (type == WebPageType::Group)
|
||||||
|
? tr::lng_view_button_group(tr::now)
|
||||||
|
: (type == WebPageType::WallPaper)
|
||||||
|
? tr::lng_view_button_background(tr::now)
|
||||||
|
: (type == WebPageType::Channel)
|
||||||
|
? tr::lng_view_button_channel(tr::now)
|
||||||
|
: (type == WebPageType::VoiceChat)
|
||||||
|
? tr::lng_view_button_voice_chat(tr::now)
|
||||||
|
: (type == WebPageType::Livestream)
|
||||||
|
? tr::lng_view_button_voice_chat_channel(tr::now)
|
||||||
|
: (type == WebPageType::Bot)
|
||||||
|
? tr::lng_view_button_bot(tr::now)
|
||||||
|
: (type == WebPageType::User)
|
||||||
|
? tr::lng_view_button_user(tr::now)
|
||||||
|
: QString());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
struct ViewButton::Inner {
|
struct ViewButton::Inner {
|
||||||
Inner(not_null<PeerData*> peer, Fn<void()> updateCallback);
|
Inner(not_null<PeerData*> peer, Fn<void()> updateCallback);
|
||||||
|
Inner(not_null<Data::Media*> media, Fn<void()> updateCallback);
|
||||||
void updateMask(int height);
|
void updateMask(int height);
|
||||||
void toggleRipple(bool pressed);
|
void toggleRipple(bool pressed);
|
||||||
|
|
||||||
const style::margins &margins;
|
const style::margins &margins;
|
||||||
const ClickHandlerPtr link;
|
const ClickHandlerPtr link;
|
||||||
const Fn<void()> updateCallback;
|
const Fn<void()> updateCallback;
|
||||||
|
bool underDate = true;
|
||||||
int lastWidth = 0;
|
int lastWidth = 0;
|
||||||
QPoint lastPoint;
|
QPoint lastPoint;
|
||||||
std::unique_ptr<Ui::RippleAnimation> ripple;
|
std::unique_ptr<Ui::RippleAnimation> ripple;
|
||||||
Ui::Text::String text;
|
Ui::Text::String text;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
bool ViewButton::MediaHasViewButton(not_null<Data::Media*> media) {
|
||||||
|
return media->webpage()
|
||||||
|
? MediaHasViewButton(media->webpage())
|
||||||
|
: false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ViewButton::MediaHasViewButton(
|
||||||
|
not_null<WebPageData*> webpage) {
|
||||||
|
const auto type = webpage->type;
|
||||||
|
return (type == WebPageType::Message)
|
||||||
|
|| (type == WebPageType::Group)
|
||||||
|
|| (type == WebPageType::Channel)
|
||||||
|
// || (type == WebPageType::Bot)
|
||||||
|
// || (type == WebPageType::User)
|
||||||
|
|| (type == WebPageType::VoiceChat)
|
||||||
|
|| (type == WebPageType::Livestream)
|
||||||
|
|| ((type == WebPageType::Theme)
|
||||||
|
&& webpage->document
|
||||||
|
&& webpage->document->isTheme())
|
||||||
|
|| ((type == WebPageType::WallPaper)
|
||||||
|
&& webpage->document
|
||||||
|
&& webpage->document->isWallPaper());
|
||||||
|
}
|
||||||
|
|
||||||
ViewButton::Inner::Inner(not_null<PeerData*> peer, Fn<void()> updateCallback)
|
ViewButton::Inner::Inner(not_null<PeerData*> peer, Fn<void()> updateCallback)
|
||||||
: margins(st::historyViewButtonMargins)
|
: margins(st::historyViewButtonMargins)
|
||||||
, link(std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
, link(std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||||
|
@ -73,6 +125,26 @@ ViewButton::Inner::Inner(not_null<PeerData*> peer, Fn<void()> updateCallback)
|
||||||
, text(st::historyViewButtonTextStyle, PeerToPhrase(peer)) {
|
, text(st::historyViewButtonTextStyle, PeerToPhrase(peer)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewButton::Inner::Inner(
|
||||||
|
not_null<Data::Media*> media,
|
||||||
|
Fn<void()> updateCallback)
|
||||||
|
: margins(st::historyViewButtonMargins)
|
||||||
|
, link(std::make_shared<LambdaClickHandler>([=](ClickContext context) {
|
||||||
|
const auto my = context.other.value<ClickHandlerContext>();
|
||||||
|
if (const auto controller = my.sessionWindow.get()) {
|
||||||
|
const auto &data = controller->session().data();
|
||||||
|
const auto webpage = media->webpage();
|
||||||
|
if (!webpage) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HiddenUrlClickHandler::Open(webpage->url, context.other);
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
, updateCallback(std::move(updateCallback))
|
||||||
|
, underDate(false)
|
||||||
|
, text(st::historyViewButtonTextStyle, WebPageToPhrase(media->webpage())) {
|
||||||
|
}
|
||||||
|
|
||||||
void ViewButton::Inner::updateMask(int height) {
|
void ViewButton::Inner::updateMask(int height) {
|
||||||
ripple = std::make_unique<Ui::RippleAnimation>(
|
ripple = std::make_unique<Ui::RippleAnimation>(
|
||||||
st::defaultRippleAnimation,
|
st::defaultRippleAnimation,
|
||||||
|
@ -96,6 +168,12 @@ ViewButton::ViewButton(not_null<PeerData*> peer, Fn<void()> updateCallback)
|
||||||
: _inner(std::make_unique<Inner>(peer, std::move(updateCallback))) {
|
: _inner(std::make_unique<Inner>(peer, std::move(updateCallback))) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ViewButton::ViewButton(
|
||||||
|
not_null<Data::Media*> media,
|
||||||
|
Fn<void()> updateCallback)
|
||||||
|
: _inner(std::make_unique<Inner>(media, std::move(updateCallback))) {
|
||||||
|
}
|
||||||
|
|
||||||
ViewButton::~ViewButton() {
|
ViewButton::~ViewButton() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,10 +247,11 @@ bool ViewButton::getState(
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect ViewButton::countSponsoredRect(const QRect &r) const {
|
QRect ViewButton::countRect(const QRect &r) const {
|
||||||
|
const auto dateHeight = (_inner->underDate ? 0 : st::msgDateFont->height);
|
||||||
return QRect(
|
return QRect(
|
||||||
r.left(),
|
r.left(),
|
||||||
r.top() + r.height() - height(),
|
r.top() + r.height() - height() - dateHeight,
|
||||||
r.width(),
|
r.width(),
|
||||||
height()) - _inner->margins;
|
height()) - _inner->margins;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
|
|
||||||
|
namespace Data {
|
||||||
|
class Media;
|
||||||
|
} // namespace Data
|
||||||
|
|
||||||
|
struct WebPageData;
|
||||||
|
|
||||||
namespace HistoryView {
|
namespace HistoryView {
|
||||||
|
|
||||||
struct TextState;
|
struct TextState;
|
||||||
|
@ -16,8 +22,14 @@ struct TextState;
|
||||||
class ViewButton {
|
class ViewButton {
|
||||||
public:
|
public:
|
||||||
ViewButton(not_null<PeerData*> peer, Fn<void()> updateCallback);
|
ViewButton(not_null<PeerData*> peer, Fn<void()> updateCallback);
|
||||||
|
ViewButton(not_null<Data::Media*> media, Fn<void()> updateCallback);
|
||||||
~ViewButton();
|
~ViewButton();
|
||||||
|
|
||||||
|
[[nodiscard]] static bool MediaHasViewButton(
|
||||||
|
not_null<Data::Media*> media);
|
||||||
|
[[nodiscard]] static bool MediaHasViewButton(
|
||||||
|
not_null<WebPageData*> webpage);
|
||||||
|
|
||||||
[[nodiscard]] int height() const;
|
[[nodiscard]] int height() const;
|
||||||
|
|
||||||
void draw(
|
void draw(
|
||||||
|
@ -28,7 +40,7 @@ public:
|
||||||
[[nodiscard]] const ClickHandlerPtr &link() const;
|
[[nodiscard]] const ClickHandlerPtr &link() const;
|
||||||
bool checkLink(const ClickHandlerPtr &other, bool pressed);
|
bool checkLink(const ClickHandlerPtr &other, bool pressed);
|
||||||
|
|
||||||
[[nodiscard]] QRect countSponsoredRect(const QRect &r) const;
|
[[nodiscard]] QRect countRect(const QRect &r) const;
|
||||||
|
|
||||||
[[nodiscard]] bool getState(
|
[[nodiscard]] bool getState(
|
||||||
QPoint point,
|
QPoint point,
|
||||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/view/history_view_element.h"
|
#include "history/view/history_view_element.h"
|
||||||
#include "history/view/history_view_cursor_state.h"
|
#include "history/view/history_view_cursor_state.h"
|
||||||
|
#include "history/view/history_view_view_button.h"
|
||||||
#include "history/view/media/history_view_media_common.h"
|
#include "history/view/media/history_view_media_common.h"
|
||||||
#include "history/view/media/history_view_theme_document.h"
|
#include "history/view/media/history_view_theme_document.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
|
@ -188,7 +189,12 @@ QSize WebPage::countOptimalSize() {
|
||||||
_data->url);
|
_data->url);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto textFloatsAroundInfo = !_asArticle && !_attach && isBubbleBottom();
|
_hasViewButton = ViewButton::MediaHasViewButton(_data);
|
||||||
|
|
||||||
|
const auto textFloatsAroundInfo = !_asArticle
|
||||||
|
&& !_attach
|
||||||
|
&& isBubbleBottom()
|
||||||
|
&& !_hasViewButton;
|
||||||
|
|
||||||
// init strings
|
// init strings
|
||||||
if (_description.isEmpty() && !_data->description.text.isEmpty()) {
|
if (_description.isEmpty() && !_data->description.text.isEmpty()) {
|
||||||
|
@ -391,6 +397,8 @@ QSize WebPage::countCurrentSize(int newWidth) {
|
||||||
} else if (isBubbleBottom() && _attach->customInfoLayout() && _attach->width() + _parent->skipBlockWidth() > innerWidth + bubble.left() + bubble.right()) {
|
} else if (isBubbleBottom() && _attach->customInfoLayout() && _attach->width() + _parent->skipBlockWidth() > innerWidth + bubble.left() + bubble.right()) {
|
||||||
newHeight += bottomInfoPadding();
|
newHeight += bottomInfoPadding();
|
||||||
}
|
}
|
||||||
|
} else if (_hasViewButton) {
|
||||||
|
newHeight += bottomInfoPadding();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
auto padding = inBubblePadding();
|
auto padding = inBubblePadding();
|
||||||
|
@ -471,6 +479,8 @@ void WebPage::draw(Painter &p, const PaintContext &context) const {
|
||||||
bshift += bottomInfoPadding();
|
bshift += bottomInfoPadding();
|
||||||
} else if (isBubbleBottom() && _attach && _attach->customInfoLayout() && _attach->width() + _parent->skipBlockWidth() > paintw + bubble.left() + bubble.right()) {
|
} else if (isBubbleBottom() && _attach && _attach->customInfoLayout() && _attach->width() + _parent->skipBlockWidth() > paintw + bubble.left() + bubble.right()) {
|
||||||
bshift += bottomInfoPadding();
|
bshift += bottomInfoPadding();
|
||||||
|
} else if (_hasViewButton) {
|
||||||
|
bshift += bottomInfoPadding();
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect bar(style::rtlrect(st::msgPadding.left(), tshift, st::webPageBar, height() - tshift - bshift, width()));
|
QRect bar(style::rtlrect(st::msgPadding.left(), tshift, st::webPageBar, height() - tshift - bshift, width()));
|
||||||
|
|
|
@ -117,6 +117,7 @@ private:
|
||||||
mutable std::shared_ptr<Data::PhotoMedia> _photoMedia;
|
mutable std::shared_ptr<Data::PhotoMedia> _photoMedia;
|
||||||
|
|
||||||
bool _asArticle = false;
|
bool _asArticle = false;
|
||||||
|
bool _hasViewButton = false;
|
||||||
int _dataVersion = -1;
|
int _dataVersion = -1;
|
||||||
int _siteNameLines = 0;
|
int _siteNameLines = 0;
|
||||||
int _titleLines = 0;
|
int _titleLines = 0;
|
||||||
|
|
|
@ -751,7 +751,7 @@ historyPollInChosen: icon {{ "poll_select_check", historyFileInIconFg }};
|
||||||
historyPollInChosenSelected: icon {{ "poll_select_check", historyFileInIconFgSelected }};
|
historyPollInChosenSelected: icon {{ "poll_select_check", historyFileInIconFgSelected }};
|
||||||
|
|
||||||
historyViewButtonHeight: 42px;
|
historyViewButtonHeight: 42px;
|
||||||
historyViewButtonMargins: margins(5px, 5px, 5px, 5px);
|
historyViewButtonMargins: margins(13px, 5px, 13px, 5px);
|
||||||
historyViewButtonOutline: margins(2px, 2px, 2px, 2px);
|
historyViewButtonOutline: margins(2px, 2px, 2px, 2px);
|
||||||
historyViewButtonTextStyle: semiboldTextStyle;
|
historyViewButtonTextStyle: semiboldTextStyle;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue