mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 13:17:08 +02:00
Added initial ability to play video messages with ttl.
This commit is contained in:
parent
40ff71b2cd
commit
21dcb7b13c
13 changed files with 128 additions and 22 deletions
4
Telegram/Resources/art/ttl/video_message_icon.svg
Normal file
4
Telegram/Resources/art/ttl/video_message_icon.svg
Normal 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 |
BIN
Telegram/Resources/icons/chat/audio_once.png
Normal file
BIN
Telegram/Resources/icons/chat/audio_once.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 776 B |
BIN
Telegram/Resources/icons/chat/audio_once@2x.png
Normal file
BIN
Telegram/Resources/icons/chat/audio_once@2x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
BIN
Telegram/Resources/icons/chat/audio_once@3x.png
Normal file
BIN
Telegram/Resources/icons/chat/audio_once@3x.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
|
@ -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>
|
||||
|
|
|
@ -808,7 +808,3 @@ void ClearMediaAsExpired(not_null<HistoryItem*> item) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] bool IsVoiceOncePlayable(not_null<HistoryItem*> item) {
|
||||
return !item->out() && item->media()->ttlSeconds();
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 };
|
||||
};
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue