mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Move preview paint to Dialogs::Ui::MessageView.
This commit is contained in:
parent
5136cc3c9c
commit
8c21fad642
21 changed files with 265 additions and 151 deletions
|
@ -484,6 +484,8 @@ PRIVATE
|
|||
dialogs/dialogs_widget.h
|
||||
dialogs/ui/dialogs_layout.cpp
|
||||
dialogs/ui/dialogs_layout.h
|
||||
dialogs/ui/dialogs_message_view.cpp
|
||||
dialogs/ui/dialogs_message_view.h
|
||||
editor/color_picker.cpp
|
||||
editor/color_picker.h
|
||||
editor/controllers/controllers.h
|
||||
|
|
|
@ -148,7 +148,7 @@ struct MessageUpdate {
|
|||
NewMaybeAdded = (1U << 7),
|
||||
RepliesUnreadCount = (1U << 8),
|
||||
|
||||
LastUsedBit = (1U << 7),
|
||||
LastUsedBit = (1U << 8),
|
||||
};
|
||||
using Flags = base::flags<Flag>;
|
||||
friend inline constexpr auto is_flag_type(Flag) { return true; }
|
||||
|
|
|
@ -55,6 +55,8 @@ namespace {
|
|||
|
||||
constexpr auto kFastRevokeRestriction = 24 * 60 * TimeId(60);
|
||||
|
||||
using ItemPreview = HistoryView::ItemPreview;
|
||||
|
||||
[[nodiscard]] Call ComputeCallData(const MTPDmessageActionPhoneCall &call) {
|
||||
auto result = Call();
|
||||
result.finishReason = [&] {
|
||||
|
@ -201,11 +203,12 @@ bool Media::canBeGrouped() const {
|
|||
return false;
|
||||
}
|
||||
|
||||
QString Media::chatListText(DrawInDialog way) const {
|
||||
ItemPreview Media::toPreview(ToPreviewOptions options) const {
|
||||
auto result = notificationText();
|
||||
return result.isEmpty()
|
||||
auto text = result.isEmpty()
|
||||
? QString()
|
||||
: textcmdLink(1, TextUtilities::Clean(std::move(result)));
|
||||
return { .text = std::move(text) };
|
||||
}
|
||||
|
||||
bool Media::hasReplyPreview() const {
|
||||
|
@ -341,11 +344,16 @@ QString MediaPhoto::notificationText() const {
|
|||
parent()->originalText().text);
|
||||
}
|
||||
|
||||
QString MediaPhoto::chatListText(DrawInDialog way) const {
|
||||
const auto caption = (way == DrawInDialog::WithoutSenderAndCaption)
|
||||
ItemPreview MediaPhoto::toPreview(ToPreviewOptions options) const {
|
||||
const auto caption = options.hideCaption
|
||||
? QString()
|
||||
: parent()->originalText().text;
|
||||
return WithCaptionDialogsText(tr::lng_in_dlg_photo(tr::now), caption);
|
||||
// #TODO minis generate images and support albums
|
||||
return {
|
||||
.text = WithCaptionDialogsText(
|
||||
tr::lng_in_dlg_photo(tr::now),
|
||||
caption)
|
||||
};
|
||||
}
|
||||
|
||||
QString MediaPhoto::pinnedTextSubstring() const {
|
||||
|
@ -511,16 +519,16 @@ bool MediaFile::replyPreviewLoaded() const {
|
|||
return _document->replyPreviewLoaded();
|
||||
}
|
||||
|
||||
QString MediaFile::chatListText(DrawInDialog way) const {
|
||||
ItemPreview MediaFile::toPreview(ToPreviewOptions options) const {
|
||||
if (const auto sticker = _document->sticker()) {
|
||||
return Media::chatListText(way);
|
||||
return Media::toPreview(options);
|
||||
}
|
||||
const auto type = [&] {
|
||||
using namespace Ui::Text;
|
||||
if (_document->isVideoMessage()) {
|
||||
return tr::lng_in_dlg_video_message(tr::now);
|
||||
} else if (_document->isAnimation()) {
|
||||
return qsl("GIF");
|
||||
return u"GIF"_q;
|
||||
} else if (_document->isVideoFile()) {
|
||||
return tr::lng_in_dlg_video(tr::now);
|
||||
} else if (_document->isVoiceMessage()) {
|
||||
|
@ -533,10 +541,13 @@ QString MediaFile::chatListText(DrawInDialog way) const {
|
|||
}
|
||||
return tr::lng_in_dlg_file(tr::now);
|
||||
}();
|
||||
const auto caption = (way == DrawInDialog::WithoutSenderAndCaption)
|
||||
const auto caption = options.hideCaption
|
||||
? QString()
|
||||
: parent()->originalText().text;
|
||||
return WithCaptionDialogsText(type, caption);
|
||||
// #TODO minis generate images and support albums
|
||||
return {
|
||||
.text = WithCaptionDialogsText(type, caption),
|
||||
};
|
||||
}
|
||||
|
||||
QString MediaFile::notificationText() const {
|
||||
|
@ -855,8 +866,11 @@ Data::CloudImage *MediaLocation::location() const {
|
|||
return _location;
|
||||
}
|
||||
|
||||
QString MediaLocation::chatListText(DrawInDialog way) const {
|
||||
return WithCaptionDialogsText(tr::lng_maps_point(tr::now), _title);
|
||||
ItemPreview MediaLocation::toPreview(ToPreviewOptions options) const {
|
||||
// #TODO minis generate images
|
||||
return {
|
||||
.text = WithCaptionDialogsText(tr::lng_maps_point(tr::now), _title),
|
||||
};
|
||||
}
|
||||
|
||||
QString MediaLocation::notificationText() const {
|
||||
|
@ -1049,8 +1063,8 @@ bool MediaWebPage::replyPreviewLoaded() const {
|
|||
return true;
|
||||
}
|
||||
|
||||
QString MediaWebPage::chatListText(DrawInDialog way) const {
|
||||
return notificationText();
|
||||
ItemPreview MediaWebPage::toPreview(ToPreviewOptions options) const {
|
||||
return { .text = notificationText() };
|
||||
}
|
||||
|
||||
QString MediaWebPage::notificationText() const {
|
||||
|
|
|
@ -27,7 +27,8 @@ namespace HistoryView {
|
|||
enum class Context : char;
|
||||
class Element;
|
||||
class Media;
|
||||
enum class DrawInDialog;
|
||||
struct ItemPreview;
|
||||
struct ToPreviewOptions;
|
||||
} // namespace HistoryView
|
||||
|
||||
namespace Data {
|
||||
|
@ -73,7 +74,8 @@ public:
|
|||
|
||||
not_null<HistoryItem*> parent() const;
|
||||
|
||||
using DrawInDialog = HistoryView::DrawInDialog;
|
||||
using ToPreviewOptions = HistoryView::ToPreviewOptions;
|
||||
using ItemPreview = HistoryView::ItemPreview;
|
||||
|
||||
virtual std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) = 0;
|
||||
|
||||
|
@ -95,7 +97,7 @@ public:
|
|||
virtual bool replyPreviewLoaded() const;
|
||||
// Returns text with link-start and link-end commands for service-color highlighting.
|
||||
// Example: "[link1-start]You:[link1-end] [link1-start]Photo,[link1-end] caption text"
|
||||
virtual QString chatListText(DrawInDialog way) const;
|
||||
virtual ItemPreview toPreview(ToPreviewOptions way) const;
|
||||
virtual QString notificationText() const = 0;
|
||||
virtual QString pinnedTextSubstring() const = 0;
|
||||
virtual TextForMimeData clipboardText() const = 0;
|
||||
|
@ -151,7 +153,7 @@ public:
|
|||
bool hasReplyPreview() const override;
|
||||
Image *replyPreview() const override;
|
||||
bool replyPreviewLoaded() const override;
|
||||
QString chatListText(DrawInDialog way) const override;
|
||||
ItemPreview toPreview(ToPreviewOptions options) const override;
|
||||
QString notificationText() const override;
|
||||
QString pinnedTextSubstring() const override;
|
||||
TextForMimeData clipboardText() const override;
|
||||
|
@ -189,7 +191,7 @@ public:
|
|||
bool hasReplyPreview() const override;
|
||||
Image *replyPreview() const override;
|
||||
bool replyPreviewLoaded() const override;
|
||||
QString chatListText(DrawInDialog way) const override;
|
||||
ItemPreview toPreview(ToPreviewOptions options) const override;
|
||||
QString notificationText() const override;
|
||||
QString pinnedTextSubstring() const override;
|
||||
TextForMimeData clipboardText() const override;
|
||||
|
@ -255,7 +257,7 @@ public:
|
|||
std::unique_ptr<Media> clone(not_null<HistoryItem*> parent) override;
|
||||
|
||||
Data::CloudImage *location() const override;
|
||||
QString chatListText(DrawInDialog way) const override;
|
||||
ItemPreview toPreview(ToPreviewOptions options) const override;
|
||||
QString notificationText() const override;
|
||||
QString pinnedTextSubstring() const override;
|
||||
TextForMimeData clipboardText() const override;
|
||||
|
@ -323,7 +325,7 @@ public:
|
|||
bool hasReplyPreview() const override;
|
||||
Image *replyPreview() const override;
|
||||
bool replyPreviewLoaded() const override;
|
||||
QString chatListText(DrawInDialog way) const override;
|
||||
ItemPreview toPreview(ToPreviewOptions options) const override;
|
||||
QString notificationText() const override;
|
||||
QString pinnedTextSubstring() const override;
|
||||
TextForMimeData clipboardText() const override;
|
||||
|
|
|
@ -1382,6 +1382,10 @@ void Session::requestItemRepaint(not_null<const HistoryItem*> item) {
|
|||
}
|
||||
}
|
||||
}
|
||||
const auto history = item->history();
|
||||
if (history->lastItemDialogsView.dependsOn(item)) {
|
||||
history->updateChatListEntry();
|
||||
}
|
||||
}
|
||||
|
||||
rpl::producer<not_null<const HistoryItem*>> Session::itemRepaintRequest() const {
|
||||
|
|
|
@ -296,3 +296,6 @@ dialogsScamFont: font(9px semibold);
|
|||
dialogsScamSkip: 4px;
|
||||
dialogsScamRadius: 2px;
|
||||
|
||||
dialogsMiniPreview: 32px;
|
||||
dialogsMiniPreviewSkip: 4px;
|
||||
dialogsMiniPreviewRight: 6px;
|
||||
|
|
|
@ -43,8 +43,7 @@ uint64 PinnedDialogPos(int pinnedIndex) {
|
|||
} // namespace
|
||||
|
||||
Entry::Entry(not_null<Data::Session*> owner, Type type)
|
||||
: lastItemTextCache(st::dialogsTextWidthMin)
|
||||
, _owner(owner)
|
||||
: _owner(owner)
|
||||
, _isFolder(type == Type::Folder) {
|
||||
}
|
||||
|
||||
|
|
|
@ -183,13 +183,10 @@ public:
|
|||
paintUserpic(p, view, rtl() ? (w - x - size) : x, y, size);
|
||||
}
|
||||
|
||||
TimeId chatListTimeId() const {
|
||||
[[nodiscard]] TimeId chatListTimeId() const {
|
||||
return _timeId;
|
||||
}
|
||||
|
||||
mutable const HistoryItem *textCachedFor = nullptr; // cache
|
||||
mutable Ui::Text::String lastItemTextCache;
|
||||
|
||||
protected:
|
||||
void notifyUnreadStateChange(const UnreadState &wasState);
|
||||
auto unreadStateChangeNotifier(bool required) {
|
||||
|
|
|
@ -154,14 +154,6 @@ InnerWidget::InnerWidget(
|
|||
dialogRowReplaced(r.old, r.now);
|
||||
}, lifetime());
|
||||
|
||||
session().data().itemRepaintRequest(
|
||||
) | rpl::start_with_next([=](auto item) {
|
||||
const auto history = item->history();
|
||||
if (history->textCachedFor == item) {
|
||||
history->updateChatListEntry();
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
session().data().sendActionManager().animationUpdated(
|
||||
) | rpl::start_with_next([=](
|
||||
const Data::SendActionManager::AnimationUpdate &update) {
|
||||
|
@ -235,16 +227,9 @@ InnerWidget::InnerWidget(
|
|||
}, lifetime());
|
||||
|
||||
session().changes().messageUpdates(
|
||||
Data::MessageUpdate::Flag::DialogRowRepaint
|
||||
| Data::MessageUpdate::Flag::DialogRowRefresh
|
||||
Data::MessageUpdate::Flag::DialogRowRefresh
|
||||
) | rpl::start_with_next([=](const Data::MessageUpdate &update) {
|
||||
const auto item = update.item;
|
||||
if (update.flags & Data::MessageUpdate::Flag::DialogRowRefresh) {
|
||||
refreshDialogRow({ item->history(), item->fullId() });
|
||||
}
|
||||
if (update.flags & Data::MessageUpdate::Flag::DialogRowRepaint) {
|
||||
repaintDialogRow({ item->history(), item->fullId() });
|
||||
}
|
||||
refreshDialogRow({ update.item->history(), update.item->fullId() });
|
||||
}, lifetime());
|
||||
|
||||
session().changes().entryUpdates(
|
||||
|
@ -1530,7 +1515,7 @@ void InnerWidget::refreshDialogRow(RowDescriptor row) {
|
|||
if (row.fullId) {
|
||||
for (const auto &result : _searchResults) {
|
||||
if (result->item()->fullId() == row.fullId) {
|
||||
result->invalidateCache();
|
||||
result->itemView().itemInvalidated(result->item());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -285,8 +285,7 @@ void Row::validateListEntryCache() const {
|
|||
|
||||
FakeRow::FakeRow(Key searchInChat, not_null<HistoryItem*> item)
|
||||
: _searchInChat(searchInChat)
|
||||
, _item(item)
|
||||
, _cache(st::dialogsTextWidthMin) {
|
||||
, _item(item) {
|
||||
}
|
||||
|
||||
} // namespace Dialogs
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/text.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "dialogs/dialogs_key.h"
|
||||
#include "dialogs/ui/dialogs_message_view.h"
|
||||
|
||||
class History;
|
||||
class HistoryItem;
|
||||
|
@ -138,10 +139,8 @@ public:
|
|||
[[nodiscard]] not_null<HistoryItem*> item() const {
|
||||
return _item;
|
||||
}
|
||||
|
||||
void invalidateCache() {
|
||||
_cacheFor = nullptr;
|
||||
_cache = Ui::Text::String();
|
||||
[[nodiscard]] Ui::MessageView &itemView() const {
|
||||
return _itemView;
|
||||
}
|
||||
|
||||
private:
|
||||
|
@ -149,8 +148,7 @@ private:
|
|||
|
||||
Key _searchInChat;
|
||||
not_null<HistoryItem*> _item;
|
||||
mutable const HistoryItem *_cacheFor = nullptr;
|
||||
mutable Ui::Text::String _cache;
|
||||
mutable Ui::MessageView _itemView;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -775,14 +775,13 @@ void RowPainter::paint(
|
|||
if (const auto folder = row->folder()) {
|
||||
PaintListEntryText(p, itemRect, active, selected, row);
|
||||
} else if (history && !actionWasPainted) {
|
||||
item->drawInDialog(
|
||||
history->lastItemDialogsView.paint(
|
||||
p,
|
||||
item,
|
||||
itemRect,
|
||||
active,
|
||||
selected,
|
||||
HistoryItem::DrawInDialog::Normal,
|
||||
history->textCachedFor,
|
||||
history->lastItemTextCache);
|
||||
{});
|
||||
}
|
||||
};
|
||||
const auto paintCounterCallback = [&] {
|
||||
|
@ -845,15 +844,15 @@ void RowPainter::paint(
|
|||
}
|
||||
return nullptr;
|
||||
}();
|
||||
const auto drawInDialogWay = [&] {
|
||||
const auto previewOptions = [&]() -> HistoryView::ToPreviewOptions {
|
||||
if (const auto searchChat = row->searchInChat()) {
|
||||
if (const auto peer = searchChat.peer()) {
|
||||
if (!peer->isChannel() || peer->isMegagroup()) {
|
||||
return HistoryItem::DrawInDialog::WithoutSender;
|
||||
return { .hideSender = true };
|
||||
}
|
||||
}
|
||||
}
|
||||
return HistoryItem::DrawInDialog::Normal;
|
||||
return {};
|
||||
}();
|
||||
|
||||
const auto unreadCount = displayUnreadInfo
|
||||
|
@ -895,14 +894,13 @@ void RowPainter::paint(
|
|||
texttop,
|
||||
availableWidth,
|
||||
st::dialogsTextFont->height);
|
||||
item->drawInDialog(
|
||||
row->itemView().paint(
|
||||
p,
|
||||
item,
|
||||
itemRect,
|
||||
active,
|
||||
selected,
|
||||
drawInDialogWay,
|
||||
row->_cacheFor,
|
||||
row->_cache);
|
||||
previewOptions);
|
||||
};
|
||||
const auto paintCounterCallback = [&] {
|
||||
PaintNarrowCounter(
|
||||
|
|
69
Telegram/SourceFiles/dialogs/ui/dialogs_message_view.cpp
Normal file
69
Telegram/SourceFiles/dialogs/ui/dialogs_message_view.cpp
Normal file
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
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 "dialogs/ui/dialogs_message_view.h"
|
||||
|
||||
#include "history/history_item.h"
|
||||
#include "ui/text/text_options.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
|
||||
namespace Dialogs::Ui {
|
||||
namespace {
|
||||
|
||||
} // namespace
|
||||
|
||||
MessageView::MessageView()
|
||||
: _textCache(st::dialogsTextWidthMin) {
|
||||
}
|
||||
|
||||
MessageView::~MessageView() = default;
|
||||
|
||||
void MessageView::itemInvalidated(not_null<const HistoryItem*> item) {
|
||||
if (_textCachedFor == item.get()) {
|
||||
_textCachedFor = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool MessageView::dependsOn(not_null<const HistoryItem*> item) const {
|
||||
return (_textCachedFor == item.get());
|
||||
}
|
||||
|
||||
void MessageView::paint(
|
||||
Painter &p,
|
||||
not_null<const HistoryItem*> item,
|
||||
const QRect &geometry,
|
||||
bool active,
|
||||
bool selected,
|
||||
ToPreviewOptions options) const {
|
||||
if (geometry.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (_textCachedFor != item.get()) {
|
||||
const auto preview = item->toPreview(options);
|
||||
_textCache.setText(
|
||||
st::dialogsTextStyle,
|
||||
preview.text,
|
||||
DialogTextOptions());
|
||||
_textCachedFor = item;
|
||||
}
|
||||
p.setTextPalette(active
|
||||
? st::dialogsTextPaletteActive
|
||||
: selected
|
||||
? st::dialogsTextPaletteOver
|
||||
: st::dialogsTextPalette);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg));
|
||||
_textCache.drawElided(
|
||||
p,
|
||||
geometry.left(),
|
||||
geometry.top(),
|
||||
geometry.width(),
|
||||
geometry.height() / st::dialogsTextFont->height);
|
||||
p.restoreTextPalette();
|
||||
}
|
||||
|
||||
} // namespace Dialogs::Ui
|
51
Telegram/SourceFiles/dialogs/ui/dialogs_message_view.h
Normal file
51
Telegram/SourceFiles/dialogs/ui/dialogs_message_view.h
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
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
|
||||
|
||||
class HistoryItem;
|
||||
|
||||
namespace Ui {
|
||||
|
||||
} // namespace Ui
|
||||
|
||||
namespace HistoryView {
|
||||
struct ToPreviewOptions;
|
||||
struct ItemPreview;
|
||||
} // namespace HistoryView
|
||||
|
||||
namespace Dialogs::Ui {
|
||||
|
||||
using namespace ::Ui;
|
||||
|
||||
class MessageView final {
|
||||
public:
|
||||
MessageView();
|
||||
~MessageView();
|
||||
|
||||
using ToPreviewOptions = HistoryView::ToPreviewOptions;
|
||||
using ItemPreview = HistoryView::ItemPreview;
|
||||
|
||||
void itemInvalidated(not_null<const HistoryItem*> item);
|
||||
[[nodiscard]] bool dependsOn(not_null<const HistoryItem*> item) const;
|
||||
|
||||
void paint(
|
||||
Painter &p,
|
||||
not_null<const HistoryItem*> item,
|
||||
const QRect &geometry,
|
||||
bool active,
|
||||
bool selected,
|
||||
ToPreviewOptions options) const;
|
||||
|
||||
private:
|
||||
mutable const HistoryItem *_textCachedFor = nullptr;
|
||||
mutable Ui::Text::String _textCache;
|
||||
mutable std::vector<QImage> _imagesCache;
|
||||
|
||||
};
|
||||
|
||||
} // namespace Dialogs::Ui
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_peer.h"
|
||||
#include "data/data_drafts.h"
|
||||
#include "dialogs/dialogs_entry.h"
|
||||
#include "dialogs/ui/dialogs_message_view.h"
|
||||
#include "history/view/history_view_send_action.h"
|
||||
#include "base/observer.h"
|
||||
#include "base/timer.h"
|
||||
|
@ -457,6 +458,7 @@ public:
|
|||
mtpRequestId sendRequestId = 0;
|
||||
|
||||
Ui::Text::String cloudDraftTextCache;
|
||||
Dialogs::Ui::MessageView lastItemDialogsView;
|
||||
|
||||
private:
|
||||
friend class HistoryBlock;
|
||||
|
|
|
@ -49,6 +49,8 @@ namespace {
|
|||
|
||||
constexpr auto kNotificationTextLimit = 255;
|
||||
|
||||
using ItemPreview = HistoryView::ItemPreview;
|
||||
|
||||
enum class MediaCheckResult {
|
||||
Good,
|
||||
Unsupported,
|
||||
|
@ -292,17 +294,7 @@ void HistoryItem::invalidateChatListEntry() {
|
|||
history()->session().changes().messageUpdated(
|
||||
this,
|
||||
Data::MessageUpdate::Flag::DialogRowRefresh);
|
||||
|
||||
// invalidate cache for drawInDialog
|
||||
if (history()->textCachedFor == this) {
|
||||
history()->textCachedFor = nullptr;
|
||||
}
|
||||
//if (const auto feed = history()->peer->feed()) { // #TODO archive
|
||||
// if (feed->textCachedFor == this) {
|
||||
// feed->textCachedFor = nullptr;
|
||||
// feed->updateChatListEntry();
|
||||
// }
|
||||
//}
|
||||
history()->lastItemDialogsView.itemInvalidated(this);
|
||||
}
|
||||
|
||||
void HistoryItem::finishEditionToEmpty() {
|
||||
|
@ -946,20 +938,25 @@ QString HistoryItem::notificationText() const {
|
|||
: result.mid(0, kNotificationTextLimit) + qsl("...");
|
||||
}
|
||||
|
||||
QString HistoryItem::inDialogsText(DrawInDialog way) const {
|
||||
const auto plainText = [&] {
|
||||
ItemPreview HistoryItem::toPreview(ToPreviewOptions options) const {
|
||||
auto result = [&]() -> ItemPreview {
|
||||
if (_media) {
|
||||
if (_groupId) {
|
||||
return textcmdLink(1, TextUtilities::Clean(tr::lng_in_dlg_album(tr::now)));
|
||||
// #TODO minis generate albums correctly
|
||||
return {
|
||||
.text = textcmdLink(
|
||||
1,
|
||||
TextUtilities::Clean(tr::lng_in_dlg_album(tr::now))),
|
||||
};
|
||||
}
|
||||
return _media->chatListText(way);
|
||||
return _media->toPreview(options);
|
||||
} else if (!emptyText()) {
|
||||
return TextUtilities::Clean(_text.toString());
|
||||
return { .text = TextUtilities::Clean(_text.toString()) };
|
||||
}
|
||||
return QString();
|
||||
return {};
|
||||
}();
|
||||
const auto sender = [&]() -> PeerData* {
|
||||
if (isPost() || isEmpty() || (way != DrawInDialog::Normal)) {
|
||||
if (options.hideSender || isPost() || isEmpty()) {
|
||||
return nullptr;
|
||||
} else if (!_history->peer->isUser() || out()) {
|
||||
return displayFrom();
|
||||
|
@ -969,39 +966,29 @@ QString HistoryItem::inDialogsText(DrawInDialog way) const {
|
|||
return nullptr;
|
||||
}();
|
||||
if (sender) {
|
||||
auto fromText = sender->isSelf() ? tr::lng_from_you(tr::now) : sender->shortName();
|
||||
auto fromWrapped = textcmdLink(1, tr::lng_dialogs_text_from_wrapped(tr::now, lt_from, TextUtilities::Clean(fromText)));
|
||||
return tr::lng_dialogs_text_with_from(tr::now, lt_from_part, fromWrapped, lt_message, plainText);
|
||||
const auto fromText = sender->isSelf()
|
||||
? tr::lng_from_you(tr::now)
|
||||
: sender->shortName();
|
||||
const auto fromWrapped = textcmdLink(
|
||||
1,
|
||||
tr::lng_dialogs_text_from_wrapped(
|
||||
tr::now,
|
||||
lt_from,
|
||||
TextUtilities::Clean(fromText)));
|
||||
result.text = tr::lng_dialogs_text_with_from(
|
||||
tr::now,
|
||||
lt_from_part,
|
||||
fromWrapped,
|
||||
lt_message,
|
||||
std::move(result.text));
|
||||
}
|
||||
return plainText;
|
||||
return result;
|
||||
}
|
||||
|
||||
Ui::Text::IsolatedEmoji HistoryItem::isolatedEmoji() const {
|
||||
return Ui::Text::IsolatedEmoji();
|
||||
}
|
||||
|
||||
void HistoryItem::drawInDialog(
|
||||
Painter &p,
|
||||
const QRect &r,
|
||||
bool active,
|
||||
bool selected,
|
||||
DrawInDialog way,
|
||||
const HistoryItem *&cacheFor,
|
||||
Ui::Text::String &cache) const {
|
||||
if (r.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
if (cacheFor != this) {
|
||||
cacheFor = this;
|
||||
cache.setText(st::dialogsTextStyle, inDialogsText(way), Ui::DialogTextOptions());
|
||||
}
|
||||
p.setTextPalette(active ? st::dialogsTextPaletteActive : (selected ? st::dialogsTextPaletteOver : st::dialogsTextPalette));
|
||||
p.setFont(st::dialogsTextFont);
|
||||
p.setPen(active ? st::dialogsTextFgActive : (selected ? st::dialogsTextFgOver : st::dialogsTextFg));
|
||||
cache.drawElided(p, r.left(), r.top(), r.width(), r.height() / st::dialogsTextFont->height);
|
||||
p.restoreTextPalette();
|
||||
}
|
||||
|
||||
HistoryItem::~HistoryItem() {
|
||||
applyTTL(0);
|
||||
}
|
||||
|
|
|
@ -46,17 +46,25 @@ class SessionController;
|
|||
} // namespace Window
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
struct TextState;
|
||||
struct StateRequest;
|
||||
enum class CursorState : char;
|
||||
enum class PointState : char;
|
||||
enum class Context : char;
|
||||
class ElementDelegate;
|
||||
enum class DrawInDialog {
|
||||
Normal,
|
||||
WithoutSender,
|
||||
WithoutSenderAndCaption,
|
||||
|
||||
struct ToPreviewOptions {
|
||||
bool hideSender = false;
|
||||
bool hideCaption = false;
|
||||
bool generateImages = true;
|
||||
};
|
||||
|
||||
struct ItemPreview {
|
||||
QString text;
|
||||
std::vector<QImage> images;
|
||||
};
|
||||
|
||||
} // namespace HistoryView
|
||||
|
||||
struct HiddenSenderInfo;
|
||||
|
@ -298,13 +306,18 @@ public:
|
|||
}
|
||||
[[nodiscard]] virtual QString notificationText() const;
|
||||
|
||||
using DrawInDialog = HistoryView::DrawInDialog;
|
||||
using ToPreviewOptions = HistoryView::ToPreviewOptions;
|
||||
using ItemPreview = HistoryView::ItemPreview;
|
||||
|
||||
// Returns text with link-start and link-end commands for service-color highlighting.
|
||||
// Example: "[link1-start]You:[link1-end] [link1-start]Photo,[link1-end] caption text"
|
||||
[[nodiscard]] virtual QString inDialogsText(DrawInDialog way) const;
|
||||
[[nodiscard]] virtual ItemPreview toPreview(
|
||||
ToPreviewOptions options) const;
|
||||
[[nodiscard]] virtual QString inReplyText() const {
|
||||
return inDialogsText(DrawInDialog::WithoutSender);
|
||||
return toPreview({
|
||||
.hideSender = true,
|
||||
.generateImages = false,
|
||||
}).text;
|
||||
}
|
||||
[[nodiscard]] virtual Ui::Text::IsolatedEmoji isolatedEmoji() const;
|
||||
[[nodiscard]] virtual TextWithEntities originalText() const {
|
||||
|
@ -335,15 +348,6 @@ public:
|
|||
virtual void incrementReplyToTopCounter() {
|
||||
}
|
||||
|
||||
void drawInDialog(
|
||||
Painter &p,
|
||||
const QRect &r,
|
||||
bool active,
|
||||
bool selected,
|
||||
DrawInDialog way,
|
||||
const HistoryItem *&cacheFor,
|
||||
Ui::Text::String &cache) const;
|
||||
|
||||
[[nodiscard]] bool emptyText() const {
|
||||
return _text.isEmpty();
|
||||
}
|
||||
|
|
|
@ -43,6 +43,8 @@ namespace {
|
|||
|
||||
constexpr auto kPinnedMessageTextLimit = 16;
|
||||
|
||||
using ItemPreview = HistoryView::ItemPreview;
|
||||
|
||||
[[nodiscard]] bool PeerCallKnown(not_null<PeerData*> peer) {
|
||||
if (peer->groupCall() != nullptr) {
|
||||
return true;
|
||||
|
@ -923,14 +925,18 @@ bool HistoryService::needCheck() const {
|
|||
return out() && !isEmpty();
|
||||
}
|
||||
|
||||
QString HistoryService::inDialogsText(DrawInDialog way) const {
|
||||
return textcmdLink(1, TextUtilities::Clean(notificationText()));
|
||||
ItemPreview HistoryService::toPreview(ToPreviewOptions options) const {
|
||||
// #TODO minis generate images
|
||||
return {
|
||||
.text = textcmdLink(1, TextUtilities::Clean(notificationText())),
|
||||
};
|
||||
}
|
||||
|
||||
QString HistoryService::inReplyText() const {
|
||||
const auto result = HistoryService::notificationText();
|
||||
const auto text = result.trimmed().startsWith(author()->name)
|
||||
? result.trimmed().mid(author()->name.size()).trimmed()
|
||||
const auto &name = author()->name;
|
||||
const auto text = result.trimmed().startsWith(name)
|
||||
? result.trimmed().mid(name.size()).trimmed()
|
||||
: result;
|
||||
return textcmdLink(1, text);
|
||||
}
|
||||
|
@ -1190,19 +1196,7 @@ void HistoryService::updateDependentText() {
|
|||
void HistoryService::updateText(PreparedText &&text) {
|
||||
setServiceText(text);
|
||||
history()->owner().requestItemResize(this);
|
||||
const auto inDialogsHistory = history()->migrateToOrMe();
|
||||
if (inDialogsHistory->textCachedFor == this) {
|
||||
inDialogsHistory->textCachedFor = nullptr;
|
||||
}
|
||||
//if (const auto feed = history()->peer->feed()) { // #TODO archive
|
||||
// if (feed->textCachedFor == this) {
|
||||
// feed->textCachedFor = nullptr;
|
||||
// feed->updateChatListEntry();
|
||||
// }
|
||||
//}
|
||||
history()->session().changes().messageUpdated(
|
||||
this,
|
||||
Data::MessageUpdate::Flag::DialogRowRepaint);
|
||||
invalidateChatListEntry();
|
||||
history()->owner().updateDependentMessages(this);
|
||||
}
|
||||
|
||||
|
|
|
@ -111,7 +111,7 @@ public:
|
|||
bool serviceMsg() const override {
|
||||
return true;
|
||||
}
|
||||
QString inDialogsText(DrawInDialog way) const override;
|
||||
ItemPreview toPreview(ToPreviewOptions options) const override;
|
||||
QString inReplyText() const override;
|
||||
|
||||
std::unique_ptr<HistoryView::Element> createView(
|
||||
|
|
|
@ -6853,11 +6853,16 @@ void HistoryWidget::updateForwardingTexts() {
|
|||
}
|
||||
|
||||
if (count < 2) {
|
||||
text = _toForward.items.front()->inDialogsText(keepCaptions
|
||||
? HistoryItem::DrawInDialog::WithoutSender
|
||||
: HistoryItem::DrawInDialog::WithoutSenderAndCaption);
|
||||
// #TODO minis use images
|
||||
text = _toForward.items.front()->toPreview({
|
||||
.hideSender = true,
|
||||
.hideCaption = !keepCaptions,
|
||||
.generateImages = false,
|
||||
}).text;
|
||||
} else {
|
||||
text = textcmdLink(1, tr::lng_forward_messages(tr::now, lt_count, count));
|
||||
text = textcmdLink(
|
||||
1,
|
||||
tr::lng_forward_messages(tr::now, lt_count, count));
|
||||
}
|
||||
}
|
||||
_toForwardFrom.setText(st::msgNameStyle, from, Ui::NameTextOptions());
|
||||
|
|
|
@ -804,10 +804,11 @@ void Notification::updateNotifyDisplay() {
|
|||
p.setTextPalette(st::dialogsTextPalette);
|
||||
p.setPen(st::dialogsTextFg);
|
||||
p.setFont(st::dialogsTextFont);
|
||||
const auto text = _item
|
||||
? _item->inDialogsText(reminder
|
||||
? HistoryItem::DrawInDialog::WithoutSender
|
||||
: HistoryItem::DrawInDialog::Normal)
|
||||
const auto text = _item // #TODO minis use images
|
||||
? _item->toPreview({
|
||||
.hideSender = reminder,
|
||||
.generateImages = false,
|
||||
}).text
|
||||
: ((!_author.isEmpty()
|
||||
? textcmdLink(1, _author)
|
||||
: QString())
|
||||
|
|
Loading…
Add table
Reference in a new issue