Files
AyuGramDesktop/Telegram/SourceFiles/history/view/history_view_message.h
T

407 lines
11 KiB
C++

/*
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 "history/view/history_view_element.h"
#include "history/view/history_view_bottom_info.h"
#include "ui/effects/animations.h"
class HistoryItem;
struct HistoryMessageEdited;
struct HistoryMessageForwarded;
struct HistoryMessageReplyMarkup;
struct HistoryMessageSuggestion;
struct HistoryMessageReply;
namespace Data {
struct ReactionId;
} // namespace Data
namespace Ui {
struct BubbleRounding;
class RoundCheckbox;
} // namespace Ui
namespace HistoryView {
class ViewButton;
class WebPage;
class TranscribeButton;
namespace Reactions {
class InlineList;
} // namespace Reactions
namespace ReplyButton {
struct ButtonParameters;
} // namespace ReplyButton
// Special type of Component for the channel actions log.
struct LogEntryOriginal : RuntimeComponent<LogEntryOriginal, Element> {
LogEntryOriginal();
LogEntryOriginal(LogEntryOriginal &&other);
LogEntryOriginal &operator=(LogEntryOriginal &&other);
~LogEntryOriginal();
std::unique_ptr<WebPage> page;
};
struct Factcheck : RuntimeComponent<Factcheck, Element> {
std::unique_ptr<WebPage> page;
bool expanded = false;
};
struct PsaTooltipState : RuntimeComponent<PsaTooltipState, Element> {
QString type;
mutable ClickHandlerPtr link;
mutable Ui::Animations::Simple buttonVisibleAnimation;
mutable bool buttonVisible = true;
};
enum class BadgeRole : uchar {
User,
Admin,
Creator,
};
struct RightBadge : RuntimeComponent<RightBadge, Element> {
Ui::Text::String tag;
Ui::Text::String boosts;
mutable ClickHandlerPtr tagLink;
mutable ClickHandlerPtr boostsLink;
int width = 0;
BadgeRole role = BadgeRole::User;
bool overridden = false;
bool special = false;
mutable std::unique_ptr<Ui::RippleAnimation> ripple;
mutable QPoint lastPoint;
};
struct BottomRippleMask {
QImage image;
int shift = 0;
};
class Message final : public Element {
public:
Message(
not_null<ElementDelegate*> delegate,
not_null<HistoryItem*> data,
Element *replacing);
~Message();
void clickHandlerPressedChanged(
const ClickHandlerPtr &handler,
bool pressed) override;
[[nodiscard]] const HistoryMessageEdited *displayedEditBadge() const;
[[nodiscard]] HistoryMessageEdited *displayedEditBadge();
bool embedReactionsInBubble() const override;
int marginTop() const override;
int marginBottom() const override;
void draw(Painter &p, const PaintContext &context) const override;
PointState pointState(QPoint point) const override;
TextState textState(
QPoint point,
StateRequest request) const override;
void updatePressed(QPoint point) override;
void drawInfo(
Painter &p,
const PaintContext &context,
int right,
int bottom,
int width,
InfoDisplayType type) const override;
TextState bottomInfoTextState(
int right,
int bottom,
QPoint point,
InfoDisplayType type) const override;
TextForMimeData selectedText(TextSelection selection) const override;
SelectedQuote selectedQuote(TextSelection selection) const override;
TextSelection selectionFromQuote(
const SelectedQuote &quote) const override;
TextSelection adjustSelection(
TextSelection selection,
TextSelectType type) const override;
Reactions::ButtonParameters reactionButtonParameters(
QPoint position,
const TextState &reactionState) const override;
ReplyButton::ButtonParameters replyButtonParameters(
QPoint position,
const TextState &replyState) const override;
int reactionsOptimalWidth() const override;
void unloadHeavyPart() override;
// hasFromPhoto() returns true even if we don't display the photo
// but we need to skip a place at the left side for this photo
bool hasFromPhoto() const override;
bool displayFromPhoto() const override;
bool hasFromName() const override;
bool displayFromName() const override;
bool displayForwardedFrom() const override;
bool hasOutLayout() const override;
bool drawBubble() const override;
bool hasBubble() const override;
TopicButton *displayedTopicButton() const override;
bool unwrapped() const override;
int minWidthForMedia() const override;
bool displayRightActionComments() const;
std::optional<QSize> rightActionSize() const override;
void drawRightAction(
Painter &p,
const PaintContext &context,
int left,
int top,
int outerWidth) const override;
[[nodiscard]] ClickHandlerPtr rightActionLink(
std::optional<QPoint> pressPoint) const override;
[[nodiscard]] TimeId displayedEditDate() const override;
[[nodiscard]] bool toggleSelectionByHandlerClick(
const ClickHandlerPtr &handler) const override;
[[nodiscard]] bool allowTextSelectionByHandler(
const ClickHandlerPtr &handler) const override;
[[nodiscard]] int infoWidth() const override;
[[nodiscard]] int bottomInfoFirstLineWidth() const override;
[[nodiscard]] bool bottomInfoIsWide() const override;
[[nodiscard]] bool isSignedAuthorElided() const override;
void itemDataChanged() override;
VerticalRepaintRange verticalRepaintRange() const override;
void applyGroupAdminChanges(
const base::flat_set<UserId> &changes) override;
void animateReaction(Ui::ReactionFlyAnimationArgs &&args) override;
auto takeEffectAnimation()
-> std::unique_ptr<Ui::ReactionFlyAnimation> override;
QRect effectIconGeometry() const override;
QRect innerGeometry() const override;
QPoint mediaTopLeft() const override;
[[nodiscard]] BottomRippleMask bottomRippleMask(int buttonHeight) const;
private:
struct CommentsButton;
struct LinkRipple;
struct FromNameStatus;
struct RightAction;
void refreshDataIdHook() override;
bool hasHeavyPart() const override;
bool updateBottomInfo();
void initPaidInformation();
void refreshSuggestedInfo(
not_null<HistoryItem*> item,
not_null<const HistoryMessageSuggestion*> suggest,
const HistoryMessageReply *reply);
void initLogEntryOriginal();
void initPsa();
void fromNameUpdated(int width) const;
[[nodiscard]] TextSelection skipTextSelection(
TextSelection selection) const;
[[nodiscard]] TextSelection unskipTextSelection(
TextSelection selection) const;
void toggleCommentsButtonRipple(bool pressed);
void createCommentsButtonRipple();
void toggleTopicButtonRipple(bool pressed);
void createTopicButtonRipple();
void toggleLinkRipple(bool pressed);
void recordLinkRipplePoint(
QPoint point,
QPoint textOrigin) const;
void paintLinkRipple(
Painter &p,
const ClickHandlerPtr &handler,
QRect linkRect,
QPoint textPosition) const;
void createLinkRippleMask(
const QPainterPath &path,
QPoint textPosition,
int useWidth,
style::margins padding,
int radius) const;
void createLinkRippleMask(
QRect linkRect,
QPoint textPosition,
style::margins padding,
int radius) const;
void toggleRightActionRipple(bool pressed);
void toggleBadgeRipple(bool pressed);
void toggleReplyRipple(bool pressed);
void toggleSummaryHeaderRipple(bool pressed);
void paintCommentsButton(
Painter &p,
QRect &g,
const PaintContext &context) const;
void paintFromName(
Painter &p,
QRect &trect,
const PaintContext &context) const;
void paintTopicButton(
Painter &p,
QRect &trect,
const PaintContext &context) const;
void paintForwardedInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const;
void paintReplyInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const;
void paintSummaryHeaderInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const;
// This method draws "via @bot" if it is not painted
// in forwarded info or in from name.
void paintViaBotIdInfo(
Painter &p,
QRect &trect,
const PaintContext &context) const;
void paintText(
Painter &p,
QRect &trect,
const PaintContext &context) const;
bool getStateCommentsButton(
QPoint point,
QRect &g,
not_null<TextState*> outResult) const;
bool getStateFromName(
QPoint point,
QRect &trect,
not_null<TextState*> outResult) const;
bool getStateTopicButton(
QPoint point,
QRect &trect,
not_null<TextState*> outResult) const;
bool getStateForwardedInfo(
QPoint point,
QRect &trect,
not_null<TextState*> outResult,
StateRequest request) const;
bool getStateReplyInfo(
QPoint point,
QRect &trect,
not_null<TextState*> outResult) const;
bool getStateSummaryHeaderInfo(
QPoint point,
QRect &trect,
not_null<TextState*> outResult) const;
bool getStateViaBotIdInfo(
QPoint point,
QRect &trect,
not_null<TextState*> outResult) const;
bool getStateText(
QPoint point,
QRect &trect,
not_null<TextState*> outResult,
StateRequest request) const;
void updateMediaInBubbleState();
QRect countGeometry() const;
[[nodiscard]] Ui::BubbleRounding countMessageRounding() const;
[[nodiscard]] Ui::BubbleRounding countBubbleRounding(
Ui::BubbleRounding messageRounding) const;
[[nodiscard]] Ui::BubbleRounding countBubbleRounding() const;
int resizeContentGetHeight(int newWidth);
QSize performCountOptimalSize() override;
QSize performCountCurrentSize(int newWidth) override;
bool hasVisibleText() const override;
[[nodiscard]] int visibleTextLength() const;
[[nodiscard]] int visibleMediaTextLength() const;
[[nodiscard]] bool needInfoDisplay() const;
[[nodiscard]] bool invertMedia() const;
[[nodiscard]] bool hasFastReply() const;
[[nodiscard]] bool displayFastReply() const;
[[nodiscard]] bool isPinnedContext() const;
[[nodiscard]] bool isCommentsRootView() const;
[[nodiscard]] bool displayFastShare() const;
[[nodiscard]] bool displayGoToOriginal() const;
[[nodiscard]] ClickHandlerPtr fastReplyLink() const;
[[nodiscard]] ClickHandlerPtr prepareRightActionLink() const;
void ensureRightAction() const;
void refreshTopicButton();
void refreshInfoSkipBlock(HistoryItem *textItem);
[[nodiscard]] int monospaceMaxWidth() const;
[[nodiscard]] int bubbleTextWidth(int bubbleWidth) const;
[[nodiscard]] int bubbleTextualWidth() const;
void ensureSummarizeButton() const;
void paintSummarize(
Painter &p,
int x,
int y,
bool right,
const PaintContext &context,
QRect g) const;
void updateViewButtonExistence();
[[nodiscard]] int viewButtonHeight() const;
[[nodiscard]] WebPage *logEntryOriginal() const;
[[nodiscard]] WebPage *factcheckBlock() const;
[[nodiscard]] ClickHandlerPtr createGoToCommentsLink() const;
[[nodiscard]] ClickHandlerPtr psaTooltipLink() const;
void psaTooltipToggled(bool shown) const;
void invalidateTextDependentCache() override;
void refreshRightBadge();
[[nodiscard]] int rightBadgeWidth() const;
void validateFromNameText(PeerData *from) const;
void ensureFromNameStatusLink(not_null<PeerData*> peer) const;
mutable std::unique_ptr<RightAction> _rightAction;
mutable ClickHandlerPtr _fastReplyLink;
mutable std::unique_ptr<ViewButton> _viewButton;
std::unique_ptr<TopicButton> _topicButton;
mutable std::unique_ptr<LinkRipple> _linkRipple;
mutable QPoint _linkRippleLastPoint;
mutable std::unique_ptr<CommentsButton> _comments;
mutable std::unique_ptr<TranscribeButton> _summarize;
mutable Ui::Text::String _fromName;
mutable std::unique_ptr<FromNameStatus> _fromNameStatus;
mutable std::unique_ptr<Ui::RoundCheckbox> _selectionRoundCheckbox;
mutable int _fromNameVersion = 0;
mutable int _bubbleTextualWidthMinimum : 16 = -1;
mutable int _bubbleTextualWidthCache : 16 = 0;
uint32 _bubbleWidthLimit : 27 = 0;
uint32 _invertMedia : 1 = 0;
uint32 _hideReply : 1 = 0;
uint32 _postShowingAuthor : 1 = 0;
BottomInfo _bottomInfo;
mutable QPoint _lastMediaPosition;
};
} // namespace HistoryView