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
TranscribeButton::TranscribeButton(not_null<HistoryItem*> item)
: _item(item) {
TranscribeButton::TranscribeButton(
not_null<HistoryItem*> 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<void()> 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

View file

@ -20,7 +20,7 @@ using PaintContext = Ui::ChatPaintContext;
class TranscribeButton final {
public:
explicit TranscribeButton(not_null<HistoryItem*> item);
explicit TranscribeButton(not_null<HistoryItem*> 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<HistoryItem*> _item;
const bool _roundview = false;
const QSize _size;
mutable std::unique_ptr<Ui::InfiniteRadialAnimation> _animation;
ClickHandlerPtr _link;
@ -40,6 +43,7 @@ private:
Ui::Animations::Simple _openedAnimation;
bool _loading = false;
bool _opened = false;
QPoint _lastPaintedPoint;
};

View file

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

View file

@ -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<LambdaClickHandler>([=,
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<TranscribeButton>(
_realParent,
true);
}
} else {
_transcribe = nullptr;
}
}
} // namespace HistoryView

View file

@ -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<DocumentData*> _data;
Ui::Text::String _caption;
std::unique_ptr<Streamed> _streamed;
mutable std::unique_ptr<TranscribeButton> _transcribe;
mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
mutable std::unique_ptr<Image> _videoThumbnailFrame;
QString _downloadSize;
@ -201,8 +212,6 @@ private:
mutable bool _thumbCacheBlurred = false;
mutable bool _thumbIsEllipse = false;
ClickHandlerPtr _transcribe;
};
} // namespace HistoryView