mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-25 04:38:23 +00:00
Add support for imported messages.
This commit is contained in:
parent
34f7391ec9
commit
19455d44db
@ -1223,11 +1223,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
"lng_forwarded_channel_via" = "Forwarded from {channel} via {inline_bot}";
|
||||
"lng_forwarded_signed" = "{channel} ({user})";
|
||||
"lng_forwarded_hidden" = "The account was hidden by the user.";
|
||||
"lng_forwarded_imported" = "This message was imported from another app. It may not be real.";
|
||||
"lng_signed_author" = "Author: {user}";
|
||||
"lng_in_reply_to" = "In reply to";
|
||||
"lng_edited" = "edited";
|
||||
"lng_edited_date" = "Edited: {date}";
|
||||
"lng_sent_date" = "Sent: {date}";
|
||||
"lng_imported" = "imported";
|
||||
"lng_admin_badge" = "admin";
|
||||
"lng_owner_badge" = "owner";
|
||||
"lng_channel_badge" = "channel";
|
||||
|
@ -451,6 +451,12 @@ void paintRow(
|
||||
sendStateIcon->paint(p, rectForName.topLeft() + QPoint(rectForName.width(), 0), fullWidth);
|
||||
}
|
||||
|
||||
p.setFont(st::msgNameFont);
|
||||
p.setPen(active
|
||||
? st::dialogsNameFgActive
|
||||
: selected
|
||||
? st::dialogsNameFgOver
|
||||
: st::dialogsNameFg);
|
||||
if (flags & (Flag::SavedMessages | Flag::RepliesMessages)) {
|
||||
auto text = (flags & Flag::SavedMessages)
|
||||
? tr::lng_saved_messages(tr::now)
|
||||
@ -459,12 +465,6 @@ void paintRow(
|
||||
if (textWidth > rectForName.width()) {
|
||||
text = st::msgNameFont->elided(text, rectForName.width());
|
||||
}
|
||||
p.setFont(st::msgNameFont);
|
||||
p.setPen(active
|
||||
? st::dialogsNameFgActive
|
||||
: selected
|
||||
? st::dialogsNameFgOver
|
||||
: st::dialogsNameFg);
|
||||
p.drawTextLeft(rectForName.left(), rectForName.top(), fullWidth, text);
|
||||
} else if (from) {
|
||||
if (!(flags & Flag::SearchResult)) {
|
||||
@ -488,22 +488,15 @@ void paintRow(
|
||||
badgeStyle);
|
||||
rectForName.setWidth(rectForName.width() - badgeWidth);
|
||||
}
|
||||
p.setPen(active
|
||||
? st::dialogsNameFgActive
|
||||
: selected
|
||||
? st::dialogsNameFgOver
|
||||
: st::dialogsNameFg);
|
||||
from->nameText().drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
} else if (hiddenSenderInfo) {
|
||||
hiddenSenderInfo->nameText.drawElided(p, rectForName.left(), rectForName.top(), rectForName.width());
|
||||
} else {
|
||||
const auto nameFg = active
|
||||
? st::dialogsNameFgActive
|
||||
: (selected
|
||||
if (!active) {
|
||||
p.setPen(selected
|
||||
? st::dialogsArchiveFgOver
|
||||
: st::dialogsArchiveFg);
|
||||
p.setPen(nameFg);
|
||||
p.setFont(st::msgNameFont);
|
||||
}
|
||||
auto text = entry->chatListName(); // TODO feed name with emoji
|
||||
auto textWidth = st::msgNameFont->width(text);
|
||||
if (textWidth > rectForName.width()) {
|
||||
@ -825,8 +818,10 @@ void RowPainter::paint(
|
||||
const auto hiddenSenderInfo = [&]() -> const HiddenSenderInfo* {
|
||||
if (const auto searchChat = row->searchInChat()) {
|
||||
if (const auto peer = searchChat.peer()) {
|
||||
if (peer->isSelf()) {
|
||||
return item->hiddenForwardedInfo();
|
||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||
if (peer->isSelf() || forwarded->imported) {
|
||||
return forwarded->hiddenSenderInfo.get();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2779,10 +2779,7 @@ void HistoryInner::mouseActionUpdate() {
|
||||
const auto message = view->data()->toHistoryMessage();
|
||||
Assert(message != nullptr);
|
||||
|
||||
const auto from = message->displayFrom();
|
||||
dragState = TextState(nullptr, from
|
||||
? from->openLink()
|
||||
: hiddenUserpicLink(message->fullId()));
|
||||
dragState = TextState(nullptr, view->fromPhotoLink());
|
||||
_dragStateItem = session().data().message(dragState.itemId);
|
||||
lnkhost = view;
|
||||
return false;
|
||||
@ -2923,13 +2920,6 @@ void HistoryInner::mouseActionUpdate() {
|
||||
}
|
||||
}
|
||||
|
||||
ClickHandlerPtr HistoryInner::hiddenUserpicLink(FullMsgId id) {
|
||||
static const auto result = std::make_shared<LambdaClickHandler>([] {
|
||||
Ui::Toast::Show(tr::lng_forwarded_hidden(tr::now));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void HistoryInner::updateDragSelection(Element *dragSelFrom, Element *dragSelTo, bool dragSelecting) {
|
||||
if (_dragSelFrom == dragSelFrom && _dragSelTo == dragSelTo && _dragSelecting == dragSelecting) {
|
||||
return;
|
||||
|
@ -214,8 +214,6 @@ private:
|
||||
template <typename Method>
|
||||
void enumerateDates(Method method);
|
||||
|
||||
ClickHandlerPtr hiddenUserpicLink(FullMsgId id);
|
||||
|
||||
void scrollDateCheck();
|
||||
void scrollDateHideByTimer();
|
||||
bool canHaveFromUserpics() const;
|
||||
|
@ -273,9 +273,10 @@ HistoryItem *HistoryItem::lookupDiscussionPostOriginal() const {
|
||||
PeerData *HistoryItem::displayFrom() const {
|
||||
if (const auto sender = discussionPostOriginalSender()) {
|
||||
return sender;
|
||||
} else if (history()->peer->isSelf()
|
||||
|| history()->peer->isRepliesChat()) {
|
||||
return senderOriginal();
|
||||
} else if (const auto forwarded = Get<HistoryMessageForwarded>()) {
|
||||
if (history()->peer->isSelf() || history()->peer->isRepliesChat() || forwarded->imported) {
|
||||
return forwarded->originalSender;
|
||||
}
|
||||
}
|
||||
return author().get();
|
||||
}
|
||||
|
@ -112,10 +112,14 @@ int HistoryMessageEdited::maxWidth() const {
|
||||
return text.maxWidth();
|
||||
}
|
||||
|
||||
HiddenSenderInfo::HiddenSenderInfo(const QString &name)
|
||||
HiddenSenderInfo::HiddenSenderInfo(const QString &name, bool external)
|
||||
: name(name)
|
||||
, colorPeerId(Data::FakePeerIdForJustName(name))
|
||||
, userpic(Data::PeerUserpicColor(colorPeerId), name) {
|
||||
, userpic(
|
||||
Data::PeerUserpicColor(colorPeerId),
|
||||
(external
|
||||
? Ui::EmptyUserpic::ExternalName()
|
||||
: name)) {
|
||||
nameText.setText(st::msgNameStyle, name, Ui::NameTextOptions());
|
||||
const auto parts = name.trimmed().split(' ', base::QStringSkipEmptyParts);
|
||||
firstName = parts[0];
|
||||
|
@ -71,7 +71,7 @@ struct HistoryMessageEdited : public RuntimeComponent<HistoryMessageEdited, Hist
|
||||
};
|
||||
|
||||
struct HiddenSenderInfo {
|
||||
explicit HiddenSenderInfo(const QString &name);
|
||||
HiddenSenderInfo(const QString &name, bool external);
|
||||
|
||||
QString name;
|
||||
QString firstName;
|
||||
@ -101,6 +101,7 @@ struct HistoryMessageForwarded : public RuntimeComponent<HistoryMessageForwarded
|
||||
|
||||
PeerData *savedFromPeer = nullptr;
|
||||
MsgId savedFromMsgId = 0;
|
||||
bool imported = false;
|
||||
};
|
||||
|
||||
struct HistoryMessageReply : public RuntimeComponent<HistoryMessageReply, HistoryItem> {
|
||||
|
@ -440,6 +440,7 @@ struct HistoryMessage::CreateConfig {
|
||||
QString authorOriginal;
|
||||
TimeId originalDate = 0;
|
||||
TimeId editDate = 0;
|
||||
bool imported = false;
|
||||
|
||||
// For messages created from MTP structs.
|
||||
const MTPMessageReplies *mtpReplies = nullptr;
|
||||
@ -466,6 +467,7 @@ void HistoryMessage::FillForwardedInfo(
|
||||
config.savedFromPeer = peerFromMTP(*savedFromPeer);
|
||||
config.savedFromMsgId = savedFromMsgId->v;
|
||||
}
|
||||
config.imported = data.is_imported();
|
||||
}
|
||||
|
||||
HistoryMessage::HistoryMessage(
|
||||
@ -1118,7 +1120,8 @@ void HistoryMessage::setupForwardedComponent(const CreateConfig &config) {
|
||||
: nullptr;
|
||||
if (!forwarded->originalSender) {
|
||||
forwarded->hiddenSenderInfo = std::make_unique<HiddenSenderInfo>(
|
||||
config.senderNameOriginal);
|
||||
config.senderNameOriginal,
|
||||
config.imported);
|
||||
}
|
||||
forwarded->originalId = config.originalId;
|
||||
forwarded->originalAuthor = config.authorOriginal;
|
||||
@ -1126,6 +1129,7 @@ void HistoryMessage::setupForwardedComponent(const CreateConfig &config) {
|
||||
forwarded->savedFromPeer = history()->owner().peerLoaded(
|
||||
config.savedFromPeer);
|
||||
forwarded->savedFromMsgId = config.savedFromMsgId;
|
||||
forwarded->imported = config.imported;
|
||||
}
|
||||
|
||||
void HistoryMessage::refreshMedia(const MTPMessageMedia *media) {
|
||||
|
@ -22,6 +22,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "main/main_session.h"
|
||||
#include "chat_helpers/stickers_emoji_pack.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "ui/toast/toast.h"
|
||||
#include "ui/toasts/common_toasts.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_groups.h"
|
||||
#include "data/data_media_types.h"
|
||||
@ -38,18 +40,19 @@ constexpr int kAttachMessageToPreviousSecondsDelta = 900;
|
||||
|
||||
bool IsAttachedToPreviousInSavedMessages(
|
||||
not_null<HistoryItem*> previous,
|
||||
not_null<HistoryItem*> item) {
|
||||
const auto forwarded = previous->Has<HistoryMessageForwarded>();
|
||||
HistoryMessageForwarded *prevForwarded,
|
||||
not_null<HistoryItem*> item,
|
||||
HistoryMessageForwarded *forwarded) {
|
||||
const auto sender = previous->senderOriginal();
|
||||
if (forwarded != item->Has<HistoryMessageForwarded>()) {
|
||||
if ((prevForwarded != nullptr) != (forwarded != nullptr)) {
|
||||
return false;
|
||||
} else if (sender != item->senderOriginal()) {
|
||||
return false;
|
||||
} else if (!forwarded || sender) {
|
||||
} else if (!prevForwarded || sender) {
|
||||
return true;
|
||||
}
|
||||
const auto previousInfo = previous->hiddenForwardedInfo();
|
||||
const auto itemInfo = item->hiddenForwardedInfo();
|
||||
const auto previousInfo = prevForwarded->hiddenSenderInfo.get();
|
||||
const auto itemInfo = forwarded->hiddenSenderInfo.get();
|
||||
Assert(previousInfo != nullptr);
|
||||
Assert(itemInfo != nullptr);
|
||||
return (*previousInfo == *itemInfo);
|
||||
@ -174,14 +177,26 @@ QString DateTooltipText(not_null<Element*> view) {
|
||||
base::unixtime::parse(forwarded->originalDate).toString(format));
|
||||
if (const auto media = view->media()) {
|
||||
if (media->hidesForwardedInfo()) {
|
||||
dateText += '\n' + tr::lng_forwarded(
|
||||
tr::now,
|
||||
lt_user,
|
||||
(forwarded->originalSender
|
||||
? forwarded->originalSender->shortName()
|
||||
: forwarded->hiddenSenderInfo->firstName));
|
||||
const auto from = forwarded->originalSender
|
||||
? forwarded->originalSender->shortName()
|
||||
: forwarded->hiddenSenderInfo->firstName;
|
||||
if (forwarded->imported) {
|
||||
dateText += '\n' + tr::lng_signed_author(
|
||||
tr::now,
|
||||
lt_user,
|
||||
from);
|
||||
} else {
|
||||
dateText += '\n' + tr::lng_forwarded(
|
||||
tr::now,
|
||||
lt_user,
|
||||
from);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (forwarded->imported) {
|
||||
dateText = tr::lng_forwarded_imported(tr::now)
|
||||
+ "\n\n" + dateText;
|
||||
}
|
||||
}
|
||||
if (const auto msgsigned = view->data()->Get<HistoryMessageSigned>()) {
|
||||
if (msgsigned->isElided && !msgsigned->isAnonymousRank) {
|
||||
@ -492,9 +507,17 @@ bool Element::computeIsAttachToPrevious(not_null<Element*> previous) {
|
||||
&& mayBeAttached(item)
|
||||
&& mayBeAttached(prev);
|
||||
if (possible) {
|
||||
const auto forwarded = item->Get<HistoryMessageForwarded>();
|
||||
const auto prevForwarded = prev->Get<HistoryMessageForwarded>();
|
||||
if (item->history()->peer->isSelf()
|
||||
|| item->history()->peer->isRepliesChat()) {
|
||||
return IsAttachedToPreviousInSavedMessages(prev, item);
|
||||
|| item->history()->peer->isRepliesChat()
|
||||
|| (forwarded && forwarded->imported)
|
||||
|| (prevForwarded && prevForwarded->imported)) {
|
||||
return IsAttachedToPreviousInSavedMessages(
|
||||
prev,
|
||||
prevForwarded,
|
||||
item,
|
||||
forwarded);
|
||||
} else {
|
||||
return prev->from() == item->from();
|
||||
}
|
||||
@ -503,6 +526,28 @@ bool Element::computeIsAttachToPrevious(not_null<Element*> previous) {
|
||||
return false;
|
||||
}
|
||||
|
||||
ClickHandlerPtr Element::fromLink() const {
|
||||
const auto item = data();
|
||||
const auto from = item->displayFrom();
|
||||
if (from) {
|
||||
return from->openLink();
|
||||
}
|
||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||
if (forwarded->imported) {
|
||||
static const auto imported = std::make_shared<LambdaClickHandler>([] {
|
||||
Ui::ShowMultilineToast({
|
||||
.text = { tr::lng_forwarded_imported(tr::now) },
|
||||
});
|
||||
});
|
||||
return imported;
|
||||
}
|
||||
}
|
||||
static const auto hidden = std::make_shared<LambdaClickHandler>([] {
|
||||
Ui::Toast::Show(tr::lng_forwarded_hidden(tr::now));
|
||||
});
|
||||
return hidden;
|
||||
}
|
||||
|
||||
void Element::createUnreadBar(rpl::producer<QString> text) {
|
||||
if (!AddComponents(UnreadBar::Bit())) {
|
||||
return;
|
||||
|
@ -325,6 +325,10 @@ public:
|
||||
void previousInBlocksChanged();
|
||||
void nextInBlocksRemoved();
|
||||
|
||||
[[nodiscard]] ClickHandlerPtr fromPhotoLink() const {
|
||||
return fromLink();
|
||||
}
|
||||
|
||||
virtual ~Element();
|
||||
|
||||
protected:
|
||||
@ -332,6 +336,8 @@ protected:
|
||||
Painter &p,
|
||||
int geometryHeight) const;
|
||||
|
||||
[[nodiscard]] ClickHandlerPtr fromLink() const;
|
||||
|
||||
virtual void refreshDataIdHook();
|
||||
|
||||
private:
|
||||
|
@ -2387,9 +2387,7 @@ void ListWidget::mouseActionUpdate() {
|
||||
Assert(message != nullptr);
|
||||
|
||||
const auto from = message->displayFrom();
|
||||
dragState = TextState(nullptr, from
|
||||
? from->openLink()
|
||||
: hiddenUserpicLink(message->fullId()));
|
||||
dragState = TextState(nullptr, view->fromPhotoLink());
|
||||
_overItemExact = session().data().message(dragState.itemId);
|
||||
lnkhost = view;
|
||||
return false;
|
||||
@ -2461,13 +2459,6 @@ void ListWidget::mouseActionUpdate() {
|
||||
//} // #TODO select scroll
|
||||
}
|
||||
|
||||
ClickHandlerPtr ListWidget::hiddenUserpicLink(FullMsgId id) {
|
||||
static const auto result = std::make_shared<LambdaClickHandler>([] {
|
||||
Ui::Toast::Show(tr::lng_forwarded_hidden(tr::now));
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
style::cursor ListWidget::computeMouseCursor() const {
|
||||
if (ClickHandler::getPressed() || ClickHandler::getActive()) {
|
||||
return style::cur_pointer;
|
||||
|
@ -472,8 +472,6 @@ private:
|
||||
template <typename Method>
|
||||
void enumerateDates(Method method);
|
||||
|
||||
ClickHandlerPtr hiddenUserpicLink(FullMsgId id);
|
||||
|
||||
static constexpr auto kMinimalIdsLimit = 24;
|
||||
|
||||
const not_null<ListDelegate*> _delegate;
|
||||
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/view/history_view_group_call_tracker.h" // UserpicInRow.
|
||||
#include "history/history.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "core/application.h"
|
||||
#include "core/core_settings.h"
|
||||
#include "ui/toast/toast.h"
|
||||
@ -1181,9 +1182,10 @@ void Message::unloadHeavyPart() {
|
||||
_comments = nullptr;
|
||||
}
|
||||
|
||||
bool Message::showForwardsFromSender() const {
|
||||
bool Message::showForwardsFromSender(
|
||||
not_null<HistoryMessageForwarded*> forwarded) const {
|
||||
const auto peer = message()->history()->peer;
|
||||
return peer->isSelf() || peer->isRepliesChat();
|
||||
return peer->isSelf() || peer->isRepliesChat() || forwarded->imported;
|
||||
}
|
||||
|
||||
bool Message::hasFromPhoto() const {
|
||||
@ -1204,8 +1206,10 @@ bool Message::hasFromPhoto() const {
|
||||
return false;
|
||||
} else if (Core::App().settings().chatWide()) {
|
||||
return true;
|
||||
} else if (showForwardsFromSender()) {
|
||||
return item->Has<HistoryMessageForwarded>();
|
||||
} else if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||
if (showForwardsFromSender(forwarded)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return !item->out() && !item->history()->peer->isUser();
|
||||
} break;
|
||||
@ -1436,10 +1440,7 @@ bool Message::getStateFromName(
|
||||
if (point.x() >= availableLeft
|
||||
&& point.x() < availableLeft + availableWidth
|
||||
&& point.x() < availableLeft + nameText->maxWidth()) {
|
||||
static const auto hidden = std::make_shared<LambdaClickHandler>([] {
|
||||
Ui::Toast::Show(tr::lng_forwarded_hidden(tr::now));
|
||||
});
|
||||
outResult->link = from ? from->openLink() : hidden;
|
||||
outResult->link = fromLink();
|
||||
return true;
|
||||
}
|
||||
auto via = item->Get<HistoryMessageVia>();
|
||||
@ -2068,9 +2069,17 @@ bool Message::hasFromName() const {
|
||||
case Context::Pinned:
|
||||
case Context::Replies: {
|
||||
const auto item = message();
|
||||
return (!hasOutLayout() || item->from()->isMegagroup())
|
||||
&& (!item->history()->peer->isUser()
|
||||
|| showForwardsFromSender());
|
||||
if (hasOutLayout() && !item->from()->isMegagroup()) {
|
||||
return false;
|
||||
} else if (!item->history()->peer->isUser()) {
|
||||
return true;
|
||||
}
|
||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||
if (showForwardsFromSender(forwarded)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
} break;
|
||||
case Context::ContactPreview:
|
||||
return false;
|
||||
@ -2087,10 +2096,10 @@ bool Message::displayFromName() const {
|
||||
|
||||
bool Message::displayForwardedFrom() const {
|
||||
const auto item = message();
|
||||
if (showForwardsFromSender()) {
|
||||
return false;
|
||||
}
|
||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||
if (showForwardsFromSender(forwarded)) {
|
||||
return false;
|
||||
}
|
||||
if (const auto sender = item->discussionPostOriginalSender()) {
|
||||
if (sender == forwarded->originalSender) {
|
||||
return false;
|
||||
@ -2111,8 +2120,10 @@ bool Message::hasOutLayout() const {
|
||||
const auto item = message();
|
||||
if (item->history()->peer->isSelf()) {
|
||||
return !item->Has<HistoryMessageForwarded>();
|
||||
} else if (showForwardsFromSender()) {
|
||||
return false;
|
||||
} else if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||
if (showForwardsFromSender(forwarded)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return item->out() && !item->isPost();
|
||||
}
|
||||
@ -2217,7 +2228,7 @@ bool Message::displayFastShare() const {
|
||||
return !peer->isMegagroup();
|
||||
} else if (const auto user = peer->asUser()) {
|
||||
if (const auto forwarded = item->Get<HistoryMessageForwarded>()) {
|
||||
return !showForwardsFromSender()
|
||||
return !showForwardsFromSender(forwarded)
|
||||
&& !item->out()
|
||||
&& forwarded->originalSender
|
||||
&& forwarded->originalSender->isChannel()
|
||||
@ -2701,7 +2712,15 @@ void Message::initTime() {
|
||||
} else if (const auto edited = displayedEditBadge()) {
|
||||
item->_timeWidth = edited->maxWidth();
|
||||
} else {
|
||||
item->_timeText = dateTime().toString(cTimeFormat());
|
||||
const auto forwarded = item->Get<HistoryMessageForwarded>();
|
||||
if (forwarded && forwarded->imported) {
|
||||
const auto date = base::unixtime::parse(forwarded->originalDate);
|
||||
item->_timeText = date.toString(
|
||||
u"d.MM.yy "_q + cTimeFormat() + ' '
|
||||
) + tr::lng_imported(tr::now);
|
||||
} else {
|
||||
item->_timeText = dateTime().toString(cTimeFormat());
|
||||
}
|
||||
item->_timeWidth = st::msgDateFont->width(item->_timeText);
|
||||
}
|
||||
if (item->_text.hasSkipBlock()) {
|
||||
|
@ -125,7 +125,8 @@ private:
|
||||
void refreshEditedBadge();
|
||||
void fromNameUpdated(int width) const;
|
||||
|
||||
[[nodiscard]] bool showForwardsFromSender() const;
|
||||
[[nodiscard]] bool showForwardsFromSender(
|
||||
not_null<HistoryMessageForwarded*> forwarded) const;
|
||||
[[nodiscard]] TextSelection skipTextSelection(
|
||||
TextSelection selection) const;
|
||||
[[nodiscard]] TextSelection unskipTextSelection(
|
||||
|
@ -13,16 +13,23 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "app.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
#include "styles/style_widgets.h" // style::IconButton
|
||||
#include "styles/style_info.h" // st::topBarCall
|
||||
|
||||
namespace Ui {
|
||||
namespace {
|
||||
|
||||
[[nodiscard]] bool IsExternal(const QString &name) {
|
||||
return !name.isEmpty()
|
||||
&& (name.front() == QChar(0))
|
||||
&& QStringView(name).mid(1) == qstr("external");
|
||||
}
|
||||
|
||||
void PaintSavedMessagesInner(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int size,
|
||||
const style::color &bg,
|
||||
const style::color &fg) {
|
||||
// |<----width----->|
|
||||
//
|
||||
@ -92,27 +99,28 @@ void PaintSavedMessagesInner(
|
||||
}
|
||||
}
|
||||
|
||||
void PaintRepliesMessagesInner(
|
||||
void PaintIconInner(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int size,
|
||||
const style::color &bg,
|
||||
int defaultSize,
|
||||
const style::icon &icon,
|
||||
const style::color &fg) {
|
||||
if (size == st::dialogsPhotoSize) {
|
||||
if (size == defaultSize) {
|
||||
const auto rect = QRect{ x, y, size, size };
|
||||
st::dialogsRepliesUserpic.paintInCenter(
|
||||
icon.paintInCenter(
|
||||
p,
|
||||
rect,
|
||||
fg->c);
|
||||
} else {
|
||||
p.save();
|
||||
const auto ratio = size / float64(st::dialogsPhotoSize);
|
||||
const auto ratio = size / float64(defaultSize);
|
||||
p.translate(x + size / 2., y + size / 2.);
|
||||
p.scale(ratio, ratio);
|
||||
const auto skip = st::dialogsPhotoSize;
|
||||
const auto skip = defaultSize;
|
||||
const auto rect = QRect{ -skip, -skip, 2 * skip, 2 * skip };
|
||||
st::dialogsRepliesUserpic.paintInCenter(
|
||||
icon.paintInCenter(
|
||||
p,
|
||||
rect,
|
||||
fg->c);
|
||||
@ -120,6 +128,38 @@ void PaintRepliesMessagesInner(
|
||||
}
|
||||
}
|
||||
|
||||
void PaintRepliesMessagesInner(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int size,
|
||||
const style::color &fg) {
|
||||
PaintIconInner(
|
||||
p,
|
||||
x,
|
||||
y,
|
||||
size,
|
||||
st::dialogsPhotoSize,
|
||||
st::dialogsRepliesUserpic,
|
||||
fg);
|
||||
}
|
||||
|
||||
void PaintExternalMessagesInner(
|
||||
Painter &p,
|
||||
int x,
|
||||
int y,
|
||||
int size,
|
||||
const style::color &fg) {
|
||||
PaintIconInner(
|
||||
p,
|
||||
x,
|
||||
y,
|
||||
size,
|
||||
st::msgPhotoSize,
|
||||
st::topBarCall.icon,
|
||||
fg);
|
||||
}
|
||||
|
||||
template <typename Callback>
|
||||
[[nodiscard]] QPixmap Generate(int size, Callback callback) {
|
||||
auto result = QImage(
|
||||
@ -141,6 +181,10 @@ EmptyUserpic::EmptyUserpic(const style::color &color, const QString &name)
|
||||
fillString(name);
|
||||
}
|
||||
|
||||
QString EmptyUserpic::ExternalName() {
|
||||
return QChar(0) + u"external"_q;
|
||||
}
|
||||
|
||||
template <typename Callback>
|
||||
void EmptyUserpic::paint(
|
||||
Painter &p,
|
||||
@ -160,10 +204,17 @@ void EmptyUserpic::paint(
|
||||
p.setPen(Qt::NoPen);
|
||||
paintBackground();
|
||||
|
||||
p.setFont(font);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.setPen(st::historyPeerUserpicFg);
|
||||
p.drawText(QRect(x, y, size, size), _string, QTextOption(style::al_center));
|
||||
if (IsExternal(_string)) {
|
||||
PaintExternalMessagesInner(p, x, y, size, st::historyPeerUserpicFg);
|
||||
} else {
|
||||
p.setFont(font);
|
||||
p.setBrush(Qt::NoBrush);
|
||||
p.setPen(st::historyPeerUserpicFg);
|
||||
p.drawText(
|
||||
QRect(x, y, size, size),
|
||||
_string,
|
||||
QTextOption(style::al_center));
|
||||
}
|
||||
}
|
||||
|
||||
void EmptyUserpic::paint(
|
||||
@ -226,7 +277,7 @@ void EmptyUserpic::PaintSavedMessages(
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(x, y, size, size);
|
||||
|
||||
PaintSavedMessagesInner(p, x, y, size, bg, fg);
|
||||
PaintSavedMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintSavedMessagesRounded(
|
||||
@ -244,7 +295,7 @@ void EmptyUserpic::PaintSavedMessagesRounded(
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(x, y, size, size, st::roundRadiusSmall, st::roundRadiusSmall);
|
||||
|
||||
PaintSavedMessagesInner(p, x, y, size, bg, fg);
|
||||
PaintSavedMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
QPixmap EmptyUserpic::GenerateSavedMessages(int size) {
|
||||
@ -296,7 +347,7 @@ void EmptyUserpic::PaintRepliesMessages(
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawEllipse(x, y, size, size);
|
||||
|
||||
PaintRepliesMessagesInner(p, x, y, size, bg, fg);
|
||||
PaintRepliesMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintRepliesMessagesRounded(
|
||||
@ -314,7 +365,7 @@ void EmptyUserpic::PaintRepliesMessagesRounded(
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(x, y, size, size, st::roundRadiusSmall, st::roundRadiusSmall);
|
||||
|
||||
PaintRepliesMessagesInner(p, x, y, size, bg, fg);
|
||||
PaintRepliesMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
QPixmap EmptyUserpic::GenerateRepliesMessages(int size) {
|
||||
@ -349,6 +400,10 @@ QPixmap EmptyUserpic::generate(int size) {
|
||||
}
|
||||
|
||||
void EmptyUserpic::fillString(const QString &name) {
|
||||
if (IsExternal(name)) {
|
||||
_string = name;
|
||||
return;
|
||||
}
|
||||
QList<QString> letters;
|
||||
QList<int> levels;
|
||||
|
||||
|
@ -11,6 +11,8 @@ namespace Ui {
|
||||
|
||||
class EmptyUserpic {
|
||||
public:
|
||||
[[nodiscard]] static QString ExternalName();
|
||||
|
||||
EmptyUserpic(const style::color &color, const QString &name);
|
||||
|
||||
void paint(
|
||||
|
Loading…
Reference in New Issue
Block a user