Improved display of transcribe button for video messages.

This commit is contained in:
23rd 2022-10-24 05:15:09 +03:00 committed by John Preston
parent 579b20fff7
commit dec47eafb8
5 changed files with 145 additions and 50 deletions

View file

@ -27,14 +27,20 @@ constexpr auto kOutNonChosenOpacity = 0.18;
} // namespace } // namespace
TranscribeButton::TranscribeButton(not_null<HistoryItem*> item) TranscribeButton::TranscribeButton(
: _item(item) { not_null<HistoryItem*> item,
bool roundview)
: _item(item)
, _roundview(roundview)
, _size(!roundview
? st::historyTranscribeSize
: QSize(st::historyFastShareSize, st::historyFastShareSize)) {
} }
TranscribeButton::~TranscribeButton() = default; TranscribeButton::~TranscribeButton() = default;
QSize TranscribeButton::size() const { QSize TranscribeButton::size() const {
return st::historyTranscribeSize; return _size;
} }
void TranscribeButton::setLoading(bool loading, Fn<void()> update) { void TranscribeButton::setLoading(bool loading, Fn<void()> update) {
@ -60,6 +66,41 @@ void TranscribeButton::paint(
auto hq = PainterHighQualityEnabler(p); auto hq = PainterHighQualityEnabler(p);
const auto opened = _openedAnimation.value(_opened ? 1. : 0.); const auto opened = _openedAnimation.value(_opened ? 1. : 0.);
const auto stm = context.messageStyle(); const auto stm = context.messageStyle();
if (_roundview) {
_lastPaintedPoint = { x, y };
PainterHighQualityEnabler hq(p);
p.setPen(Qt::NoPen);
p.setBrush(context.st->msgServiceBg());
const auto r = QRect(QPoint(x, y), size());
p.drawEllipse(r);
context.st->historyFastTranscribeIcon().paintInCenter(p, r);
const auto state = _animation
? _animation->computeState()
: Ui::RadialState();
auto pen = QPen(st::msgServiceFg);
pen.setCapStyle(Qt::RoundCap);
p.setPen(pen);
if (_animation && state.shown > 0 && anim::Disabled()) {
const auto _st = &st::defaultRadio;
anim::DrawStaticLoading(
p,
r,
_st->thickness,
pen.color(),
_st->bg);
} else if (state.arcLength < FullArcLength) {
const auto opacity = p.opacity();
p.setOpacity(state.shown * (1. - opened));
p.drawArc(r, state.arcFrom, state.arcLength);
p.setOpacity(opacity);
}
return;
}
auto bg = stm->msgFileBg->c; auto bg = stm->msgFileBg->c;
bg.setAlphaF(bg.alphaF() * (context.outbg bg.setAlphaF(bg.alphaF() * (context.outbg
? kOutNonChosenOpacity ? kOutNonChosenOpacity
@ -154,4 +195,8 @@ ClickHandlerPtr TranscribeButton::link() {
return _link; return _link;
} }
QRect TranscribeButton::lastPaintedRect() const {
return { _lastPaintedPoint, size() };
}
} // namespace HistoryView } // namespace HistoryView

View file

@ -20,7 +20,7 @@ using PaintContext = Ui::ChatPaintContext;
class TranscribeButton final { class TranscribeButton final {
public: public:
explicit TranscribeButton(not_null<HistoryItem*> item); explicit TranscribeButton(not_null<HistoryItem*> item, bool roundview);
~TranscribeButton(); ~TranscribeButton();
[[nodiscard]] QSize size() const; [[nodiscard]] QSize size() const;
@ -30,9 +30,12 @@ public:
void paint(QPainter &p, int x, int y, const PaintContext &context); void paint(QPainter &p, int x, int y, const PaintContext &context);
[[nodiscard]] ClickHandlerPtr link(); [[nodiscard]] ClickHandlerPtr link();
[[nodiscard]] QRect lastPaintedRect() const;
private: private:
const not_null<HistoryItem*> _item; const not_null<HistoryItem*> _item;
const bool _roundview = false;
const QSize _size;
mutable std::unique_ptr<Ui::InfiniteRadialAnimation> _animation; mutable std::unique_ptr<Ui::InfiniteRadialAnimation> _animation;
ClickHandlerPtr _link; ClickHandlerPtr _link;
@ -40,6 +43,7 @@ private:
Ui::Animations::Simple _openedAnimation; Ui::Animations::Simple _openedAnimation;
bool _loading = false; bool _loading = false;
bool _opened = false; bool _opened = false;
QPoint _lastPaintedPoint;
}; };

View file

@ -288,7 +288,8 @@ QSize Document::countOptimalSize() {
const auto creating = !voice->transcribe; const auto creating = !voice->transcribe;
if (creating) { if (creating) {
voice->transcribe = std::make_unique<TranscribeButton>( voice->transcribe = std::make_unique<TranscribeButton>(
_realParent); _realParent,
false);
} }
const auto &entry = session->api().transcribes().entry( const auto &entry = session->api().transcribes().entry(
_realParent); _realParent);

View file

@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h" #include "history/history.h"
#include "history/view/history_view_element.h" #include "history/view/history_view_element.h"
#include "history/view/history_view_cursor_state.h" #include "history/view/history_view_cursor_state.h"
#include "history/view/history_view_transcribe_button.h"
#include "history/view/media/history_view_media_common.h" #include "history/view/media/history_view_media_common.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "core/application.h" // Application::showDocument. #include "core/application.h" // Application::showDocument.
@ -95,13 +96,7 @@ Gif::Gif(
_data->loadVideoThumbnail(realParent->fullId()); _data->loadVideoThumbnail(realParent->fullId());
} }
} }
ensureTranscribeButton();
_transcribe = std::make_shared<LambdaClickHandler>([=,
id = realParent->fullId()] {
if (const auto item = _data->session().data().message(id)) {
_data->session().api().transcribes().toggle(item);
}
});
} }
Gif::~Gif() { Gif::~Gif() {
@ -154,6 +149,13 @@ QSize Gif::countOptimalSize() {
_parent->skipBlockWidth(), _parent->skipBlockWidth(),
_parent->skipBlockHeight()); _parent->skipBlockHeight());
} }
if (_data->isVideoMessage() && _transcribe) {
const auto &entry = _data->session().api().transcribes().entry(
_realParent);
_transcribe->setLoading(
entry.shown && (entry.requestId || entry.pending),
[=] { repaint(); });
}
const auto minWidth = std::clamp( const auto minWidth = std::clamp(
_parent->minWidthForMedia(), _parent->minWidthForMedia(),
@ -586,6 +588,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
p.drawEllipse(style::rtlrect(statusX - st::msgDateImgPadding.x() + statusW - st::msgDateImgPadding.x() - st::mediaUnreadSize, statusY + st::mediaUnreadTop, st::mediaUnreadSize, st::mediaUnreadSize, width())); p.drawEllipse(style::rtlrect(statusX - st::msgDateImgPadding.x() + statusW - st::msgDateImgPadding.x() - st::mediaUnreadSize, statusY + st::mediaUnreadTop, st::mediaUnreadSize, st::mediaUnreadSize, width()));
} }
} }
ensureTranscribeButton();
} }
if (via || reply || forwarded) { if (via || reply || forwarded) {
auto rectw = width() - usew - st::msgReplyPadding.left(); auto rectw = width() - usew - st::msgReplyPadding.left();
@ -674,33 +677,54 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
? InfoDisplayType::Background ? InfoDisplayType::Background
: InfoDisplayType::Image)); : InfoDisplayType::Image));
} }
if (const auto size = bubble ? std::nullopt : _parent->rightActionSize()) { if (const auto size = bubble ? std::nullopt : _parent->rightActionSize()
; size || _transcribe) {
const auto rightActionWidth = size
? size->width()
: _transcribe->size().width();
auto fastShareLeft = (fullRight + st::historyFastShareLeft); auto fastShareLeft = (fullRight + st::historyFastShareLeft);
auto fastShareTop = (fullBottom - st::historyFastShareBottom - size->height()); auto fastShareTop = fullBottom
if (fastShareLeft + size->width() > maxRight) { - st::historyFastShareBottom
fastShareLeft = (fullRight - size->width() - st::msgDateImgDelta); - (size ? size->height() : 0);
fastShareTop -= (st::msgDateImgDelta + st::msgDateImgPadding.y() + st::msgDateFont->height + st::msgDateImgPadding.y()); if (fastShareLeft + rightActionWidth > maxRight) {
fastShareLeft = fullRight
- rightActionWidth
- st::msgDateImgDelta;
fastShareTop -= st::msgDateImgDelta
+ st::msgDateImgPadding.y()
+ st::msgDateFont->height
+ st::msgDateImgPadding.y();
} }
_parent->drawRightAction(p, context, fastShareLeft, fastShareTop, 2 * paintx + paintw); if (size) {
if (_data->session().premium()) { _parent->drawRightAction(p, context, fastShareLeft, fastShareTop, 2 * paintx + paintw);
const auto stm = context.messageStyle(); }
PainterHighQualityEnabler hq(p); if (_transcribe) {
p.setPen(Qt::NoPen); paintTranscribe(p, fastShareLeft, fastShareTop, true, context);
p.setBrush(context.st->msgServiceBg());
const auto s = st::historyFastShareSize;
const auto r = QRect(
fastShareLeft,
fastShareTop - s - st::msgDateImgDelta,
s,
s);
p.drawEllipse(r);
context.st->historyFastTranscribeIcon().paintInCenter(p, r);
} }
} }
if (_parent->hasOutLayout() && _transcribe) {
paintTranscribe(p, usex, fullBottom, false, context);
}
} }
} }
void Gif::paintTranscribe(
Painter &p,
int x,
int y,
bool right,
const PaintContext &context) const {
if (!_transcribe) {
return;
}
const auto s = _transcribe->size();
_transcribe->paint(
p,
x - (right ? 0 : s.width()),
y - s.height() - st::msgDateImgDelta,
context);
}
void Gif::validateVideoThumbnail() const { void Gif::validateVideoThumbnail() const {
const auto content = _dataMedia->videoThumbnailContent(); const auto content = _dataMedia->videoThumbnailContent();
if (_videoThumbnailFrame || content.isEmpty()) { if (_videoThumbnailFrame || content.isEmpty()) {
@ -991,26 +1015,26 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
} }
} }
if (const auto size = bubble ? std::nullopt : _parent->rightActionSize()) { if (const auto size = bubble ? std::nullopt : _parent->rightActionSize()) {
const auto rightActionWidth = size->width();
auto fastShareLeft = (fullRight + st::historyFastShareLeft); auto fastShareLeft = (fullRight + st::historyFastShareLeft);
auto fastShareTop = (fullBottom - st::historyFastShareBottom - size->height()); auto fastShareTop = fullBottom
if (fastShareLeft + size->width() > maxRight) { - st::historyFastShareBottom
fastShareLeft = (fullRight - size->width() - st::msgDateImgDelta); - size->height();
fastShareTop -= st::msgDateImgDelta + st::msgDateImgPadding.y() + st::msgDateFont->height + st::msgDateImgPadding.y(); if (fastShareLeft + rightActionWidth > maxRight) {
fastShareLeft = fullRight
- rightActionWidth
- st::msgDateImgDelta;
fastShareTop -= st::msgDateImgDelta
+ st::msgDateImgPadding.y()
+ st::msgDateFont->height
+ st::msgDateImgPadding.y();
} }
if (QRect(fastShareLeft, fastShareTop, size->width(), size->height()).contains(point)) { if (QRect(QPoint(fastShareLeft, fastShareTop), *size).contains(point)) {
result.link = _parent->rightActionLink(); result.link = _parent->rightActionLink();
} }
if (_data->session().premium()) { }
const auto s = st::historyFastShareSize; if (_transcribe && _transcribe->lastPaintedRect().contains(point)) {
const auto r = QRect( result.link = _transcribe->link();
fastShareLeft,
fastShareTop - s - st::msgDateImgDelta,
s,
s);
if (r.contains(point)) {
result.link = _transcribe;
}
}
} }
} }
return result; return result;
@ -1727,4 +1751,16 @@ bool Gif::needCornerStatusDisplay() const {
|| needInfoDisplay(); || needInfoDisplay();
} }
void Gif::ensureTranscribeButton() const {
if (_data->session().premium()) {
if (!_transcribe) {
_transcribe = std::make_unique<TranscribeButton>(
_realParent,
true);
}
} else {
_transcribe = nullptr;
}
}
} // namespace HistoryView } // namespace HistoryView

