mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2026-07-25 06:54:43 +00:00
Add spoilers to shared GIFs.
This commit is contained in:
@@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "info/media/info_media_list_section.h"
|
||||
#include "info/info_controller.h"
|
||||
#include "layout/layout_selection.h"
|
||||
#include "main/main_app_config.h"
|
||||
#include "main/main_session.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "history/history.h"
|
||||
@@ -59,6 +60,16 @@ Provider::Provider(not_null<AbstractController*> controller)
|
||||
layout.second.item->invalidateCache();
|
||||
}
|
||||
}, _lifetime);
|
||||
|
||||
_controller->session().appConfig().ignoredRestrictionReasonsChanges(
|
||||
) | rpl::start_with_next([=](std::vector<QString> &&changed) {
|
||||
const auto sensitive = Data::UnavailableReason::Sensitive();
|
||||
if (ranges::contains(changed, sensitive.reason)) {
|
||||
for (auto &[id, layout] : _layouts) {
|
||||
layout.item->maybeClearSensitiveSpoiler();
|
||||
}
|
||||
}
|
||||
}, _lifetime);
|
||||
}
|
||||
|
||||
Type Provider::type() {
|
||||
|
||||
@@ -30,6 +30,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||
#include "history/history_item_components.h"
|
||||
#include "history/history_item_helpers.h"
|
||||
#include "history/view/history_view_cursor_state.h"
|
||||
#include "history/view/media/history_view_media_common.h"
|
||||
#include "history/view/media/history_view_document.h" // DrawThumbnailAsSongCover
|
||||
#include "base/unixtime.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
@@ -98,6 +99,27 @@ constexpr auto kStoryRatio = 1.46;
|
||||
}
|
||||
}
|
||||
|
||||
void PaintSensitiveTag(Painter &p, QRect r) {
|
||||
auto text = Ui::Text::String();
|
||||
text.setText(
|
||||
st::semiboldTextStyle,
|
||||
tr::lng_sensitive_tag(tr::now));
|
||||
const auto width = text.maxWidth();
|
||||
const auto inner = QRect(0, 0, width, text.minHeight());
|
||||
const auto outer = style::centerrect(r, inner.marginsAdded(st::paidTagPadding));
|
||||
const auto size = outer.size();
|
||||
const auto radius = std::min(size.width(), size.height()) / 2;
|
||||
auto hq = PainterHighQualityEnabler(p);
|
||||
|
||||
p.setPen(Qt::NoPen);
|
||||
p.setBrush(st::radialBg);
|
||||
p.drawRoundedRect(outer, radius, radius);
|
||||
p.setPen(st::radialFg);
|
||||
text.draw(p, {
|
||||
.position = outer.marginsRemoved(st::paidTagPadding).topLeft(),
|
||||
});
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
class Checkbox {
|
||||
@@ -327,18 +349,21 @@ Photo::Photo(
|
||||
MediaOptions options)
|
||||
: ItemBase(delegate, parent)
|
||||
, _data(photo)
|
||||
, _link(std::make_shared<PhotoOpenClickHandler>(
|
||||
photo,
|
||||
crl::guard(this, [=](FullMsgId id) {
|
||||
clearSpoiler();
|
||||
delegate->openPhoto(photo, id);
|
||||
}),
|
||||
parent->fullId()))
|
||||
, _spoiler(options.spoiler ? std::make_unique<Ui::SpoilerAnimation>([=] {
|
||||
, _spoiler((options.spoiler || parent->isMediaSensitive())
|
||||
? std::make_unique<Ui::SpoilerAnimation>([=] {
|
||||
delegate->repaintItem(this);
|
||||
}) : nullptr)
|
||||
})
|
||||
: nullptr)
|
||||
, _sensitiveSpoiler(parent->isMediaSensitive() ? 1 : 0)
|
||||
, _pinned(options.pinned)
|
||||
, _story(options.story) {
|
||||
, _story(options.story)
|
||||
, _link(_sensitiveSpoiler
|
||||
? HistoryView::MakeSensitiveMediaLink(
|
||||
std::make_shared<LambdaClickHandler>(crl::guard(this, [=] {
|
||||
maybeClearSensitiveSpoiler();
|
||||
})),
|
||||
parent)
|
||||
: makeOpenPhotoHandler()) {
|
||||
if (_data->inlineThumbnailBytes().isEmpty()
|
||||
&& (_data->hasExact(Data::PhotoSize::Small)
|
||||
|| _data->hasExact(Data::PhotoSize::Thumbnail))) {
|
||||
@@ -348,6 +373,16 @@ Photo::Photo(
|
||||
|
||||
Photo::~Photo() = default;
|
||||
|
||||
ClickHandlerPtr Photo::makeOpenPhotoHandler() {
|
||||
return std::make_shared<PhotoOpenClickHandler>(
|
||||
_data,
|
||||
crl::guard(this, [=](FullMsgId id) {
|
||||
clearSpoiler();
|
||||
delegate()->openPhoto(_data, id);
|
||||
}),
|
||||
parent()->fullId());
|
||||
}
|
||||
|
||||
void Photo::initDimensions() {
|
||||
_maxw = 2 * st::overviewPhotoMinSize;
|
||||
_minh = _story ? qRound(_maxw * kStoryRatio) : _maxw;
|
||||
@@ -401,6 +436,10 @@ void Photo::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||
QRect(0, 0, _width, _height),
|
||||
Ui::DefaultImageSpoiler().frame(
|
||||
_spoiler->index(context->ms, paused)));
|
||||
|
||||
if (_sensitiveSpoiler) {
|
||||
PaintSensitiveTag(p, QRect(0, 0, _width, _height));
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
@@ -453,11 +492,19 @@ void Photo::ensureDataMediaCreated() const {
|
||||
void Photo::clearSpoiler() {
|
||||
if (_spoiler) {
|
||||
_spoiler = nullptr;
|
||||
_sensitiveSpoiler = false;
|
||||
_pix = QPixmap();
|
||||
delegate()->repaintItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Photo::maybeClearSensitiveSpoiler() {
|
||||
if (_sensitiveSpoiler) {
|
||||
clearSpoiler();
|
||||
_link = makeOpenPhotoHandler();
|
||||
}
|
||||
}
|
||||
|
||||
void Photo::itemDataChanged() {
|
||||
const auto pinned = parent()->isPinned();
|
||||
if (_pinned != pinned) {
|
||||
@@ -488,12 +535,23 @@ Video::Video(
|
||||
, _data(video)
|
||||
, _videoCover(LookupVideoCover(video, parent))
|
||||
, _duration(Ui::FormatDurationText(_data->duration() / 1000))
|
||||
, _spoiler(options.spoiler ? std::make_unique<Ui::SpoilerAnimation>([=] {
|
||||
, _spoiler((options.spoiler || parent->isMediaSensitive())
|
||||
? std::make_unique<Ui::SpoilerAnimation>([=] {
|
||||
delegate->repaintItem(this);
|
||||
}) : nullptr)
|
||||
})
|
||||
: nullptr)
|
||||
, _sensitiveSpoiler(parent->isMediaSensitive() ? 1 : 0)
|
||||
, _pinned(options.pinned)
|
||||
, _story(options.story) {
|
||||
setDocumentLinks(_data);
|
||||
if (_sensitiveSpoiler) {
|
||||
_openl = HistoryView::MakeSensitiveMediaLink(
|
||||
std::make_shared<LambdaClickHandler>(crl::guard(this, [=] {
|
||||
clearSpoiler();
|
||||
setDocumentLinks(_data);
|
||||
})),
|
||||
parent);
|
||||
}
|
||||
if (!_videoCover) {
|
||||
_data->loadThumbnail(parent->fullId());
|
||||
} else if (_videoCover->inlineThumbnailBytes().isEmpty()
|
||||
@@ -574,6 +632,10 @@ void Video::paint(Painter &p, const QRect &clip, TextSelection selection, const
|
||||
QRect(0, 0, _width, _height),
|
||||
Ui::DefaultImageSpoiler().frame(
|
||||
_spoiler->index(context->ms, paused)));
|
||||
|
||||
if (_sensitiveSpoiler) {
|
||||
PaintSensitiveTag(p, QRect(0, 0, _width, _height));
|
||||
}
|
||||
}
|
||||
|
||||
if (selected) {
|
||||
@@ -660,11 +722,19 @@ void Video::ensureDataMediaCreated() const {
|
||||
void Video::clearSpoiler() {
|
||||
if (_spoiler) {
|
||||
_spoiler = nullptr;
|
||||
_sensitiveSpoiler = false;
|
||||
_pix = QPixmap();
|
||||
delegate()->repaintItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Video::maybeClearSensitiveSpoiler() {
|
||||
if (_sensitiveSpoiler) {
|
||||
clearSpoiler();
|
||||
setDocumentLinks(_data);
|
||||
}
|
||||
}
|
||||
|
||||
void Video::itemDataChanged() {
|
||||
const auto pinned = parent()->isPinned();
|
||||
if (_pinned != pinned) {
|
||||
@@ -700,7 +770,9 @@ TextState Video::getState(
|
||||
StateRequest request) const {
|
||||
if (hasPoint(point)) {
|
||||
ensureDataMediaCreated();
|
||||
const auto link = (_data->loading() || _data->uploading())
|
||||
const auto link = _sensitiveSpoiler
|
||||
? _openl
|
||||
: (_data->loading() || _data->uploading())
|
||||
? _cancell
|
||||
: (dataLoaded() || _dataMedia->canBePlayed(parent()))
|
||||
? _openl
|
||||
@@ -2036,8 +2108,22 @@ Gif::Gif(
|
||||
not_null<HistoryItem*> parent,
|
||||
not_null<DocumentData*> gif)
|
||||
: RadialProgressItem(delegate, parent)
|
||||
, _data(gif) {
|
||||
, _data(gif)
|
||||
, _spoiler(parent->isMediaSensitive()
|
||||
? std::make_unique<Ui::SpoilerAnimation>([=] {
|
||||
delegate->repaintItem(this);
|
||||
})
|
||||
: nullptr)
|
||||
, _sensitiveSpoiler(parent->isMediaSensitive() ? 1 : 0) {
|
||||
setDocumentLinks(_data, true);
|
||||
if (_sensitiveSpoiler) {
|
||||
_openl = HistoryView::MakeSensitiveMediaLink(
|
||||
std::make_shared<LambdaClickHandler>(crl::guard(this, [=] {
|
||||
clearSpoiler();
|
||||
setDocumentLinks(_data, true);
|
||||
})),
|
||||
parent);
|
||||
}
|
||||
_data->loadThumbnail(parent->fullId());
|
||||
}
|
||||
|
||||
@@ -2140,6 +2226,23 @@ void Gif::clipCallback(Media::Clip::Notification notification) {
|
||||
}
|
||||
}
|
||||
|
||||
void Gif::clearSpoiler() {
|
||||
if (_spoiler) {
|
||||
_spoiler = nullptr;
|
||||
_sensitiveSpoiler = false;
|
||||
_thumb = QImage();
|
||||
_thumbGood = false;
|
||||
delegate()->repaintItem(this);
|
||||
}
|
||||
}
|
||||
|
||||
void Gif::maybeClearSensitiveSpoiler() {
|
||||
if (_sensitiveSpoiler) {
|
||||
clearSpoiler();
|
||||
setDocumentLinks(_data);
|
||||
}
|
||||
}
|
||||
|
||||
void Gif::validateThumbnail(
|
||||
Image *image,
|
||||
QSize size,
|
||||
@@ -2165,7 +2268,9 @@ void Gif::prepareThumbnail(QSize size, QSize frame) {
|
||||
Assert(document != nullptr);
|
||||
|
||||
ensureDataMediaCreated();
|
||||
if (!_spoiler) {
|
||||
validateThumbnail(_dataMedia->thumbnail(), size, frame, true);
|
||||
}
|
||||
validateThumbnail(_dataMedia->thumbnailInline(), size, frame, false);
|
||||
}
|
||||
|
||||
@@ -2194,7 +2299,7 @@ void Gif::paint(
|
||||
});
|
||||
}
|
||||
|
||||
const auto animating = (_gif && _gif->started());
|
||||
const auto animating = !_spoiler && (_gif && _gif->started());
|
||||
if (displayLoading) {
|
||||
ensureRadial();
|
||||
if (!_radial->animating()) {
|
||||
@@ -2224,6 +2329,19 @@ void Gif::paint(
|
||||
}
|
||||
}
|
||||
|
||||
if (_spoiler) {
|
||||
const auto paused = context->paused || On(PowerSaving::kChatSpoiler);
|
||||
Ui::FillSpoilerRect(
|
||||
p,
|
||||
r,
|
||||
Ui::DefaultImageSpoiler().frame(
|
||||
_spoiler->index(context->ms, paused)));
|
||||
|
||||
if (_sensitiveSpoiler) {
|
||||
PaintSensitiveTag(p, r);
|
||||
}
|
||||
}
|
||||
|
||||
const auto selected = (selection == FullSelection);
|
||||
|
||||
if (radial
|
||||
|
||||
@@ -76,6 +76,9 @@ public:
|
||||
virtual void clearHeavyPart() {
|
||||
}
|
||||
|
||||
virtual void maybeClearSensitiveSpoiler() {
|
||||
}
|
||||
|
||||
protected:
|
||||
[[nodiscard]] not_null<HistoryItem*> parent() const {
|
||||
return _parent;
|
||||
@@ -210,21 +213,26 @@ public:
|
||||
void itemDataChanged() override;
|
||||
void clearHeavyPart() override;
|
||||
|
||||
void maybeClearSensitiveSpoiler() override;
|
||||
|
||||
private:
|
||||
void ensureDataMediaCreated() const;
|
||||
void setPixFrom(not_null<Image*> image);
|
||||
[[nodiscard]] ClickHandlerPtr makeOpenPhotoHandler();
|
||||
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;
|
||||
bool _sensitiveSpoiler = false;
|
||||
bool _pinned = false;
|
||||
bool _story = false;
|
||||
|
||||
ClickHandlerPtr _link;
|
||||
|
||||
};
|
||||
|
||||
class Gif final : public RadialProgressItem {
|
||||
@@ -249,6 +257,9 @@ public:
|
||||
void clearHeavyPart() override;
|
||||
void setPosition(int32 position) override;
|
||||
|
||||
void clearSpoiler() override;
|
||||
void maybeClearSensitiveSpoiler() override;
|
||||
|
||||
protected:
|
||||
float64 dataProgress() const override;
|
||||
bool dataFinished() const override;
|
||||
@@ -279,9 +290,11 @@ private:
|
||||
const not_null<DocumentData*> _data;
|
||||
mutable std::shared_ptr<Data::DocumentMedia> _dataMedia;
|
||||
StatusText _status;
|
||||
std::unique_ptr<Ui::SpoilerAnimation> _spoiler;
|
||||
|
||||
QImage _thumb;
|
||||
bool _thumbGood = false;
|
||||
bool _sensitiveSpoiler = false;
|
||||
|
||||
};
|
||||
|
||||
@@ -305,6 +318,8 @@ public:
|
||||
void clearHeavyPart() override;
|
||||
void clearSpoiler() override;
|
||||
|
||||
void maybeClearSensitiveSpoiler() override;
|
||||
|
||||
protected:
|
||||
float64 dataProgress() const override;
|
||||
bool dataFinished() const override;
|
||||
@@ -326,6 +341,7 @@ private:
|
||||
|
||||
QPixmap _pix;
|
||||
bool _pixBlurred = true;
|
||||
bool _sensitiveSpoiler = false;
|
||||
bool _pinned = false;
|
||||
bool _story = false;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user