mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Show effect preview before sending.
This commit is contained in:
parent
e120ae6ae6
commit
144109db05
4 changed files with 232 additions and 45 deletions
|
@ -563,6 +563,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
|
|
||||||
"lng_effect_add_title" = "Add an animated effect";
|
"lng_effect_add_title" = "Add an animated effect";
|
||||||
"lng_effect_stickers_title" = "Message Effects";
|
"lng_effect_stickers_title" = "Message Effects";
|
||||||
|
"lng_effect_send" = "Send with Effect";
|
||||||
|
|
||||||
"lng_languages" = "Languages";
|
"lng_languages" = "Languages";
|
||||||
"lng_languages_none" = "No languages found.";
|
"lng_languages_none" = "No languages found.";
|
||||||
|
|
|
@ -228,6 +228,9 @@ void ScheduledMessages::sendNowSimpleMessage(
|
||||||
: MTPDmessage::Flag(0))
|
: MTPDmessage::Flag(0))
|
||||||
| ((localFlags & MessageFlag::Outgoing)
|
| ((localFlags & MessageFlag::Outgoing)
|
||||||
? MTPDmessage::Flag::f_out
|
? MTPDmessage::Flag::f_out
|
||||||
|
: MTPDmessage::Flag(0))
|
||||||
|
| (local->effectId()
|
||||||
|
? MTPDmessage::Flag::f_effect
|
||||||
: MTPDmessage::Flag(0));
|
: MTPDmessage::Flag(0));
|
||||||
const auto views = 1;
|
const auto views = 1;
|
||||||
const auto forwards = 0;
|
const auto forwards = 0;
|
||||||
|
|
|
@ -11,15 +11,22 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "base/event_filter.h"
|
#include "base/event_filter.h"
|
||||||
#include "boxes/abstract_box.h"
|
#include "boxes/abstract_box.h"
|
||||||
#include "chat_helpers/compose/compose_show.h"
|
#include "chat_helpers/compose/compose_show.h"
|
||||||
|
#include "chat_helpers/stickers_emoji_pack.h"
|
||||||
#include "core/shortcuts.h"
|
#include "core/shortcuts.h"
|
||||||
#include "history/view/media/history_view_sticker.h"
|
#include "history/view/media/history_view_sticker.h"
|
||||||
#include "history/view/reactions/history_view_reactions_selector.h"
|
#include "history/view/reactions/history_view_reactions_selector.h"
|
||||||
#include "history/view/history_view_schedule_box.h"
|
#include "history/view/history_view_schedule_box.h"
|
||||||
#include "lang/lang_keys.h"
|
#include "lang/lang_keys.h"
|
||||||
|
#include "lottie/lottie_single_player.h"
|
||||||
#include "ui/chat/chat_style.h"
|
#include "ui/chat/chat_style.h"
|
||||||
#include "ui/chat/chat_theme.h"
|
#include "ui/chat/chat_theme.h"
|
||||||
|
#include "ui/effects/ripple_animation.h"
|
||||||
#include "ui/widgets/buttons.h"
|
#include "ui/widgets/buttons.h"
|
||||||
#include "ui/widgets/popup_menu.h"
|
#include "ui/widgets/popup_menu.h"
|
||||||
|
#include "ui/widgets/shadow.h"
|
||||||
|
#include "ui/painter.h"
|
||||||
|
#include "data/data_document.h"
|
||||||
|
#include "data/data_document_media.h"
|
||||||
#include "data/data_peer.h"
|
#include "data/data_peer.h"
|
||||||
#include "data/data_forum.h"
|
#include "data/data_forum.h"
|
||||||
#include "data/data_forum_topic.h"
|
#include "data/data_forum_topic.h"
|
||||||
|
@ -48,25 +55,77 @@ public:
|
||||||
Details details,
|
Details details,
|
||||||
QPoint position,
|
QPoint position,
|
||||||
const Data::Reaction &effect,
|
const Data::Reaction &effect,
|
||||||
Fn<void(Action, Details)> action);
|
Fn<void(Action, Details)> action,
|
||||||
|
Fn<void()> done);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
void mousePressEvent(QMouseEvent *e) override;
|
void mousePressEvent(QMouseEvent *e) override;
|
||||||
|
|
||||||
void setupGeometry(QPoint position);
|
void setupGeometry(QPoint position);
|
||||||
void setupBackground();
|
void setupBackground();
|
||||||
|
void repaintBackground();
|
||||||
|
void setupLottie();
|
||||||
void setupSend(Details details);
|
void setupSend(Details details);
|
||||||
|
void createLottie();
|
||||||
|
|
||||||
|
[[nodiscard]] bool checkReady();
|
||||||
|
|
||||||
|
const Data::Reaction _effect;
|
||||||
const std::shared_ptr<ChatHelpers::Show> _show;
|
const std::shared_ptr<ChatHelpers::Show> _show;
|
||||||
const std::shared_ptr<Ui::ChatTheme> _theme;
|
const std::shared_ptr<Ui::ChatTheme> _theme;
|
||||||
const std::unique_ptr<Ui::ChatStyle> _chatStyle;
|
const std::unique_ptr<Ui::ChatStyle> _chatStyle;
|
||||||
const std::unique_ptr<Ui::FlatButton> _send;
|
const std::unique_ptr<Ui::FlatButton> _send;
|
||||||
const Fn<void(Action, Details)> _actionWithEffect;
|
const Fn<void(Action, Details)> _actionWithEffect;
|
||||||
|
|
||||||
|
QImage _icon;
|
||||||
|
std::shared_ptr<Data::DocumentMedia> _media;
|
||||||
|
QByteArray _bytes;
|
||||||
|
QString _filepath;
|
||||||
|
std::unique_ptr<Lottie::SinglePlayer> _lottie;
|
||||||
|
|
||||||
QRect _inner;
|
QRect _inner;
|
||||||
QImage _bg;
|
QImage _bg;
|
||||||
|
|
||||||
|
rpl::lifetime _readyCheckLifetime;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class BottomRounded final : public Ui::FlatButton {
|
||||||
|
public:
|
||||||
|
using FlatButton::FlatButton;
|
||||||
|
|
||||||
|
private:
|
||||||
|
QImage prepareRippleMask() const override;
|
||||||
|
void paintEvent(QPaintEvent *e) override;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
QImage BottomRounded::prepareRippleMask() const {
|
||||||
|
const auto fill = false;
|
||||||
|
return Ui::RippleAnimation::MaskByDrawer(size(), fill, [&](QPainter &p) {
|
||||||
|
const auto radius = st::previewMenu.radius;
|
||||||
|
const auto expanded = rect().marginsAdded({ 0, 2 * radius, 0, 0 });
|
||||||
|
p.drawRoundedRect(expanded, radius, radius);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
void BottomRounded::paintEvent(QPaintEvent *e) {
|
||||||
|
auto p = QPainter(this);
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
const auto radius = st::previewMenu.radius;
|
||||||
|
const auto expanded = rect().marginsAdded({ 0, 2 * radius, 0, 0 });
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
const auto &st = st::previewMarkRead;
|
||||||
|
if (isOver()) {
|
||||||
|
p.setBrush(st.overBgColor);
|
||||||
|
}
|
||||||
|
p.drawRoundedRect(expanded, radius, radius);
|
||||||
|
p.end();
|
||||||
|
|
||||||
|
Ui::FlatButton::paintEvent(e);
|
||||||
|
}
|
||||||
|
|
||||||
[[nodiscard]] Data::PossibleItemReactionsRef LookupPossibleEffects(
|
[[nodiscard]] Data::PossibleItemReactionsRef LookupPossibleEffects(
|
||||||
not_null<Main::Session*> session) {
|
not_null<Main::Session*> session) {
|
||||||
auto result = Data::PossibleItemReactionsRef();
|
auto result = Data::PossibleItemReactionsRef();
|
||||||
|
@ -85,35 +144,19 @@ private:
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShowEffectPreview(
|
|
||||||
not_null<QWidget*> parent,
|
|
||||||
std::shared_ptr<ChatHelpers::Show> show,
|
|
||||||
Details details,
|
|
||||||
QPoint position,
|
|
||||||
const Data::Reaction &effect,
|
|
||||||
Fn<void(Action, Details)> action) {
|
|
||||||
const auto widget = Ui::CreateChild<EffectPreview>(
|
|
||||||
parent,
|
|
||||||
show,
|
|
||||||
details,
|
|
||||||
position,
|
|
||||||
effect,
|
|
||||||
action);
|
|
||||||
widget->raise();
|
|
||||||
widget->show();
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] Fn<void(Action, Details)> ComposeActionWithEffect(
|
[[nodiscard]] Fn<void(Action, Details)> ComposeActionWithEffect(
|
||||||
Fn<void(Action, Details)> sendAction,
|
Fn<void(Action, Details)> sendAction,
|
||||||
EffectId id) {
|
EffectId id,
|
||||||
if (!id) {
|
Fn<void()> done) {
|
||||||
return sendAction;
|
|
||||||
}
|
|
||||||
return [=](Action action, Details details) {
|
return [=](Action action, Details details) {
|
||||||
if (const auto options = std::get_if<Api::SendOptions>(&action)) {
|
if (const auto options = std::get_if<Api::SendOptions>(&action)) {
|
||||||
options->effectId = id;
|
options->effectId = id;
|
||||||
}
|
}
|
||||||
|
const auto onstack = done;
|
||||||
sendAction(action, details);
|
sendAction(action, details);
|
||||||
|
if (onstack) {
|
||||||
|
onstack();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -123,27 +166,49 @@ EffectPreview::EffectPreview(
|
||||||
Details details,
|
Details details,
|
||||||
QPoint position,
|
QPoint position,
|
||||||
const Data::Reaction &effect,
|
const Data::Reaction &effect,
|
||||||
Fn<void(Action, Details)> action)
|
Fn<void(Action, Details)> action,
|
||||||
|
Fn<void()> done)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
|
, _effect(effect)
|
||||||
, _show(show)
|
, _show(show)
|
||||||
, _theme(Window::Theme::DefaultChatThemeOn(lifetime()))
|
, _theme(Window::Theme::DefaultChatThemeOn(lifetime()))
|
||||||
, _chatStyle(
|
, _chatStyle(
|
||||||
std::make_unique<Ui::ChatStyle>(
|
std::make_unique<Ui::ChatStyle>(
|
||||||
_show->session().colorIndicesValue()))
|
_show->session().colorIndicesValue()))
|
||||||
, _send(
|
, _send(
|
||||||
std::make_unique<Ui::FlatButton>(
|
std::make_unique<BottomRounded>(
|
||||||
this,
|
this,
|
||||||
u"Send with Effect"_q,AssertIsDebug()
|
tr::lng_effect_send(tr::now),
|
||||||
st::previewMarkRead))
|
st::effectPreviewSend))
|
||||||
, _actionWithEffect(ComposeActionWithEffect(action, effect.id.custom())) {
|
, _actionWithEffect(
|
||||||
|
ComposeActionWithEffect(
|
||||||
|
action,
|
||||||
|
effect.id.custom(),
|
||||||
|
done)) {
|
||||||
setupGeometry(position);
|
setupGeometry(position);
|
||||||
setupBackground();
|
setupBackground();
|
||||||
|
setupLottie();
|
||||||
setupSend(details);
|
setupSend(details);
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectPreview::paintEvent(QPaintEvent *e) {
|
void EffectPreview::paintEvent(QPaintEvent *e) {
|
||||||
auto p = QPainter(this);
|
auto p = QPainter(this);
|
||||||
p.drawImage(0, 0, _bg);
|
p.drawImage(0, 0, _bg);
|
||||||
|
|
||||||
|
if (_lottie && _lottie->ready()) {
|
||||||
|
const auto factor = style::DevicePixelRatio();
|
||||||
|
auto request = Lottie::FrameRequest();
|
||||||
|
request.box = _inner.size() * factor;
|
||||||
|
const auto rightAligned = false;// hasRightLayout();
|
||||||
|
if (!rightAligned) {
|
||||||
|
request.mirrorHorizontal = true;
|
||||||
|
}
|
||||||
|
const auto frame = _lottie->frameInfo(request);
|
||||||
|
p.drawImage(
|
||||||
|
QRect(_inner.topLeft(), frame.image.size() / factor),
|
||||||
|
frame.image);
|
||||||
|
_lottie->markFrameShown();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectPreview::mousePressEvent(QMouseEvent *e) {
|
void EffectPreview::mousePressEvent(QMouseEvent *e) {
|
||||||
|
@ -156,7 +221,8 @@ void EffectPreview::setupGeometry(QPoint position) {
|
||||||
const auto shadow = st::previewMenu.shadow;
|
const auto shadow = st::previewMenu.shadow;
|
||||||
const auto extend = shadow.extend;
|
const auto extend = shadow.extend;
|
||||||
_inner = QRect(QPoint(extend.left(), extend.top()), innerSize);
|
_inner = QRect(QPoint(extend.left(), extend.top()), innerSize);
|
||||||
const auto size = _inner.marginsAdded(extend).size();
|
const auto size = _inner.marginsAdded(extend).size()
|
||||||
|
+ QSize(0, _send->height());
|
||||||
const auto left = std::max(
|
const auto left = std::max(
|
||||||
std::min(
|
std::min(
|
||||||
position.x() - size.width() / 2,
|
position.x() - size.width() / 2,
|
||||||
|
@ -168,29 +234,112 @@ void EffectPreview::setupGeometry(QPoint position) {
|
||||||
position.y() - size.height() / 2,
|
position.y() - size.height() / 2,
|
||||||
parent->height() - size.height()),
|
parent->height() - size.height()),
|
||||||
topMin);
|
topMin);
|
||||||
setGeometry(left, top, size.width(), size.height() + _send->height());
|
setGeometry(left, top, size.width(), size.height());
|
||||||
_send->setGeometry(0, size.height(), size.width(), _send->height());
|
_send->setGeometry(
|
||||||
|
_inner.x(),
|
||||||
|
_inner.y() + _inner.height(),
|
||||||
|
_inner.width(),
|
||||||
|
_send->height());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectPreview::setupBackground() {
|
void EffectPreview::setupBackground() {
|
||||||
const auto ratio = style::DevicePixelRatio();
|
const auto ratio = style::DevicePixelRatio();
|
||||||
_bg = QImage(
|
_bg = QImage(
|
||||||
_inner.size() * ratio,
|
size() * ratio,
|
||||||
QImage::Format_ARGB32_Premultiplied);
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
_bg.setDevicePixelRatio(ratio);
|
||||||
|
repaintBackground();
|
||||||
|
_theme->repaintBackgroundRequests() | rpl::start_with_next([=] {
|
||||||
|
repaintBackground();
|
||||||
|
update();
|
||||||
|
}, lifetime());
|
||||||
|
}
|
||||||
|
|
||||||
const auto paint = [=] {
|
void EffectPreview::repaintBackground() {
|
||||||
auto p = QPainter(&_bg);
|
const auto ratio = style::DevicePixelRatio();
|
||||||
|
const auto inner = _inner.size() + QSize(0, _send->height());
|
||||||
|
auto bg = QImage(
|
||||||
|
inner * ratio,
|
||||||
|
QImage::Format_ARGB32_Premultiplied);
|
||||||
|
bg.setDevicePixelRatio(ratio);
|
||||||
|
|
||||||
|
{
|
||||||
|
auto p = QPainter(&bg);
|
||||||
Window::SectionWidget::PaintBackground(
|
Window::SectionWidget::PaintBackground(
|
||||||
p,
|
p,
|
||||||
_theme.get(),
|
_theme.get(),
|
||||||
QSize(width(), height() * 5),
|
QSize(inner.width(), inner.height() * 5),
|
||||||
QRect(QPoint(), size()));
|
QRect(QPoint(), inner));
|
||||||
};
|
|
||||||
paint();
|
{ // bubble
|
||||||
_theme->repaintBackgroundRequests() | rpl::start_with_next([=] {
|
const auto radius = st::bubbleRadiusLarge;
|
||||||
paint();
|
const auto out = 2 * radius;
|
||||||
update();
|
p.setPen(Qt::NoPen);
|
||||||
}, lifetime());
|
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);
|
||||||
|
auto hq = PainterHighQualityEnabler(p);
|
||||||
|
p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||||
|
auto roundRect = Ui::RoundRect(st::previewMenu.radius, st::menuBg);
|
||||||
|
roundRect.paint(p, QRect(QPoint(), inner), RectPart::AllCorners);
|
||||||
|
}
|
||||||
|
|
||||||
|
_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);
|
||||||
|
p.drawImage(_inner.topLeft(), bg);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectPreview::setupLottie() {
|
||||||
|
const auto id = _effect.id.custom();
|
||||||
|
const auto reactions = &_show->session().data().reactions();
|
||||||
|
reactions->preloadEffectImageFor(id);
|
||||||
|
|
||||||
|
if (const auto document = _effect.aroundAnimation) {
|
||||||
|
_media = document->createMediaView();
|
||||||
|
} else {
|
||||||
|
_media = _effect.selectAnimation->createMediaView();
|
||||||
|
}
|
||||||
|
rpl::single(rpl::empty) | rpl::then(
|
||||||
|
_show->session().downloaderTaskFinished()
|
||||||
|
) | rpl::start_with_next([=] {
|
||||||
|
if (checkReady()) {
|
||||||
|
_readyCheckLifetime.destroy();
|
||||||
|
createLottie();
|
||||||
|
}
|
||||||
|
}, _readyCheckLifetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
void EffectPreview::createLottie() {
|
||||||
|
_lottie = _show->session().emojiStickersPack().effectPlayer(
|
||||||
|
_media->owner(),
|
||||||
|
_bytes,
|
||||||
|
_filepath,
|
||||||
|
Stickers::EffectType::MessageEffect);
|
||||||
|
const auto raw = _lottie.get();
|
||||||
|
raw->updates(
|
||||||
|
) | rpl::start_with_next([=](Lottie::Update update) {
|
||||||
|
v::match(update.data, [&](const Lottie::Information &information) {
|
||||||
|
}, [&](const Lottie::DisplayFrameRequest &request) {
|
||||||
|
this->update();
|
||||||
|
});
|
||||||
|
}, raw->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
void EffectPreview::setupSend(Details details) {
|
void EffectPreview::setupSend(Details details) {
|
||||||
|
@ -203,6 +352,22 @@ void EffectPreview::setupSend(Details details) {
|
||||||
}, _actionWithEffect);
|
}, _actionWithEffect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool EffectPreview::checkReady() {
|
||||||
|
if (_icon.isNull()) {
|
||||||
|
const auto reactions = &_show->session().data().reactions();
|
||||||
|
_icon = reactions->resolveEffectImageFor(_effect.id.custom());
|
||||||
|
repaintBackground();
|
||||||
|
update();
|
||||||
|
}
|
||||||
|
if (_effect.aroundAnimation) {
|
||||||
|
_bytes = _media->bytes();
|
||||||
|
_filepath = _media->owner()->filepath();
|
||||||
|
} else {
|
||||||
|
_bytes = _media->videoThumbnailContent();
|
||||||
|
}
|
||||||
|
return !_icon.isNull() && (!_bytes.isEmpty() || !_filepath.isEmpty());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Fn<void(Action, Details)> DefaultCallback(
|
Fn<void(Action, Details)> DefaultCallback(
|
||||||
|
@ -281,19 +446,32 @@ FillMenuResult FillSendMenu(
|
||||||
return FillMenuResult::Prepared;
|
return FillMenuResult::Prepared;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const auto effect = std::make_shared<QPointer<EffectPreview>>();
|
||||||
(*selector)->chosen(
|
(*selector)->chosen(
|
||||||
) | rpl::start_with_next([=](ChosenReaction chosen) {
|
) | rpl::start_with_next([=](ChosenReaction chosen) {
|
||||||
const auto &reactions = showForEffect->session().data().reactions();
|
const auto &reactions = showForEffect->session().data().reactions();
|
||||||
const auto &effects = reactions.list(Data::Reactions::Type::Effects);
|
const auto &effects = reactions.list(Data::Reactions::Type::Effects);
|
||||||
const auto i = ranges::find(effects, chosen.id, &Data::Reaction::id);
|
const auto i = ranges::find(effects, chosen.id, &Data::Reaction::id);
|
||||||
if (i != end(effects)) {
|
if (i != end(effects)) {
|
||||||
ShowEffectPreview(
|
if (const auto strong = effect->data()) {
|
||||||
|
delete strong;
|
||||||
|
}
|
||||||
|
const auto weak = Ui::MakeWeak(menu);
|
||||||
|
const auto done = [=] {
|
||||||
|
delete effect->data();
|
||||||
|
if (const auto strong = weak.data()) {
|
||||||
|
strong->hideMenu(true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
*effect = Ui::CreateChild<EffectPreview>(
|
||||||
menu,
|
menu,
|
||||||
showForEffect,
|
showForEffect,
|
||||||
details,
|
details,
|
||||||
menu->mapFromGlobal(chosen.globalGeometry.center()),
|
menu->mapFromGlobal(chosen.globalGeometry.center()),
|
||||||
*i,
|
*i,
|
||||||
action);
|
action,
|
||||||
|
crl::guard(menu, done));
|
||||||
|
(*effect)->show();
|
||||||
}
|
}
|
||||||
}, menu->lifetime());
|
}, menu->lifetime());
|
||||||
|
|
||||||
|
|
|
@ -1101,7 +1101,7 @@ previewTop: PeerListItem(defaultPeerListItem) {
|
||||||
photoSize: 40px;
|
photoSize: 40px;
|
||||||
}
|
}
|
||||||
previewMarkRead: FlatButton(historyComposeButton) {
|
previewMarkRead: FlatButton(historyComposeButton) {
|
||||||
height: 40px;
|
height: 39px;
|
||||||
textTop: 10px;
|
textTop: 10px;
|
||||||
}
|
}
|
||||||
previewName: FlatLabel(defaultFlatLabel) {
|
previewName: FlatLabel(defaultFlatLabel) {
|
||||||
|
@ -1115,3 +1115,8 @@ previewUserpic: UserpicButton(defaultUserpicButton) {
|
||||||
size: size(40px, 40px);
|
size: size(40px, 40px);
|
||||||
photoSize: 40px;
|
photoSize: 40px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
effectPreviewSend: FlatButton(previewMarkRead) {
|
||||||
|
bgColor: transparent;
|
||||||
|
overBgColor: transparent;
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue