Show spoilers in shared media overview.

This commit is contained in:
John Preston 2022-12-27 13:10:38 +04:00
parent 2cbd2725e5
commit b4571b80d6
5 changed files with 95 additions and 22 deletions

View File

@ -761,8 +761,11 @@ void ListWidget::paintEvent(QPaintEvent *e) {
auto tillSectionIt = findSectionAfterBottom(
fromSectionIt,
clip.y() + clip.height());
auto context = ListContext {
Overview::Layout::PaintContext(ms, hasSelectedItems()),
const auto window = _controller->parentController();
const auto paused = window->isGifPausedAtLeastFor(
Window::GifPauseReason::Layer);
auto context = ListContext{
Overview::Layout::PaintContext(ms, hasSelectedItems(), paused),
&_selected,
&_dragSelected,
_dragSelectAction

View File

@ -416,18 +416,24 @@ std::unique_ptr<BaseLayout> Provider::createLayout(
return nullptr;
};
const auto getFile = [&]() -> DocumentData* {
if (auto media = item->media()) {
if (const auto media = item->media()) {
return media->document();
}
return nullptr;
};
const auto spoiler = [&] {
if (const auto media = item->media()) {
return media->hasSpoiler();
}
return false;
};
const auto &songSt = st::overviewFileLayout;
using namespace Overview::Layout;
switch (type) {
case Type::Photo:
if (const auto photo = getPhoto()) {
return std::make_unique<Photo>(delegate, item, photo);
return std::make_unique<Photo>(delegate, item, photo, spoiler());
}
return nullptr;
case Type::GIF:
@ -437,7 +443,7 @@ std::unique_ptr<BaseLayout> Provider::createLayout(
return nullptr;
case Type::Video:
if (const auto file = getFile()) {
return std::make_unique<Video>(delegate, item, file);
return std::make_unique<Video>(delegate, item, file, spoiler());
}
return nullptr;
case Type::File:

View File

@ -16,8 +16,8 @@ public:
: ms(ms)
, selecting(selecting) {
}
crl::time ms;
bool selecting;
crl::time ms = 0;
bool selecting = false;
};

View File

@ -40,6 +40,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/view/media/history_view_document.h" // DrawThumbnailAsSongCover
#include "base/unixtime.h"
#include "ui/effects/round_checkbox.h"
#include "ui/effects/spoiler_mess.h"
#include "ui/image/image.h"
#include "ui/text/format_song_document_name.h"
#include "ui/text/format_values.h"
@ -201,6 +202,7 @@ void RadialProgressItem::setDocumentLinks(
std::make_shared<DocumentOpenClickHandler>(
document,
crl::guard(this, [=](FullMsgId id) {
clearSpoiler();
delegate()->openDocument(document, id, forceOpen);
}),
context),
@ -294,13 +296,20 @@ void StatusText::setSize(int64 newSize) {
Photo::Photo(
not_null<Delegate*> delegate,
not_null<HistoryItem*> parent,
not_null<PhotoData*> photo)
not_null<PhotoData*> photo,
bool spoiler)
: ItemBase(delegate, parent)
, _data(photo)
, _link(std::make_shared<PhotoOpenClickHandler>(
photo,
crl::guard(this, [=](FullMsgId id) { delegate->openPhoto(photo, id); }),
parent->fullId())) {
crl::guard(this, [=](FullMsgId id) {
clearSpoiler();
delegate->openPhoto(photo, id);
}),
parent->fullId()))
, _spoiler(spoiler ? std::make_unique<Ui::SpoilerAnimation>([=] {
delegate->repaintItem(this);
}) : nullptr) {
if (_data->inlineThumbnailBytes().isEmpty()
&& (_data->hasExact(Data::PhotoSize::Small)
|| _data->hasExact(Data::PhotoSize::Thumbnail))) {
@ -327,8 +336,9 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const
const auto widthChanged = _pix.width() != _width * cIntRetinaFactor();
if (!_goodLoaded || widthChanged) {
ensureDataMediaCreated();
const auto good = _dataMedia->loaded()
|| (_dataMedia->image(Data::PhotoSize::Thumbnail) != nullptr);
const auto good = !_spoiler
&& (_dataMedia->loaded()
|| _dataMedia->image(Data::PhotoSize::Thumbnail));
if ((good && !_goodLoaded) || widthChanged) {
_goodLoaded = good;
_pix = QPixmap();
@ -336,8 +346,9 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const
setPixFrom(_dataMedia->image(Data::PhotoSize::Large)
? _dataMedia->image(Data::PhotoSize::Large)
: _dataMedia->image(Data::PhotoSize::Thumbnail));
} else if (const auto small = _dataMedia->image(
Data::PhotoSize::Small)) {
} else if (const auto small = _spoiler
? nullptr
: _dataMedia->image(Data::PhotoSize::Small)) {
setPixFrom(small);
} else if (const auto blurred = _dataMedia->thumbnailInline()) {
setPixFrom(blurred);
@ -351,6 +362,14 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const
p.drawPixmap(0, 0, _pix);
}
if (_spoiler) {
Ui::FillSpoilerRect(
p,
QRect(0, 0, _width, _height),
Ui::DefaultImageSpoiler().frame(
_spoiler->index(context->ms, context->paused)));
}
if (selected) {
p.fillRect(0, 0, _width, _height, st::overviewPhotoSelectOverlay);
}
@ -399,6 +418,14 @@ void Photo::ensureDataMediaCreated() const {
delegate()->registerHeavyItem(this);
}
void Photo::clearSpoiler() {
if (_spoiler) {
_spoiler = nullptr;
_pix = QPixmap();
delegate()->repaintItem(this);
}
}
void Photo::clearHeavyPart() {
_dataMedia = nullptr;
}
@ -415,10 +442,14 @@ TextState Photo::getState(
Video::Video(
not_null<Delegate*> delegate,
not_null<HistoryItem*> parent,
not_null<DocumentData*> video)
not_null<DocumentData*> video,
bool spoiler)
: RadialProgressItem(delegate, parent)
, _data(video)
, _duration(Ui::FormatDurationText(_data->getDuration())) {
, _duration(Ui::FormatDurationText(_data->getDuration()))
, _spoiler(spoiler ? std::make_unique<Ui::SpoilerAnimation>([=] {
delegate->repaintItem(this);
}) : nullptr) {
setDocumentLinks(_data);
_data->loadThumbnail(parent->fullId());
}
@ -441,8 +472,8 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
const auto selected = (selection == FullSelection);
const auto blurred = _dataMedia->thumbnailInline();
const auto thumbnail = _dataMedia->thumbnail();
const auto good = _dataMedia->goodThumbnail();
const auto thumbnail = _spoiler ? nullptr : _dataMedia->thumbnail();
const auto good = _spoiler ? nullptr : _dataMedia->goodThumbnail();
bool loaded = dataLoaded(), displayLoading = _data->displayLoading();
if (displayLoading) {
@ -485,6 +516,14 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
p.drawPixmap(0, 0, _pix);
}
if (_spoiler) {
Ui::FillSpoilerRect(
p,
QRect(0, 0, _width, _height),
Ui::DefaultImageSpoiler().frame(
_spoiler->index(context->ms, context->paused)));
}
if (selected) {
p.fillRect(QRect(0, 0, _width, _height), st::overviewPhotoSelectOverlay);
}
@ -554,6 +593,14 @@ void Video::ensureDataMediaCreated() const {
delegate()->registerHeavyItem(this);
}
void Video::clearSpoiler() {
if (_spoiler) {
_spoiler = nullptr;
_pix = QPixmap();
delegate()->repaintItem(this);
}
}
void Video::clearHeavyPart() {
_dataMedia = nullptr;
}
@ -2060,7 +2107,7 @@ void Gif::paint(
const auto pixmap = _gif->current({
.frame = frame,
.outer = r.size(),
}, /*context->paused ? 0 : */context->ms);
}, context->paused ? 0 : context->ms);
if (_thumb.isNull()) {
_thumb = pixmap;
_thumbGood = true;

View File

@ -27,6 +27,10 @@ class PhotoMedia;
class DocumentMedia;
} // namespace Data
namespace Ui {
class SpoilerAnimation;
} // namespace Ui
namespace Overview {
namespace Layout {
@ -36,9 +40,12 @@ class Delegate;
class PaintContext : public PaintContextBase {
public:
PaintContext(crl::time ms, bool selecting) : PaintContextBase(ms, selecting) {
PaintContext(crl::time ms, bool selecting, bool paused)
: PaintContextBase(ms, selecting)
, paused(paused) {
}
bool skipBorder = false;
bool paused = false;
};
@ -102,6 +109,9 @@ public:
void clickHandlerActiveChanged(const ClickHandlerPtr &action, bool active) override;
virtual void clearSpoiler() {
}
~RadialProgressItem();
protected:
@ -178,7 +188,8 @@ public:
Photo(
not_null<Delegate*> delegate,
not_null<HistoryItem*> parent,
not_null<PhotoData*> photo);
not_null<PhotoData*> photo,
bool spoiler);
void initDimensions() override;
int32 resizeGetHeight(int32 width) override;
@ -192,10 +203,12 @@ public:
private:
void ensureDataMediaCreated() const;
void setPixFrom(not_null<Image*> image);
void clearSpoiler();
const not_null<PhotoData*> _data;
mutable std::shared_ptr<Data::PhotoMedia> _dataMedia;
ClickHandlerPtr _link;
std::unique_ptr<Ui::SpoilerAnimation> _spoiler;
QPixmap _pix;
bool _goodLoaded = false;
@ -265,7 +278,8 @@ public:
Video(
not_null<Delegate*> delegate,
not_null<HistoryItem*> parent,
not_null<DocumentData*> video);
not_null<DocumentData*> video,
bool spoiler);
~Video();
void initDimensions() override;
@ -276,6 +290,7 @@ public:
StateRequest request) const override;
void clearHeavyPart() override;
void clearSpoiler() override;
protected:
float64 dataProgress() const override;
@ -292,6 +307,8 @@ private:
StatusText _status;
QString _duration;
std::unique_ptr<Ui::SpoilerAnimation> _spoiler;
QPixmap _pix;
bool _pixBlurred = true;