Added initial ability to play video messages with ttl.

This commit is contained in:
23rd 2024-01-14 03:49:09 +03:00 committed by John Preston
parent 40ff71b2cd
commit 21dcb7b13c
13 changed files with 128 additions and 22 deletions

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<svg baseProfile="tiny" version="1.2" viewBox="0 0 72 72" xmlns="http://www.w3.org/2000/svg">
<path d="m27.57 30.79q0.77-0.44 1.14-1.28 4.38-9.86 4.67-24.25 0.03-1.64 1.63-1.54 1.14 0.07 1.9 0.65c14.45 10.9 28.35 31.97 18.06 50.37-9.55 17.08-32.38 15.75-41.59-0.69-5.25-9.37-0.83-23.06 4.26-32.03a2.13 2.12 43.5 0 1 3.64-0.09l5.53 8.68a0.57 0.56-31.3 0 0 0.76 0.18z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 427 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 776 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

View file

@ -26,6 +26,7 @@
<file alias="recording/info_audio.svg">../../art/recording/recording_info_audio.svg</file>
<file alias="recording/info_video_landscape.svg">../../art/recording/recording_info_video_landscape.svg</file>
<file alias="recording/info_video_portrait.svg">../../art/recording/recording_info_video_portrait.svg</file>
<file alias="ttl/video_message_icon.svg">../../art/ttl/video_message_icon.svg</file>
<file alias="icons/settings/dino.svg">../../icons/settings/dino.svg</file>
<file alias="icons/settings/star.svg">../../icons/settings/star.svg</file>
<file alias="icons/settings/starmini.svg">../../icons/settings/starmini.svg</file>

View file

@ -808,7 +808,3 @@ void ClearMediaAsExpired(not_null<HistoryItem*> item) {
}
}
}
[[nodiscard]] bool IsVoiceOncePlayable(not_null<HistoryItem*> item) {
return !item->out() && item->media()->ttlSeconds();
}

View file

