diff --git a/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp b/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp index 02f0abbaa..fb2941de3 100644 --- a/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp +++ b/Telegram/SourceFiles/history/view/history_view_transcribe_button.cpp @@ -27,14 +27,20 @@ constexpr auto kOutNonChosenOpacity = 0.18; } // namespace -TranscribeButton::TranscribeButton(not_null item) -: _item(item) { +TranscribeButton::TranscribeButton( + not_null item, + bool roundview) +: _item(item) +, _roundview(roundview) +, _size(!roundview + ? st::historyTranscribeSize + : QSize(st::historyFastShareSize, st::historyFastShareSize)) { } TranscribeButton::~TranscribeButton() = default; QSize TranscribeButton::size() const { - return st::historyTranscribeSize; + return _size; } void TranscribeButton::setLoading(bool loading, Fn update) { @@ -60,6 +66,41 @@ void TranscribeButton::paint( auto hq = PainterHighQualityEnabler(p); const auto opened = _openedAnimation.value(_opened ? 1. : 0.); 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; bg.setAlphaF(bg.alphaF() * (context.outbg ? kOutNonChosenOpacity @@ -154,4 +195,8 @@ ClickHandlerPtr TranscribeButton::link() { return _link; } +QRect TranscribeButton::lastPaintedRect() const { + return { _lastPaintedPoint, size() }; +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/history_view_transcribe_button.h b/Telegram/SourceFiles/history/view/history_view_transcribe_button.h index 69ee34413..1765d80d3 100644 --- a/Telegram/SourceFiles/history/view/history_view_transcribe_button.h +++ b/Telegram/SourceFiles/history/view/history_view_transcribe_button.h @@ -20,7 +20,7 @@ using PaintContext = Ui::ChatPaintContext; class TranscribeButton final { public: - explicit TranscribeButton(not_null item); + explicit TranscribeButton(not_null item, bool roundview); ~TranscribeButton(); [[nodiscard]] QSize size() const; @@ -30,9 +30,12 @@ public: void paint(QPainter &p, int x, int y, const PaintContext &context); [[nodiscard]] ClickHandlerPtr link(); + [[nodiscard]] QRect lastPaintedRect() const; private: const not_null _item; + const bool _roundview = false; + const QSize _size; mutable std::unique_ptr _animation; ClickHandlerPtr _link; @@ -40,6 +43,7 @@ private: Ui::Animations::Simple _openedAnimation; bool _loading = false; bool _opened = false; + QPoint _lastPaintedPoint; }; diff --git a/Telegram/SourceFiles/history/view/media/history_view_document.cpp b/Telegram/SourceFiles/history/view/media/history_view_document.cpp index 132e13be7..299b61412 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_document.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_document.cpp @@ -288,7 +288,8 @@ QSize Document::countOptimalSize() { const auto creating = !voice->transcribe; if (creating) { voice->transcribe = std::make_unique( - _realParent); + _realParent, + false); } const auto &entry = session->api().transcribes().entry( _realParent); diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp index 1f5605a0e..05f9cbd88 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.cpp +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.cpp @@ -27,6 +27,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "history/history.h" #include "history/view/history_view_element.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 "window/window_session_controller.h" #include "core/application.h" // Application::showDocument. @@ -95,13 +96,7 @@ Gif::Gif( _data->loadVideoThumbnail(realParent->fullId()); } } - - _transcribe = std::make_shared([=, - id = realParent->fullId()] { - if (const auto item = _data->session().data().message(id)) { - _data->session().api().transcribes().toggle(item); - } - }); + ensureTranscribeButton(); } Gif::~Gif() { @@ -154,6 +149,13 @@ QSize Gif::countOptimalSize() { _parent->skipBlockWidth(), _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( _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())); } } + ensureTranscribeButton(); } if (via || reply || forwarded) { auto rectw = width() - usew - st::msgReplyPadding.left(); @@ -674,33 +677,54 @@ void Gif::draw(Painter &p, const PaintContext &context) const { ? InfoDisplayType::Background : 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 fastShareTop = (fullBottom - st::historyFastShareBottom - size->height()); - if (fastShareLeft + size->width() > maxRight) { - fastShareLeft = (fullRight - size->width() - st::msgDateImgDelta); - fastShareTop -= (st::msgDateImgDelta + st::msgDateImgPadding.y() + st::msgDateFont->height + st::msgDateImgPadding.y()); + auto fastShareTop = fullBottom + - st::historyFastShareBottom + - (size ? size->height() : 0); + 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 (_data->session().premium()) { - const auto stm = context.messageStyle(); - PainterHighQualityEnabler hq(p); - p.setPen(Qt::NoPen); - 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 (size) { + _parent->drawRightAction(p, context, fastShareLeft, fastShareTop, 2 * paintx + paintw); + } + if (_transcribe) { + paintTranscribe(p, fastShareLeft, fastShareTop, true, context); } } + 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 { const auto content = _dataMedia->videoThumbnailContent(); 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()) { + const auto rightActionWidth = size->width(); auto fastShareLeft = (fullRight + st::historyFastShareLeft); - auto fastShareTop = (fullBottom - st::historyFastShareBottom - size->height()); - if (fastShareLeft + size->width() > maxRight) { - fastShareLeft = (fullRight - size->width() - st::msgDateImgDelta); - fastShareTop -= st::msgDateImgDelta + st::msgDateImgPadding.y() + st::msgDateFont->height + st::msgDateImgPadding.y(); + auto fastShareTop = fullBottom + - st::historyFastShareBottom + - size->height(); + 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(); } - if (_data->session().premium()) { - const auto s = st::historyFastShareSize; - const auto r = QRect( - fastShareLeft, - fastShareTop - s - st::msgDateImgDelta, - s, - s); - if (r.contains(point)) { - result.link = _transcribe; - } - } + } + if (_transcribe && _transcribe->lastPaintedRect().contains(point)) { + result.link = _transcribe->link(); } } return result; @@ -1727,4 +1751,16 @@ bool Gif::needCornerStatusDisplay() const { || needInfoDisplay(); } +void Gif::ensureTranscribeButton() const { + if (_data->session().premium()) { + if (!_transcribe) { + _transcribe = std::make_unique( + _realParent, + true); + } + } else { + _transcribe = nullptr; + } +} + } // namespace HistoryView diff --git a/Telegram/SourceFiles/history/view/media/history_view_gif.h b/Telegram/SourceFiles/history/view/media/history_view_gif.h index 540144b2c..270fa8aad 100644 --- a/Telegram/SourceFiles/history/view/media/history_view_gif.h +++ b/Telegram/SourceFiles/history/view/media/history_view_gif.h @@ -37,6 +37,8 @@ enum class Error; namespace HistoryView { +class TranscribeButton; + class Gif final : public File { public: Gif( @@ -152,6 +154,14 @@ private: void handleStreamingError(::Media::Streaming::Error &&error); void streamingReady(::Media::Streaming::Information &&info); 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 needCornerStatusDisplay() const; @@ -192,6 +202,7 @@ private: const not_null _data; Ui::Text::String _caption; std::unique_ptr _streamed; + mutable std::unique_ptr _transcribe; mutable std::shared_ptr _dataMedia; mutable std::unique_ptr _videoThumbnailFrame; QString _downloadSize; @@ -201,8 +212,6 @@ private: mutable bool _thumbCacheBlurred = false; mutable bool _thumbIsEllipse = false; - ClickHandlerPtr _transcribe; - }; } // namespace HistoryView