View file

@ -37,6 +37,8 @@ enum class Error;
namespace HistoryView { namespace HistoryView {
class TranscribeButton;
class Gif final : public File { class Gif final : public File {
public: public:
Gif( Gif(
@ -152,6 +154,14 @@ private:
void handleStreamingError(::Media::Streaming::Error &&error); void handleStreamingError(::Media::Streaming::Error &&error);
void streamingReady(::Media::Streaming::Information &&info); void streamingReady(::Media::Streaming::Information &&info);
void repaintStreamedContent(); void repaintStreamedContent();
void ensureTranscribeButton() const;
void paintTranscribe(
Painter &p,
int x,
int y,
bool right,
const PaintContext &context) const;
[[nodiscard]] bool needInfoDisplay() const; [[nodiscard]] bool needInfoDisplay() const;
[[nodiscard]] bool needCornerStatusDisplay() const; [[nodiscard]] bool needCornerStatusDisplay() const;
@ -192,6 +202,7 @@ private:
const not_null<DocumentData*> _data; const not_null<DocumentData*> _data;
Ui::Text::String _caption; Ui::Text::String _caption;
std::unique_ptr<Streamed> _streamed; std::unique_ptr<Streamed> _streamed;
mutable std::unique_ptr<TranscribeButton> _transcribe;
mutable std::shared_ptr<Data::DocumentMedia> _dataMedia; mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
mutable std::unique_ptr<Image> _videoThumbnailFrame; mutable std::unique_ptr<Image> _videoThumbnailFrame;
QString _downloadSize; QString _downloadSize;
@ -201,8 +212,6 @@ private:
mutable bool _thumbCacheBlurred = false; mutable bool _thumbCacheBlurred = false;
mutable bool _thumbIsEllipse = false; mutable bool _thumbIsEllipse = false;
ClickHandlerPtr _transcribe;
}; };
} // namespace HistoryView } // namespace HistoryView