mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-16 14:17:12 +02:00
Support displaying of video spoilers.
This commit is contained in:
parent
ae3659d15b
commit
3a38497c4c
2 changed files with 117 additions and 56 deletions
|
@ -92,6 +92,10 @@ Gif::Gif(
|
|||
setDocumentLinks(_data, realParent);
|
||||
setStatusSize(Ui::FileStatusSizeReady);
|
||||
|
||||
if (_spoiler) {
|
||||
createSpoilerLink(_spoiler.get());
|
||||
}
|
||||
|
||||
refreshCaption();
|
||||
if ((_dataMedia = _data->activeMediaView())) {
|
||||
dataMediaCreated();
|
||||
|
@ -328,9 +332,59 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
&& canBePlayed
|
||||
&& CanPlayInline(_data);
|
||||
const auto activeRoundPlaying = activeRoundStreamed();
|
||||
|
||||
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
||||
auto captionw = paintw - st::msgPadding.left() - st::msgPadding.right();
|
||||
const bool bubble = _parent->hasBubble();
|
||||
const auto outbg = context.outbg;
|
||||
const auto inWebPage = (_parent->media() != this);
|
||||
const auto isRound = _data->isVideoMessage();
|
||||
|
||||
const auto rounding = inWebPage
|
||||
? std::optional<Ui::BubbleRounding>()
|
||||
: adjustedBubbleRoundingWithCaption(_caption);
|
||||
if (bubble) {
|
||||
if (!_caption.isEmpty()) {
|
||||
painth -= st::mediaCaptionSkip + _caption.countHeight(captionw);
|
||||
if (isBubbleBottom()) {
|
||||
painth -= st::msgPadding.bottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto usex = 0, usew = paintw;
|
||||
const auto unwrapped = isUnwrapped();
|
||||
const auto via = unwrapped ? item->Get<HistoryMessageVia>() : nullptr;
|
||||
const auto reply = unwrapped ? _parent->displayedReply() : nullptr;
|
||||
const auto forwarded = unwrapped ? item->Get<HistoryMessageForwarded>() : nullptr;
|
||||
const auto rightAligned = unwrapped
|
||||
&& outbg
|
||||
&& !_parent->delegate()->elementIsChatWide();
|
||||
if (via || reply || forwarded) {
|
||||
usew = maxWidth() - additionalWidth(via, reply, forwarded);
|
||||
if (rightAligned) {
|
||||
usex = width() - usew;
|
||||
}
|
||||
}
|
||||
if (isRound) {
|
||||
accumulate_min(usew, painth);
|
||||
}
|
||||
if (rtl()) usex = width() - usex - usew;
|
||||
|
||||
QRect rthumb(style::rtlrect(usex + paintx, painty, usew, painth, width()));
|
||||
|
||||
const auto revealed = (!isRound && _spoiler)
|
||||
? _spoiler->revealAnimation.value(_spoiler->revealed ? 1. : 0.)
|
||||
: 1.;
|
||||
const auto fullHiddenBySpoiler = (revealed == 0.);
|
||||
if (revealed < 1.) {
|
||||
validateSpoilerImageCache(rthumb.size(), rounding);
|
||||
}
|
||||
|
||||
const auto startPlay = autoplay
|
||||
&& !_streamed
|
||||
&& !activeRoundPlaying;
|
||||
&& !activeRoundPlaying
|
||||
&& !fullHiddenBySpoiler;
|
||||
if (startPlay) {
|
||||
const_cast<Gif*>(this)->playAnimation(true);
|
||||
} else {
|
||||
|
@ -339,13 +393,6 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
const auto streamingMode = _streamed || activeRoundPlaying || autoplay;
|
||||
const auto activeOwnPlaying = activeOwnStreamed();
|
||||
|
||||
auto paintx = 0, painty = 0, paintw = width(), painth = height();
|
||||
auto captionw = paintw - st::msgPadding.left() - st::msgPadding.right();
|
||||
const bool bubble = _parent->hasBubble();
|
||||
const auto outbg = context.outbg;
|
||||
const auto inWebPage = (_parent->media() != this);
|
||||
const auto isRound = _data->isVideoMessage();
|
||||
const auto unwrapped = isUnwrapped();
|
||||
auto displayMute = false;
|
||||
const auto streamed = activeRoundPlaying
|
||||
? activeRoundPlaying
|
||||
|
@ -372,38 +419,6 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
const auto radial = isRadialAnimation()
|
||||
|| (streamedForWaiting && streamedForWaiting->waitingShown());
|
||||
|
||||
const auto rounding = inWebPage
|
||||
? std::optional<Ui::BubbleRounding>()
|
||||
: adjustedBubbleRoundingWithCaption(_caption);
|
||||
if (bubble) {
|
||||
if (!_caption.isEmpty()) {
|
||||
painth -= st::mediaCaptionSkip + _caption.countHeight(captionw);
|
||||
if (isBubbleBottom()) {
|
||||
painth -= st::msgPadding.bottom();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
auto usex = 0, usew = paintw;
|
||||
const auto via = unwrapped ? item->Get<HistoryMessageVia>() : nullptr;
|
||||
const auto reply = unwrapped ? _parent->displayedReply() : nullptr;
|
||||
const auto forwarded = unwrapped ? item->Get<HistoryMessageForwarded>() : nullptr;
|
||||
const auto rightAligned = unwrapped
|
||||
&& outbg
|
||||
&& !_parent->delegate()->elementIsChatWide();
|
||||
if (via || reply || forwarded) {
|
||||
usew = maxWidth() - additionalWidth(via, reply, forwarded);
|
||||
if (rightAligned) {
|
||||
usex = width() - usew;
|
||||
}
|
||||
}
|
||||
if (isRound) {
|
||||
accumulate_min(usew, painth);
|
||||
}
|
||||
if (rtl()) usex = width() - usex - usew;
|
||||
|
||||
QRect rthumb(style::rtlrect(usex + paintx, painty, usew, painth, width()));
|
||||
|
||||
if (!bubble && !unwrapped) {
|
||||
Assert(rounding.has_value());
|
||||
fillImageShadow(p, rthumb, *rounding, context);
|
||||
|
@ -411,7 +426,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
|
||||
const auto skipDrawingContent = context.skipDrawingParts
|
||||
== PaintContext::SkipDrawingParts::Content;
|
||||
if (streamed && !skipDrawingContent) {
|
||||
if (streamed && !skipDrawingContent && !fullHiddenBySpoiler) {
|
||||
auto paused = context.paused;
|
||||
auto request = ::Media::Streaming::FrameRequest{
|
||||
.outer = QSize(usew, painth) * cIntRetinaFactor(),
|
||||
|
@ -474,18 +489,17 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
p.setOpacity(1.);
|
||||
}
|
||||
}
|
||||
} else if (!skipDrawingContent) {
|
||||
} else if (!skipDrawingContent && !fullHiddenBySpoiler) {
|
||||
ensureDataMediaCreated();
|
||||
validateThumbCache({ usew, painth }, isRound, rounding);
|
||||
p.drawImage(rthumb, _thumbCache);
|
||||
}
|
||||
|
||||
if (!isRound && _spoiler) {
|
||||
fillImageSpoiler(
|
||||
p,
|
||||
_spoiler.get(),
|
||||
rthumb,
|
||||
context);
|
||||
if (!isRound && revealed < 1.) {
|
||||
p.setOpacity(1. - revealed);
|
||||
p.drawImage(rthumb.topLeft(), _spoiler->background);
|
||||
fillImageSpoiler(p, _spoiler.get(), rthumb, context);
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
if (context.selected()) {
|
||||
if (isRound) {
|
||||
|
@ -498,13 +512,14 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
if (radial
|
||||
|| (!streamingMode
|
||||
&& ((!loaded && !_data->loading()) || !autoplay))) {
|
||||
const auto radialOpacity = (item->isSending() || _data->uploading())
|
||||
const auto opacity = (item->isSending() || _data->uploading())
|
||||
? 1.
|
||||
: streamedForWaiting
|
||||
? streamedForWaiting->waitingOpacity()
|
||||
: (radial && loaded)
|
||||
? _animation->radial.opacity()
|
||||
: 1.;
|
||||
const auto radialOpacity = opacity * revealed;
|
||||
const auto innerSize = st::msgFileLayout.thumbSize;
|
||||
auto inner = QRect(rthumb.x() + (rthumb.width() - innerSize) / 2, rthumb.y() + (rthumb.height() - innerSize) / 2, innerSize, innerSize);
|
||||
p.setPen(Qt::NoPen);
|
||||
|
@ -542,7 +557,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
if (icon) {
|
||||
icon->paintInCenter(p, inner);
|
||||
}
|
||||
p.setOpacity(1);
|
||||
p.setOpacity(revealed);
|
||||
if (radial) {
|
||||
QRect rinner(inner.marginsRemoved(QMargins(st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine, st::msgFileRadialLine)));
|
||||
if (streamedForWaiting && !_data->uploading()) {
|
||||
|
@ -562,6 +577,7 @@ void Gif::draw(Painter &p, const PaintContext &context) const {
|
|||
sti->historyFileThumbRadialFg);
|
||||
}
|
||||
}
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
if (displayMute) {
|
||||
auto muteRect = style::rtlrect(rthumb.x() + (rthumb.width() - st::historyVideoMessageMuteSize) / 2, rthumb.y() + st::msgDateImgDelta, st::historyVideoMessageMuteSize, st::historyVideoMessageMuteSize, width());
|
||||
|
@ -808,6 +824,26 @@ QImage Gif::prepareThumbCache(QSize outer) const {
|
|||
blurFromLarge ? large : blurred);
|
||||
}
|
||||
|
||||
void Gif::validateSpoilerImageCache(
|
||||
QSize outer,
|
||||
std::optional<Ui::BubbleRounding> rounding) const {
|
||||
Expects(_spoiler != nullptr);
|
||||
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
if (_spoiler->background.size() == (outer * ratio)
|
||||
&& _spoiler->backgroundRounding == rounding) {
|
||||
return;
|
||||
}
|
||||
_spoiler->background = Images::Round(
|
||||
PrepareWithBlurredBackground(
|
||||
outer,
|
||||
::Media::Streaming::ExpandDecision(),
|
||||
nullptr,
|
||||
_dataMedia->thumbnailInline()),
|
||||
MediaRoundingMask(rounding));
|
||||
_spoiler->backgroundRounding = rounding;
|
||||
}
|
||||
|
||||
void Gif::drawCornerStatus(
|
||||
Painter &p,
|
||||
const PaintContext &context,
|
||||
|
@ -984,7 +1020,9 @@ TextState Gif::textState(QPoint point, StateRequest request) const {
|
|||
}
|
||||
if (QRect(usex + paintx, painty, usew, painth).contains(point)) {
|
||||
ensureDataMediaCreated();
|
||||
result.link = _data->uploading()
|
||||
result.link = (_spoiler && !_spoiler->revealed)
|
||||
? _spoiler->link
|
||||
: _data->uploading()
|
||||
? _cancell
|
||||
: _realParent->isSending()
|
||||
? nullptr
|
||||
|
@ -1105,6 +1143,15 @@ void Gif::drawGrouped(
|
|||
const auto fullFeatured = fullFeaturedGrouped(sides);
|
||||
const auto cornerDownload = fullFeatured && downloadInCorner();
|
||||
const auto canBePlayed = _dataMedia->canBePlayed(_realParent);
|
||||
|
||||
const auto revealed = _spoiler
|
||||
? _spoiler->revealAnimation.value(_spoiler->revealed ? 1. : 0.)
|
||||
: 1.;
|
||||
const auto fullHiddenBySpoiler = (revealed == 0.);
|
||||
if (revealed < 1.) {
|
||||
validateSpoilerImageCache(geometry.size(), rounding);
|
||||
}
|
||||
|
||||
const auto autoplay = fullFeatured
|
||||
&& autoplayEnabled()
|
||||
&& canBePlayed
|
||||
|
@ -1139,7 +1186,7 @@ void Gif::drawGrouped(
|
|||
const auto radial = isRadialAnimation()
|
||||
|| (streamedForWaiting && streamedForWaiting->waitingShown());
|
||||
|
||||
if (streamed) {
|
||||
if (streamed && !fullHiddenBySpoiler) {
|
||||
const auto original = sizeForAspectRatio();
|
||||
const auto originalWidth = style::ConvertScale(original.width());
|
||||
const auto originalHeight = style::ConvertScale(original.height());
|
||||
|
@ -1171,11 +1218,18 @@ void Gif::drawGrouped(
|
|||
streamed->markFrameShown();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
} else if (!fullHiddenBySpoiler) {
|
||||
validateGroupedCache(geometry, rounding, cacheKey, cache);
|
||||
p.drawPixmap(geometry, *cache);
|
||||
}
|
||||
|
||||
if (revealed < 1.) {
|
||||
p.setOpacity(1. - revealed);
|
||||
p.drawImage(geometry.topLeft(), _spoiler->background);
|
||||
fillImageSpoiler(p, _spoiler.get(), geometry, context);
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
||||
const auto overlayOpacity = context.selected()
|
||||
? (1. - highlightOpacity)
|
||||
: highlightOpacity;
|
||||
|
@ -1191,13 +1245,14 @@ void Gif::drawGrouped(
|
|||
if (radial
|
||||
|| (!streamingMode
|
||||
&& ((!loaded && !_data->loading()) || !autoplay))) {
|
||||
const auto radialOpacity = (item->isSending() || _data->uploading())
|
||||
const auto opacity = (item->isSending() || _data->uploading())
|
||||
? 1.
|
||||
: streamedForWaiting
|
||||
? streamedForWaiting->waitingOpacity()
|
||||
: (radial && loaded)
|
||||
? _animation->radial.opacity()
|
||||
: 1.;
|
||||
const auto radialOpacity = opacity * revealed;
|
||||
const auto radialSize = st::historyGroupRadialSize;
|
||||
const auto inner = QRect(
|
||||
geometry.x() + (geometry.width() - radialSize) / 2,
|
||||
|
@ -1248,7 +1303,7 @@ void Gif::drawGrouped(
|
|||
icon->paintInCenter(p, inner);
|
||||
}
|
||||
}
|
||||
p.setOpacity(1);
|
||||
p.setOpacity(revealed);
|
||||
if (radial) {
|
||||
const auto line = st::historyGroupRadialLine;
|
||||
const auto rinner = inner.marginsRemoved({ line, line, line, line });
|
||||
|
@ -1269,6 +1324,7 @@ void Gif::drawGrouped(
|
|||
sti->historyFileThumbRadialFg);
|
||||
}
|
||||
}
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
if (fullFeatured) {
|
||||
drawCornerStatus(p, context, geometry.topLeft());
|
||||
|
@ -1289,7 +1345,9 @@ TextState Gif::getStateGrouped(
|
|||
}
|
||||
}
|
||||
ensureDataMediaCreated();
|
||||
return TextState(_parent, _data->uploading()
|
||||
return TextState(_parent, (_spoiler && !_spoiler->revealed)
|
||||
? _spoiler->link
|
||||
: _data->uploading()
|
||||
? _cancell
|
||||
: _realParent->isSending()
|
||||
? nullptr
|
||||
|
|
|
@ -183,6 +183,9 @@ private:
|
|||
bool isEllipse,
|
||||
std::optional<Ui::BubbleRounding> rounding) const;
|
||||
[[nodiscard]] QImage prepareThumbCache(QSize outer) const;
|
||||
void validateSpoilerImageCache(
|
||||
QSize outer,
|
||||
std::optional<Ui::BubbleRounding> rounding) const;
|
||||
|
||||
void validateGroupedCache(
|
||||
const QRect &geometry,
|
||||
|
|
Loading…
Add table
Reference in a new issue