mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-02-25 18:10:35 +00:00
Use nice fake message for effect preview.
This commit is contained in:
parent
144109db05
commit
f371cd1af2
@ -799,6 +799,8 @@ PRIVATE
|
||||
history/view/history_view_emoji_interactions.h
|
||||
history/view/history_view_empty_list_bubble.cpp
|
||||
history/view/history_view_empty_list_bubble.h
|
||||
history/view/history_view_fake_items.cpp
|
||||
history/view/history_view_fake_items.h
|
||||
history/view/history_view_group_call_bar.cpp
|
||||
history/view/history_view_group_call_bar.h
|
||||
history/view/history_view_item_preview.h
|
||||
|
@ -16,8 +16,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/admin_log/history_admin_log_item.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/view/history_view_element.h"
|
||||
#include "history/view/reactions/history_view_reactions_strip.h"
|
||||
#include "history/view/history_view_element.h"
|
||||
#include "history/view/history_view_fake_items.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "boxes/premium_preview_box.h"
|
||||
#include "main/main_session.h"
|
||||
@ -43,53 +44,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
namespace {
|
||||
|
||||
PeerId GenerateUser(not_null<History*> history, const QString &name) {
|
||||
Expects(history->peer->isUser());
|
||||
|
||||
const auto peerId = Data::FakePeerIdForJustName(name);
|
||||
history->owner().processUser(MTP_user(
|
||||
MTP_flags(MTPDuser::Flag::f_first_name | MTPDuser::Flag::f_min),
|
||||
peerToBareMTPInt(peerId),
|
||||
MTP_long(0),
|
||||
MTP_string(tr::lng_settings_chat_message_reply_from(tr::now)),
|
||||
MTPstring(), // last name
|
||||
MTPstring(), // username
|
||||
MTPstring(), // phone
|
||||
MTPUserProfilePhoto(), // profile photo
|
||||
MTPUserStatus(), // status
|
||||
MTP_int(0), // bot info version
|
||||
MTPVector<MTPRestrictionReason>(), // restrictions
|
||||
MTPstring(), // bot placeholder
|
||||
MTPstring(), // lang code
|
||||
MTPEmojiStatus(),
|
||||
MTPVector<MTPUsername>(),
|
||||
MTPint(), // stories_max_id
|
||||
MTPPeerColor(), // color
|
||||
MTPPeerColor())); // profile_color
|
||||
return peerId;
|
||||
}
|
||||
|
||||
AdminLog::OwnedItem GenerateItem(
|
||||
not_null<HistoryView::ElementDelegate*> delegate,
|
||||
not_null<History*> history,
|
||||
PeerId from,
|
||||
FullMsgId replyTo,
|
||||
const QString &text) {
|
||||
Expects(history->peer->isUser());
|
||||
|
||||
const auto item = history->addNewLocalMessage({
|
||||
.id = history->nextNonHistoryEntryId(),
|
||||
.flags = (MessageFlag::FakeHistoryItem
|
||||
| MessageFlag::HasFromId
|
||||
| MessageFlag::HasReplyInfo),
|
||||
.from = from,
|
||||
.replyTo = FullReplyTo{ .messageId = replyTo },
|
||||
.date = base::unixtime::now(),
|
||||
}, TextWithEntities{ .text = text }, MTP_messageMediaEmpty());
|
||||
|
||||
return AdminLog::OwnedItem(delegate, item);
|
||||
}
|
||||
|
||||
void AddMessage(
|
||||
not_null<Ui::VerticalLayout*> container,
|
||||
not_null<Window::SessionController*> controller,
|
||||
@ -135,15 +89,15 @@ void AddMessage(
|
||||
|
||||
const auto history = controller->session().data().history(
|
||||
PeerData::kServiceNotificationsId);
|
||||
state->reply = GenerateItem(
|
||||
state->reply = HistoryView::GenerateItem(
|
||||
state->delegate.get(),
|
||||
history,
|
||||
GenerateUser(
|
||||
HistoryView::GenerateUser(
|
||||
history,
|
||||
tr::lng_settings_chat_message_reply_from(tr::now)),
|
||||
FullMsgId(),
|
||||
tr::lng_settings_chat_message_reply(tr::now));
|
||||
auto message = GenerateItem(
|
||||
auto message = HistoryView::GenerateItem(
|
||||
state->delegate.get(),
|
||||
history,
|
||||
history->peer->id,
|
||||
|
@ -0,0 +1,66 @@
|
||||
/*
|
||||
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_fake_items.h"
|
||||
|
||||
#include "base/unixtime.h"
|
||||
#include "data/data_session.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
AdminLog::OwnedItem GenerateItem(
|
||||
not_null<HistoryView::ElementDelegate*> delegate,
|
||||
not_null<History*> history,
|
||||
PeerId from,
|
||||
FullMsgId replyTo,
|
||||
const QString &text,
|
||||
EffectId effectId) {
|
||||
Expects(history->peer->isUser());
|
||||
|
||||
const auto item = history->addNewLocalMessage({
|
||||
.id = history->nextNonHistoryEntryId(),
|
||||
.flags = (MessageFlag::FakeHistoryItem
|
||||
| MessageFlag::HasFromId
|
||||
| MessageFlag::HasReplyInfo),
|
||||
.from = from,
|
||||
.replyTo = FullReplyTo{.messageId = replyTo },
|
||||
.date = base::unixtime::now(),
|
||||
.effectId = effectId,
|
||||
}, TextWithEntities{ .text = text }, MTP_messageMediaEmpty());
|
||||
|
||||
return AdminLog::OwnedItem(delegate, item);
|
||||
}
|
||||
|
||||
PeerId GenerateUser(not_null<History*> history, const QString &name) {
|
||||
Expects(history->peer->isUser());
|
||||
|
||||
const auto peerId = Data::FakePeerIdForJustName(name);
|
||||
history->owner().processUser(MTP_user(
|
||||
MTP_flags(MTPDuser::Flag::f_first_name | MTPDuser::Flag::f_min),
|
||||
peerToBareMTPInt(peerId),
|
||||
MTP_long(0),
|
||||
MTP_string(name),
|
||||
MTPstring(), // last name
|
||||
MTPstring(), // username
|
||||
MTPstring(), // phone
|
||||
MTPUserProfilePhoto(), // profile photo
|
||||
MTPUserStatus(), // status
|
||||
MTP_int(0), // bot info version
|
||||
MTPVector<MTPRestrictionReason>(), // restrictions
|
||||
MTPstring(), // bot placeholder
|
||||
MTPstring(), // lang code
|
||||
MTPEmojiStatus(),
|
||||
MTPVector<MTPUsername>(),
|
||||
MTPint(), // stories_max_id
|
||||
MTPPeerColor(), // color
|
||||
MTPPeerColor())); // profile_color
|
||||
return peerId;
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
26
Telegram/SourceFiles/history/view/history_view_fake_items.h
Normal file
26
Telegram/SourceFiles/history/view/history_view_fake_items.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
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/admin_log/history_admin_log_item.h"
|
||||
|
||||
namespace HistoryView {
|
||||
|
||||
[[nodiscard]] AdminLog::OwnedItem GenerateItem(
|
||||
not_null<HistoryView::ElementDelegate*> delegate,
|
||||
not_null<History*> history,
|
||||
PeerId from,
|
||||
FullMsgId replyTo,
|
||||
const QString &text,
|
||||
EffectId effectId = 0);
|
||||
|
||||
[[nodiscard]] PeerId GenerateUser(
|
||||
not_null<History*> history,
|
||||
const QString &name);
|
||||
|
||||
} // namespace HistoryView
|
@ -9,17 +9,25 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
|
||||
#include "api/api_common.h"
|
||||
#include "base/event_filter.h"
|
||||
#include "base/unixtime.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "chat_helpers/compose/compose_show.h"
|
||||
#include "chat_helpers/stickers_emoji_pack.h"
|
||||
#include "core/shortcuts.h"
|
||||
#include "history/admin_log/history_admin_log_item.h"
|
||||
#include "history/view/media/history_view_sticker.h"
|
||||
#include "history/view/reactions/history_view_reactions_selector.h"
|
||||
#include "history/view/history_view_element.h"
|
||||
#include "history/view/history_view_fake_items.h"
|
||||
#include "history/view/history_view_schedule_box.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
#include "history/history_unread_things.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "lottie/lottie_single_player.h"
|
||||
#include "ui/chat/chat_style.h"
|
||||
#include "ui/chat/chat_theme.h"
|
||||
#include "ui/effects/path_shift_gradient.h"
|
||||
#include "ui/effects/ripple_animation.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/popup_menu.h"
|
||||
@ -33,20 +41,39 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "data/data_message_reactions.h"
|
||||
#include "data/data_session.h"
|
||||
#include "main/main_session.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_unread_things.h"
|
||||
#include "apiwrap.h"
|
||||
#include "window/themes/window_theme.h"
|
||||
#include "window/section_widget.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_chat_helpers.h"
|
||||
#include "styles/style_menu_icons.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
#include <QtWidgets/QApplication>
|
||||
|
||||
namespace SendMenu {
|
||||
namespace {
|
||||
|
||||
class Delegate final : public HistoryView::DefaultElementDelegate {
|
||||
public:
|
||||
Delegate(not_null<Ui::PathShiftGradient*> pathGradient)
|
||||
: _pathGradient(pathGradient) {
|
||||
}
|
||||
|
||||
private:
|
||||
bool elementAnimationsPaused() override {
|
||||
return false;
|
||||
}
|
||||
not_null<Ui::PathShiftGradient*> elementPathShiftGradient() override {
|
||||
return _pathGradient;
|
||||
}
|
||||
HistoryView::Context elementContext() override {
|
||||
return HistoryView::Context::ContactPreview;
|
||||
}
|
||||
|
||||
const not_null<Ui::PathShiftGradient*> _pathGradient;
|
||||
};
|
||||
|
||||
class EffectPreview final : public Ui::RpWidget {
|
||||
public:
|
||||
EffectPreview(
|
||||
@ -64,6 +91,7 @@ private:
|
||||
|
||||
void setupGeometry(QPoint position);
|
||||
void setupBackground();
|
||||
void setupItem();
|
||||
void repaintBackground();
|
||||
void setupLottie();
|
||||
void setupSend(Details details);
|
||||
@ -71,10 +99,16 @@ private:
|
||||
|
||||
[[nodiscard]] bool checkReady();
|
||||
|
||||
const EffectId _effectId = 0;
|
||||
const Data::Reaction _effect;
|
||||
const std::shared_ptr<ChatHelpers::Show> _show;
|
||||
const std::shared_ptr<Ui::ChatTheme> _theme;
|
||||
const std::unique_ptr<Ui::ChatStyle> _chatStyle;
|
||||
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
||||
const std::unique_ptr<Delegate> _delegate;
|
||||
const not_null<History*> _history;
|
||||
const AdminLog::OwnedItem _replyTo;
|
||||
const AdminLog::OwnedItem _item;
|
||||
const std::unique_ptr<Ui::FlatButton> _send;
|
||||
const Fn<void(Action, Details)> _actionWithEffect;
|
||||
|
||||
@ -86,6 +120,7 @@ private:
|
||||
|
||||
QRect _inner;
|
||||
QImage _bg;
|
||||
QPoint _itemShift;
|
||||
|
||||
rpl::lifetime _readyCheckLifetime;
|
||||
|
||||
@ -169,37 +204,67 @@ EffectPreview::EffectPreview(
|
||||
Fn<void(Action, Details)> action,
|
||||
Fn<void()> done)
|
||||
: RpWidget(parent)
|
||||
, _effectId(effect.id.custom())
|
||||
, _effect(effect)
|
||||
, _show(show)
|
||||
, _theme(Window::Theme::DefaultChatThemeOn(lifetime()))
|
||||
, _chatStyle(
|
||||
std::make_unique<Ui::ChatStyle>(
|
||||
_show->session().colorIndicesValue()))
|
||||
, _pathGradient(
|
||||
HistoryView::MakePathShiftGradient(_chatStyle.get(), [=] { update(); }))
|
||||
, _delegate(std::make_unique<Delegate>(_pathGradient.get()))
|
||||
, _history(show->session().data().history(
|
||||
PeerData::kServiceNotificationsId))
|
||||
, _replyTo(HistoryView::GenerateItem(
|
||||
_delegate.get(),
|
||||
_history,
|
||||
HistoryView::GenerateUser(
|
||||
_history,
|
||||
tr::lng_settings_chat_message_reply_from(tr::now)),
|
||||
FullMsgId(),
|
||||
tr::lng_settings_chat_message(tr::now)))
|
||||
, _item(HistoryView::GenerateItem(
|
||||
_delegate.get(),
|
||||
_history,
|
||||
_history->peer->id,
|
||||
_replyTo->data()->fullId(),
|
||||
tr::lng_settings_chat_message_reply(tr::now),
|
||||
_effectId))
|
||||
, _send(
|
||||
std::make_unique<BottomRounded>(
|
||||
this,
|
||||
tr::lng_effect_send(tr::now),
|
||||
st::effectPreviewSend))
|
||||
, _actionWithEffect(
|
||||
ComposeActionWithEffect(
|
||||
action,
|
||||
effect.id.custom(),
|
||||
done)) {
|
||||
, _actionWithEffect(ComposeActionWithEffect(action, _effectId, done)) {
|
||||
setupGeometry(position);
|
||||
setupBackground();
|
||||
setupItem();
|
||||
setupLottie();
|
||||
setupSend(details);
|
||||
}
|
||||
|
||||
void EffectPreview::paintEvent(QPaintEvent *e) {
|
||||
auto p = QPainter(this);
|
||||
auto p = Painter(this);
|
||||
p.drawImage(0, 0, _bg);
|
||||
|
||||
p.setClipRect(_inner);
|
||||
p.translate(_itemShift);
|
||||
auto rect = QRect(0, 0, st::windowMinWidth, _inner.height());
|
||||
auto context = _theme->preparePaintContext(
|
||||
_chatStyle.get(),
|
||||
rect,
|
||||
rect,
|
||||
false);
|
||||
context.outbg = _item->hasOutLayout();
|
||||
_item->draw(p, context);
|
||||
p.translate(-_itemShift);
|
||||
|
||||
if (_lottie && _lottie->ready()) {
|
||||
const auto factor = style::DevicePixelRatio();
|
||||
auto request = Lottie::FrameRequest();
|
||||
request.box = _inner.size() * factor;
|
||||
const auto rightAligned = false;// hasRightLayout();
|
||||
const auto rightAligned = _item->hasRightLayout();
|
||||
if (!rightAligned) {
|
||||
request.mirrorHorizontal = true;
|
||||
}
|
||||
@ -255,6 +320,22 @@ void EffectPreview::setupBackground() {
|
||||
}, lifetime());
|
||||
}
|
||||
|
||||
void EffectPreview::setupItem() {
|
||||
_item->resizeGetHeight(st::windowMinWidth);
|
||||
|
||||
const auto icon = _item->effectIconGeometry();
|
||||
Assert(!icon.isEmpty());
|
||||
|
||||
const auto size = _inner.size();
|
||||
const auto shift = _item->hasRightLayout()
|
||||
? (-size.width() / 3)
|
||||
: (size.width() / 3);
|
||||
const auto position = QPoint(
|
||||
shift + icon.x() + (icon.width() - size.width()) / 2,
|
||||
icon.y() + (icon.height() - size.height()) / 2);
|
||||
_itemShift = _inner.topLeft() - position;
|
||||
}
|
||||
|
||||
void EffectPreview::repaintBackground() {
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto inner = _inner.size() + QSize(0, _send->height());
|
||||
@ -270,25 +351,6 @@ void EffectPreview::repaintBackground() {
|
||||
_theme.get(),
|
||||
QSize(inner.width(), inner.height() * 5),
|
||||
QRect(QPoint(), inner));
|
||||
|
||||
{ // bubble
|
||||
const auto radius = st::bubbleRadiusLarge;
|
||||
const auto out = 2 * radius;
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(_chatStyle->msgInShadow());
|
||||
const auto skip = st::msgPadding.bottom() - st::msgDateDelta.y();
|
||||
p.drawRoundedRect(-out, -out, out + inner.width() / 3, out + inner.height() / 2 + st::normalFont->height / 2 + st::msgShadow, radius, radius);
|
||||
p.setBrush(_chatStyle->msgInBg());
|
||||
p.drawRoundedRect(-out, -out, out + inner.width() / 3, out + inner.height() / 2 + st::normalFont->height / 2, radius, radius);
|
||||
|
||||
if (!_icon.isNull()) {
|
||||
p.drawImage(
|
||||
inner.width() / 3 - _icon.width(),
|
||||
inner.height() / 2 + st::normalFont->height / 2 - _icon.height(),
|
||||
_icon);
|
||||
}
|
||||
}
|
||||
|
||||
p.fillRect(
|
||||
QRect(0, _inner.height(), _inner.width(), _send->height()),
|
||||
st::previewMarkRead.bgColor);
|
||||
@ -300,6 +362,7 @@ void EffectPreview::repaintBackground() {
|
||||
|
||||
_bg.fill(Qt::transparent);
|
||||
auto p = QPainter(&_bg);
|
||||
|
||||
const auto &shadow = st::previewMenu.animation.shadow;
|
||||
const auto shadowed = QRect(_inner.topLeft(), inner);
|
||||
Ui::Shadow::paint(p, shadowed, width(), shadow);
|
||||
@ -307,9 +370,8 @@ void EffectPreview::repaintBackground() {
|
||||
}
|
||||
|
||||
void EffectPreview::setupLottie() {
|
||||
const auto id = _effect.id.custom();
|
||||
const auto reactions = &_show->session().data().reactions();
|
||||
reactions->preloadEffectImageFor(id);
|
||||
reactions->preloadEffectImageFor(_effectId);
|
||||
|
||||
if (const auto document = _effect.aroundAnimation) {
|
||||
_media = document->createMediaView();
|
||||
|
Loading…
Reference in New Issue
Block a user