mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Play ttl media horizontally where the message was.
This commit is contained in:
parent
b462d7627f
commit
104cf504ab
3 changed files with 99 additions and 50 deletions
|
@ -31,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/widgets/tooltip.h"
|
#include "ui/widgets/tooltip.h"
|
||||||
#include "window/section_widget.h" // Window::ChatThemeValueFromPeer.
|
#include "window/section_widget.h" // Window::ChatThemeValueFromPeer.
|
||||||
#include "window/themes/window_theme.h"
|
#include "window/themes/window_theme.h"
|
||||||
|
#include "window/window_controller.h"
|
||||||
#include "window/window_session_controller.h"
|
#include "window/window_session_controller.h"
|
||||||
#include "styles/style_chat.h"
|
#include "styles/style_chat.h"
|
||||||
#include "styles/style_chat_helpers.h"
|
#include "styles/style_chat_helpers.h"
|
||||||
|
@ -44,6 +45,7 @@ public:
|
||||||
PreviewDelegate(
|
PreviewDelegate(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
not_null<Ui::ChatStyle*> st,
|
not_null<Ui::ChatStyle*> st,
|
||||||
|
rpl::producer<bool> chatWideValue,
|
||||||
Fn<void()> update);
|
Fn<void()> update);
|
||||||
|
|
||||||
bool elementAnimationsPaused() override;
|
bool elementAnimationsPaused() override;
|
||||||
|
@ -54,15 +56,18 @@ public:
|
||||||
private:
|
private:
|
||||||
const not_null<QWidget*> _parent;
|
const not_null<QWidget*> _parent;
|
||||||
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
||||||
|
rpl::variable<bool> _chatWide;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
PreviewDelegate::PreviewDelegate(
|
PreviewDelegate::PreviewDelegate(
|
||||||
not_null<QWidget*> parent,
|
not_null<QWidget*> parent,
|
||||||
not_null<Ui::ChatStyle*> st,
|
not_null<Ui::ChatStyle*> st,
|
||||||
|
rpl::producer<bool> chatWideValue,
|
||||||
Fn<void()> update)
|
Fn<void()> update)
|
||||||
: _parent(parent)
|
: _parent(parent)
|
||||||
, _pathGradient(HistoryView::MakePathShiftGradient(st, update)) {
|
, _pathGradient(HistoryView::MakePathShiftGradient(st, update))
|
||||||
|
, _chatWide(std::move(chatWideValue)) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PreviewDelegate::elementAnimationsPaused() {
|
bool PreviewDelegate::elementAnimationsPaused() {
|
||||||
|
@ -78,7 +83,7 @@ HistoryView::Context PreviewDelegate::elementContext() {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool PreviewDelegate::elementIsChatWide() {
|
bool PreviewDelegate::elementIsChatWide() {
|
||||||
return true;
|
return _chatWide.current();
|
||||||
}
|
}
|
||||||
|
|
||||||
class PreviewWrap final : public Ui::RpWidget {
|
class PreviewWrap final : public Ui::RpWidget {
|
||||||
|
@ -86,6 +91,8 @@ public:
|
||||||
PreviewWrap(
|
PreviewWrap(
|
||||||
not_null<Ui::RpWidget*> parent,
|
not_null<Ui::RpWidget*> parent,
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
|
rpl::producer<QRect> viewportValue,
|
||||||
|
rpl::producer<bool> chatWideValue,
|
||||||
rpl::producer<std::shared_ptr<Ui::ChatTheme>> theme);
|
rpl::producer<std::shared_ptr<Ui::ChatTheme>> theme);
|
||||||
~PreviewWrap();
|
~PreviewWrap();
|
||||||
|
|
||||||
|
@ -93,13 +100,17 @@ public:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void paintEvent(QPaintEvent *e) override;
|
void paintEvent(QPaintEvent *e) override;
|
||||||
[[nodiscard]] QRect elementRect() const;
|
|
||||||
|
|
||||||
const not_null<HistoryItem*> _item;
|
const not_null<HistoryItem*> _item;
|
||||||
const std::unique_ptr<Ui::ChatStyle> _style;
|
const std::unique_ptr<Ui::ChatStyle> _style;
|
||||||
const std::unique_ptr<PreviewDelegate> _delegate;
|
const std::unique_ptr<PreviewDelegate> _delegate;
|
||||||
|
rpl::variable<QRect> _globalViewport;
|
||||||
|
rpl::variable<bool> _chatWide;
|
||||||
std::shared_ptr<Ui::ChatTheme> _theme;
|
std::shared_ptr<Ui::ChatTheme> _theme;
|
||||||
std::unique_ptr<HistoryView::Element> _element;
|
std::unique_ptr<HistoryView::Element> _element;
|
||||||
|
QRect _viewport;
|
||||||
|
QRect _elementGeometry;
|
||||||
|
rpl::variable<QRect> _elementInner;
|
||||||
rpl::lifetime _elementLifetime;
|
rpl::lifetime _elementLifetime;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
@ -114,6 +125,8 @@ private:
|
||||||
PreviewWrap::PreviewWrap(
|
PreviewWrap::PreviewWrap(
|
||||||
not_null<Ui::RpWidget*> parent,
|
not_null<Ui::RpWidget*> parent,
|
||||||
not_null<HistoryItem*> item,
|
not_null<HistoryItem*> item,
|
||||||
|
rpl::producer<QRect> viewportValue,
|
||||||
|
rpl::producer<bool> chatWideValue,
|
||||||
rpl::producer<std::shared_ptr<Ui::ChatTheme>> theme)
|
rpl::producer<std::shared_ptr<Ui::ChatTheme>> theme)
|
||||||
: RpWidget(parent)
|
: RpWidget(parent)
|
||||||
, _item(item)
|
, _item(item)
|
||||||
|
@ -122,8 +135,9 @@ PreviewWrap::PreviewWrap(
|
||||||
, _delegate(std::make_unique<PreviewDelegate>(
|
, _delegate(std::make_unique<PreviewDelegate>(
|
||||||
parent,
|
parent,
|
||||||
_style.get(),
|
_style.get(),
|
||||||
[=] { update(elementRect()); })) {
|
std::move(chatWideValue),
|
||||||
|
[=] { update(_elementGeometry); }))
|
||||||
|
, _globalViewport(std::move(viewportValue)) {
|
||||||
const auto isRound = _item
|
const auto isRound = _item
|
||||||
&& _item->media()
|
&& _item->media()
|
||||||
&& _item->media()->document()
|
&& _item->media()->document()
|
||||||
|
@ -140,7 +154,7 @@ PreviewWrap::PreviewWrap(
|
||||||
session->data().viewRepaintRequest(
|
session->data().viewRepaintRequest(
|
||||||
) | rpl::start_with_next([=](not_null<const HistoryView::Element*> view) {
|
) | rpl::start_with_next([=](not_null<const HistoryView::Element*> view) {
|
||||||
if (view == _element.get()) {
|
if (view == _element.get()) {
|
||||||
update(elementRect());
|
update(_elementGeometry);
|
||||||
}
|
}
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
|
|
||||||
|
@ -157,11 +171,15 @@ PreviewWrap::PreviewWrap(
|
||||||
close->setClickedCallback(closeCallback);
|
close->setClickedCallback(closeCallback);
|
||||||
close->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
close->setTextTransform(Ui::RoundButton::TextTransform::NoTransform);
|
||||||
|
|
||||||
sizeValue(
|
rpl::combine(
|
||||||
) | rpl::start_with_next([=](const QSize &s) {
|
sizeValue(),
|
||||||
|
_elementInner.value()
|
||||||
|
) | rpl::start_with_next([=](QSize size, QRect inner) {
|
||||||
close->moveToLeft(
|
close->moveToLeft(
|
||||||
(s.width() - close->width()) / 2,
|
inner.x() + (inner.width() - close->width()) / 2,
|
||||||
s.height() - close->height() - st::ttlMediaButtonBottomSkip);
|
(size.height()
|
||||||
|
- close->height()
|
||||||
|
- st::ttlMediaButtonBottomSkip));
|
||||||
}, close->lifetime());
|
}, close->lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,11 +188,27 @@ PreviewWrap::PreviewWrap(
|
||||||
|
|
||||||
{
|
{
|
||||||
_element->initDimensions();
|
_element->initDimensions();
|
||||||
widthValue(
|
rpl::combine(
|
||||||
) | rpl::filter([=](int width) {
|
sizeValue(),
|
||||||
return width > st::msgMinWidth;
|
_globalViewport.value()
|
||||||
}) | rpl::start_with_next([=](int width) {
|
) | rpl::start_with_next([=](QSize outer, QRect globalViewport) {
|
||||||
_element->resizeGetHeight(width);
|
_viewport = globalViewport.isEmpty()
|
||||||
|
? rect()
|
||||||
|
: mapFromGlobal(globalViewport);
|
||||||
|
if (_viewport.width() < st::msgMinWidth) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_element->resizeGetHeight(_viewport.width());
|
||||||
|
_elementGeometry = QRect(
|
||||||
|
(_viewport.width() - _element->width()) / 2,
|
||||||
|
(_viewport.height() - _element->height()) / 2,
|
||||||
|
_element->width(),
|
||||||
|
_element->height()
|
||||||
|
).translated(_viewport.topLeft());
|
||||||
|
const auto media = _element->media();
|
||||||
|
_elementInner = _element->innerGeometry().translated(
|
||||||
|
_elementGeometry.topLeft());
|
||||||
|
update();
|
||||||
}, _elementLifetime);
|
}, _elementLifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,22 +237,17 @@ PreviewWrap::PreviewWrap(
|
||||||
st::defaultImportantTooltip.padding),
|
st::defaultImportantTooltip.padding),
|
||||||
st::dialogsStoriesTooltip);
|
st::dialogsStoriesTooltip);
|
||||||
tooltip->toggleFast(true);
|
tooltip->toggleFast(true);
|
||||||
sizeValue(
|
_elementInner.value(
|
||||||
) | rpl::filter(
|
) | rpl::filter([](const QRect &inner) {
|
||||||
[](const QSize &s) { return !s.isNull(); }
|
return !inner.isEmpty();
|
||||||
) | rpl::take(1) | rpl::start_with_next([=](const QSize &s) {
|
}) | rpl::start_with_next([=](const QRect &inner) {
|
||||||
if (s.isEmpty()) {
|
tooltip->pointAt(inner, RectPart::Top, [=](QSize size) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
auto area = elementRect();
|
|
||||||
area.setWidth(_element->media()
|
|
||||||
? _element->media()->width()
|
|
||||||
: _element->width());
|
|
||||||
tooltip->pointAt(area, RectPart::Top, [=](QSize size) {
|
|
||||||
return QPoint{
|
return QPoint{
|
||||||
(area.width() - size.width()) / 2,
|
inner.x() + (inner.width() - size.width()) / 2,
|
||||||
(s.height() - size.height() * 2 - _element->height()) / 2
|
(inner.y()
|
||||||
- st::defaultImportantTooltip.padding.top(),
|
- st::normalFont->height
|
||||||
|
- size.height()
|
||||||
|
- st::defaultImportantTooltip.padding.top()),
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
}, tooltip->lifetime());
|
}, tooltip->lifetime());
|
||||||
|
@ -232,14 +261,6 @@ PreviewWrap::PreviewWrap(
|
||||||
}, lifetime());
|
}, lifetime());
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect PreviewWrap::elementRect() const {
|
|
||||||
return QRect(
|
|
||||||
(width() - _element->width()) / 2,
|
|
||||||
(height() - _element->height()) / 2,
|
|
||||||
_element->width(),
|
|
||||||
_element->height());
|
|
||||||
}
|
|
||||||
|
|
||||||
rpl::producer<> PreviewWrap::closeRequests() const {
|
rpl::producer<> PreviewWrap::closeRequests() const {
|
||||||
return _closeRequests.events();
|
return _closeRequests.events();
|
||||||
}
|
}
|
||||||
|
@ -250,13 +271,14 @@ PreviewWrap::~PreviewWrap() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewWrap::paintEvent(QPaintEvent *e) {
|
void PreviewWrap::paintEvent(QPaintEvent *e) {
|
||||||
if (!_element) {
|
if (!_element || _elementGeometry.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto p = QPainter(this);
|
auto p = QPainter(this);
|
||||||
const auto r = rect();
|
//p.fillRect(_viewport, QColor(255, 0, 0, 64));
|
||||||
|
//p.fillRect(_elementGeometry, QColor(0, 255, 0, 64));
|
||||||
|
//p.fillRect(_elementInner.current(), QColor(0, 0, 255, 64));
|
||||||
if (!_last.use) {
|
if (!_last.use) {
|
||||||
const auto size = _element->currentSize();
|
const auto size = _element->currentSize();
|
||||||
auto result = QImage(
|
auto result = QImage(
|
||||||
|
@ -276,12 +298,35 @@ void PreviewWrap::paintEvent(QPaintEvent *e) {
|
||||||
}
|
}
|
||||||
_last.frame = std::move(result);
|
_last.frame = std::move(result);
|
||||||
}
|
}
|
||||||
p.translate(
|
p.translate(_elementGeometry.topLeft());
|
||||||
(r.width() - _element->width()) / 2,
|
|
||||||
(r.height() - _element->height()) / 2);
|
|
||||||
p.drawImage(0, 0, _last.frame);
|
p.drawImage(0, 0, _last.frame);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rpl::producer<QRect> GlobalViewportForWindow(
|
||||||
|
not_null<Window::SessionController*> controller) {
|
||||||
|
const auto delegate = controller->window().floatPlayerDelegate();
|
||||||
|
return rpl::single(rpl::empty) | rpl::then(
|
||||||
|
delegate->floatPlayerAreaUpdates()
|
||||||
|
) | rpl::map([=] {
|
||||||
|
auto section = (Media::Player::FloatSectionDelegate*)nullptr;
|
||||||
|
delegate->floatPlayerEnumerateSections([&](
|
||||||
|
not_null<Media::Player::FloatSectionDelegate*> check,
|
||||||
|
Window::Column column) {
|
||||||
|
if ((column == Window::Column::First && !section)
|
||||||
|
|| column == Window::Column::Second) {
|
||||||
|
section = check;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (section) {
|
||||||
|
const auto rect = section->floatPlayerAvailableRect();
|
||||||
|
if (rect.width() >= st::msgMinWidth) {
|
||||||
|
return rect;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return QRect();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void ShowTTLMediaLayerWidget(
|
void ShowTTLMediaLayerWidget(
|
||||||
|
@ -292,6 +337,8 @@ void ShowTTLMediaLayerWidget(
|
||||||
auto preview = base::make_unique_q<PreviewWrap>(
|
auto preview = base::make_unique_q<PreviewWrap>(
|
||||||
parent,
|
parent,
|
||||||
item,
|
item,
|
||||||
|
GlobalViewportForWindow(controller),
|
||||||
|
controller->adaptive().chatWideValue(),
|
||||||
Window::ChatThemeValueFromPeer(
|
Window::ChatThemeValueFromPeer(
|
||||||
controller,
|
controller,
|
||||||
item->history()->peer));
|
item->history()->peer));
|
||||||
|
|
|
@ -1984,6 +1984,7 @@ bool Message::hasFromPhoto() const {
|
||||||
case Context::AdminLog:
|
case Context::AdminLog:
|
||||||
return true;
|
return true;
|
||||||
case Context::History:
|
case Context::History:
|
||||||
|
case Context::TTLViewer:
|
||||||
case Context::Pinned:
|
case Context::Pinned:
|
||||||
case Context::Replies:
|
case Context::Replies:
|
||||||
case Context::SavedSublist: {
|
case Context::SavedSublist: {
|
||||||
|
@ -2005,7 +2006,6 @@ bool Message::hasFromPhoto() const {
|
||||||
return !item->out() && !item->history()->peer->isUser();
|
return !item->out() && !item->history()->peer->isUser();
|
||||||
} break;
|
} break;
|
||||||
case Context::ContactPreview:
|
case Context::ContactPreview:
|
||||||
case Context::TTLViewer:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Unexpected("Context in Message::hasFromPhoto.");
|
Unexpected("Context in Message::hasFromPhoto.");
|
||||||
|
@ -3171,6 +3171,7 @@ bool Message::hasFromName() const {
|
||||||
case Context::AdminLog:
|
case Context::AdminLog:
|
||||||
return true;
|
return true;
|
||||||
case Context::History:
|
case Context::History:
|
||||||
|
case Context::TTLViewer:
|
||||||
case Context::Pinned:
|
case Context::Pinned:
|
||||||
case Context::Replies:
|
case Context::Replies:
|
||||||
case Context::SavedSublist: {
|
case Context::SavedSublist: {
|
||||||
|
@ -3201,7 +3202,6 @@ bool Message::hasFromName() const {
|
||||||
return false;
|
return false;
|
||||||
} break;
|
} break;
|
||||||
case Context::ContactPreview:
|
case Context::ContactPreview:
|
||||||
case Context::TTLViewer:
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
Unexpected("Context in Message::hasFromName.");
|
Unexpected("Context in Message::hasFromName.");
|
||||||
|
|
|
@ -243,10 +243,12 @@ void PaintWaveform(
|
||||||
p.fillRect(
|
p.fillRect(
|
||||||
QRectF(barLeft, barTop, leftWidth, barHeight),
|
QRectF(barLeft, barTop, leftWidth, barHeight),
|
||||||
active);
|
active);
|
||||||
p.fillRect(
|
if (!ttl) {
|
||||||
QRectF(activeWidth, barTop, rightWidth, barHeight),
|
p.fillRect(
|
||||||
inactive);
|
QRectF(activeWidth, barTop, rightWidth, barHeight),
|
||||||
} else {
|
inactive);
|
||||||
|
}
|
||||||
|
} else if (!ttl || barLeft < activeWidth) {
|
||||||
const auto &color = (barLeft >= activeWidth) ? inactive : active;
|
const auto &color = (barLeft >= activeWidth) ? inactive : active;
|
||||||
p.fillRect(QRectF(barLeft, barTop, barWidth, barHeight), color);
|
p.fillRect(QRectF(barLeft, barTop, barWidth, barHeight), color);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue