mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 21:27:07 +02:00
Support custom emoji in reply / pinned / forward bars.
This commit is contained in:
parent
2fc43a44a4
commit
3238cf2b4b
12 changed files with 112 additions and 39 deletions
|
@ -431,6 +431,7 @@ public:
|
|||
|
||||
void updateDate(TimeId newDate);
|
||||
[[nodiscard]] bool canUpdateDate() const;
|
||||
void customEmojiRepaint();
|
||||
|
||||
[[nodiscard]] TimeId ttlDestroyAt() const {
|
||||
return _ttlDestroyAt;
|
||||
|
@ -463,7 +464,6 @@ protected:
|
|||
MessageFlags _flags = 0;
|
||||
|
||||
void invalidateChatListEntry();
|
||||
void customEmojiRepaint();
|
||||
|
||||
void setGroupId(MessageGroupId groupId);
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_service_message.h"
|
||||
#include "history/view/media/history_view_document.h"
|
||||
#include "core/click_handler_types.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "layout/layout_position.h"
|
||||
#include "mainwindow.h"
|
||||
#include "media/audio/media_audio.h"
|
||||
|
@ -256,10 +257,15 @@ bool HistoryMessageReply::updateData(
|
|||
}
|
||||
|
||||
if (replyToMsg) {
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &holder->history()->session(),
|
||||
.customEmojiRepaint = [=] { holder->customEmojiRepaint(); },
|
||||
};
|
||||
replyToText.setMarkedText(
|
||||
st::messageTextStyle,
|
||||
replyToMsg->inReplyText(),
|
||||
Ui::DialogTextOptions());
|
||||
Ui::DialogTextOptions(),
|
||||
context);
|
||||
|
||||
updateName(holder);
|
||||
|
||||
|
@ -447,6 +453,7 @@ void HistoryMessageReply::paint(
|
|||
p.setTextPalette(inBubble
|
||||
? stm->replyTextPalette
|
||||
: st->imgReplyTextPalette());
|
||||
holder->prepareCustomEmojiPaint(p, replyToText);
|
||||
replyToText.drawLeftElided(p, x + st::msgReplyBarSkip + previewSkip, y + st::msgReplyPadding.top() + st::msgServiceNameFont->height, w - st::msgReplyBarSkip - previewSkip, w + 2 * x);
|
||||
p.setTextPalette(stm->textPalette);
|
||||
}
|
||||
|
|
|
@ -149,6 +149,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "chat_helpers/emoji_suggestions_widget.h"
|
||||
#include "core/crash_reports.h"
|
||||
#include "core/shortcuts.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "support/support_common.h"
|
||||
#include "support/support_autocomplete.h"
|
||||
#include "support/support_preload.h"
|
||||
|
@ -6365,10 +6366,10 @@ void HistoryWidget::checkPinnedBarState() {
|
|||
return;
|
||||
}
|
||||
|
||||
auto barContent = HistoryView::PinnedBarContent(
|
||||
&session(),
|
||||
_pinnedTracker->shownMessageId());
|
||||
_pinnedBar = std::make_unique<Ui::PinnedBar>(this);
|
||||
_pinnedBar = std::make_unique<Ui::PinnedBar>(this, [=] {
|
||||
return controller()->isGifPausedAtLeastFor(
|
||||
Window::GifPauseReason::Any);
|
||||
});
|
||||
rpl::combine(
|
||||
Info::Profile::SharedMediaCountValue(
|
||||
_peer,
|
||||
|
@ -6389,7 +6390,11 @@ void HistoryWidget::checkPinnedBarState() {
|
|||
) | rpl::start_with_next([=](bool many, HistoryItem *item) {
|
||||
refreshPinnedBarButton(many, item);
|
||||
}, _pinnedBar->lifetime());
|
||||
_pinnedBar->setContent(std::move(barContent));
|
||||
|
||||
_pinnedBar->setContent(HistoryView::PinnedBarContent(
|
||||
&session(),
|
||||
_pinnedTracker->shownMessageId(),
|
||||
[bar = _pinnedBar.get()] { bar->update(); }));
|
||||
|
||||
controller()->adaptive().oneColumnValue(
|
||||
) | rpl::start_with_next([=](bool one) {
|
||||
|
@ -7417,10 +7422,15 @@ void HistoryWidget::messageDataReceived(
|
|||
}
|
||||
|
||||
void HistoryWidget::updateReplyEditText(not_null<HistoryItem*> item) {
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &session(),
|
||||
.customEmojiRepaint = [=] { updateField(); },
|
||||
};
|
||||
_replyEditMsgText.setMarkedText(
|
||||
st::messageTextStyle,
|
||||
item->inReplyText(),
|
||||
Ui::DialogTextOptions());
|
||||
Ui::DialogTextOptions(),
|
||||
context);
|
||||
if (!_field->isHidden() || isRecording()) {
|
||||
_fieldBarCancel->show();
|
||||
updateMouseTracking();
|
||||
|
@ -7518,10 +7528,15 @@ void HistoryWidget::updateForwardingTexts() {
|
|||
}
|
||||
}
|
||||
_toForwardFrom.setText(st::msgNameStyle, from, Ui::NameTextOptions());
|
||||
const auto context = Core::MarkedTextContext{
|
||||
.session = &session(),
|
||||
.customEmojiRepaint = [=] { updateField(); },
|
||||
};
|
||||
_toForwardText.setMarkedText(
|
||||
st::messageTextStyle,
|
||||
text,
|
||||
Ui::DialogTextOptions());
|
||||
Ui::DialogTextOptions(),
|
||||
context);
|
||||
_toForwardNameVersion = keepNames ? version : keepCaptions ? -1 : -2;
|
||||
}
|
||||
|
||||
|
@ -7570,7 +7585,7 @@ void HistoryWidget::updateReplyToName() {
|
|||
}
|
||||
|
||||
void HistoryWidget::updateField() {
|
||||
auto fieldAreaTop = _scroll->y() + _scroll->height();
|
||||
const auto fieldAreaTop = _scroll->y() + _scroll->height();
|
||||
rtlupdate(0, fieldAreaTop, width(), height() - fieldAreaTop);
|
||||
}
|
||||
|
||||
|
@ -7594,6 +7609,8 @@ void HistoryWidget::drawField(Painter &p, const QRect &rect) {
|
|||
backh += st::historyReplyHeight;
|
||||
}
|
||||
auto drawWebPagePreview = (_previewData && _previewData->pendingTill >= 0) && !_replyForwardPressed;
|
||||
p.setInactive(
|
||||
controller()->isGifPausedAtLeastFor(Window::GifPauseReason::Any));
|
||||
p.fillRect(myrtlrect(0, backy, width(), backh), st::historyReplyBg);
|
||||
if (_editMsgId || _replyToId || (!hasForward && _kbReplyTo)) {
|
||||
auto replyLeft = st::historyReplySkip;
|
||||
|
|
|
@ -944,6 +944,9 @@ void Element::unloadHeavyPart() {
|
|||
if (_heavyCustomEmoji) {
|
||||
_heavyCustomEmoji = false;
|
||||
data()->_text.unloadCustomEmoji();
|
||||
if (const auto reply = data()->Get<HistoryMessageReply>()) {
|
||||
reply->replyToText.unloadCustomEmoji();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "history/view/history_view_pinned_tracker.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history.h"
|
||||
#include "core/ui_integration.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "apiwrap.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
@ -23,16 +24,22 @@ namespace HistoryView {
|
|||
namespace {
|
||||
|
||||
[[nodiscard]] Ui::MessageBarContent ContentWithoutPreview(
|
||||
not_null<HistoryItem*> item) {
|
||||
not_null<HistoryItem*> item,
|
||||
Fn<void()> repaint) {
|
||||
return Ui::MessageBarContent{
|
||||
.text = item->inReplyText(),
|
||||
.context = Core::MarkedTextContext{
|
||||
.session = &item->history()->session(),
|
||||
.customEmojiRepaint = std::move(repaint),
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[[nodiscard]] Ui::MessageBarContent ContentWithPreview(
|
||||
not_null<HistoryItem*> item,
|
||||
Image *preview) {
|
||||
auto result = ContentWithoutPreview(item);
|
||||
Image *preview,
|
||||
Fn<void()> repaint) {
|
||||
auto result = ContentWithoutPreview(item, std::move(repaint));
|
||||
if (!preview) {
|
||||
static const auto kEmpty = [&] {
|
||||
const auto size = st::historyReplyHeight * cIntRetinaFactor();
|
||||
|
@ -51,14 +58,15 @@ namespace {
|
|||
}
|
||||
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItem(
|
||||
not_null<HistoryItem*> item) {
|
||||
not_null<HistoryItem*> item,
|
||||
Fn<void()> repaint) {
|
||||
return item->history()->session().changes().messageFlagsValue(
|
||||
item,
|
||||
Data::MessageUpdate::Flag::Edited
|
||||
) | rpl::map([=]() -> rpl::producer<Ui::MessageBarContent> {
|
||||
const auto media = item->media();
|
||||
if (!media || !media->hasReplyPreview()) {
|
||||
return rpl::single(ContentWithoutPreview(item));
|
||||
return rpl::single(ContentWithoutPreview(item, repaint));
|
||||
}
|
||||
constexpr auto kFullLoaded = 2;
|
||||
constexpr auto kSomeLoaded = 1;
|
||||
|
@ -82,7 +90,7 @@ namespace {
|
|||
}) | rpl::then(
|
||||
rpl::single(kFullLoaded)
|
||||
) | rpl::map([=] {
|
||||
return ContentWithPreview(item, media->replyPreview());
|
||||
return ContentWithPreview(item, media->replyPreview(), repaint);
|
||||
});
|
||||
}) | rpl::flatten_latest();
|
||||
}
|
||||
|
@ -90,11 +98,12 @@ namespace {
|
|||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> ContentByItemId(
|
||||
not_null<Main::Session*> session,
|
||||
FullMsgId id,
|
||||
Fn<void()> repaint,
|
||||
bool alreadyLoaded = false) {
|
||||
if (!id) {
|
||||
return rpl::single(Ui::MessageBarContent());
|
||||
} else if (const auto item = session->data().message(id)) {
|
||||
return ContentByItem(item);
|
||||
return ContentByItem(item, repaint);
|
||||
} else if (alreadyLoaded) {
|
||||
return rpl::single(Ui::MessageBarContent()); // Deleted message?..
|
||||
}
|
||||
|
@ -110,7 +119,7 @@ namespace {
|
|||
return std::move(
|
||||
load
|
||||
) | rpl::then(rpl::deferred([=] {
|
||||
return ContentByItemId(session, id, true);
|
||||
return ContentByItemId(session, id, repaint, true);
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -137,20 +146,23 @@ auto WithPinnedTitle(not_null<Main::Session*> session, PinnedId id) {
|
|||
|
||||
rpl::producer<Ui::MessageBarContent> MessageBarContentByItemId(
|
||||
not_null<Main::Session*> session,
|
||||
FullMsgId id) {
|
||||
return ContentByItemId(session, id);
|
||||
FullMsgId id,
|
||||
Fn<void()> repaint) {
|
||||
return ContentByItemId(session, id, std::move(repaint));
|
||||
}
|
||||
|
||||
rpl::producer<Ui::MessageBarContent> PinnedBarContent(
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<PinnedId> id) {
|
||||
rpl::producer<PinnedId> id,
|
||||
Fn<void()> repaint) {
|
||||
return std::move(
|
||||
id
|
||||
) | rpl::distinct_until_changed(
|
||||
) | rpl::map([=](PinnedId id) {
|
||||
return ContentByItemId(
|
||||
session,
|
||||
id.message
|
||||
id.message,
|
||||
repaint
|
||||
) | rpl::map(WithPinnedTitle(session, id));
|
||||
}) | rpl::flatten_latest();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ namespace HistoryView {
|
|||
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> MessageBarContentByItemId(
|
||||
not_null<Main::Session*> session,
|
||||
FullMsgId id);
|
||||
FullMsgId id,
|
||||
Fn<void()> repaint);
|
||||
|
||||
enum class PinnedIdType;
|
||||
struct PinnedId {
|
||||
|
@ -47,7 +48,8 @@ struct PinnedId {
|
|||
};
|
||||
[[nodiscard]] rpl::producer<Ui::MessageBarContent> PinnedBarContent(
|
||||
not_null<Main::Session*> session,
|
||||
rpl::producer<PinnedId> id);
|
||||
rpl::producer<PinnedId> id,
|
||||
Fn<void()> repaint);
|
||||
|
||||
[[nodiscard]] rpl::producer<HistoryItem*> PinnedBarItemWithReplyMarkup(
|
||||
not_null<Main::Session*> session,
|
||||
|
|
|
@ -90,10 +90,12 @@ bool CanSendFiles(not_null<const QMimeData*> data) {
|
|||
|
||||
rpl::producer<Ui::MessageBarContent> RootViewContent(
|
||||
not_null<History*> history,
|
||||
MsgId rootId) {
|
||||
MsgId rootId,
|
||||
Fn<void()> repaint) {
|
||||
return MessageBarContentByItemId(
|
||||
&history->session(),
|
||||
FullMsgId(history->peer->id, rootId)
|
||||
FullMsgId(history->peer->id, rootId),
|
||||
std::move(repaint)
|
||||
) | rpl::map([=](Ui::MessageBarContent &&content) {
|
||||
const auto item = history->owner().message(history->peer, rootId);
|
||||
if (!item) {
|
||||
|
@ -387,14 +389,19 @@ void RepliesWidget::setupRoot() {
|
|||
}
|
||||
|
||||
void RepliesWidget::setupRootView() {
|
||||
auto content = rpl::combine(
|
||||
RootViewContent(_history, _rootId),
|
||||
_rootView = std::make_unique<Ui::PinnedBar>(this, [=] {
|
||||
return controller()->isGifPausedAtLeastFor(
|
||||
Window::GifPauseReason::Any);
|
||||
});
|
||||
_rootView->setContent(rpl::combine(
|
||||
RootViewContent(
|
||||
_history,
|
||||
_rootId,
|
||||
[bar = _rootView.get()] { bar->update(); }),
|
||||
_rootVisible.value()
|
||||
) | rpl::map([=](Ui::MessageBarContent &&content, bool shown) {
|
||||
return shown ? std::move(content) : Ui::MessageBarContent();
|
||||
});
|
||||
_rootView = std::make_unique<Ui::PinnedBar>(this);
|
||||
_rootView->setContent(std::move(content));
|
||||
}));
|
||||
|
||||
controller()->adaptive().oneColumnValue(
|
||||
) | rpl::start_with_next([=](bool one) {
|
||||
|
|
|
@ -250,6 +250,7 @@ void BotAction::validateIcon() {
|
|||
_mask = QImage(
|
||||
size * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
_mask.setDevicePixelRatio(style::DevicePixelRatio());
|
||||
_mask.fill(Qt::transparent);
|
||||
{
|
||||
auto p = QPainter(&_mask);
|
||||
|
|
|
@ -41,9 +41,13 @@ namespace {
|
|||
|
||||
} // namespace
|
||||
|
||||
MessageBar::MessageBar(not_null<QWidget*> parent, const style::MessageBar &st)
|
||||
MessageBar::MessageBar(
|
||||
not_null<QWidget*> parent,
|
||||
const style::MessageBar &st,
|
||||
Fn<bool()> customEmojiPaused)
|
||||
: _st(st)
|
||||
, _widget(parent) {
|
||||
, _widget(parent)
|
||||
, _customEmojiPaused(std::move(customEmojiPaused)) {
|
||||
setup();
|
||||
|
||||
style::PaletteChanged(
|
||||
|
@ -57,6 +61,7 @@ void MessageBar::setup() {
|
|||
_widget.paintRequest(
|
||||
) | rpl::start_with_next([=](QRect rect) {
|
||||
auto p = Painter(&_widget);
|
||||
p.setInactive(_customEmojiPaused());
|
||||
paint(p);
|
||||
}, _widget.lifetime());
|
||||
}
|
||||
|
@ -187,7 +192,11 @@ void MessageBar::tweenTo(MessageBarContent &&content) {
|
|||
void MessageBar::updateFromContent(MessageBarContent &&content) {
|
||||
_content = std::move(content);
|
||||
_title.setText(_st.title, _content.title);
|
||||
_text.setMarkedText(_st.text, _content.text, Ui::DialogTextOptions());
|
||||
_text.setMarkedText(
|
||||
_st.text,
|
||||
_content.text,
|
||||
Ui::DialogTextOptions(),
|
||||
_content.context);
|
||||
_image = prepareImage(_content.preview);
|
||||
}
|
||||
|
||||
|
|
|
@ -23,13 +23,17 @@ struct MessageBarContent {
|
|||
int count = 1;
|
||||
QString title;
|
||||
TextWithEntities text;
|
||||
std::any context;
|
||||
QImage preview;
|
||||
style::margins margins;
|
||||
};
|
||||
|
||||
class MessageBar final {
|
||||
public:
|
||||
MessageBar(not_null<QWidget*> parent, const style::MessageBar &st);
|
||||
MessageBar(
|
||||
not_null<QWidget*> parent,
|
||||
const style::MessageBar &st,
|
||||
Fn<bool()> customEmojiPaused);
|
||||
|
||||
void set(MessageBarContent &&content);
|
||||
void set(rpl::producer<MessageBarContent> content);
|
||||
|
@ -100,6 +104,7 @@ private:
|
|||
|
||||
const style::MessageBar &_st;
|
||||
Ui::RpWidget _widget;
|
||||
Fn<bool()> _customEmojiPaused;
|
||||
MessageBarContent _content;
|
||||
rpl::lifetime _contentLifetime;
|
||||
Ui::Text::String _title, _text;
|
||||
|
|
|
@ -18,9 +18,10 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Ui {
|
||||
|
||||
PinnedBar::PinnedBar(not_null<QWidget*> parent)
|
||||
PinnedBar::PinnedBar(not_null<QWidget*> parent, Fn<bool()> customEmojiPaused)
|
||||
: _wrap(parent, object_ptr<RpWidget>(parent))
|
||||
, _shadow(std::make_unique<PlainShadow>(_wrap.parentWidget())) {
|
||||
, _shadow(std::make_unique<PlainShadow>(_wrap.parentWidget()))
|
||||
, _customEmojiPaused(std::move(customEmojiPaused)) {
|
||||
_wrap.hide(anim::type::instant);
|
||||
_shadow->hide();
|
||||
|
||||
|
@ -133,7 +134,8 @@ void PinnedBar::createControls() {
|
|||
|
||||
_bar = std::make_unique<MessageBar>(
|
||||
_wrap.entity(),
|
||||
st::defaultMessageBar);
|
||||
st::defaultMessageBar,
|
||||
_customEmojiPaused);
|
||||
if (_right.button) {
|
||||
_right.button->raise();
|
||||
}
|
||||
|
@ -205,6 +207,12 @@ void PinnedBar::raise() {
|
|||
_shadow->raise();
|
||||
}
|
||||
|
||||
void PinnedBar::update() {
|
||||
if (_bar) {
|
||||
_bar->widget()->update();
|
||||
}
|
||||
}
|
||||
|
||||
void PinnedBar::finishAnimating() {
|
||||
_wrap.finishAnimating();
|
||||
}
|
||||
|
|
|
@ -22,12 +22,13 @@ class RpWidget;
|
|||
|
||||
class PinnedBar final {
|
||||
public:
|
||||
PinnedBar(not_null<QWidget*> parent);
|
||||
PinnedBar(not_null<QWidget*> parent, Fn<bool()> customEmojiPaused);
|
||||
~PinnedBar();
|
||||
|
||||
void show();
|
||||
void hide();
|
||||
void raise();
|
||||
void update();
|
||||
void finishAnimating();
|
||||
|
||||
void setShadowGeometryPostprocess(Fn<QRect(QRect)> postprocess);
|
||||
|
@ -60,6 +61,7 @@ private:
|
|||
} _right;
|
||||
|
||||
std::unique_ptr<Ui::PlainShadow> _shadow;
|
||||
Fn<bool()> _customEmojiPaused;
|
||||
rpl::event_stream<> _barClicks;
|
||||
Fn<QRect(QRect)> _shadowGeometryPostprocess;
|
||||
bool _shouldBeShown = false;
|
||||
|
|
Loading…
Add table
Reference in a new issue