From b73f1be856f1d7bf0ce748a19a46e07f9d7fc369 Mon Sep 17 00:00:00 2001 From: John Preston <johnprestonmail@gmail.com> Date: Tue, 30 Jul 2019 16:57:39 +0200 Subject: [PATCH] Make some video player code reusable. --- Telegram/CMakeLists.txt | 2 + .../streaming/media_streaming_document.cpp | 255 ++++++++++++++++++ .../streaming/media_streaming_document.h | 84 ++++++ .../media/view/media_view_overlay_widget.cpp | 202 ++++---------- .../media/view/media_view_overlay_widget.h | 2 - .../SourceFiles/media/view/mediaview.style | 5 - Telegram/gyp/telegram/sources.txt | 2 + Telegram/lib_ui | 2 +- 8 files changed, 398 insertions(+), 156 deletions(-) create mode 100644 Telegram/SourceFiles/media/streaming/media_streaming_document.cpp create mode 100644 Telegram/SourceFiles/media/streaming/media_streaming_document.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 390011b00..98f543538 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -617,6 +617,8 @@ PRIVATE media/streaming/media_streaming_audio_track.cpp media/streaming/media_streaming_audio_track.h media/streaming/media_streaming_common.h + media/streaming/media_streaming_document.cpp + media/streaming/media_streaming_document.h media/streaming/media_streaming_file.cpp media/streaming/media_streaming_file.h media/streaming/media_streaming_file_delegate.h diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_document.cpp b/Telegram/SourceFiles/media/streaming/media_streaming_document.cpp new file mode 100644 index 000000000..e967f363e --- /dev/null +++ b/Telegram/SourceFiles/media/streaming/media_streaming_document.cpp @@ -0,0 +1,255 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#include "media/streaming/media_streaming_document.h" + +#include "data/data_session.h" +#include "data/data_document.h" +#include "data/data_file_origin.h" +#include "storage/file_download.h" // Storage::kMaxFileInMemory. +#include "styles/style_widgets.h" + +#include <QtCore/QBuffer> + +namespace Media { +namespace Streaming { +namespace { + +constexpr auto kWaitingFastDuration = crl::time(200); +constexpr auto kWaitingShowDuration = crl::time(500); +constexpr auto kWaitingShowDelay = crl::time(500); +constexpr auto kGoodThumbnailQuality = 87; + +} // namespace + +void Instance::setWaitingCallback(Fn<void()> callback) { + _waitingCallback = std::move(callback); +} + +void Instance::callWaitingCallback() { + if (_waitingCallback) { + _waitingCallback(); + } +} + +Document::Document( + not_null<DocumentData*> document, + Data::FileOrigin origin) +: _player( + &document->owner(), + document->owner().documentStreamedReader(document, origin)) +, _radial( + [=] { waitingCallback(); }, + st::defaultInfiniteRadialAnimation) +, _document(document) { + _player.updates( + ) | rpl::start_with_next_error([=](Update &&update) { + handleUpdate(std::move(update)); + }, [=](Streaming::Error &&error) { + handleError(std::move(error)); + }, lifetime()); + + _player.fullInCache( + ) | rpl::start_with_next([=](bool fullInCache) { + _document->setLoadedInMediaCache(fullInCache); + }, lifetime()); +} + +const Player &Document::player() const { + return _player; +} + +const Information &Document::info() const { + return _info; +} + +void Document::play(const PlaybackOptions &options) { + _player.play(options); + _info.audio.state.position + = _info.video.state.position + = options.position; + waitingChange(true); +} + +void Document::pause() { + _player.pause(); +} + +void Document::resume() { + _player.resume(); +} + +void Document::saveFrameToCover() { + auto request = Streaming::FrameRequest(); + //request.radius = (_doc && _doc->isVideoMessage()) + // ? ImageRoundRadius::Ellipse + // : ImageRoundRadius::None; + _info.video.cover = _player.ready() + ? _player.frame(request) + : _info.video.cover; +} + +not_null<Instance*> Document::addInstance() { + return _instances.emplace(std::make_unique<Instance>()).first->get(); +} + +void Document::removeInstance(not_null<Instance*> instance) { + const auto i = ranges::lower_bound( + _instances, + instance.get(), + ranges::less(), + &std::unique_ptr<Instance>::get); + if (i != _instances.end() && i->get() == instance) { + _instances.erase(i); + } +} + +bool Document::waitingShown() const { + if (!_fading.animating() && !_waiting) { + _radial.stop(anim::type::instant); + return false; + } + return _radial.animating(); +} + +float64 Document::waitingOpacity() const { + return _fading.value(_waiting ? 1. : 0.); +} + +Ui::RadialState Document::waitingState() const { + return _radial.computeState(); +} + +rpl::lifetime &Document::lifetime() { + return _player.lifetime(); +} + +void Document::handleUpdate(Update &&update) { + update.data.match([&](Information &update) { + ready(std::move(update)); + }, [&](const PreloadedVideo &update) { + _info.video.state.receivedTill = update.till; + }, [&](const UpdateVideo &update) { + _info.video.state.position = update.position; + }, [&](const PreloadedAudio &update) { + _info.audio.state.receivedTill = update.till; + }, [&](const UpdateAudio &update) { + _info.audio.state.position = update.position; + }, [&](const WaitingForData &update) { + waitingChange(update.waiting); + }, [&](MutedByOther) { + }, [&](Finished) { + const auto finishTrack = [](TrackState &state) { + state.position = state.receivedTill = state.duration; + }; + finishTrack(_info.audio.state); + finishTrack(_info.video.state); + }); +} + +void Document::handleError(Error &&error) { + if (error == Error::NotStreamable) { + _document->setNotSupportsStreaming(); + } else if (error == Error::OpenFailed) { + _document->setInappPlaybackFailed(); + } + waitingChange(false); +} + +void Document::ready(Information &&info) { + _info = std::move(info); + validateGoodThumbnail(); + waitingChange(false); +} + +void Document::waitingChange(bool waiting) { + if (_waiting == waiting) { + return; + } + _waiting = waiting; + const auto fade = [=](crl::time duration) { + if (!_radial.animating()) { + _radial.start( + st::defaultInfiniteRadialAnimation.sineDuration); + } + _fading.start( + [=] { waitingCallback(); }, + _waiting ? 0. : 1., + _waiting ? 1. : 0., + duration); + }; + if (waiting) { + if (_radial.animating()) { + _timer.cancel(); + fade(kWaitingFastDuration); + } else { + _timer.callOnce(kWaitingShowDelay); + _timer.setCallback([=] { + fade(kWaitingShowDuration); + }); + } + } else { + _timer.cancel(); + if (_radial.animating()) { + fade(kWaitingFastDuration); + } + } +} + +void Document::validateGoodThumbnail() { + const auto good = _document->goodThumbnail(); + if (_info.video.cover.isNull() + || (good && good->loaded()) + || _document->uploading()) { + return; + } + auto image = [&] { + auto result = _info.video.cover; + if (_info.video.rotation != 0) { + auto transform = QTransform(); + transform.rotate(_info.video.rotation); + result = result.transformed(transform); + } + if (result.size() != _info.video.size) { + result = result.scaled( + _info.video.size, + Qt::IgnoreAspectRatio, + Qt::SmoothTransformation); + } + return result; + }(); + + auto bytes = QByteArray(); + { + auto buffer = QBuffer(&bytes); + image.save(&buffer, "JPG", kGoodThumbnailQuality); + } + const auto length = bytes.size(); + if (!length || length > Storage::kMaxFileInMemory) { + LOG(("App Error: Bad thumbnail data for saving to cache.")); + } else if (_document->uploading()) { + _document->setGoodThumbnailOnUpload( + std::move(image), + std::move(bytes)); + } else { + _document->owner().cache().putIfEmpty( + _document->goodThumbnailCacheKey(), + Storage::Cache::Database::TaggedValue( + std::move(bytes), + Data::kImageCacheTag)); + _document->refreshGoodThumbnail(); + } +} + +void Document::waitingCallback() { + for (const auto &instance : _instances) { + instance->callWaitingCallback(); + } +} + +} // namespace Streaming +} // namespace Media diff --git a/Telegram/SourceFiles/media/streaming/media_streaming_document.h b/Telegram/SourceFiles/media/streaming/media_streaming_document.h new file mode 100644 index 000000000..8e5febb0c --- /dev/null +++ b/Telegram/SourceFiles/media/streaming/media_streaming_document.h @@ -0,0 +1,84 @@ +/* +This file is part of Telegram Desktop, +the official desktop application for the Telegram messaging service. + +For license and copyright information please follow this link: +https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL +*/ +#pragma once + +#include "media/streaming/media_streaming_player.h" +#include "ui/effects/radial_animation.h" +#include "ui/effects/animations.h" +#include "base/timer.h" + +class DocumentData; + +namespace Data { +struct FileOrigin; +} // namespace Data + +namespace Media { +namespace Streaming { + +class Instance { +public: + void setWaitingCallback(Fn<void()> callback); + + void callWaitingCallback(); + +private: + Fn<void()> _waitingCallback; + +}; + +class Document { +public: + Document( + not_null<DocumentData*> document, + Data::FileOrigin origin); + + [[nodiscard]] const Player &player() const; + [[nodiscard]] const Information &info() const; + + void play(const PlaybackOptions &options); + void pause(); + void resume(); + void saveFrameToCover(); + + [[nodiscard]] not_null<Instance*> addInstance(); + void removeInstance(not_null<Instance*> instance); + + [[nodiscard]] bool waitingShown() const; + [[nodiscard]] float64 waitingOpacity() const; + [[nodiscard]] Ui::RadialState waitingState() const; + + [[nodiscard]] rpl::lifetime &lifetime(); + +private: + void waitingCallback(); + + void handleUpdate(Update &&update); + void handleError(Error &&error); + + void ready(Information &&info); + void waitingChange(bool waiting); + + void validateGoodThumbnail(); + + Player _player; + Information _info; + + bool _waiting = false; + mutable Ui::InfiniteRadialAnimation _radial; + Ui::Animations::Simple _fading; + base::Timer _timer; + base::flat_set<std::unique_ptr<Instance>> _instances; + + not_null<DocumentData*> _document; + +}; + + +} // namespace Streaming +} // namespace Media diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp index a168f0082..5bab7bd67 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.cpp @@ -28,6 +28,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "media/view/media_view_group_thumbs.h" #include "media/streaming/media_streaming_player.h" #include "media/streaming/media_streaming_reader.h" +#include "media/streaming/media_streaming_document.h" #include "media/player/media_player_instance.h" #include "history/history.h" #include "history/history_message.h" @@ -66,10 +67,6 @@ namespace Media { namespace View { namespace { -constexpr auto kGoodThumbnailQuality = 87; -constexpr auto kWaitingFastDuration = crl::time(200); -constexpr auto kWaitingShowDuration = crl::time(500); -constexpr auto kWaitingShowDelay = crl::time(500); constexpr auto kPreloadCount = 4; // macOS OpenGL renderer fails to render larger texture @@ -188,20 +185,16 @@ struct OverlayWidget::Collage { struct OverlayWidget::Streamed { template <typename Callback> Streamed( - not_null<Data::Session*> owner, - std::shared_ptr<Streaming::Reader> reader, + not_null<DocumentData*> document, + Data::FileOrigin origin, QWidget *controlsParent, not_null<PlaybackControls::Delegate*> controlsDelegate, Callback &&loadingCallback); - Streaming::Player player; - Streaming::Information info; + Streaming::Document document; + not_null<Streaming::Instance*> instance; PlaybackControls controls; - bool waiting = false; - Ui::InfiniteRadialAnimation radial; - Ui::Animations::Simple fading; - base::Timer timer; QImage frameForDirectPaint; bool withSound = false; @@ -211,16 +204,15 @@ struct OverlayWidget::Streamed { template <typename Callback> OverlayWidget::Streamed::Streamed( - not_null<Data::Session*> owner, - std::shared_ptr<Streaming::Reader> reader, + not_null<DocumentData*> document, + Data::FileOrigin origin, QWidget *controlsParent, not_null<PlaybackControls::Delegate*> controlsDelegate, Callback &&loadingCallback) -: player(owner, std::move(reader)) -, controls(controlsParent, controlsDelegate) -, radial( - std::forward<Callback>(loadingCallback), - st::mediaviewStreamingRadial) { +: document(document, origin) +, instance(this->document.addInstance()) +, controls(controlsParent, controlsDelegate) { + instance->setWaitingCallback(std::forward<Callback>(loadingCallback)); } OverlayWidget::OverlayWidget() @@ -368,13 +360,13 @@ void OverlayWidget::moveToScreen(bool force) { } bool OverlayWidget::videoShown() const { - return _streamed && !_streamed->info.video.cover.isNull(); + return _streamed && !_streamed->document.info().video.cover.isNull(); } QSize OverlayWidget::videoSize() const { Expects(videoShown()); - return _streamed->info.video.size; + return _streamed->document.info().video.size; } bool OverlayWidget::videoIsGifv() const { @@ -388,9 +380,9 @@ QImage OverlayWidget::videoFrame() const { //request.radius = (_doc && _doc->isVideoMessage()) // ? ImageRoundRadius::Ellipse // : ImageRoundRadius::None; - return _streamed->player.ready() - ? _streamed->player.frame(request) - : _streamed->info.video.cover; + return _streamed->document.player().ready() + ? _streamed->document.player().frame(request) + : _streamed->document.info().video.cover; } QImage OverlayWidget::videoFrameForDirectPaint() const { @@ -2008,17 +2000,12 @@ void OverlayWidget::initStreaming() { Core::App().updateNonIdle(); - _streamed->player.updates( + _streamed->document.player().updates( ) | rpl::start_with_next_error([=](Streaming::Update &&update) { handleStreamingUpdate(std::move(update)); }, [=](Streaming::Error &&error) { handleStreamingError(std::move(error)); - }, _streamed->player.lifetime()); - - _streamed->player.fullInCache( - ) | rpl::start_with_next([=](bool fullInCache) { - _doc->setLoadedInMediaCache(fullInCache); - }, _streamed->player.lifetime()); + }, _streamed->document.lifetime()); restartAtSeekPosition(0); } @@ -2063,8 +2050,6 @@ void OverlayWidget::initStreamingThumbnail() { } void OverlayWidget::streamingReady(Streaming::Information &&info) { - _streamed->info = std::move(info); - validateStreamedGoodThumbnail(); if (videoShown()) { const auto contentSize = style::ConvertScale(videoSize()); if (contentSize != QSize(_width, _height)) { @@ -2075,13 +2060,12 @@ void OverlayWidget::streamingReady(Streaming::Information &&info) { } } this->update(contentRect()); - playbackWaitingChange(false); } void OverlayWidget::createStreamingObjects() { _streamed = std::make_unique<Streamed>( - &_doc->owner(), - _doc->owner().documentStreamedReader(_doc, fileOrigin()), + _doc, + fileOrigin(), this, static_cast<PlaybackControls::Delegate*>(this), [=] { waitingAnimationCallback(); }); @@ -2101,79 +2085,38 @@ void OverlayWidget::createStreamingObjects() { QImage OverlayWidget::transformVideoFrame(QImage frame) const { Expects(videoShown()); - if (_streamed->info.video.rotation != 0) { + if (_streamed->document.info().video.rotation != 0) { auto transform = QTransform(); - transform.rotate(_streamed->info.video.rotation); + transform.rotate(_streamed->document.info().video.rotation); frame = frame.transformed(transform); } - if (frame.size() != _streamed->info.video.size) { + if (frame.size() != _streamed->document.info().video.size) { frame = frame.scaled( - _streamed->info.video.size, + _streamed->document.info().video.size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation); } return frame; } -void OverlayWidget::validateStreamedGoodThumbnail() { - Expects(_streamed != nullptr); - Expects(_doc != nullptr); - - const auto good = _doc->goodThumbnail(); - if (!videoShown() || (good && good->loaded()) || _doc->uploading()) { - return; - } - auto image = transformVideoFrame(_streamed->info.video.cover); - auto bytes = QByteArray(); - { - auto buffer = QBuffer(&bytes); - image.save(&buffer, "JPG", kGoodThumbnailQuality); - } - const auto length = bytes.size(); - if (!length || length > Storage::kMaxFileInMemory) { - LOG(("App Error: Bad thumbnail data for saving to cache.")); - } else if (_doc->uploading()) { - _doc->setGoodThumbnailOnUpload( - std::move(image), - std::move(bytes)); - } else { - _doc->owner().cache().putIfEmpty( - _doc->goodThumbnailCacheKey(), - Storage::Cache::Database::TaggedValue( - std::move(bytes), - Data::kImageCacheTag)); - _doc->refreshGoodThumbnail(); - } -} - void OverlayWidget::handleStreamingUpdate(Streaming::Update &&update) { using namespace Streaming; update.data.match([&](Information &update) { streamingReady(std::move(update)); }, [&](const PreloadedVideo &update) { - _streamed->info.video.state.receivedTill = update.till; updatePlaybackState(); }, [&](const UpdateVideo &update) { - _streamed->info.video.state.position = update.position; this->update(contentRect()); Core::App().updateNonIdle(); updatePlaybackState(); }, [&](const PreloadedAudio &update) { - _streamed->info.audio.state.receivedTill = update.till; updatePlaybackState(); }, [&](const UpdateAudio &update) { - _streamed->info.audio.state.position = update.position; updatePlaybackState(); - }, [&](const WaitingForData &update) { - playbackWaitingChange(update.waiting); + }, [&](WaitingForData) { }, [&](MutedByOther) { }, [&](Finished) { - const auto finishTrack = [](Streaming::TrackState &state) { - state.position = state.receivedTill = state.duration; - }; - finishTrack(_streamed->info.audio.state); - finishTrack(_streamed->info.video.state); updatePlaybackState(); }); } @@ -2187,47 +2130,10 @@ void OverlayWidget::handleStreamingError(Streaming::Error &&error) { if (!_doc->canBePlayed()) { redisplayContent(); } else { - playbackWaitingChange(false); updatePlaybackState(); } } -void OverlayWidget::playbackWaitingChange(bool waiting) { - Expects(_streamed != nullptr); - - if (_streamed->waiting == waiting) { - return; - } - _streamed->waiting = waiting; - const auto fade = [=](crl::time duration) { - if (!_streamed->radial.animating()) { - _streamed->radial.start( - st::defaultInfiniteRadialAnimation.sineDuration); - } - _streamed->fading.start( - [=] { update(radialRect()); }, - _streamed->waiting ? 0. : 1., - _streamed->waiting ? 1. : 0., - duration); - }; - if (waiting) { - if (_streamed->radial.animating()) { - _streamed->timer.cancel(); - fade(kWaitingFastDuration); - } else { - _streamed->timer.callOnce(kWaitingShowDelay); - _streamed->timer.setCallback([=] { - fade(kWaitingShowDuration); - }); - } - } else { - _streamed->timer.cancel(); - if (_streamed->radial.animating()) { - fade(kWaitingFastDuration); - } - } -} - void OverlayWidget::initThemePreview() { using namespace Window::Theme; @@ -2363,18 +2269,18 @@ void OverlayWidget::playbackPauseResume() { Expects(_streamed != nullptr); _streamed->resumeOnCallEnd = false; - if (_streamed->player.failed()) { + if (_streamed->document.player().failed()) { clearStreaming(); initStreaming(); - } else if (_streamed->player.finished()) { + } else if (_streamed->document.player().finished()) { _streamingStartPaused = false; restartAtSeekPosition(0); - } else if (_streamed->player.paused()) { - _streamed->player.resume(); + } else if (_streamed->document.player().paused()) { + _streamed->document.resume(); updatePlaybackState(); playbackPauseMusic(); } else { - _streamed->player.pause(); + _streamed->document.pause(); updatePlaybackState(); } } @@ -2384,7 +2290,7 @@ void OverlayWidget::restartAtSeekPosition(crl::time position) { Expects(_doc != nullptr); if (videoShown()) { - _streamed->info.video.cover = videoFrame(); + _streamed->document.saveFrameToCover(); _current = Images::PixmapFast(transformVideoFrame(videoFrame())); update(contentRect()); } @@ -2395,25 +2301,22 @@ void OverlayWidget::restartAtSeekPosition(crl::time position) { options.mode = Streaming::Mode::Video; options.loop = true; } - _streamed->player.play(options); + _streamed->document.play(options); if (_streamingStartPaused) { - _streamed->player.pause(); + _streamed->document.pause(); } else { playbackPauseMusic(); } _streamed->pausedBySeek = false; - _streamed->info.audio.state.position - = _streamed->info.video.state.position - = position; updatePlaybackState(); - playbackWaitingChange(true); } void OverlayWidget::playbackControlsSeekProgress(crl::time position) { Expects(_streamed != nullptr); - if (!_streamed->player.paused() && !_streamed->player.finished()) { + if (!_streamed->document.player().paused() + && !_streamed->document.player().finished()) { _streamed->pausedBySeek = true; playbackControlsPause(); } @@ -2423,7 +2326,7 @@ void OverlayWidget::playbackControlsSeekFinished(crl::time position) { Expects(_streamed != nullptr); _streamingStartPaused = !_streamed->pausedBySeek - && !_streamed->player.finished(); + && !_streamed->document.player().finished(); restartAtSeekPosition(position); } @@ -2461,11 +2364,12 @@ void OverlayWidget::playbackToggleFullScreen() { void OverlayWidget::playbackPauseOnCall() { Expects(_streamed != nullptr); - if (_streamed->player.finished() || _streamed->player.paused()) { + if (_streamed->document.player().finished() + || _streamed->document.player().paused()) { return; } _streamed->resumeOnCallEnd = true; - _streamed->player.pause(); + _streamed->document.pause(); updatePlaybackState(); } @@ -2474,7 +2378,7 @@ void OverlayWidget::playbackResumeOnCall() { if (_streamed->resumeOnCallEnd) { _streamed->resumeOnCallEnd = false; - _streamed->player.resume(); + _streamed->document.resume(); updatePlaybackState(); playbackPauseMusic(); } @@ -2496,7 +2400,7 @@ void OverlayWidget::updatePlaybackState() { if (videoIsGifv()) { return; } - const auto state = _streamed->player.prepareLegacyState(); + const auto state = _streamed->document.player().prepareLegacyState(); if (state.position != kTimeUnknown && state.length != kTimeUnknown) { _streamed->controls.updatePlayback(state); } @@ -2799,7 +2703,8 @@ void OverlayWidget::paintEvent(QPaintEvent *e) { } void OverlayWidget::checkGroupThumbsAnimation() { - if (_groupThumbs && (!_streamed || _streamed->player.ready())) { + if (_groupThumbs + && (!_streamed || _streamed->document.player().ready())) { _groupThumbs->checkForAnimationStart(); } } @@ -2811,7 +2716,7 @@ void OverlayWidget::paintTransformedVideoFrame(Painter &p) { // const auto fill = rect.intersected(this->rect()); // PaintImageProfile(p, image, rect, fill); //} else { - const auto rotation = _streamed->info.video.rotation; + const auto rotation = _streamed->document.info().video.rotation; const auto rotated = [](QRect rect, int rotation) { switch (rotation) { case 0: return rect; @@ -2851,13 +2756,7 @@ void OverlayWidget::paintRadialLoading( bool radial, float64 radialOpacity) { if (_streamed) { - if (!_streamed->radial.animating()) { - return; - } - if (!_streamed->fading.animating() && !_streamed->waiting) { - if (!_streamed->waiting) { - _streamed->radial.stop(anim::type::instant); - } + if (!_streamed->document.waitingShown()) { return; } } else if (!radial && (!_doc || _doc->loaded())) { @@ -2910,9 +2809,16 @@ void OverlayWidget::paintRadialLoadingContent( if (_streamed) { paintBg( - _streamed->fading.value(_streamed->waiting ? 1. : 0.), + _streamed->document.waitingOpacity(), st::radialBg); - _streamed->radial.draw(p, arc.topLeft(), arc.size(), width()); + Ui::InfiniteRadialAnimation::Draw( + p, + _streamed->document.waitingState(), + arc.topLeft(), + arc.size(), + width(), + st::radialFg, + st::radialLine); return; } if (_photo) { diff --git a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h index 7c3152a13..95d2710c6 100644 --- a/Telegram/SourceFiles/media/view/media_view_overlay_widget.h +++ b/Telegram/SourceFiles/media/view/media_view_overlay_widget.h @@ -178,7 +178,6 @@ private: void playbackPauseOnCall(); void playbackResumeOnCall(); void playbackPauseMusic(); - void playbackWaitingChange(bool waiting); void updateOver(QPoint mpos); void moveToScreen(bool force = false); @@ -265,7 +264,6 @@ private: void createStreamingObjects(); void handleStreamingUpdate(Streaming::Update &&update); void handleStreamingError(Streaming::Error &&error); - void validateStreamedGoodThumbnail(); void initThemePreview(); void destroyThemePreview(); diff --git a/Telegram/SourceFiles/media/view/mediaview.style b/Telegram/SourceFiles/media/view/mediaview.style index 0f0a2c8cf..f02e0c957 100644 --- a/Telegram/SourceFiles/media/view/mediaview.style +++ b/Telegram/SourceFiles/media/view/mediaview.style @@ -188,11 +188,6 @@ mediaviewGroupWidthMax: 160px; mediaviewGroupSkip: 3px; mediaviewGroupSkipCurrent: 12px; -mediaviewStreamingRadial: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) { - color: radialFg; - thickness: radialLine; -} - themePreviewSize: size(903px, 584px); themePreviewBg: windowBg; themePreviewOverlayOpacity: 0.8; diff --git a/Telegram/gyp/telegram/sources.txt b/Telegram/gyp/telegram/sources.txt index 2fbc09079..70df322f1 100644 --- a/Telegram/gyp/telegram/sources.txt +++ b/Telegram/gyp/telegram/sources.txt @@ -512,6 +512,8 @@ <(src_loc)/media/streaming/media_streaming_audio_track.cpp <(src_loc)/media/streaming/media_streaming_audio_track.h <(src_loc)/media/streaming/media_streaming_common.h +<(src_loc)/media/streaming/media_streaming_document.cpp +<(src_loc)/media/streaming/media_streaming_document.h <(src_loc)/media/streaming/media_streaming_file.cpp <(src_loc)/media/streaming/media_streaming_file.h <(src_loc)/media/streaming/media_streaming_file_delegate.h diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 604f62599..21b976569 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 604f62599e9ee5f4d57d778ebbe9403c2a875245 +Subproject commit 21b976569ae2051955c7346295c7029a75bf1bbc