mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-25 01:50:36 +00:00
Added view button to sponsored messages.
This commit is contained in:
parent
419f6345b3
commit
c5140f34a7
@ -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
|
||||
|
@ -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...";
|
||||
|
@ -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 {
|
||||
|
@ -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;
|
||||
|
167
Telegram/SourceFiles/history/view/history_view_view_button.cpp
Normal file
167
Telegram/SourceFiles/history/view/history_view_view_button.cpp
Normal 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
|
45
Telegram/SourceFiles/history/view/history_view_view_button.h
Normal file
45
Telegram/SourceFiles/history/view/history_view_view_button.h
Normal 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
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user