@ -158,4 +158,3 @@ ClickHandlerPtr JumpToStoryClickHandler(
void ShowTrialTranscribesToast(int left, TimeId until);
void ClearMediaAsExpired(not_null<HistoryItem*> item);
[[nodiscard]] bool IsVoiceOncePlayable(not_null<HistoryItem*> item);

View file

@ -425,7 +425,7 @@ void Document::createComponents(bool caption) {
_realParent->fullId());
}
if (const auto voice = Get<HistoryDocumentVoice>()) {
voice->seekl = !IsVoiceOncePlayable(_parent->data())
voice->seekl = !_parent->data()->media()->ttlSeconds()
? std::make_shared<VoiceSeekClickHandler>(_data, [](FullMsgId) {})
: nullptr;
if (_transcribedRound) {

View file

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "media/view/media_view_playback_progress.h"
#include "ui/boxes/confirm_box.h"
#include "ui/painter.h"
#include "ui/rect.h"
#include "history/history_item_components.h"
#include "history/history_item_helpers.h"
#include "history/history_item.h"
@ -30,6 +31,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/history_view_cursor_state.h"
#include "history/view/history_view_reply.h"
#include "history/view/history_view_transcribe_button.h"
#include "history/view/media/history_view_document.h" // TTLVoiceStops
#include "history/view/media/history_view_media_common.h"
#include "history/view/media/history_view_media_spoiler.h"
#include "window/window_session_controller.h"
@ -52,6 +54,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_document_media.h"
#include "styles/style_chat.h"
#include <QSvgRenderer>
namespace HistoryView {
namespace {
@ -65,6 +69,41 @@ int gifMaxStatusWidth(DocumentData *document) {
return result;
}
[[nodiscard]] HistoryView::TtlRoundPaintCallback CreateTtlPaintCallback(
Fn<void()> update) {
const auto iconSize = Size(std::min(
st::historyFileInPause.width(),
st::historyFileInPause.height()));
const auto centerMargins = Margins(st::historyFileInPause.width() * 3);
const auto renderer = std::make_shared<QSvgRenderer>(
u":/gui/ttl/video_message_icon.svg"_q);
return [=](QPainter &p, QRect r, const PaintContext &context) {
const auto centerRect = r - centerMargins;
const auto &icon = context.imageStyle()->historyVideoMessageTtlIcon;
const auto iconRect = QRect(
rect::right(centerRect) - icon.width() * 0.75,
rect::bottom(centerRect) - icon.height() * 0.75,
icon.width(),
icon.height());
{
auto hq = PainterHighQualityEnabler(p);
auto path = QPainterPath();
path.setFillRule(Qt::WindingFill);
path.addEllipse(centerRect);
path.addEllipse(iconRect);
p.fillPath(path, st::shadowFg);
p.fillPath(path, st::shadowFg);
p.fillPath(path, st::shadowFg);
}
renderer->render(&p, centerRect - Margins(centerRect.width() / 4));
icon.paint(p, iconRect.topLeft(), centerRect.width());
};
}
} // namespace
struct Gif::Streamed {
@ -83,6 +122,12 @@ Gif::Streamed::Streamed(
: instance(std::move(shared), std::move(waitingCallback)) {
}
[[nodiscard]] bool IsHiddenRoundMessage(not_null<Element*> parent) {
return parent->delegate()->elementContext() != Context::TTLViewer
&& parent->data()->media()
&& parent->data()->media()->ttlSeconds();
}
Gif::Gif(
not_null<Element*> parent,
not_null<HistoryItem*> realParent,
@ -95,18 +140,45 @@ Gif::Gif(
: FullStoryId())
, _caption(
st::minPhotoSize - st::msgPadding.left() - st::msgPadding.right())
, _spoiler(spoiler ? std::make_unique<MediaSpoiler>() : nullptr)
, _spoiler((spoiler || IsHiddenRoundMessage(_parent))
? std::make_unique<MediaSpoiler>()
: nullptr)
, _downloadSize(Ui::FormatSizeText(_data->size)) {
setDocumentLinks(_data, realParent, [=] {
if (!_data->createMediaView()->canBePlayed(realParent)
|| !_data->isAnimation()
|| _data->isVideoMessage()
|| !CanPlayInline(_data)) {
return false;
auto hasDefaultDocumentLinks = false;
if (_data->isVideoMessage() && _parent->data()->media()->ttlSeconds()) {
if (_spoiler) {
_drawTtl = CreateTtlPaintCallback([=] { repaint(); });
}
playAnimation(false);
return true;
});
const auto fullId = _realParent->fullId();
_parent->data()->removeFromSharedMediaIndex();
setDocumentLinks(_data, realParent, [=] {
auto lifetime = std::make_shared<rpl::lifetime>();
TTLVoiceStops(fullId) | rpl::start_with_next([=]() mutable {
const auto item = _parent->data();
if (lifetime) {
base::take(lifetime)->destroy();
}
if (!item->out()) {
// Destroys this.
ClearMediaAsExpired(item);
}
}, *lifetime);
return false;
});
} else {
setDocumentLinks(_data, realParent, [=] {
if (!_data->createMediaView()->canBePlayed(realParent)
|| !_data->isAnimation()
|| _data->isVideoMessage()
|| !CanPlayInline(_data)) {
return false;
}
playAnimation(false);
return true;
});
}
setStatusSize(Ui::FileStatusSizeReady);
if (_spoiler) {
@ -403,7 +475,13 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
QRect rthumb(style::rtlrect(usex + paintx, painty, usew, painth, width()));
const auto revealed = (!isRound && _spoiler)
const auto inTTLViewer = _parent->delegate()->elementContext()
== Context::TTLViewer;
const auto revealed = (isRound
&& item->media()->ttlSeconds()
&& !inTTLViewer)
? 0
: (!isRound && _spoiler)
? _spoiler->revealAnimation.value(_spoiler->revealed ? 1. : 0.)
: 1.;
const auto fullHiddenBySpoiler = (revealed == 0.);
@ -525,10 +603,19 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
p.drawImage(rthumb, _thumbCache);
}
if (!isRound && revealed < 1.) {
if (revealed < 1.) {
p.setOpacity(1. - revealed);
p.drawImage(rthumb.topLeft(), _spoiler->background);
fillImageSpoiler(p, _spoiler.get(), rthumb, context);
if (!isRound) {
p.drawImage(rthumb.topLeft(), _spoiler->background);
fillImageSpoiler(p, _spoiler.get(), rthumb, context);
} else {
auto frame = _spoiler->background;
{
auto q = QPainter(&frame);
fillImageSpoiler(q, _spoiler.get(), rthumb, context);
}
p.drawImage(rthumb.topLeft(), Images::Circle(std::move(frame)));
}
p.setOpacity(1.);
}
if (context.selected()) {
@ -793,6 +880,9 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
paintTranscribe(p, usex, fullBottom, false, context);
}
}
if (_drawTtl) {
_drawTtl(p, rthumb, context);
}
}
void Gif::paintTranscribe(
@ -1108,7 +1198,9 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
}
if (QRect(usex + paintx, painty, usew, painth).contains(point)) {
ensureDataMediaCreated();
result.link = (_spoiler && !_spoiler->revealed)
result.link = (isRound && _parent->data()->media()->ttlSeconds())
? _openl // Overriden.
: (_spoiler && !_spoiler->revealed)
? _spoiler->link
: _data->uploading()
? _cancell
@ -1970,7 +2062,7 @@ bool Gif::needCornerStatusDisplay() const {
void Gif::ensureTranscribeButton() const {
if (_data->isVideoMessage()
&& !IsVoiceOncePlayable(_parent->data())
&& !_parent->data()->media()->ttlSeconds()
&& (_data->session().premium()
|| _data->session().api().transcribes().trialsSupport())) {
if (!_transcribe) {

View file

@ -40,6 +40,11 @@ namespace HistoryView {
class Reply;
class TranscribeButton;
using TtlRoundPaintCallback = Fn<void(
QPainter&,
QRect,
const PaintContext &context)>;
class Gif final : public File {
public:
Gif(
@ -214,6 +219,8 @@ private:
void togglePollingStory(bool enabled) const;
TtlRoundPaintCallback _drawTtl;
const not_null<DocumentData*> _data;
const FullStoryId _storyId;
Ui::Text::String _caption;

View file

@ -536,6 +536,8 @@ historyVideoMessageMute: icon {{ "volume_mute", historyFileThumbIconFg }};
historyVideoMessageMuteSelected: icon {{ "volume_mute", historyFileThumbIconFgSelected }};
historyVideoMessageMuteSize: 25px;
historyVideoMessageProgressOpacity: 0.72;
historyVideoMessageTtlIcon: icon {{ "chat/audio_once", historyFileThumbIconFg }};
historyVideoMessageTtlIconSelected: icon {{ "chat/audio_once", historyFileThumbIconFgSelected }};
historyAdminLogEmptyWidth: 260px;
historyAdminLogEmptyPadding: margins(10px, 12px, 10px, 12px);

View file

@ -528,6 +528,10 @@ ChatStyle::ChatStyle(rpl::producer<ColorIndicesCompressed> colorIndices) {
&MessageImageStyle::historyVideoMessageMute,
st::historyVideoMessageMute,
st::historyVideoMessageMuteSelected);
make(
&MessageImageStyle::historyVideoMessageTtlIcon,
st::historyVideoMessageTtlIcon,
st::historyVideoMessageTtlIconSelected);
make(
&MessageImageStyle::historyPageEnlarge,
st::historyPageEnlarge,

View file

@ -118,6 +118,7 @@ struct MessageImageStyle {
style::icon historyVideoDownload = { Qt::Uninitialized };
style::icon historyVideoCancel = { Qt::Uninitialized };
style::icon historyVideoMessageMute = { Qt::Uninitialized };
style::icon historyVideoMessageTtlIcon = { Qt::Uninitialized };
style::icon historyPageEnlarge = { Qt::Uninitialized };
};