mirror of https://github.com/procxx/kepka.git
Display correct video / music state.
This commit is contained in:
parent
fde8dd9607
commit
648cd44ddd
|
@ -301,7 +301,7 @@ void DocumentOpenClickHandler::Open(
|
||||||
location.accessDisable();
|
location.accessDisable();
|
||||||
return;
|
return;
|
||||||
} else if (data->canBePlayed()) {
|
} else if (data->canBePlayed()) {
|
||||||
if (data->isAudioFile()) {
|
if (data->isAudioFile() || data->isVoiceMessage()) {
|
||||||
Media::Player::instance()->playPause({ data, msgId });
|
Media::Player::instance()->playPause({ data, msgId });
|
||||||
} else {
|
} else {
|
||||||
Core::App().showDocument(data, context);
|
Core::App().showDocument(data, context);
|
||||||
|
@ -615,7 +615,9 @@ void DocumentData::replaceGoodThumbnail(
|
||||||
_goodThumbnail->replaceSource(std::move(source));
|
_goodThumbnail->replaceSource(std::move(source));
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::setGoodThumbnail(QImage &&image, QByteArray &&bytes) {
|
void DocumentData::setGoodThumbnailOnUpload(
|
||||||
|
QImage &&image,
|
||||||
|
QByteArray &&bytes) {
|
||||||
Expects(uploadingData != nullptr);
|
Expects(uploadingData != nullptr);
|
||||||
|
|
||||||
if (image.isNull()) {
|
if (image.isNull()) {
|
||||||
|
@ -1215,7 +1217,10 @@ bool DocumentData::canBeStreamed() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool DocumentData::canBePlayed() const {
|
bool DocumentData::canBePlayed() const {
|
||||||
return (isAnimation() || isVideoFile() || isAudioFile())
|
return (isAnimation()
|
||||||
|
|| isVideoFile()
|
||||||
|
|| isAudioFile()
|
||||||
|
|| isVoiceMessage())
|
||||||
&& (loaded() || canBeStreamed());
|
&& (loaded() || canBeStreamed());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -184,7 +184,7 @@ public:
|
||||||
|
|
||||||
[[nodiscard]] Image *goodThumbnail() const;
|
[[nodiscard]] Image *goodThumbnail() const;
|
||||||
[[nodiscard]] Storage::Cache::Key goodThumbnailCacheKey() const;
|
[[nodiscard]] Storage::Cache::Key goodThumbnailCacheKey() const;
|
||||||
void setGoodThumbnail(QImage &&image, QByteArray &&bytes);
|
void setGoodThumbnailOnUpload(QImage &&image, QByteArray &&bytes);
|
||||||
void refreshGoodThumbnail();
|
void refreshGoodThumbnail();
|
||||||
void replaceGoodThumbnail(std::unique_ptr<Images::Source> &&source);
|
void replaceGoodThumbnail(std::unique_ptr<Images::Source> &&source);
|
||||||
|
|
||||||
|
|
|
@ -59,7 +59,8 @@ MTPDmessage::Flags NewForwardedFlags(
|
||||||
result &= ~MTPDmessage::Flag::f_media;
|
result &= ~MTPDmessage::Flag::f_media;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!peer->isChannel() && media->forwardedBecomesUnread()) {
|
if ((!peer->isChannel() || peer->isMegagroup())
|
||||||
|
&& media->forwardedBecomesUnread()) {
|
||||||
result |= MTPDmessage::Flag::f_media_unread;
|
result |= MTPDmessage::Flag::f_media_unread;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4300,7 +4300,7 @@ void HistoryWidget::sendFileConfirmed(
|
||||||
MTP_long(groupId)),
|
MTP_long(groupId)),
|
||||||
NewMessageUnread);
|
NewMessageUnread);
|
||||||
} else if (file->type == SendMediaType::Audio) {
|
} else if (file->type == SendMediaType::Audio) {
|
||||||
if (!peer->isChannel()) {
|
if (!peer->isChannel() || peer->isMegagroup()) {
|
||||||
flags |= MTPDmessage::Flag::f_media_unread;
|
flags |= MTPDmessage::Flag::f_media_unread;
|
||||||
}
|
}
|
||||||
auto documentFlags = MTPDmessageMediaDocument::Flag::f_document | 0;
|
auto documentFlags = MTPDmessageMediaDocument::Flag::f_document | 0;
|
||||||
|
|
|
@ -315,10 +315,10 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
|
||||||
}
|
}
|
||||||
|
|
||||||
auto icon = [&] {
|
auto icon = [&] {
|
||||||
if (showPause) {
|
if (_data->loading() || _data->uploading()) {
|
||||||
return &(outbg ? (selected ? st::historyFileOutPauseSelected : st::historyFileOutPause) : (selected ? st::historyFileInPauseSelected : st::historyFileInPause));
|
|
||||||
} else if (radial || _data->loading()) {
|
|
||||||
return &(outbg ? (selected ? st::historyFileOutCancelSelected : st::historyFileOutCancel) : (selected ? st::historyFileInCancelSelected : st::historyFileInCancel));
|
return &(outbg ? (selected ? st::historyFileOutCancelSelected : st::historyFileOutCancel) : (selected ? st::historyFileInCancelSelected : st::historyFileInCancel));
|
||||||
|
} else if (showPause) {
|
||||||
|
return &(outbg ? (selected ? st::historyFileOutPauseSelected : st::historyFileOutPause) : (selected ? st::historyFileInPauseSelected : st::historyFileInPause));
|
||||||
} else if (loaded || _data->canBePlayed()) {
|
} else if (loaded || _data->canBePlayed()) {
|
||||||
if (_data->canBePlayed()) {
|
if (_data->canBePlayed()) {
|
||||||
return &(outbg ? (selected ? st::historyFileOutPlaySelected : st::historyFileOutPlay) : (selected ? st::historyFileInPlaySelected : st::historyFileInPlay));
|
return &(outbg ? (selected ? st::historyFileOutPlaySelected : st::historyFileOutPlay) : (selected ? st::historyFileInPlaySelected : st::historyFileInPlay));
|
||||||
|
@ -335,7 +335,7 @@ void HistoryDocument::draw(Painter &p, const QRect &r, TextSelection selection,
|
||||||
auto statuswidth = namewidth;
|
auto statuswidth = namewidth;
|
||||||
|
|
||||||
auto voiceStatusOverride = QString();
|
auto voiceStatusOverride = QString();
|
||||||
if (auto voice = Get<HistoryDocumentVoice>()) {
|
if (const auto voice = Get<HistoryDocumentVoice>()) {
|
||||||
const VoiceWaveform *wf = nullptr;
|
const VoiceWaveform *wf = nullptr;
|
||||||
uchar norm_value = 0;
|
uchar norm_value = 0;
|
||||||
if (const auto voiceData = _data->voice()) {
|
if (const auto voiceData = _data->voice()) {
|
||||||
|
@ -463,6 +463,13 @@ TextState HistoryDocument::textState(QPoint point, StateRequest request) const {
|
||||||
nametop = st::msgFileThumbNameTop - topMinus;
|
nametop = st::msgFileThumbNameTop - topMinus;
|
||||||
linktop = st::msgFileThumbLinkTop - topMinus;
|
linktop = st::msgFileThumbLinkTop - topMinus;
|
||||||
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() - topMinus;
|
bottom = st::msgFileThumbPadding.top() + st::msgFileThumbSize + st::msgFileThumbPadding.bottom() - topMinus;
|
||||||
|
|
||||||
|
QRect rthumb(rtlrect(st::msgFileThumbPadding.left(), st::msgFileThumbPadding.top() - topMinus, st::msgFileThumbSize, st::msgFileThumbSize, width()));
|
||||||
|
if ((_data->loading() || _data->uploading()) && rthumb.contains(point)) {
|
||||||
|
result.link = _cancell;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
if (_data->status != FileUploadFailed) {
|
if (_data->status != FileUploadFailed) {
|
||||||
if (rtlrect(nameleft, linktop, thumbed->_linkw, st::semiboldFont->height, width()).contains(point)) {
|
if (rtlrect(nameleft, linktop, thumbed->_linkw, st::semiboldFont->height, width()).contains(point)) {
|
||||||
result.link = (_data->loading() || _data->uploading())
|
result.link = (_data->loading() || _data->uploading())
|
||||||
|
@ -471,6 +478,17 @@ TextState HistoryDocument::textState(QPoint point, StateRequest request) const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
nameleft = st::msgFilePadding.left() + st::msgFileSize + st::msgFilePadding.right();
|
||||||
|
nameright = st::msgFilePadding.left();
|
||||||
|
nametop = st::msgFileNameTop - topMinus;
|
||||||
|
bottom = st::msgFilePadding.top() + st::msgFileSize + st::msgFilePadding.bottom() - topMinus;
|
||||||
|
|
||||||
|
QRect inner(rtlrect(st::msgFilePadding.left(), st::msgFilePadding.top() - topMinus, st::msgFileSize, st::msgFileSize, width()));
|
||||||
|
if ((_data->loading() || _data->uploading()) && inner.contains(point)) {
|
||||||
|
result.link = _cancell;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (const auto voice = Get<HistoryDocumentVoice>()) {
|
if (const auto voice = Get<HistoryDocumentVoice>()) {
|
||||||
|
@ -490,7 +508,7 @@ TextState HistoryDocument::textState(QPoint point, StateRequest request) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto painth = height();
|
auto painth = height();
|
||||||
if (auto captioned = Get<HistoryDocumentCaptioned>()) {
|
if (const auto captioned = Get<HistoryDocumentCaptioned>()) {
|
||||||
if (point.y() >= bottom) {
|
if (point.y() >= bottom) {
|
||||||
result = TextState(_parent, captioned->_caption.getState(
|
result = TextState(_parent, captioned->_caption.getState(
|
||||||
point - QPoint(st::msgPadding.left(), bottom),
|
point - QPoint(st::msgPadding.left(), bottom),
|
||||||
|
@ -504,10 +522,11 @@ TextState HistoryDocument::textState(QPoint point, StateRequest request) const {
|
||||||
painth -= st::msgPadding.bottom();
|
painth -= st::msgPadding.bottom();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (QRect(0, 0, width(), painth).contains(point) && !_data->loading() && !_data->uploading() && !_data->isNull()) {
|
if (QRect(0, 0, width(), painth).contains(point)
|
||||||
if (_data->loading() || _data->uploading()) {
|
&& !_data->loading()
|
||||||
result.link = _cancell;
|
&& !_data->uploading()
|
||||||
} else if (loaded || _data->canBePlayed()) {
|
&& !_data->isNull()) {
|
||||||
|
if (loaded || _data->canBePlayed()) {
|
||||||
result.link = _openl;
|
result.link = _openl;
|
||||||
} else {
|
} else {
|
||||||
result.link = _savel;
|
result.link = _savel;
|
||||||
|
|
|
@ -226,15 +226,13 @@ void HistoryVideo::draw(Painter &p, const QRect &r, TextSelection selection, crl
|
||||||
p.setOpacity(1);
|
p.setOpacity(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto canPlay = _data->canBePlayed();
|
|
||||||
auto icon = [&]() -> const style::icon * {
|
auto icon = [&]() -> const style::icon * {
|
||||||
if (canPlay && !radial) {
|
if (_data->loading() || _data->uploading()) {
|
||||||
return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay);
|
return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel);
|
||||||
} else if (radial || _data->loading()) {
|
} else if (!IsServerMsgId(_parent->data()->id)) {
|
||||||
if (_parent->data()->id > 0 || _data->uploading()) {
|
|
||||||
return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel);
|
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
} else if (_data->canBePlayed()) {
|
||||||
|
return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay);
|
||||||
}
|
}
|
||||||
return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload);
|
return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload);
|
||||||
}();
|
}();
|
||||||
|
@ -276,7 +274,6 @@ TextState HistoryVideo::textState(QPoint point, StateRequest request) const {
|
||||||
}
|
}
|
||||||
|
|
||||||
auto result = TextState(_parent);
|
auto result = TextState(_parent);
|
||||||
const auto canPlay = _data->canBePlayed();
|
|
||||||
|
|
||||||
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
||||||
bool bubble = _parent->hasBubble();
|
bool bubble = _parent->hasBubble();
|
||||||
|
@ -298,10 +295,13 @@ TextState HistoryVideo::textState(QPoint point, StateRequest request) const {
|
||||||
painth -= st::mediaCaptionSkip;
|
painth -= st::mediaCaptionSkip;
|
||||||
}
|
}
|
||||||
if (QRect(paintx, painty, paintw, painth).contains(point)) {
|
if (QRect(paintx, painty, paintw, painth).contains(point)) {
|
||||||
if (_data->uploading()) {
|
if (_data->loading() || _data->uploading()) {
|
||||||
result.link = _cancell;
|
result.link = _cancell;
|
||||||
|
} else if (!IsServerMsgId(_parent->data()->id)) {
|
||||||
|
} else if (_data->canBePlayed()) {
|
||||||
|
result.link = _openl;
|
||||||
} else {
|
} else {
|
||||||
result.link = canPlay ? _openl : (_data->loading() ? _cancell : _savel);
|
result.link = _savel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_caption.isEmpty() && _parent->media() == this) {
|
if (_caption.isEmpty() && _parent->media() == this) {
|
||||||
|
@ -394,13 +394,12 @@ void HistoryVideo::drawGrouped(
|
||||||
auto icon = [&]() -> const style::icon * {
|
auto icon = [&]() -> const style::icon * {
|
||||||
if (_data->waitingForAlbum()) {
|
if (_data->waitingForAlbum()) {
|
||||||
return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting);
|
return &(selected ? st::historyFileThumbWaitingSelected : st::historyFileThumbWaiting);
|
||||||
} else if (canPlay && !radial) {
|
} else if (_data->loading() || _data->uploading()) {
|
||||||
return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay);
|
return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel);
|
||||||
} else if (radial || _data->loading()) {
|
} else if (!IsServerMsgId(_realParent->id)) {
|
||||||
if (_parent->data()->id > 0 || _data->uploading()) {
|
|
||||||
return &(selected ? st::historyFileThumbCancelSelected : st::historyFileThumbCancel);
|
|
||||||
}
|
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
} else if (_data->canBePlayed()) {
|
||||||
|
return &(selected ? st::historyFileThumbPlaySelected : st::historyFileThumbPlay);
|
||||||
}
|
}
|
||||||
return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload);
|
return &(selected ? st::historyFileThumbDownloadSelected : st::historyFileThumbDownload);
|
||||||
}();
|
}();
|
||||||
|
@ -436,12 +435,12 @@ TextState HistoryVideo::getStateGrouped(
|
||||||
if (!geometry.contains(point)) {
|
if (!geometry.contains(point)) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return TextState(_parent, _data->uploading()
|
return TextState(_parent, (_data->loading() || _data->uploading())
|
||||||
? _cancell
|
? _cancell
|
||||||
|
: !IsServerMsgId(_realParent->id)
|
||||||
|
? nullptr
|
||||||
: _data->canBePlayed()
|
: _data->canBePlayed()
|
||||||
? _openl
|
? _openl
|
||||||
: _data->loading()
|
|
||||||
? _cancell
|
|
||||||
: _savel);
|
: _savel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -188,14 +188,14 @@ void Gif::paint(Painter &p, const QRect &clip, const PaintContext *context) cons
|
||||||
p.setOpacity(radialOpacity * p.opacity());
|
p.setOpacity(radialOpacity * p.opacity());
|
||||||
|
|
||||||
p.setOpacity(radialOpacity);
|
p.setOpacity(radialOpacity);
|
||||||
auto icon = ([loaded, radial, loading] {
|
auto icon = [&] {
|
||||||
if (loaded && !radial) {
|
if (radial || loading) {
|
||||||
return &st::historyFileInPlay;
|
|
||||||
} else if (radial || loading) {
|
|
||||||
return &st::historyFileInCancel;
|
return &st::historyFileInCancel;
|
||||||
|
} else if (loaded) {
|
||||||
|
return &st::historyFileInPlay;
|
||||||
}
|
}
|
||||||
return &st::historyFileInDownload;
|
return &st::historyFileInDownload;
|
||||||
})();
|
}();
|
||||||
QRect inner((_width - st::msgFileSize) / 2, (height - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
QRect inner((_width - st::msgFileSize) / 2, (height - st::msgFileSize) / 2, st::msgFileSize, st::msgFileSize);
|
||||||
icon->paintInCenter(p, inner);
|
icon->paintInCenter(p, inner);
|
||||||
if (radial) {
|
if (radial) {
|
||||||
|
@ -778,11 +778,11 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con
|
||||||
_animation->radial.draw(p, radialCircle, st::msgFileRadialLine, st::historyFileInRadialFg);
|
_animation->radial.draw(p, radialCircle, st::msgFileRadialLine, st::historyFileInRadialFg);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto icon = ([&] {
|
auto icon = [&] {
|
||||||
if (showPause) {
|
if (radial || _document->loading()) {
|
||||||
return &st::historyFileInPause;
|
|
||||||
} else if (radial || _document->loading()) {
|
|
||||||
return &st::historyFileInCancel;
|
return &st::historyFileInCancel;
|
||||||
|
} else if (showPause) {
|
||||||
|
return &st::historyFileInPause;
|
||||||
} else if (true || _document->loaded()) {
|
} else if (true || _document->loaded()) {
|
||||||
if (_document->isImage()) {
|
if (_document->isImage()) {
|
||||||
return &st::historyFileInImage;
|
return &st::historyFileInImage;
|
||||||
|
@ -793,7 +793,7 @@ void File::paint(Painter &p, const QRect &clip, const PaintContext *context) con
|
||||||
return &st::historyFileInDocument;
|
return &st::historyFileInDocument;
|
||||||
}
|
}
|
||||||
return &st::historyFileInDownload;
|
return &st::historyFileInDownload;
|
||||||
})();
|
}();
|
||||||
icon->paintInCenter(p, inner);
|
icon->paintInCenter(p, inner);
|
||||||
|
|
||||||
int titleTop = st::inlineRowMargin + st::inlineRowFileNameTop;
|
int titleTop = st::inlineRowMargin + st::inlineRowFileNameTop;
|
||||||
|
|
|
@ -798,27 +798,6 @@ void Mixer::play(
|
||||||
auto current = trackForType(type);
|
auto current = trackForType(type);
|
||||||
if (!current) return;
|
if (!current) return;
|
||||||
|
|
||||||
if (type == AudioMsgId::Type::Video) {
|
|
||||||
auto pauseType = [this](AudioMsgId::Type type) {
|
|
||||||
auto current = trackForType(type);
|
|
||||||
switch (current->state.state) {
|
|
||||||
case State::Starting:
|
|
||||||
case State::Resuming:
|
|
||||||
case State::Playing: {
|
|
||||||
current->state.state = State::Pausing;
|
|
||||||
resetFadeStartPosition(type);
|
|
||||||
} break;
|
|
||||||
case State::Stopping: {
|
|
||||||
current->state.state = State::Pausing;
|
|
||||||
} break;
|
|
||||||
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
pauseType(AudioMsgId::Type::Song);
|
|
||||||
pauseType(AudioMsgId::Type::Voice);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (current->state.id != audio) {
|
if (current->state.id != audio) {
|
||||||
if (fadedStop(type, &fadedStart)) {
|
if (fadedStop(type, &fadedStart)) {
|
||||||
stopped = current->state.id;
|
stopped = current->state.id;
|
||||||
|
|
|
@ -78,6 +78,7 @@ using PreloadedAudio = PreloadedUpdate<AudioTrack>;
|
||||||
using UpdateAudio = PlaybackUpdate<AudioTrack>;
|
using UpdateAudio = PlaybackUpdate<AudioTrack>;
|
||||||
|
|
||||||
struct WaitingForData {
|
struct WaitingForData {
|
||||||
|
bool waiting = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct MutedByOther {
|
struct MutedByOther {
|
||||||
|
|
|
@ -450,6 +450,7 @@ void Player::checkResumeFromWaitingForData() {
|
||||||
if (_pausedByWaitingForData && bothReceivedEnough(kBufferFor)) {
|
if (_pausedByWaitingForData && bothReceivedEnough(kBufferFor)) {
|
||||||
_pausedByWaitingForData = false;
|
_pausedByWaitingForData = false;
|
||||||
updatePausedState();
|
updatePausedState();
|
||||||
|
_updates.fire({ WaitingForData{ false } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -467,7 +468,7 @@ void Player::start() {
|
||||||
}) | rpl::start_with_next([=] {
|
}) | rpl::start_with_next([=] {
|
||||||
_pausedByWaitingForData = true;
|
_pausedByWaitingForData = true;
|
||||||
updatePausedState();
|
updatePausedState();
|
||||||
_updates.fire({ WaitingForData() });
|
_updates.fire({ WaitingForData{ true } });
|
||||||
}, _sessionLifetime);
|
}, _sessionLifetime);
|
||||||
|
|
||||||
if (guard && _audio) {
|
if (guard && _audio) {
|
||||||
|
|
|
@ -19,11 +19,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "ui/text_options.h"
|
#include "ui/text_options.h"
|
||||||
#include "media/audio/media_audio.h"
|
#include "media/audio/media_audio.h"
|
||||||
#include "media/clip/media_clip_reader.h"
|
|
||||||
#include "media/view/media_view_playback_controls.h"
|
#include "media/view/media_view_playback_controls.h"
|
||||||
#include "media/view/media_view_group_thumbs.h"
|
#include "media/view/media_view_group_thumbs.h"
|
||||||
#include "media/streaming/media_streaming_player.h"
|
#include "media/streaming/media_streaming_player.h"
|
||||||
#include "media/streaming/media_streaming_loader.h"
|
#include "media/streaming/media_streaming_loader.h"
|
||||||
|
#include "media/player/media_player_instance.h"
|
||||||
#include "history/history.h"
|
#include "history/history.h"
|
||||||
#include "history/history_message.h"
|
#include "history/history_message.h"
|
||||||
#include "data/data_media_types.h"
|
#include "data/data_media_types.h"
|
||||||
|
@ -45,6 +45,10 @@ namespace Media {
|
||||||
namespace View {
|
namespace View {
|
||||||
namespace {
|
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;
|
constexpr auto kPreloadCount = 4;
|
||||||
|
|
||||||
// Preload X message ids before and after current.
|
// Preload X message ids before and after current.
|
||||||
|
@ -146,20 +150,30 @@ struct OverlayWidget::Streamed {
|
||||||
not_null<Data::Session*> owner,
|
not_null<Data::Session*> owner,
|
||||||
std::unique_ptr<Streaming::Loader> loader,
|
std::unique_ptr<Streaming::Loader> loader,
|
||||||
QWidget *controlsParent,
|
QWidget *controlsParent,
|
||||||
not_null<PlaybackControls::Delegate*> controlsDelegate);
|
not_null<PlaybackControls::Delegate*> controlsDelegate,
|
||||||
|
AnimationCallbacks loadingCallbacks);
|
||||||
|
|
||||||
Streaming::Player player;
|
Streaming::Player player;
|
||||||
Streaming::Information info;
|
Streaming::Information info;
|
||||||
PlaybackControls controls;
|
PlaybackControls controls;
|
||||||
|
|
||||||
|
bool waiting = false;
|
||||||
|
Ui::InfiniteRadialAnimation radial;
|
||||||
|
Animation fading;
|
||||||
|
base::Timer timer;
|
||||||
|
|
||||||
|
bool resumeOnCallEnd = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
OverlayWidget::Streamed::Streamed(
|
OverlayWidget::Streamed::Streamed(
|
||||||
not_null<Data::Session*> owner,
|
not_null<Data::Session*> owner,
|
||||||
std::unique_ptr<Streaming::Loader> loader,
|
std::unique_ptr<Streaming::Loader> loader,
|
||||||
QWidget *controlsParent,
|
QWidget *controlsParent,
|
||||||
not_null<PlaybackControls::Delegate*> controlsDelegate)
|
not_null<PlaybackControls::Delegate*> controlsDelegate,
|
||||||
|
AnimationCallbacks loadingCallbacks)
|
||||||
: player(owner, std::move(loader))
|
: player(owner, std::move(loader))
|
||||||
, controls(controlsParent, controlsDelegate) {
|
, controls(controlsParent, controlsDelegate)
|
||||||
|
, radial(std::move(loadingCallbacks), st::mediaviewStreamingRadial) {
|
||||||
}
|
}
|
||||||
|
|
||||||
OverlayWidget::OverlayWidget()
|
OverlayWidget::OverlayWidget()
|
||||||
|
@ -195,11 +209,13 @@ OverlayWidget::OverlayWidget()
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
subscribe(Auth().calls().currentCallChanged(), [this](Calls::Call *call) {
|
subscribe(Auth().calls().currentCallChanged(), [this](Calls::Call *call) {
|
||||||
if (call
|
if (!_streamed) {
|
||||||
&& _streamed
|
return;
|
||||||
&& !_streamed->player.paused()
|
}
|
||||||
&& !_streamed->player.finished()) {
|
if (call) {
|
||||||
playbackPauseResume();
|
playbackPauseOnCall();
|
||||||
|
} else {
|
||||||
|
playbackResumeOnCall();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
subscribe(Auth().documentUpdated, [this](DocumentData *document) {
|
subscribe(Auth().documentUpdated, [this](DocumentData *document) {
|
||||||
|
@ -644,6 +660,12 @@ void OverlayWidget::step_state(crl::time ms, bool timer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OverlayWidget::step_waiting(crl::time ms, bool timer) {
|
||||||
|
if (timer && !anim::Disabled()) {
|
||||||
|
update(radialRect());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OverlayWidget::updateCursor() {
|
void OverlayWidget::updateCursor() {
|
||||||
setCursor(_controlsState == ControlsHidden
|
setCursor(_controlsState == ControlsHidden
|
||||||
? Qt::BlankCursor
|
? Qt::BlankCursor
|
||||||
|
@ -665,7 +687,7 @@ float64 OverlayWidget::radialProgress() const {
|
||||||
|
|
||||||
bool OverlayWidget::radialLoading() const {
|
bool OverlayWidget::radialLoading() const {
|
||||||
if (_doc) {
|
if (_doc) {
|
||||||
return _doc->loading();
|
return _doc->loading() && !_streamed;
|
||||||
} else if (_photo) {
|
} else if (_photo) {
|
||||||
return _photo->large()->loading();
|
return _photo->large()->loading();
|
||||||
}
|
}
|
||||||
|
@ -695,7 +717,7 @@ crl::time OverlayWidget::radialTimeShift() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::step_radial(crl::time ms, bool timer) {
|
void OverlayWidget::step_radial(crl::time ms, bool timer) {
|
||||||
if (!_doc && !_photo) {
|
if ((!_doc && !_photo) || _streamed) {
|
||||||
_radial.stop();
|
_radial.stop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -911,7 +933,7 @@ void OverlayWidget::onScreenResized(int screen) {
|
||||||
}
|
}
|
||||||
if (!ignore) {
|
if (!ignore) {
|
||||||
moveToScreen();
|
moveToScreen();
|
||||||
auto item = (_msgid ? App::histItemById(_msgid) : nullptr);
|
const auto item = App::histItemById(_msgid);
|
||||||
if (_photo) {
|
if (_photo) {
|
||||||
displayPhoto(_photo, item);
|
displayPhoto(_photo, item);
|
||||||
} else if (_doc) {
|
} else if (_doc) {
|
||||||
|
@ -921,7 +943,7 @@ void OverlayWidget::onScreenResized(int screen) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::onToMessage() {
|
void OverlayWidget::onToMessage() {
|
||||||
if (auto item = _msgid ? App::histItemById(_msgid) : 0) {
|
if (const auto item = App::histItemById(_msgid)) {
|
||||||
close();
|
close();
|
||||||
Ui::showPeerHistoryAtItem(item);
|
Ui::showPeerHistoryAtItem(item);
|
||||||
}
|
}
|
||||||
|
@ -1873,17 +1895,36 @@ void OverlayWidget::initStreaming() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::initStreamingThumbnail() {
|
void OverlayWidget::initStreamingThumbnail() {
|
||||||
if (!_doc->hasThumbnail()) {
|
Expects(_doc != nullptr);
|
||||||
|
|
||||||
|
const auto good = _doc->goodThumbnail();
|
||||||
|
const auto useGood = (good && good->loaded());
|
||||||
|
const auto thumb = _doc->thumbnail();
|
||||||
|
const auto useThumb = (thumb && thumb->loaded());
|
||||||
|
const auto blurred = _doc->thumbnailInline();
|
||||||
|
if (!useGood && !thumb && !blurred) {
|
||||||
|
return;
|
||||||
|
} else if (_doc->dimensions.isEmpty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_doc->dimensions.width() && _doc->dimensions.height()) {
|
const auto w = _doc->dimensions.width();
|
||||||
auto w = _doc->dimensions.width();
|
const auto h = _doc->dimensions.height();
|
||||||
auto h = _doc->dimensions.height();
|
const auto options = VideoThumbOptions(_doc);
|
||||||
_current = _doc->thumbnail()->pixNoCache(fileOrigin(), w, h, VideoThumbOptions(_doc), w / cIntRetinaFactor(), h / cIntRetinaFactor());
|
const auto goodOptions = (options & ~Images::Option::Blurred);
|
||||||
_current.setDevicePixelRatio(cRetinaFactor());
|
_current = (useGood
|
||||||
} else {
|
? good
|
||||||
_current = _doc->thumbnail()->pixNoCache(fileOrigin(), _doc->thumbnail()->width(), _doc->thumbnail()->height(), VideoThumbOptions(_doc), st::mediaviewFileIconSize, st::mediaviewFileIconSize);
|
: useThumb
|
||||||
}
|
? thumb
|
||||||
|
: blurred
|
||||||
|
? blurred
|
||||||
|
: Image::BlankMedia().get())->pixNoCache(
|
||||||
|
fileOrigin(),
|
||||||
|
w,
|
||||||
|
h,
|
||||||
|
useGood ? goodOptions : options,
|
||||||
|
w / cIntRetinaFactor(),
|
||||||
|
h / cIntRetinaFactor());
|
||||||
|
_current.setDevicePixelRatio(cRetinaFactor());
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::createStreamingObjects() {
|
void OverlayWidget::createStreamingObjects() {
|
||||||
|
@ -1891,7 +1932,8 @@ void OverlayWidget::createStreamingObjects() {
|
||||||
&_doc->owner(),
|
&_doc->owner(),
|
||||||
_doc->createStreamingLoader(fileOrigin()),
|
_doc->createStreamingLoader(fileOrigin()),
|
||||||
this,
|
this,
|
||||||
static_cast<PlaybackControls::Delegate *>(this));
|
static_cast<PlaybackControls::Delegate*>(this),
|
||||||
|
animation(this, &OverlayWidget::step_waiting));
|
||||||
|
|
||||||
if (videoIsGifv()) {
|
if (videoIsGifv()) {
|
||||||
_streamed->controls.hide();
|
_streamed->controls.hide();
|
||||||
|
@ -1901,27 +1943,61 @@ void OverlayWidget::createStreamingObjects() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OverlayWidget::validateStreamedGoodThumbnail() {
|
||||||
|
Expects(_streamed != nullptr);
|
||||||
|
Expects(_doc != nullptr);
|
||||||
|
|
||||||
|
const auto good = _doc->goodThumbnail();
|
||||||
|
const auto &image = _streamed->info.video.cover;
|
||||||
|
if (image.isNull() || (good && good->loaded()) || _doc->uploading()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
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(
|
||||||
|
base::duplicate(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) {
|
void OverlayWidget::handleStreamingUpdate(Streaming::Update &&update) {
|
||||||
using namespace Streaming;
|
using namespace Streaming;
|
||||||
|
|
||||||
update.data.match([&](Information &update) {
|
update.data.match([&](Information &update) {
|
||||||
_streamed->info = std::move(update);
|
_streamed->info = std::move(update);
|
||||||
|
validateStreamedGoodThumbnail();
|
||||||
this->update(contentRect());
|
this->update(contentRect());
|
||||||
}, [&](PreloadedVideo &update) {
|
playbackWaitingChange(false);
|
||||||
|
}, [&](const PreloadedVideo &update) {
|
||||||
_streamed->info.video.state.receivedTill = update.till;
|
_streamed->info.video.state.receivedTill = update.till;
|
||||||
//updatePlaybackState();
|
//updatePlaybackState();
|
||||||
}, [&](UpdateVideo &update) {
|
}, [&](const UpdateVideo &update) {
|
||||||
_streamed->info.video.state.position = update.position;
|
_streamed->info.video.state.position = update.position;
|
||||||
this->update(contentRect());
|
this->update(contentRect());
|
||||||
Core::App().updateNonIdle();
|
Core::App().updateNonIdle();
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
}, [&](PreloadedAudio &update) {
|
}, [&](const PreloadedAudio &update) {
|
||||||
_streamed->info.audio.state.receivedTill = update.till;
|
_streamed->info.audio.state.receivedTill = update.till;
|
||||||
//updatePlaybackState();
|
//updatePlaybackState();
|
||||||
}, [&](UpdateAudio & update) {
|
}, [&](const UpdateAudio &update) {
|
||||||
_streamed->info.audio.state.position = update.position;
|
_streamed->info.audio.state.position = update.position;
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
}, [&](WaitingForData) {
|
}, [&](const WaitingForData &update) {
|
||||||
|
playbackWaitingChange(update.waiting);
|
||||||
}, [&](MutedByOther) {
|
}, [&](MutedByOther) {
|
||||||
}, [&](Finished) {
|
}, [&](Finished) {
|
||||||
const auto finishTrack = [](Media::Streaming::TrackState &state) {
|
const auto finishTrack = [](Media::Streaming::TrackState &state) {
|
||||||
|
@ -1934,6 +2010,43 @@ void OverlayWidget::handleStreamingUpdate(Streaming::Update &&update) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::handleStreamingError(Streaming::Error &&error) {
|
void OverlayWidget::handleStreamingError(Streaming::Error &&error) {
|
||||||
|
playbackWaitingChange(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
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() {
|
void OverlayWidget::initThemePreview() {
|
||||||
|
@ -2026,13 +2139,16 @@ void OverlayWidget::playbackControlsFromFullScreen() {
|
||||||
void OverlayWidget::playbackPauseResume() {
|
void OverlayWidget::playbackPauseResume() {
|
||||||
Expects(_streamed != nullptr);
|
Expects(_streamed != nullptr);
|
||||||
|
|
||||||
|
_streamed->resumeOnCallEnd = false;
|
||||||
if (const auto item = App::histItemById(_msgid)) {
|
if (const auto item = App::histItemById(_msgid)) {
|
||||||
if (_streamed->player.failed()) {
|
if (_streamed->player.failed()) {
|
||||||
displayDocument(_doc, item);
|
displayDocument(_doc, item);
|
||||||
} else if (_streamed->player.finished()) {
|
} else if (_streamed->player.finished()) {
|
||||||
restartAtSeekPosition(0);
|
restartAtSeekPosition(0);
|
||||||
|
} else if (_streamed->player.paused()) {
|
||||||
|
_streamed->player.resume();
|
||||||
} else {
|
} else {
|
||||||
togglePauseResume();
|
_streamed->player.pause();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clearStreaming();
|
clearStreaming();
|
||||||
|
@ -2041,32 +2157,28 @@ void OverlayWidget::playbackPauseResume() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::togglePauseResume() {
|
|
||||||
Expects(_streamed != nullptr);
|
|
||||||
|
|
||||||
if (_streamed->player.paused()) {
|
|
||||||
_streamed->player.resume();
|
|
||||||
} else {
|
|
||||||
_streamed->player.pause();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void OverlayWidget::restartAtSeekPosition(crl::time position) {
|
void OverlayWidget::restartAtSeekPosition(crl::time position) {
|
||||||
Expects(_streamed != nullptr);
|
Expects(_streamed != nullptr);
|
||||||
|
|
||||||
_autoplayVideoDocument = _doc;
|
_autoplayVideoDocument = _doc;
|
||||||
|
|
||||||
if (_current.isNull() && videoShown()) {
|
if (videoShown()) {
|
||||||
|
_streamed->info.video.cover = videoFrame();
|
||||||
_current = Images::PixmapFast(videoFrame());
|
_current = Images::PixmapFast(videoFrame());
|
||||||
|
update(contentRect());
|
||||||
}
|
}
|
||||||
auto options = Streaming::PlaybackOptions();
|
auto options = Streaming::PlaybackOptions();
|
||||||
options.position = position;
|
options.position = position;
|
||||||
_streamed->player.play(options);
|
_streamed->player.play(options);
|
||||||
|
|
||||||
|
Media::Player::instance()->pause(AudioMsgId::Type::Voice);
|
||||||
|
Media::Player::instance()->pause(AudioMsgId::Type::Song);
|
||||||
|
|
||||||
_streamed->info.audio.state.position
|
_streamed->info.audio.state.position
|
||||||
= _streamed->info.video.state.position
|
= _streamed->info.video.state.position
|
||||||
= position;
|
= position;
|
||||||
updatePlaybackState();
|
updatePlaybackState();
|
||||||
|
playbackWaitingChange(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::playbackControlsSeekProgress(crl::time position) {
|
void OverlayWidget::playbackControlsSeekProgress(crl::time position) {
|
||||||
|
@ -2107,6 +2219,25 @@ void OverlayWidget::playbackToggleFullScreen() {
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OverlayWidget::playbackPauseOnCall() {
|
||||||
|
Expects(_streamed != nullptr);
|
||||||
|
|
||||||
|
if (_streamed->player.finished() || _streamed->player.paused()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
_streamed->player.pause();
|
||||||
|
_streamed->resumeOnCallEnd = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void OverlayWidget::playbackResumeOnCall() {
|
||||||
|
Expects(_streamed != nullptr);
|
||||||
|
|
||||||
|
if (_streamed->resumeOnCallEnd) {
|
||||||
|
_streamed->resumeOnCallEnd = false;
|
||||||
|
_streamed->player.resume();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void OverlayWidget::updatePlaybackState() {
|
void OverlayWidget::updatePlaybackState() {
|
||||||
Expects(_streamed != nullptr);
|
Expects(_streamed != nullptr);
|
||||||
|
|
||||||
|
@ -2464,9 +2595,34 @@ void OverlayWidget::checkGroupThumbsAnimation() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void OverlayWidget::paintDocRadialLoading(Painter &p, bool radial, float64 radialOpacity) {
|
void OverlayWidget::paintDocRadialLoading(Painter &p, bool radial, float64 radialOpacity) {
|
||||||
float64 o = overLevel(OverIcon);
|
QRect inner(QPoint(_docIconRect.x() + ((_docIconRect.width() - st::radialSize.width()) / 2), _docIconRect.y() + ((_docIconRect.height() - st::radialSize.height()) / 2)), st::radialSize);
|
||||||
if (radial || (_doc && !_doc->loaded() && !_streamed)) {
|
|
||||||
QRect inner(QPoint(_docIconRect.x() + ((_docIconRect.width() - st::radialSize.width()) / 2), _docIconRect.y() + ((_docIconRect.height() - st::radialSize.height()) / 2)), st::radialSize);
|
if (_streamed) {
|
||||||
|
const auto ms = crl::now();
|
||||||
|
_streamed->radial.step(ms);
|
||||||
|
if (!_streamed->radial.animating()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto fade = _streamed->fading.current(
|
||||||
|
ms,
|
||||||
|
_streamed->waiting ? 1. : 0.);
|
||||||
|
if (fade == 0.) {
|
||||||
|
if (!_streamed->waiting) {
|
||||||
|
_streamed->radial.stop(anim::type::instant);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
p.setOpacity(fade);
|
||||||
|
p.setPen(Qt::NoPen);
|
||||||
|
p.setBrush(st::msgDateImgBg);
|
||||||
|
{
|
||||||
|
PainterHighQualityEnabler hq(p);
|
||||||
|
p.drawEllipse(inner);
|
||||||
|
}
|
||||||
|
QRect arc(inner.marginsRemoved(QMargins(st::radialLine, st::radialLine, st::radialLine, st::radialLine)));
|
||||||
|
_streamed->radial.draw(p, arc.topLeft(), arc.size(), width());// , st::radialLine, st::radialFg);
|
||||||
|
} else if (radial || (_doc && !_doc->loaded())) {
|
||||||
|
float64 o = overLevel(OverIcon);
|
||||||
|
|
||||||
p.setPen(Qt::NoPen);
|
p.setPen(Qt::NoPen);
|
||||||
p.setOpacity(_doc->loaded() ? radialOpacity : 1.);
|
p.setOpacity(_doc->loaded() ? radialOpacity : 1.);
|
||||||
|
@ -2478,12 +2634,12 @@ void OverlayWidget::paintDocRadialLoading(Painter &p, bool radial, float64 radia
|
||||||
}
|
}
|
||||||
|
|
||||||
p.setOpacity(1.);
|
p.setOpacity(1.);
|
||||||
auto icon = ([radial, this]() -> const style::icon* {
|
auto icon = [&]() -> const style::icon* {
|
||||||
if (radial || _doc->loading()) {
|
if (radial || _doc->loading()) {
|
||||||
return &st::historyFileThumbCancel;
|
return &st::historyFileThumbCancel;
|
||||||
}
|
}
|
||||||
return &st::historyFileThumbDownload;
|
return &st::historyFileThumbDownload;
|
||||||
})();
|
}();
|
||||||
if (icon) {
|
if (icon) {
|
||||||
icon->paintInCenter(p, inner);
|
icon->paintInCenter(p, inner);
|
||||||
}
|
}
|
||||||
|
@ -2549,15 +2705,17 @@ void OverlayWidget::keyPressEvent(QKeyEvent *e) {
|
||||||
const auto ctrl = e->modifiers().testFlag(Qt::ControlModifier);
|
const auto ctrl = e->modifiers().testFlag(Qt::ControlModifier);
|
||||||
if (_streamed) {
|
if (_streamed) {
|
||||||
// Ctrl + F for full screen toggle is in eventFilter().
|
// Ctrl + F for full screen toggle is in eventFilter().
|
||||||
const auto toggleFull = (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) && (e->modifiers().testFlag(Qt::AltModifier) || ctrl);
|
const auto toggleFull = (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return)
|
||||||
|
&& (e->modifiers().testFlag(Qt::AltModifier) || ctrl);
|
||||||
if (toggleFull) {
|
if (toggleFull) {
|
||||||
playbackToggleFullScreen();
|
playbackToggleFullScreen();
|
||||||
return;
|
return;
|
||||||
|
} else if (e->key() == Qt::Key_Space) {
|
||||||
|
playbackPauseResume();
|
||||||
|
return;
|
||||||
} else if (_fullScreenVideo) {
|
} else if (_fullScreenVideo) {
|
||||||
if (e->key() == Qt::Key_Escape) {
|
if (e->key() == Qt::Key_Escape) {
|
||||||
playbackToggleFullScreen();
|
playbackToggleFullScreen();
|
||||||
} else if (e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return || e->key() == Qt::Key_Space) {
|
|
||||||
playbackPauseResume();
|
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,6 +161,9 @@ private:
|
||||||
void playbackControlsFromFullScreen() override;
|
void playbackControlsFromFullScreen() override;
|
||||||
void playbackPauseResume();
|
void playbackPauseResume();
|
||||||
void playbackToggleFullScreen();
|
void playbackToggleFullScreen();
|
||||||
|
void playbackPauseOnCall();
|
||||||
|
void playbackResumeOnCall();
|
||||||
|
void playbackWaitingChange(bool waiting);
|
||||||
|
|
||||||
void updateOver(QPoint mpos);
|
void updateOver(QPoint mpos);
|
||||||
void moveToScreen();
|
void moveToScreen();
|
||||||
|
@ -227,7 +230,6 @@ private:
|
||||||
|
|
||||||
void updatePlaybackState();
|
void updatePlaybackState();
|
||||||
void restartAtSeekPosition(crl::time position);
|
void restartAtSeekPosition(crl::time position);
|
||||||
void togglePauseResume();
|
|
||||||
|
|
||||||
void refreshClipControllerGeometry();
|
void refreshClipControllerGeometry();
|
||||||
void refreshCaptionGeometry();
|
void refreshCaptionGeometry();
|
||||||
|
@ -237,6 +239,7 @@ private:
|
||||||
void createStreamingObjects();
|
void createStreamingObjects();
|
||||||
void handleStreamingUpdate(Streaming::Update &&update);
|
void handleStreamingUpdate(Streaming::Update &&update);
|
||||||
void handleStreamingError(Streaming::Error &&error);
|
void handleStreamingError(Streaming::Error &&error);
|
||||||
|
void validateStreamedGoodThumbnail();
|
||||||
|
|
||||||
void initThemePreview();
|
void initThemePreview();
|
||||||
void destroyThemePreview();
|
void destroyThemePreview();
|
||||||
|
@ -259,6 +262,7 @@ private:
|
||||||
|
|
||||||
void step_state(crl::time ms, bool timer);
|
void step_state(crl::time ms, bool timer);
|
||||||
void step_radial(crl::time ms, bool timer);
|
void step_radial(crl::time ms, bool timer);
|
||||||
|
void step_waiting(crl::time ms, bool timer);
|
||||||
|
|
||||||
void zoomIn();
|
void zoomIn();
|
||||||
void zoomOut();
|
void zoomOut();
|
||||||
|
|
|
@ -187,6 +187,11 @@ mediaviewGroupWidthMax: 160px;
|
||||||
mediaviewGroupSkip: 3px;
|
mediaviewGroupSkip: 3px;
|
||||||
mediaviewGroupSkipCurrent: 12px;
|
mediaviewGroupSkipCurrent: 12px;
|
||||||
|
|
||||||
|
mediaviewStreamingRadial: InfiniteRadialAnimation(defaultInfiniteRadialAnimation) {
|
||||||
|
color: radialFg;
|
||||||
|
thickness: radialLine;
|
||||||
|
}
|
||||||
|
|
||||||
themePreviewSize: size(903px, 584px);
|
themePreviewSize: size(903px, 584px);
|
||||||
themePreviewBg: windowBg;
|
themePreviewBg: windowBg;
|
||||||
themePreviewOverlayOpacity: 0.8;
|
themePreviewOverlayOpacity: 0.8;
|
||||||
|
|
|
@ -693,12 +693,12 @@ void Voice::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||||
}
|
}
|
||||||
|
|
||||||
auto icon = [&] {
|
auto icon = [&] {
|
||||||
if (showPause) {
|
if (_data->loading() || _data->uploading()) {
|
||||||
|
return &(selected ? _st.songCancelSelected : _st.songCancel);
|
||||||
|
} else if (showPause) {
|
||||||
return &(selected ? _st.songPauseSelected : _st.songPause);
|
return &(selected ? _st.songPauseSelected : _st.songPause);
|
||||||
} else if (_status.size() < 0 || _status.size() == FileStatusSizeLoaded) {
|
} else if (_status.size() < 0 || _status.size() == FileStatusSizeLoaded) {
|
||||||
return &(selected ? _st.songPlaySelected : _st.songPlay);
|
return &(selected ? _st.songPlaySelected : _st.songPlay);
|
||||||
} else if (_data->loading()) {
|
|
||||||
return &(selected ? _st.songCancelSelected : _st.songCancel);
|
|
||||||
}
|
}
|
||||||
return &(selected ? _st.songDownloadSelected : _st.songDownload);
|
return &(selected ? _st.songDownloadSelected : _st.songDownload);
|
||||||
}();
|
}();
|
||||||
|
@ -962,10 +962,10 @@ void Document::paint(Painter &p, const QRect &clip, TextSelection selection, con
|
||||||
}
|
}
|
||||||
|
|
||||||
auto icon = [&] {
|
auto icon = [&] {
|
||||||
if (showPause) {
|
if (_data->loading() || _data->uploading()) {
|
||||||
return &(selected ? _st.songPauseSelected : _st.songPause);
|
|
||||||
} else if (_data->loading() || _data->uploading()) {
|
|
||||||
return &(selected ? _st.songCancelSelected : _st.songCancel);
|
return &(selected ? _st.songCancelSelected : _st.songCancel);
|
||||||
|
} else if (showPause) {
|
||||||
|
return &(selected ? _st.songPauseSelected : _st.songPause);
|
||||||
} else if (_data->canBePlayed()) {
|
} else if (_data->canBePlayed()) {
|
||||||
return &(selected ? _st.songPlaySelected : _st.songPlay);
|
return &(selected ? _st.songPlaySelected : _st.songPlay);
|
||||||
}
|
}
|
||||||
|
@ -1107,7 +1107,7 @@ TextState Document::getState(
|
||||||
? _cancell
|
? _cancell
|
||||||
: _data->canBePlayed()
|
: _data->canBePlayed()
|
||||||
? _openl
|
? _openl
|
||||||
: _openl;
|
: _savel;
|
||||||
return { parent(), link };
|
return { parent(), link };
|
||||||
}
|
}
|
||||||
const auto namerect = rtlrect(
|
const auto namerect = rtlrect(
|
||||||
|
@ -1137,10 +1137,10 @@ TextState Document::getState(
|
||||||
_width);
|
_width);
|
||||||
|
|
||||||
if (rthumb.contains(point)) {
|
if (rthumb.contains(point)) {
|
||||||
const auto link = loaded
|
const auto link = (_data->loading() || _data->uploading())
|
||||||
? _openl
|
|
||||||
: (_data->loading() || _data->uploading())
|
|
||||||
? _cancell
|
? _cancell
|
||||||
|
: loaded
|
||||||
|
? _openl
|
||||||
: _savel;
|
: _savel;
|
||||||
return { parent(), link };
|
return { parent(), link };
|
||||||
}
|
}
|
||||||
|
|
|
@ -201,7 +201,7 @@ void Uploader::upload(
|
||||||
std::move(file->thumb));
|
std::move(file->thumb));
|
||||||
document->uploadingData = std::make_unique<Data::UploadState>(
|
document->uploadingData = std::make_unique<Data::UploadState>(
|
||||||
document->size);
|
document->size);
|
||||||
document->setGoodThumbnail(
|
document->setGoodThumbnailOnUpload(
|
||||||
std::move(file->goodThumbnail),
|
std::move(file->goodThumbnail),
|
||||||
std::move(file->goodThumbnailBytes));
|
std::move(file->goodThumbnailBytes));
|
||||||
if (!file->content.isEmpty()) {
|
if (!file->content.isEmpty()) {
|
||||||
|
|
|
@ -127,9 +127,9 @@ void InfiniteRadialAnimation::start(crl::time skip) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void InfiniteRadialAnimation::stop() {
|
void InfiniteRadialAnimation::stop(anim::type animated) {
|
||||||
const auto now = crl::now();
|
const auto now = crl::now();
|
||||||
if (anim::Disabled()) {
|
if (anim::Disabled() || animated == anim::type::instant) {
|
||||||
_workFinished = now;
|
_workFinished = now;
|
||||||
}
|
}
|
||||||
if (!_workFinished) {
|
if (!_workFinished) {
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
void start(crl::time skip = 0);
|
void start(crl::time skip = 0);
|
||||||
void stop();
|
void stop(anim::type animated = anim::type::normal);
|
||||||
|
|
||||||
void step(crl::time ms);
|
void step(crl::time ms);
|
||||||
void step() {
|
void step() {
|
||||||
|
|
Loading…
Reference in New Issue