Added view button to sponsored messages.

This commit is contained in:
23rd 2021-10-06 01:18:53 +03:00 committed by John Preston
parent 419f6345b3
commit c5140f34a7
7 changed files with 257 additions and 3 deletions

View File

@ -631,6 +631,8 @@ PRIVATE
history/view/history_view_service_message.h
history/view/history_view_top_bar_widget.cpp
history/view/history_view_top_bar_widget.h
history/view/history_view_view_button.cpp
history/view/history_view_view_button.h
history/view/history_view_webpage_preview.cpp
history/view/history_view_webpage_preview.h
history/history.cpp

View File

@ -2889,6 +2889,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_voice_speed_fast" = "Fast";
"lng_voice_speed_very_fast" = "Very fast";
"lng_view_button_user" = "View user";
"lng_view_button_bot" = "View bot";
"lng_view_button_group" = "View group";
"lng_view_button_channel" = "View channel";
// Wnd specific
"lng_wnd_choose_program_menu" = "Choose Default Program...";

View File

@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_media.h"
#include "history/view/media/history_view_web_page.h"
#include "history/view/history_view_group_call_tracker.h" // UserpicInRow.
#include "history/view/history_view_view_button.h" // ViewButton.
#include "history/history.h"
#include "ui/effects/ripple_animation.h"
#include "base/unixtime.h"
@ -242,6 +243,12 @@ Message::Message(
: Element(delegate, data, replacing) {
initLogEntryOriginal();
initPsa();
if (data->isSponsored()) {
_viewButton = std::make_unique<ViewButton>(
data->displayFrom(),
[=] { history()->owner().requestViewRepaint(this); });
}
}
Message::~Message() {
@ -604,6 +611,12 @@ void Message::draw(Painter &p, const PaintContext &context) const {
auto inner = g;
paintCommentsButton(p, inner, context);
if (_viewButton) {
_viewButton->draw(
p,
_viewButton->countSponsoredRect(inner),
context);
}
auto trect = inner.marginsRemoved(st::msgPadding);
if (mediaOnBottom) {
@ -1066,10 +1079,12 @@ void Message::clickHandlerPressedChanged(
bool pressed) {
Element::clickHandlerPressedChanged(handler, pressed);
if (!handler || !_comments) {
if (!handler) {
return;
} else if (handler == _comments->link) {
} else if (_comments && (handler == _comments->link)) {
toggleCommentsButtonRipple(pressed);
} else if (_viewButton) {
_viewButton->checkLink(handler, pressed);
}
}
@ -1190,6 +1205,13 @@ TextState Message::textState(
if (getStateCommentsButton(point, bubble, &result)) {
return result;
}
if (_viewButton
&& _viewButton->getState(
point,
_viewButton->countSponsoredRect(bubble),
&result)) {
return result;
}
auto trect = bubble.marginsRemoved(st::msgPadding);
if (mediaOnBottom) {
@ -1732,7 +1754,8 @@ void Message::drawInfo(
; msgsigned && !msgsigned->isAnonymousRank) {
msgsigned->signature.drawElided(p, dateX, dateY, item->_timeWidth);
} else if (const auto sponsored = displayedSponsorBadge()) {
sponsored->text.drawElided(p, dateX, dateY, item->_timeWidth);
const auto skipY = _viewButton ? _viewButton->height() : 0;
sponsored->text.drawElided(p, dateX, dateY - skipY, item->_timeWidth);
} else if (const auto edited = displayedEditBadge()) {
edited->text.drawElided(p, dateX, dateY, item->_timeWidth);
} else {
@ -1970,6 +1993,8 @@ bool Message::toggleSelectionByHandlerClick(
const ClickHandlerPtr &handler) const {
if (_comments && _comments->link == handler) {
return true;
} else if (_viewButton && _viewButton->link() == handler) {
return true;
} else if (const auto media = this->media()) {
if (media->toggleSelectionByHandlerClick(handler)) {
return true;
@ -2593,6 +2618,9 @@ int Message::resizeContentGetHeight(int newWidth) {
if (item->repliesAreComments() || item->externalReply()) {
newHeight += st::historyCommentsButtonHeight;
}
if (_viewButton) {
newHeight += _viewButton->height();
}
} else if (mediaDisplayed) {
newHeight = media->height();
} else {

View File

@ -18,6 +18,7 @@ struct HistoryMessageForwarded;
namespace HistoryView {
class ViewButton;
class WebPage;
// Special type of Component for the channel actions log.
@ -223,6 +224,7 @@ private:
mutable ClickHandlerPtr _rightActionLink;
mutable ClickHandlerPtr _fastReplyLink;
mutable std::unique_ptr<CommentsButton> _comments;
std::unique_ptr<ViewButton> _viewButton;
Ui::Text::String _rightBadge;
int _bubbleWidthLimit = 0;

View File

@ -0,0 +1,167 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#include "history/view/history_view_view_button.h"
#include "core/click_handler_types.h"
#include "data/data_user.h"
#include "history/view/history_view_cursor_state.h"
#include "lang/lang_keys.h"
#include "ui/click_handler.h"
#include "ui/effects/ripple_animation.h"
#include "ui/round_rect.h"
#include "ui/text/text_utilities.h" // Ui::Text::ToUpper
#include "window/window_session_controller.h"
#include "styles/style_chat.h"
#include "styles/style_widgets.h"
#include "styles/style_window.h"
namespace HistoryView {
namespace {
inline auto PeerToPhrase(not_null<PeerData*> peer) {
const auto phrase = [&] {
if (const auto user = peer->asUser()) {
return user->isBot()
? tr::lng_view_button_bot
: tr::lng_view_button_user;
} else if (peer->isChat()) {
return tr::lng_view_button_group;
} else if (peer->isChannel()) {
return tr::lng_view_button_channel;
}
Unexpected("Invalid peer in ViewButton.");
}()(tr::now);
return Ui::Text::Upper(phrase);
}
} // namespace
struct ViewButton::Inner {
Inner(not_null<PeerData*> peer, Fn<void()> updateCallback);
void updateMask(int height);
void toggleRipple(bool pressed);
const style::margins &margins;
const ClickHandlerPtr link;
const Fn<void()> updateCallback;
int lastWidth = 0;
QPoint lastPoint;
std::unique_ptr<Ui::RippleAnimation> ripple;
Ui::Text::String text;
};
ViewButton::Inner::Inner(not_null<PeerData*> peer, Fn<void()> updateCallback)
: margins(st::historyViewButtonMargins)
, link(peer->openLink())
, updateCallback(std::move(updateCallback))
, text(st::historyViewButtonTextStyle, PeerToPhrase(peer)) {
}
void ViewButton::Inner::updateMask(int height) {
ripple = std::make_unique<Ui::RippleAnimation>(
st::defaultRippleAnimation,
Ui::RippleAnimation::roundRectMask(
QSize(lastWidth, height - margins.top() - margins.bottom()),
st::roundRadiusLarge),
updateCallback);
}
void ViewButton::Inner::toggleRipple(bool pressed) {
if (ripple) {
if (pressed) {
ripple->add(lastPoint);
} else {
ripple->lastStop();
}
}
}
ViewButton::ViewButton(not_null<PeerData*> peer, Fn<void()> updateCallback)
: _inner(std::make_unique<Inner>(peer, std::move(updateCallback))) {
}
ViewButton::~ViewButton() {
}
void ViewButton::resized() const {
_inner->updateMask(height());
}
int ViewButton::height() const {
return st::historyViewButtonHeight;
}
void ViewButton::draw(
Painter &p,
const QRect &r,
const Ui::ChatPaintContext &context) {
const auto stm = context.messageStyle();
if (_inner->ripple && !_inner->ripple->empty()) {
const auto opacity = p.opacity();
p.setOpacity(st::historyPollRippleOpacity);
const auto colorOverride = &stm->msgWaveformInactive->c;
_inner->ripple->paint(p, r.left(), r.top(), r.width(), colorOverride);
p.setOpacity(opacity);
}
p.save();
{
PainterHighQualityEnabler hq(p);
p.setPen(stm->fwdTextPalette.linkFg);
p.setBrush(Qt::NoBrush);
p.drawRoundedRect(r, st::roundRadiusLarge, st::roundRadiusLarge);
_inner->text.drawElided(
p,
r.left(),
r.top() + (r.height() - _inner->text.minHeight()) / 2,
r.width(),
1,
style::al_center);
}
p.restore();
if (_inner->lastWidth != r.width()) {
_inner->lastWidth = r.width();
resized();
}
}
const ClickHandlerPtr &ViewButton::link() const {
return _inner->link;
}
bool ViewButton::checkLink(const ClickHandlerPtr &other, bool pressed) {
if (_inner->link != other) {
return false;
}
_inner->toggleRipple(pressed);
return true;
}
bool ViewButton::getState(
QPoint point,
const QRect &g,
not_null<TextState*> outResult) const {
if (!g.contains(point)) {
return false;
}
outResult->link = _inner->link;
_inner->lastPoint = point - g.topLeft();
return true;
}
QRect ViewButton::countSponsoredRect(const QRect &r) const {
return QRect(
r.left(),
r.top() + r.height() - height(),
r.width(),
height()) - _inner->margins;
}
} // namespace HistoryView

View File

@ -0,0 +1,45 @@
/*
This file is part of Telegram Desktop,
the official desktop application for the Telegram messaging service.
For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/
#pragma once
#include "ui/chat/chat_style.h"
namespace HistoryView {
struct TextState;
class ViewButton {
public:
ViewButton(not_null<PeerData*> peer, Fn<void()> updateCallback);
~ViewButton();
[[nodiscard]] int height() const;
void draw(
Painter &p,
const QRect &r,
const Ui::ChatPaintContext &context);
[[nodiscard]] const ClickHandlerPtr &link() const;
bool checkLink(const ClickHandlerPtr &other, bool pressed);
[[nodiscard]] QRect countSponsoredRect(const QRect &r) const;
[[nodiscard]] bool getState(
QPoint point,
const QRect &g,
not_null<TextState*> outResult) const;
private:
void resized() const;
struct Inner;
const std::unique_ptr<Inner> _inner;
};
} // namespace HistoryView

View File

@ -750,6 +750,11 @@ historyPollOutChosenSelected: icon {{ "poll_select_check", historyFileOutIconFgS
historyPollInChosen: icon {{ "poll_select_check", historyFileInIconFg }};
historyPollInChosenSelected: icon {{ "poll_select_check", historyFileInIconFgSelected }};
historyViewButtonHeight: 42px;
historyViewButtonMargins: margins(5px, 5px, 5px, 5px);
historyViewButtonOutline: margins(2px, 2px, 2px, 2px);
historyViewButtonTextStyle: defaultTextStyle;
historyCommentsButtonHeight: 40px;
historyCommentsSkipLeft: 9px;
historyCommentsSkipText: 10px;