mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-14 21:27:07 +02:00
Support adaptive forum userpic rounding radius.
This commit is contained in:
parent
2407ac50bc
commit
cb653df0f6
100 changed files with 662 additions and 724 deletions
|
@ -171,6 +171,11 @@ void CheckChatInvite(
|
|||
|
||||
} // namespace Api
|
||||
|
||||
struct ConfirmInviteBox::Participant {
|
||||
not_null<UserData*> user;
|
||||
Ui::PeerUserpicView userpic;
|
||||
};
|
||||
|
||||
ConfirmInviteBox::ConfirmInviteBox(
|
||||
QWidget*,
|
||||
not_null<Main::Session*> session,
|
||||
|
@ -356,7 +361,7 @@ void ConfirmInviteBox::paintEvent(QPaintEvent *e) {
|
|||
{ .options = Images::Option::RoundCircle }));
|
||||
}
|
||||
} else if (_photoEmpty) {
|
||||
_photoEmpty->paint(
|
||||
_photoEmpty->paintCircle(
|
||||
p,
|
||||
(width() - st::confirmInvitePhotoSize) / 2,
|
||||
st::confirmInvitePhotoTop,
|
||||
|
|
|
@ -21,7 +21,6 @@ class SessionController;
|
|||
} // namespace Window
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
class PhotoMedia;
|
||||
} // namespace Data
|
||||
|
||||
|
@ -55,10 +54,7 @@ protected:
|
|||
void paintEvent(QPaintEvent *e) override;
|
||||
|
||||
private:
|
||||
struct Participant {
|
||||
not_null<UserData*> user;
|
||||
std::shared_ptr<Data::CloudImageView> userpic;
|
||||
};
|
||||
struct Participant;
|
||||
struct ChatInvite {
|
||||
QString title;
|
||||
QString about;
|
||||
|
|
|
@ -114,7 +114,7 @@ struct Context {
|
|||
struct Userpic {
|
||||
not_null<PeerData*> peer;
|
||||
QString customEntityData;
|
||||
mutable std::shared_ptr<Data::CloudImageView> view;
|
||||
mutable Ui::PeerUserpicView view;
|
||||
mutable InMemoryKey uniqueKey;
|
||||
};
|
||||
|
||||
|
@ -380,7 +380,7 @@ bool UpdateUserpics(
|
|||
const auto peer = not_null{ resolved.peer };
|
||||
const auto &data = ReactionEntityData(resolved.reaction);
|
||||
const auto i = ranges::find(was, peer, &Userpic::peer);
|
||||
if (i != end(was) && i->view) {
|
||||
if (i != end(was) && i->view.cloud) {
|
||||
now.push_back(std::move(*i));
|
||||
now.back().customEntityData = data;
|
||||
continue;
|
||||
|
|
|
@ -84,7 +84,7 @@ private:
|
|||
};
|
||||
struct PeerButton {
|
||||
not_null<History*> history;
|
||||
std::shared_ptr<Data::CloudImageView> userpic;
|
||||
Ui::PeerUserpicView userpic;
|
||||
Ui::Text::String name;
|
||||
Button button;
|
||||
};
|
||||
|
|
|
@ -157,7 +157,7 @@ PaintRoundImageCallback ExceptionRow::generatePaintUserpicCallback() {
|
|||
const auto peer = this->peer();
|
||||
const auto saved = peer->isSelf();
|
||||
const auto replies = peer->isRepliesChat();
|
||||
auto userpic = saved ? nullptr : ensureUserpicView();
|
||||
auto userpic = saved ? Ui::PeerUserpicView() : ensureUserpicView();
|
||||
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
|
||||
if (saved) {
|
||||
Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size);
|
||||
|
|
|
@ -48,7 +48,7 @@ PaintRoundImageCallback PaintUserpicCallback(
|
|||
};
|
||||
}
|
||||
}
|
||||
auto userpic = std::shared_ptr<Data::CloudImageView>();
|
||||
auto userpic = Ui::PeerUserpicView();
|
||||
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
|
||||
peer->paintUserpicLeft(p, userpic, x, y, outerWidth, size);
|
||||
};
|
||||
|
@ -635,8 +635,8 @@ QString PeerListRow::generateShortName() {
|
|||
: peer()->shortName();
|
||||
}
|
||||
|
||||
std::shared_ptr<Data::CloudImageView> &PeerListRow::ensureUserpicView() {
|
||||
if (!_userpic) {
|
||||
Ui::PeerUserpicView &PeerListRow::ensureUserpicView() {
|
||||
if (!_userpic.cloud && peer()->hasUserpic()) {
|
||||
_userpic = peer()->createUserpicView();
|
||||
}
|
||||
return _userpic;
|
||||
|
@ -646,7 +646,7 @@ PaintRoundImageCallback PeerListRow::generatePaintUserpicCallback() {
|
|||
const auto saved = _isSavedMessagesChat;
|
||||
const auto replies = _isRepliesMessagesChat;
|
||||
const auto peer = this->peer();
|
||||
auto userpic = saved ? nullptr : ensureUserpicView();
|
||||
auto userpic = saved ? Ui::PeerUserpicView() : ensureUserpicView();
|
||||
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
|
||||
if (saved) {
|
||||
Ui::EmptyUserpic::PaintSavedMessages(p, x, y, outerWidth, size);
|
||||
|
@ -840,10 +840,10 @@ void PeerListRow::lazyInitialize(const style::PeerListItem &st) {
|
|||
void PeerListRow::createCheckbox(
|
||||
const style::RoundImageCheckbox &st,
|
||||
Fn<void()> updateCallback) {
|
||||
const auto generateRadius = [=] {
|
||||
const auto generateRadius = [=](int size) {
|
||||
return (!special() && peer()->isForum())
|
||||
? ImageRoundRadius::Large
|
||||
: ImageRoundRadius::Ellipse;
|
||||
? int(size * Ui::ForumUserpicRadiusMultiplier())
|
||||
: std::optional<int>();
|
||||
};
|
||||
_checkbox = std::make_unique<Ui::RoundImageCheckbox>(
|
||||
st,
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/rp_widget.h"
|
||||
#include "ui/empty_userpic.h"
|
||||
#include "ui/unread_badge.h"
|
||||
#include "ui/userpic_view.h"
|
||||
#include "boxes/abstract_box.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "data/data_cloud_file.h"
|
||||
|
@ -84,7 +85,7 @@ public:
|
|||
return _id;
|
||||
}
|
||||
|
||||
[[nodiscard]] std::shared_ptr<Data::CloudImageView> &ensureUserpicView();
|
||||
[[nodiscard]] Ui::PeerUserpicView &ensureUserpicView();
|
||||
|
||||
[[nodiscard]] virtual QString generateName();
|
||||
[[nodiscard]] virtual QString generateShortName();
|
||||
|
@ -262,7 +263,7 @@ private:
|
|||
|
||||
PeerListRowId _id = 0;
|
||||
PeerData *_peer = nullptr;
|
||||
mutable std::shared_ptr<Data::CloudImageView> _userpic;
|
||||
mutable Ui::PeerUserpicView _userpic;
|
||||
std::unique_ptr<Ui::RippleAnimation> _ripple;
|
||||
std::unique_ptr<Ui::RoundImageCheckbox> _checkbox;
|
||||
Ui::Text::String _name;
|
||||
|
|
|
@ -632,7 +632,7 @@ auto ChooseTopicBoxController::Row::generatePaintUserpicCallback()
|
|||
int y,
|
||||
int outerWidth,
|
||||
int size) {
|
||||
auto view = std::shared_ptr<Data::CloudImageView>();
|
||||
auto view = Ui::PeerUserpicView();
|
||||
p.translate(x, y);
|
||||
_topic->paintUserpic(p, view, {
|
||||
.st = &st::forumTopicRow,
|
||||
|
|
|
@ -1042,11 +1042,12 @@ void AddPermanentLinkBlock(
|
|||
state->allUserpicsLoaded = ranges::all_of(
|
||||
state->list,
|
||||
[](const HistoryView::UserpicInRow &element) {
|
||||
return !element.peer->hasUserpic() || element.view->image();
|
||||
return !element.peer->hasUserpic()
|
||||
|| !Ui::PeerUserpicLoading(element.view);
|
||||
});
|
||||
state->content = Ui::JoinedCountContent{
|
||||
.count = state->count,
|
||||
.userpics = state->cachedUserpics
|
||||
.userpics = state->cachedUserpics,
|
||||
};
|
||||
};
|
||||
value->value(
|
||||
|
@ -1087,7 +1088,7 @@ void AddPermanentLinkBlock(
|
|||
} else if (element.peer->userpicUniqueKey(element.view)
|
||||
!= element.uniqueKey) {
|
||||
pushing = true;
|
||||
} else if (!element.view->image()) {
|
||||
} else if (Ui::PeerUserpicLoading(element.view)) {
|
||||
state->allUserpicsLoaded = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ struct UserpicState {
|
|||
PeerShortInfoUserpic current;
|
||||
std::optional<UserPhotosSlice> userSlice;
|
||||
PhotoId userpicPhotoId = PeerData::kUnknownPhotoId;
|
||||
std::shared_ptr<Data::CloudImageView> userpicView;
|
||||
Ui::PeerUserpicView userpicView;
|
||||
std::shared_ptr<Data::PhotoMedia> photoView;
|
||||
std::vector<std::shared_ptr<Data::PhotoMedia>> photoPreloads;
|
||||
InMemoryKey userpicKey;
|
||||
|
@ -76,27 +76,26 @@ void ProcessUserpic(
|
|||
not_null<UserpicState*> state) {
|
||||
state->current.videoDocument = nullptr;
|
||||
state->userpicKey = peer->userpicUniqueKey(state->userpicView);
|
||||
if (!state->userpicView) {
|
||||
if (!state->userpicView.cloud) {
|
||||
GenerateImage(
|
||||
state,
|
||||
peer->generateUserpicImage(
|
||||
state->userpicView,
|
||||
st::shortInfoWidth * style::DevicePixelRatio(),
|
||||
ImageRoundRadius::None),
|
||||
0),
|
||||
false);
|
||||
state->current.photoLoadingProgress = 1.;
|
||||
state->photoView = nullptr;
|
||||
return;
|
||||
}
|
||||
peer->loadUserpic();
|
||||
const auto image = state->userpicView->image();
|
||||
if (!image) {
|
||||
if (Ui::PeerUserpicLoading(state->userpicView)) {
|
||||
state->current.photoLoadingProgress = 0.;
|
||||
state->current.photo = QImage();
|
||||
state->waitingLoad = true;
|
||||
return;
|
||||
}
|
||||
GenerateImage(state, image, true);
|
||||
GenerateImage(state, *state->userpicView.cloud, true);
|
||||
state->current.photoLoadingProgress = peer->userpicPhotoId() ? 0. : 1.;
|
||||
state->photoView = nullptr;
|
||||
}
|
||||
|
@ -411,7 +410,7 @@ bool ProcessCurrent(
|
|||
return state->waitingLoad
|
||||
&& (state->photoView
|
||||
? (!!state->photoView->image(Data::PhotoSize::Large))
|
||||
: (state->userpicView && state->userpicView->image()));
|
||||
: (!Ui::PeerUserpicLoading(state->userpicView)));
|
||||
}) | rpl::start_with_next([=] {
|
||||
push();
|
||||
}, lifetime);
|
||||
|
|
|
@ -536,7 +536,7 @@ void ShareBox::applyFilterUpdate(const QString &query) {
|
|||
}
|
||||
|
||||
PaintRoundImageCallback ForceRoundUserpicCallback(not_null<PeerData*> peer) {
|
||||
auto userpic = std::shared_ptr<Data::CloudImageView>();
|
||||
auto userpic = Ui::PeerUserpicView();
|
||||
auto cache = std::make_shared<QImage>();
|
||||
return [=](Painter &p, int x, int y, int outerWidth, int size) mutable {
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
|
@ -956,9 +956,9 @@ ShareBox::Inner::Chat::Chat(
|
|||
st.checkbox,
|
||||
updateCallback,
|
||||
PaintUserpicCallback(peer, true),
|
||||
[=] { return peer->isForum()
|
||||
? ImageRoundRadius::Large
|
||||
: ImageRoundRadius::Ellipse; })
|
||||
[=](int size) { return peer->isForum()
|
||||
? int(size * Ui::ForumUserpicRadiusMultiplier())
|
||||
: std::optional<int>(); })
|
||||
, name(st.checkbox.imageRadius * 2) {
|
||||
}
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@ class PowerSaveBlocker;
|
|||
|
||||
namespace Data {
|
||||
class PhotoMedia;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
|
|
|
@ -159,7 +159,12 @@ void Userpic::refreshPhoto() {
|
|||
_userPhotoFull = true;
|
||||
createCache(_photo->image(Data::PhotoSize::Thumbnail));
|
||||
} else if (_userPhoto.isNull()) {
|
||||
createCache(_userpic ? _userpic->image() : nullptr);
|
||||
if (const auto cloud = _peer->userpicCloudImage(_userpic)) {
|
||||
auto image = Image(base::duplicate(*cloud));
|
||||
createCache(&image);
|
||||
} else {
|
||||
createCache(nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,7 +205,7 @@ void Userpic::createCache(Image *image) {
|
|||
Ui::EmptyUserpic::UserpicColor(
|
||||
Data::PeerColorIndex(_peer->id)),
|
||||
_peer->name()
|
||||
).paint(p, 0, 0, size, size);
|
||||
).paintCircle(p, 0, 0, size, size);
|
||||
}
|
||||
//_userPhoto = Images::PixmapFast(Images::Round(
|
||||
// std::move(filled),
|
||||
|
|
|
@ -8,13 +8,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/userpic_view.h"
|
||||
#include "ui/effects/animations.h"
|
||||
|
||||
class PeerData;
|
||||
class Image;
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
class PhotoMedia;
|
||||
} // namespace Data
|
||||
|
||||
|
@ -51,7 +51,7 @@ private:
|
|||
Ui::RpWidget _content;
|
||||
|
||||
not_null<PeerData*> _peer;
|
||||
std::shared_ptr<Data::CloudImageView> _userpic;
|
||||
Ui::PeerUserpicView _userpic;
|
||||
std::shared_ptr<Data::PhotoMedia> _photo;
|
||||
Ui::Animations::Simple _mutedAnimation;
|
||||
QPixmap _userPhoto;
|
||||
|
|
|
@ -350,7 +350,7 @@ void MembersRow::updateBlobAnimation(crl::time now) {
|
|||
}
|
||||
|
||||
void MembersRow::ensureUserpicCache(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int size) {
|
||||
Expects(_blobsAnimation != nullptr);
|
||||
|
||||
|
@ -401,7 +401,7 @@ void MembersRow::paintBlobs(
|
|||
|
||||
void MembersRow::paintScaledUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &userpic,
|
||||
Ui::PeerUserpicView &userpic,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
|
|
|
@ -19,6 +19,7 @@ struct GroupCallParticipant;
|
|||
|
||||
namespace Ui {
|
||||
class RippleAnimation;
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Calls::Group {
|
||||
|
@ -180,7 +181,7 @@ private:
|
|||
void setVolume(int volume);
|
||||
|
||||
void ensureUserpicCache(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int size);
|
||||
void paintBlobs(
|
||||
Painter &p,
|
||||
|
@ -190,7 +191,7 @@ private:
|
|||
int sizeh, PanelMode mode);
|
||||
void paintScaledUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &userpic,
|
||||
Ui::PeerUserpicView &userpic,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
|
|
|
@ -59,7 +59,7 @@ private:
|
|||
const not_null<QAction*> _dummyAction;
|
||||
const style::Menu &_st;
|
||||
const not_null<PeerData*> _peer;
|
||||
std::shared_ptr<Data::CloudImageView> _userpicView;
|
||||
Ui::PeerUserpicView _userpicView;
|
||||
|
||||
Ui::Text::String _text;
|
||||
Ui::Text::String _name;
|
||||
|
|
|
@ -29,7 +29,6 @@ class PowerSaveBlocker;
|
|||
|
||||
namespace Data {
|
||||
class PhotoMedia;
|
||||
class CloudImageView;
|
||||
class GroupCall;
|
||||
} // namespace Data
|
||||
|
||||
|
|
|
@ -462,7 +462,7 @@ void Viewport::RendererGL::validateUserpicFrame(
|
|||
tileData.userpicFrame = tile->row()->peer()->generateUserpicImage(
|
||||
tile->row()->ensureUserpicView(),
|
||||
size.width(),
|
||||
ImageRoundRadius::None);
|
||||
0);
|
||||
}
|
||||
|
||||
void Viewport::RendererGL::paintTile(
|
||||
|
|
|
@ -80,7 +80,7 @@ void Viewport::RendererSW::validateUserpicFrame(
|
|||
tile->row()->peer()->generateUserpicImage(
|
||||
tile->row()->ensureUserpicView(),
|
||||
size.width(),
|
||||
ImageRoundRadius::None),
|
||||
0),
|
||||
kBlurRadius);
|
||||
}
|
||||
|
||||
|
|
|
@ -165,6 +165,20 @@ struct FieldAutocomplete::StickerSuggestion {
|
|||
QImage premiumLock;
|
||||
};
|
||||
|
||||
struct FieldAutocomplete::MentionRow {
|
||||
not_null<UserData*> user;
|
||||
Ui::Text::String name;
|
||||
Ui::PeerUserpicView userpic;
|
||||
};
|
||||
|
||||
struct FieldAutocomplete::BotCommandRow {
|
||||
not_null<UserData*> user;
|
||||
QString command;
|
||||
QString description;
|
||||
Ui::PeerUserpicView userpic;
|
||||
Ui::Text::String descriptionText;
|
||||
};
|
||||
|
||||
FieldAutocomplete::FieldAutocomplete(
|
||||
QWidget *parent,
|
||||
not_null<Window::SessionController*> controller)
|
||||
|
|
|
@ -31,7 +31,6 @@ class SessionController;
|
|||
|
||||
namespace Data {
|
||||
class DocumentMedia;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace SendMenu {
|
||||
|
@ -131,20 +130,8 @@ private:
|
|||
class Inner;
|
||||
friend class Inner;
|
||||
struct StickerSuggestion;
|
||||
|
||||
struct MentionRow {
|
||||
not_null<UserData*> user;
|
||||
Ui::Text::String name;
|
||||
std::shared_ptr<Data::CloudImageView> userpic;
|
||||
};
|
||||
|
||||
struct BotCommandRow {
|
||||
not_null<UserData*> user;
|
||||
QString command;
|
||||
QString description;
|
||||
std::shared_ptr<Data::CloudImageView> userpic;
|
||||
Ui::Text::String descriptionText;
|
||||
};
|
||||
struct MentionRow;
|
||||
struct BotCommandRow;
|
||||
|
||||
using HashtagRows = std::vector<QString>;
|
||||
using BotCommandRows = std::vector<BotCommandRow>;
|
||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "chat_helpers/tabbed_selector.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "ui/round_rect.h"
|
||||
#include "ui/userpic_view.h"
|
||||
|
||||
namespace Ui {
|
||||
class InputField;
|
||||
|
@ -21,7 +22,6 @@ namespace Data {
|
|||
class StickersSet;
|
||||
class StickersSetThumbnailView;
|
||||
class DocumentMedia;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Lottie {
|
||||
|
@ -73,7 +73,7 @@ struct StickerIcon {
|
|||
ChannelData *megagroup = nullptr;
|
||||
mutable std::shared_ptr<Data::StickersSetThumbnailView> thumbnailMedia;
|
||||
mutable std::shared_ptr<Data::DocumentMedia> stickerMedia;
|
||||
mutable std::shared_ptr<Data::CloudImageView> megagroupUserpic;
|
||||
mutable Ui::PeerUserpicView megagroupUserpic;
|
||||
int pixw = 0;
|
||||
int pixh = 0;
|
||||
mutable rpl::lifetime lifetime;
|
||||
|
|
|
@ -22,13 +22,6 @@ CloudFile::~CloudFile() {
|
|||
base::take(loader);
|
||||
}
|
||||
|
||||
void CloudImageView::set(
|
||||
not_null<Main::Session*> session,
|
||||
QImage image) {
|
||||
_image.emplace(std::move(image));
|
||||
session->notifyDownloaderTaskFinished();
|
||||
}
|
||||
|
||||
CloudImage::CloudImage() = default;
|
||||
|
||||
CloudImage::CloudImage(
|
||||
|
@ -37,10 +30,6 @@ CloudImage::CloudImage(
|
|||
update(session, data);
|
||||
}
|
||||
|
||||
Image *CloudImageView::image() {
|
||||
return _image ? &*_image : nullptr;
|
||||
}
|
||||
|
||||
void CloudImage::set(
|
||||
not_null<Main::Session*> session,
|
||||
const ImageWithLocation &data) {
|
||||
|
@ -52,11 +41,11 @@ void CloudImage::set(
|
|||
_file.location = ImageLocation();
|
||||
_file.byteSize = 0;
|
||||
_file.flags = CloudFile::Flag();
|
||||
_view = std::weak_ptr<CloudImageView>();
|
||||
_view = std::weak_ptr<QImage>();
|
||||
} else if (was != now
|
||||
&& (!v::is<InMemoryLocation>(was) || v::is<InMemoryLocation>(now))) {
|
||||
_file.location = ImageLocation();
|
||||
_view = std::weak_ptr<CloudImageView>();
|
||||
_view = std::weak_ptr<QImage>();
|
||||
}
|
||||
UpdateCloudFile(
|
||||
_file,
|
||||
|
@ -65,9 +54,7 @@ void CloudImage::set(
|
|||
kImageCacheTag,
|
||||
[=](FileOrigin origin) { load(session, origin); },
|
||||
[=](QImage preloaded, QByteArray) {
|
||||
if (const auto view = activeView()) {
|
||||
view->set(session, data.preloaded);
|
||||
}
|
||||
setToActive(session, std::move(preloaded));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -81,9 +68,7 @@ void CloudImage::update(
|
|||
kImageCacheTag,
|
||||
[=](FileOrigin origin) { load(session, origin); },
|
||||
[=](QImage preloaded, QByteArray) {
|
||||
if (const auto view = activeView()) {
|
||||
view->set(session, data.preloaded);
|
||||
}
|
||||
setToActive(session, std::move(preloaded));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -107,16 +92,14 @@ void CloudImage::load(not_null<Main::Session*> session, FileOrigin origin) {
|
|||
const auto autoLoading = false;
|
||||
const auto finalCheck = [=] {
|
||||
if (const auto active = activeView()) {
|
||||
return !active->image();
|
||||
return active->isNull();
|
||||
} else if (_file.flags & CloudFile::Flag::Loaded) {
|
||||
return false;
|
||||
}
|
||||
return !(_file.flags & CloudFile::Flag::Loaded);
|
||||
};
|
||||
const auto done = [=](QImage result, QByteArray) {
|
||||
if (const auto active = activeView()) {
|
||||
active->set(session, std::move(result));
|
||||
}
|
||||
setToActive(session, std::move(result));
|
||||
};
|
||||
LoadCloudFile(
|
||||
session,
|
||||
|
@ -137,27 +120,37 @@ int CloudImage::byteSize() const {
|
|||
return _file.byteSize;
|
||||
}
|
||||
|
||||
std::shared_ptr<CloudImageView> CloudImage::createView() {
|
||||
std::shared_ptr<QImage> CloudImage::createView() {
|
||||
if (auto active = activeView()) {
|
||||
return active;
|
||||
}
|
||||
auto view = std::make_shared<CloudImageView>();
|
||||
auto view = std::make_shared<QImage>();
|
||||
_view = view;
|
||||
return view;
|
||||
}
|
||||
|
||||
std::shared_ptr<CloudImageView> CloudImage::activeView() const {
|
||||
std::shared_ptr<QImage> CloudImage::activeView() const {
|
||||
return _view.lock();
|
||||
}
|
||||
|
||||
bool CloudImage::isCurrentView(
|
||||
const std::shared_ptr<CloudImageView> &view) const {
|
||||
bool CloudImage::isCurrentView(const std::shared_ptr<QImage> &view) const {
|
||||
if (!view) {
|
||||
return empty();
|
||||
}
|
||||
return !view.owner_before(_view) && !_view.owner_before(view);
|
||||
}
|
||||
|
||||
void CloudImage::setToActive(
|
||||
not_null<Main::Session*> session,
|
||||
QImage image) {
|
||||
if (const auto view = activeView()) {
|
||||
*view = image.isNull()
|
||||
? Image::Empty()->original()
|
||||
: std::move(image);
|
||||
session->notifyDownloaderTaskFinished();
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateCloudFile(
|
||||
CloudFile &file,
|
||||
const ImageWithLocation &data,
|
||||
|
|
|
@ -44,17 +44,6 @@ struct CloudFile final {
|
|||
base::flags<Flag> flags;
|
||||
};
|
||||
|
||||
class CloudImageView final {
|
||||
public:
|
||||
void set(not_null<Main::Session*> session, QImage image);
|
||||
|
||||
[[nodiscard]] Image *image();
|
||||
|
||||
private:
|
||||
std::optional<Image> _image;
|
||||
|
||||
};
|
||||
|
||||
class CloudImage final {
|
||||
public:
|
||||
CloudImage();
|
||||
|
@ -79,14 +68,16 @@ public:
|
|||
[[nodiscard]] const ImageLocation &location() const;
|
||||
[[nodiscard]] int byteSize() const;
|
||||
|
||||
[[nodiscard]] std::shared_ptr<CloudImageView> createView();
|
||||
[[nodiscard]] std::shared_ptr<CloudImageView> activeView() const;
|
||||
[[nodiscard]] std::shared_ptr<QImage> createView();
|
||||
[[nodiscard]] std::shared_ptr<QImage> activeView() const;
|
||||
[[nodiscard]] bool isCurrentView(
|
||||
const std::shared_ptr<CloudImageView> &view) const;
|
||||
const std::shared_ptr<QImage> &view) const;
|
||||
|
||||
private:
|
||||
void setToActive(not_null<Main::Session*> session, QImage image);
|
||||
|
||||
CloudFile _file;
|
||||
std::weak_ptr<CloudImageView> _view;
|
||||
std::weak_ptr<QImage> _view;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -216,7 +216,7 @@ void Folder::loadUserpic() {
|
|||
|
||||
void Folder::paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Dialogs::Ui::PaintContext &context) const {
|
||||
paintUserpic(
|
||||
p,
|
||||
|
|
|
@ -57,7 +57,7 @@ public:
|
|||
void loadUserpic() override;
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Dialogs::Ui::PaintContext &context) const override;
|
||||
void paintUserpic(Painter &p, int x, int y, int size) const;
|
||||
void paintUserpic(
|
||||
|
|
|
@ -568,7 +568,7 @@ void ForumTopic::loadUserpic() {
|
|||
|
||||
void ForumTopic::paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Dialogs::Ui::PaintContext &context) const {
|
||||
const auto &st = context.st;
|
||||
auto position = QPoint(st->padding.left(), st->padding.top());
|
||||
|
|
|
@ -150,7 +150,7 @@ public:
|
|||
void loadUserpic() override;
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Dialogs::Ui::PaintContext &context) const override;
|
||||
void clearUserpicLoops();
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ void PeerData::updateNameDelayed(
|
|||
}
|
||||
}
|
||||
_name = newName;
|
||||
_userpicEmpty = nullptr;
|
||||
invalidateEmptyUserpic();
|
||||
|
||||
auto flags = UpdateFlag::None | UpdateFlag::None;
|
||||
auto oldFirstLetters = base::flat_set<QChar>();
|
||||
|
@ -231,13 +231,17 @@ not_null<Ui::EmptyUserpic*> PeerData::ensureEmptyUserpic() const {
|
|||
const auto user = asUser();
|
||||
_userpicEmpty = std::make_unique<Ui::EmptyUserpic>(
|
||||
Ui::EmptyUserpic::UserpicColor(Data::PeerColorIndex(id)),
|
||||
user && user->isInaccessible()
|
||||
((user && user->isInaccessible())
|
||||
? Ui::EmptyUserpic::InaccessibleName()
|
||||
: name());
|
||||
: name()));
|
||||
}
|
||||
return _userpicEmpty.get();
|
||||
}
|
||||
|
||||
void PeerData::invalidateEmptyUserpic() {
|
||||
_userpicEmpty = nullptr;
|
||||
}
|
||||
|
||||
ClickHandlerPtr PeerData::createOpenLink() {
|
||||
return std::make_shared<PeerClickHandler>(this);
|
||||
}
|
||||
|
@ -265,50 +269,45 @@ void PeerData::setUserpicPhoto(const MTPPhoto &data) {
|
|||
}
|
||||
}
|
||||
|
||||
Image *PeerData::currentUserpic(
|
||||
std::shared_ptr<Data::CloudImageView> &view) const {
|
||||
if (!_userpic.isCurrentView(view)) {
|
||||
view = _userpic.createView();
|
||||
_userpic.load(&session(), userpicOrigin());
|
||||
QImage *PeerData::userpicCloudImage(Ui::PeerUserpicView &view) const {
|
||||
if (!_userpic.isCurrentView(view.cloud)) {
|
||||
if (!_userpic.empty()) {
|
||||
view.cloud = _userpic.createView();
|
||||
_userpic.load(&session(), userpicOrigin());
|
||||
} else {
|
||||
view.cloud = nullptr;
|
||||
if (view.empty.null()) {
|
||||
view.paletteVersion = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
const auto image = view ? view->image() : nullptr;
|
||||
if (image) {
|
||||
if (const auto image = view.cloud.get(); image && !image->isNull()) {
|
||||
_userpicEmpty = nullptr;
|
||||
return image;
|
||||
} else if (isNotificationsUser()) {
|
||||
static auto result = Image(
|
||||
Window::LogoNoMargin().scaledToWidth(
|
||||
kUserpicSize,
|
||||
Qt::SmoothTransformation));
|
||||
static auto result = Window::LogoNoMargin().scaledToWidth(
|
||||
kUserpicSize,
|
||||
Qt::SmoothTransformation);
|
||||
return &result;
|
||||
}
|
||||
return image;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void PeerData::paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int size) const {
|
||||
if (const auto userpic = currentUserpic(view)) {
|
||||
const auto rounding = isForum()
|
||||
? Images::Option::RoundLarge
|
||||
: Images::Option::RoundCircle;
|
||||
p.drawPixmap(
|
||||
x,
|
||||
y,
|
||||
userpic->pix(size, size, { .options = rounding }));
|
||||
} else if (isForum()) {
|
||||
ensureEmptyUserpic()->paintRounded(
|
||||
p,
|
||||
x,
|
||||
y,
|
||||
x + size + x,
|
||||
size,
|
||||
st::roundRadiusLarge);
|
||||
} else{
|
||||
ensureEmptyUserpic()->paint(p, x, y, x + size + x, size);
|
||||
}
|
||||
const auto cloud = userpicCloudImage(view);
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
Ui::ValidateUserpicCache(
|
||||
view,
|
||||
cloud,
|
||||
cloud ? nullptr : ensureEmptyUserpic().get(),
|
||||
size * ratio,
|
||||
isForum());
|
||||
p.drawImage(QRect(x, y, size, size), view.cached);
|
||||
}
|
||||
|
||||
void PeerData::loadUserpic() {
|
||||
|
@ -319,112 +318,76 @@ bool PeerData::hasUserpic() const {
|
|||
return !_userpic.empty();
|
||||
}
|
||||
|
||||
std::shared_ptr<Data::CloudImageView> PeerData::activeUserpicView() {
|
||||
return _userpic.empty() ? nullptr : _userpic.activeView();
|
||||
Ui::PeerUserpicView PeerData::activeUserpicView() {
|
||||
return { .cloud = _userpic.empty() ? nullptr : _userpic.activeView() };
|
||||
}
|
||||
|
||||
std::shared_ptr<Data::CloudImageView> PeerData::createUserpicView() {
|
||||
Ui::PeerUserpicView PeerData::createUserpicView() {
|
||||
if (_userpic.empty()) {
|
||||
return nullptr;
|
||||
return {};
|
||||
}
|
||||
auto result = _userpic.createView();
|
||||
_userpic.load(&session(), userpicPhotoOrigin());
|
||||
return result;
|
||||
return { .cloud = result };
|
||||
}
|
||||
|
||||
bool PeerData::useEmptyUserpic(
|
||||
std::shared_ptr<Data::CloudImageView> &view) const {
|
||||
return !currentUserpic(view);
|
||||
bool PeerData::useEmptyUserpic(Ui::PeerUserpicView &view) const {
|
||||
return !userpicCloudImage(view);
|
||||
}
|
||||
|
||||
InMemoryKey PeerData::userpicUniqueKey(
|
||||
std::shared_ptr<Data::CloudImageView> &view) const {
|
||||
InMemoryKey PeerData::userpicUniqueKey(Ui::PeerUserpicView &view) const {
|
||||
return useEmptyUserpic(view)
|
||||
? ensureEmptyUserpic()->uniqueKey()
|
||||
: inMemoryKey(_userpic.location());
|
||||
}
|
||||
|
||||
void PeerData::saveUserpic(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
const QString &path,
|
||||
int size) const {
|
||||
generateUserpicImage(view, size * cIntRetinaFactor()).save(path, "PNG");
|
||||
}
|
||||
|
||||
void PeerData::saveUserpicRounded(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
const QString &path,
|
||||
int size) const {
|
||||
generateUserpicImage(
|
||||
view,
|
||||
size * cIntRetinaFactor(),
|
||||
ImageRoundRadius::Small).save(path, "PNG");
|
||||
}
|
||||
|
||||
QPixmap PeerData::genUserpic(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
int size) const {
|
||||
if (const auto userpic = currentUserpic(view)) {
|
||||
const auto rounding = isForum()
|
||||
? Images::Option::RoundLarge
|
||||
: Images::Option::RoundCircle;
|
||||
return userpic->pix(size, size, { .options = rounding });
|
||||
}
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
auto result = QImage(
|
||||
QSize(size, size) * ratio,
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
result.setDevicePixelRatio(ratio);
|
||||
result.fill(Qt::transparent);
|
||||
{
|
||||
Painter p(&result);
|
||||
paintUserpic(p, view, 0, 0, size);
|
||||
}
|
||||
return Ui::PixmapFromImage(std::move(result));
|
||||
}
|
||||
|
||||
QImage PeerData::generateUserpicImage(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
int size) const {
|
||||
return generateUserpicImage(
|
||||
view,
|
||||
size,
|
||||
isForum() ? ImageRoundRadius::Large : ImageRoundRadius::Ellipse);
|
||||
}
|
||||
|
||||
QImage PeerData::generateUserpicImage(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int size,
|
||||
ImageRoundRadius radius) const {
|
||||
if (const auto userpic = currentUserpic(view)) {
|
||||
const auto options = (radius == ImageRoundRadius::Ellipse)
|
||||
? Images::Option::RoundCircle
|
||||
: (radius == ImageRoundRadius::Large)
|
||||
? Images::Option::RoundLarge
|
||||
: (radius == ImageRoundRadius::Small)
|
||||
? Images::Option::RoundSmall
|
||||
: Images::Option();
|
||||
return userpic->pixNoCache(
|
||||
std::optional<int> radius) const {
|
||||
if (const auto userpic = userpicCloudImage(view)) {
|
||||
auto image = userpic->scaled(
|
||||
{ size, size },
|
||||
{ .options = options }).toImage();
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
const auto round = [&](int radius) {
|
||||
return Images::Round(
|
||||
std::move(image),
|
||||
Images::CornersMask(radius));
|
||||
};
|
||||
if (radius == 0) {
|
||||
return image;
|
||||
} else if (radius) {
|
||||
return round(*radius);
|
||||
} else if (isForum()) {
|
||||
return round(size * Ui::ForumUserpicRadiusMultiplier());
|
||||
} else {
|
||||
return Images::Circle(std::move(image));
|
||||
}
|
||||
}
|
||||
auto result = QImage(
|
||||
QSize(size, size),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
result.fill(Qt::transparent);
|
||||
{
|
||||
Painter p(&result);
|
||||
if (radius == ImageRoundRadius::Ellipse) {
|
||||
ensureEmptyUserpic()->paint(p, 0, 0, size, size);
|
||||
} else if (radius == ImageRoundRadius::None) {
|
||||
ensureEmptyUserpic()->paintSquare(p, 0, 0, size, size);
|
||||
} else if (radius == ImageRoundRadius::Large) {
|
||||
const auto radius = st::roundRadiusLarge;
|
||||
ensureEmptyUserpic()->paintRounded(p, 0, 0, size, size, radius);
|
||||
} else {
|
||||
ensureEmptyUserpic()->paintRounded(p, 0, 0, size, size);
|
||||
}
|
||||
|
||||
Painter p(&result);
|
||||
if (radius == 0) {
|
||||
ensureEmptyUserpic()->paintSquare(p, 0, 0, size, size);
|
||||
} else if (radius) {
|
||||
ensureEmptyUserpic()->paintRounded(p, 0, 0, size, size, *radius);
|
||||
} else if (isForum()) {
|
||||
ensureEmptyUserpic()->paintRounded(
|
||||
p,
|
||||
0,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
size * Ui::ForumUserpicRadiusMultiplier());
|
||||
} else {
|
||||
ensureEmptyUserpic()->paintCircle(p, 0, 0, size, size);
|
||||
}
|
||||
p.end();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_flags.h"
|
||||
#include "data/notify/data_peer_notify_settings.h"
|
||||
#include "data/data_cloud_file.h"
|
||||
#include "ui/userpic_view.h"
|
||||
|
||||
struct BotInfo;
|
||||
class PeerData;
|
||||
|
@ -36,13 +37,12 @@ class Forum;
|
|||
class ForumTopic;
|
||||
class Session;
|
||||
class GroupCall;
|
||||
class CloudImageView;
|
||||
struct ReactionId;
|
||||
|
||||
int PeerColorIndex(PeerId peerId);
|
||||
[[nodiscard]] int PeerColorIndex(PeerId peerId);
|
||||
|
||||
// Must be used only for PeerColor-s.
|
||||
PeerId FakePeerIdForJustName(const QString &name);
|
||||
[[nodiscard]] PeerId FakePeerIdForJustName(const QString &name);
|
||||
|
||||
class RestrictionCheckResult {
|
||||
public:
|
||||
|
@ -264,13 +264,13 @@ public:
|
|||
void setUserpicPhoto(const MTPPhoto &data);
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int size) const;
|
||||
void paintUserpicLeft(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
|
@ -279,30 +279,14 @@ public:
|
|||
}
|
||||
void loadUserpic();
|
||||
[[nodiscard]] bool hasUserpic() const;
|
||||
[[nodiscard]] std::shared_ptr<Data::CloudImageView> activeUserpicView();
|
||||
[[nodiscard]] std::shared_ptr<Data::CloudImageView> createUserpicView();
|
||||
[[nodiscard]] bool useEmptyUserpic(
|
||||
std::shared_ptr<Data::CloudImageView> &view) const;
|
||||
[[nodiscard]] InMemoryKey userpicUniqueKey(
|
||||
std::shared_ptr<Data::CloudImageView> &view) const;
|
||||
void saveUserpic(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
const QString &path,
|
||||
int size) const;
|
||||
void saveUserpicRounded(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
const QString &path,
|
||||
int size) const;
|
||||
[[nodiscard]] QPixmap genUserpic(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
int size) const;
|
||||
[[nodiscard]] Ui::PeerUserpicView activeUserpicView();
|
||||
[[nodiscard]] Ui::PeerUserpicView createUserpicView();
|
||||
[[nodiscard]] bool useEmptyUserpic(Ui::PeerUserpicView &view) const;
|
||||
[[nodiscard]] InMemoryKey userpicUniqueKey(Ui::PeerUserpicView &view) const;
|
||||
[[nodiscard]] QImage generateUserpicImage(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
int size) const;
|
||||
[[nodiscard]] QImage generateUserpicImage(
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int size,
|
||||
ImageRoundRadius radius) const;
|
||||
std::optional<int> radius = {}) const;
|
||||
[[nodiscard]] ImageLocation userpicLocation() const {
|
||||
return _userpic.location();
|
||||
}
|
||||
|
@ -332,8 +316,7 @@ public:
|
|||
return _openLink;
|
||||
}
|
||||
|
||||
[[nodiscard]] Image *currentUserpic(
|
||||
std::shared_ptr<Data::CloudImageView> &view) const;
|
||||
[[nodiscard]] QImage *userpicCloudImage(Ui::PeerUserpicView &view) const;
|
||||
|
||||
[[nodiscard]] bool canPinMessages() const;
|
||||
[[nodiscard]] bool canEditMessagesIndefinitely() const;
|
||||
|
@ -423,6 +406,7 @@ protected:
|
|||
const QString &newUsername);
|
||||
void updateUserpic(PhotoId photoId, MTP::DcId dcId, bool hasVideo);
|
||||
void clearUserpic();
|
||||
void invalidateEmptyUserpic();
|
||||
|
||||
private:
|
||||
void fillNames();
|
||||
|
|
|
@ -515,17 +515,10 @@ bool ChannelHasActiveCall(not_null<ChannelData*> channel) {
|
|||
rpl::producer<QImage> PeerUserpicImageValue(
|
||||
not_null<PeerData*> peer,
|
||||
int size) {
|
||||
return PeerUserpicImageValue(peer, size, ImageRoundRadius::Ellipse);
|
||||
}
|
||||
|
||||
rpl::producer<QImage> PeerUserpicImageValue(
|
||||
not_null<PeerData*> peer,
|
||||
int size,
|
||||
ImageRoundRadius radius) {
|
||||
return [=](auto consumer) {
|
||||
auto result = rpl::lifetime();
|
||||
struct State {
|
||||
std::shared_ptr<CloudImageView> view;
|
||||
Ui::PeerUserpicView view;
|
||||
rpl::lifetime waiting;
|
||||
InMemoryKey key = {};
|
||||
bool empty = true;
|
||||
|
@ -534,7 +527,7 @@ rpl::producer<QImage> PeerUserpicImageValue(
|
|||
const auto state = result.make_state<State>();
|
||||
state->push = [=] {
|
||||
const auto key = peer->userpicUniqueKey(state->view);
|
||||
const auto loading = state->view && !state->view->image();
|
||||
const auto loading = Ui::PeerUserpicLoading(state->view);
|
||||
|
||||
if (loading && !state->waiting) {
|
||||
peer->session().downloaderTaskFinished(
|
||||
|
@ -548,8 +541,7 @@ rpl::producer<QImage> PeerUserpicImageValue(
|
|||
}
|
||||
state->key = key;
|
||||
state->empty = false;
|
||||
consumer.put_next(
|
||||
peer->generateUserpicImage(state->view, size, radius));
|
||||
consumer.put_next(peer->generateUserpicImage(state->view, size));
|
||||
};
|
||||
peer->session().changes().peerFlagsValue(
|
||||
peer,
|
||||
|
|
|
@ -134,10 +134,6 @@ inline auto PeerFullFlagValue(
|
|||
[[nodiscard]] rpl::producer<QImage> PeerUserpicImageValue(
|
||||
not_null<PeerData*> peer,
|
||||
int size);
|
||||
[[nodiscard]] rpl::producer<QImage> PeerUserpicImageValue(
|
||||
not_null<PeerData*> peer,
|
||||
int size,
|
||||
ImageRoundRadius radius);
|
||||
|
||||
[[nodiscard]] const AllowedReactions &PeerAllowedReactions(
|
||||
not_null<PeerData*> peer);
|
||||
|
|
|
@ -228,22 +228,27 @@ void UserData::setAccessHash(uint64 accessHash) {
|
|||
if (accessHash == kInaccessibleAccessHashOld) {
|
||||
_accessHash = 0;
|
||||
_flags.add(Flag::Deleted);
|
||||
invalidateEmptyUserpic();
|
||||
} else {
|
||||
_accessHash = accessHash;
|
||||
}
|
||||
}
|
||||
|
||||
void UserData::setFlags(UserDataFlags which) {
|
||||
if ((which & UserDataFlag::Deleted)
|
||||
!= (flags() & UserDataFlag::Deleted)) {
|
||||
invalidateEmptyUserpic();
|
||||
}
|
||||
_flags.set((flags() & UserDataFlag::Self)
|
||||
| (which & ~UserDataFlag::Self));
|
||||
}
|
||||
|
||||
void UserData::addFlags(UserDataFlags which) {
|
||||
_flags.add(which & ~UserDataFlag::Self);
|
||||
setFlags(flags() | which);
|
||||
}
|
||||
|
||||
void UserData::removeFlags(UserDataFlags which) {
|
||||
_flags.remove(which & ~UserDataFlag::Self);
|
||||
setFlags(flags() & ~which);
|
||||
}
|
||||
|
||||
bool UserData::isVerified() const {
|
||||
|
|
|
@ -25,10 +25,10 @@ class Session;
|
|||
class Forum;
|
||||
class Folder;
|
||||
class ForumTopic;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Dialogs::Ui {
|
||||
|
@ -233,7 +233,7 @@ public:
|
|||
virtual void loadUserpic() = 0;
|
||||
virtual void paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Ui::PaintContext &context) const = 0;
|
||||
|
||||
[[nodiscard]] TimeId chatListTimeId() const {
|
||||
|
|
|
@ -1134,7 +1134,7 @@ void InnerWidget::paintSearchInFilter(
|
|||
void InnerWidget::paintSearchInPeer(
|
||||
Painter &p,
|
||||
not_null<PeerData*> peer,
|
||||
std::shared_ptr<Data::CloudImageView> &userpic,
|
||||
Ui::PeerUserpicView &userpic,
|
||||
int top,
|
||||
const Ui::Text::String &text) const {
|
||||
const auto paintUserpic = [&](Painter &p, int x, int y, int size) {
|
||||
|
@ -1168,7 +1168,7 @@ void InnerWidget::paintSearchInTopic(
|
|||
Painter &p,
|
||||
const Ui::PaintContext &context,
|
||||
not_null<Data::ForumTopic*> topic,
|
||||
std::shared_ptr<Data::CloudImageView> &userpic,
|
||||
Ui::PeerUserpicView &userpic,
|
||||
int top,
|
||||
const Ui::Text::String &text) const {
|
||||
const auto paintUserpic = [&](Painter &p, int x, int y, int size) {
|
||||
|
@ -2846,7 +2846,7 @@ void InnerWidget::searchInChat(Key key, PeerData *from) {
|
|||
_searchFromUserUserpic = _searchFromPeer->createUserpicView();
|
||||
} else {
|
||||
_cancelSearchFromUser->hide();
|
||||
_searchFromUserUserpic = nullptr;
|
||||
_searchFromUserUserpic = {};
|
||||
}
|
||||
if (_searchInChat || _searchFromPeer) {
|
||||
refreshSearchInChatLabel();
|
||||
|
@ -2855,7 +2855,7 @@ void InnerWidget::searchInChat(Key key, PeerData *from) {
|
|||
if (const auto peer = _searchInChat.peer()) {
|
||||
_searchInChatUserpic = peer->createUserpicView();
|
||||
} else {
|
||||
_searchInChatUserpic = nullptr;
|
||||
_searchInChatUserpic = {};
|
||||
}
|
||||
moveCancelSearchButtons();
|
||||
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/dragging_scroll_manager.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/userpic_view.h"
|
||||
#include "base/flags.h"
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
|
@ -39,7 +40,6 @@ class SessionController;
|
|||
} // namespace Window
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
class Thread;
|
||||
class Folder;
|
||||
class Forum;
|
||||
|
@ -340,7 +340,7 @@ private:
|
|||
void paintSearchInPeer(
|
||||
Painter &p,
|
||||
not_null<PeerData*> peer,
|
||||
std::shared_ptr<Data::CloudImageView> &userpic,
|
||||
Ui::PeerUserpicView &userpic,
|
||||
int top,
|
||||
const Ui::Text::String &text) const;
|
||||
void paintSearchInSaved(
|
||||
|
@ -355,7 +355,7 @@ private:
|
|||
Painter &p,
|
||||
const Ui::PaintContext &context,
|
||||
not_null<Data::ForumTopic*> topic,
|
||||
std::shared_ptr<Data::CloudImageView> &userpic,
|
||||
Ui::PeerUserpicView &userpic,
|
||||
int top,
|
||||
const Ui::Text::String &text) const;
|
||||
template <typename PaintUserpic>
|
||||
|
@ -470,8 +470,8 @@ private:
|
|||
Key _searchInChat;
|
||||
History *_searchInMigrated = nullptr;
|
||||
PeerData *_searchFromPeer = nullptr;
|
||||
mutable std::shared_ptr<Data::CloudImageView> _searchInChatUserpic;
|
||||
mutable std::shared_ptr<Data::CloudImageView> _searchFromUserUserpic;
|
||||
mutable Ui::PeerUserpicView _searchInChatUserpic;
|
||||
mutable Ui::PeerUserpicView _searchFromUserUserpic;
|
||||
Ui::Text::String _searchInChatText;
|
||||
Ui::Text::String _searchFromUserText;
|
||||
RowDescriptor _menuRow;
|
||||
|
|
|
@ -38,11 +38,11 @@ constexpr auto kNoneLayer = 0;
|
|||
void PaintCornerBadgeTTLFrame(
|
||||
QPainter &q,
|
||||
not_null<PeerData*> peer,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
float64 progress,
|
||||
int photoSize) {
|
||||
const auto ttl = peer->messagesTTL();
|
||||
if (!ttl || !view) {
|
||||
if (!ttl) {
|
||||
return;
|
||||
}
|
||||
using Radius = ImageRoundRadius;
|
||||
|
@ -54,7 +54,7 @@ void PaintCornerBadgeTTLFrame(
|
|||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto fullSize = photoSize;
|
||||
const auto blurredFull = Images::BlurLargeImage(
|
||||
peer->generateUserpicImage(view, fullSize * ratio, Radius::None),
|
||||
peer->generateUserpicImage(view, fullSize * ratio, 0),
|
||||
kBlurRadius);
|
||||
const auto partRect = CornerBadgeTTLRect(fullSize);
|
||||
const auto &partSize = partRect.width();
|
||||
|
@ -338,7 +338,7 @@ void Row::PaintCornerBadgeFrame(
|
|||
not_null<CornerBadgeUserpic*> data,
|
||||
not_null<PeerData*> peer,
|
||||
Ui::VideoUserpic *videoUserpic,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Ui::PaintContext &context) {
|
||||
data->frame.fill(Qt::transparent);
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/text/text.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/unread_badge.h"
|
||||
#include "ui/userpic_view.h"
|
||||
#include "dialogs/dialogs_key.h"
|
||||
#include "dialogs/ui/dialogs_message_view.h"
|
||||
|
||||
|
@ -20,10 +21,6 @@ namespace style {
|
|||
struct DialogRow;
|
||||
} // namespace style
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class RippleAnimation;
|
||||
} // namespace Ui
|
||||
|
@ -69,13 +66,12 @@ public:
|
|||
int outerWidth,
|
||||
const QColor *colorOverride = nullptr) const;
|
||||
|
||||
[[nodiscard]] auto userpicView() const
|
||||
-> std::shared_ptr<Data::CloudImageView> & {
|
||||
[[nodiscard]] Ui::PeerUserpicView &userpicView() const {
|
||||
return _userpic;
|
||||
}
|
||||
|
||||
private:
|
||||
mutable std::shared_ptr<Data::CloudImageView> _userpic;
|
||||
mutable Ui::PeerUserpicView _userpic;
|
||||
mutable std::unique_ptr<Ui::RippleAnimation> _ripple;
|
||||
|
||||
};
|
||||
|
@ -182,7 +178,7 @@ private:
|
|||
not_null<CornerBadgeUserpic*> data,
|
||||
not_null<PeerData*> peer,
|
||||
Ui::VideoUserpic *videoUserpic,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Ui::PaintContext &context);
|
||||
|
||||
Key _id;
|
||||
|
|
|
@ -285,9 +285,9 @@ void PaintRow(
|
|||
not_null<Entry*> entry,
|
||||
VideoUserpic *videoUserpic,
|
||||
PeerData *from,
|
||||
Ui::PeerBadge &fromBadge,
|
||||
PeerBadge &fromBadge,
|
||||
Fn<void()> customEmojiRepaint,
|
||||
const Ui::Text::String &fromName,
|
||||
const Text::String &fromName,
|
||||
const HiddenSenderInfo *hiddenSenderInfo,
|
||||
HistoryItem *item,
|
||||
const Data::Draft *draft,
|
||||
|
@ -306,8 +306,8 @@ void PaintRow(
|
|||
: context.selected
|
||||
? st::dialogsBgOver
|
||||
: anim::brush(
|
||||
st::dialogsBg,
|
||||
st::dialogsBgOver,
|
||||
st::dialogsBg,
|
||||
st::dialogsBgOver,
|
||||
context.childListShown);
|
||||
p.fillRect(geometry, bg);
|
||||
if (!(flags & Flag::TopicJumpRipple)) {
|
||||
|
@ -342,7 +342,7 @@ void PaintRow(
|
|||
(flags & Flag::AllowUserOnline) ? history : nullptr,
|
||||
context);
|
||||
} else if (hiddenSenderInfo) {
|
||||
hiddenSenderInfo->emptyUserpic.paint(
|
||||
hiddenSenderInfo->emptyUserpic.paintCircle(
|
||||
p,
|
||||
context.st->padding.left(),
|
||||
context.st->padding.top(),
|
||||
|
|
|
@ -38,8 +38,8 @@ using namespace ::Ui;
|
|||
class VideoUserpic;
|
||||
|
||||
struct TopicJumpCorners {
|
||||
Ui::CornersPixmaps normal;
|
||||
Ui::CornersPixmaps inverted;
|
||||
CornersPixmaps normal;
|
||||
CornersPixmaps inverted;
|
||||
QPixmap small;
|
||||
int invertedRadius = 0;
|
||||
int smallKey = 0; // = `-radius` if top right else `radius`.
|
||||
|
|
|
@ -30,7 +30,7 @@ int VideoUserpic::frameIndex() const {
|
|||
|
||||
void VideoUserpic::paintLeft(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
|
@ -133,7 +133,7 @@ void PaintUserpic(
|
|||
Painter &p,
|
||||
not_null<PeerData*> peer,
|
||||
Ui::VideoUserpic *videoUserpic,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
|
|
|
@ -12,10 +12,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
class Painter;
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
class PhotoMedia;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Dialogs::Ui {
|
||||
|
||||
using namespace ::Ui;
|
||||
|
@ -29,7 +32,7 @@ public:
|
|||
|
||||
void paintLeft(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int w,
|
||||
|
@ -54,8 +57,8 @@ private:
|
|||
void PaintUserpic(
|
||||
Painter &p,
|
||||
not_null<PeerData*> peer,
|
||||
Ui::VideoUserpic *videoUserpic,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
VideoUserpic *videoUserpic,
|
||||
PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
|
|
|
@ -7,6 +7,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#include "editor/editor_crop.h"
|
||||
|
||||
#include "ui/userpic_view.h"
|
||||
#include "styles/style_editor.h"
|
||||
#include "styles/style_basic.h"
|
||||
#include "styles/style_dialogs.h"
|
||||
|
@ -149,7 +150,7 @@ void Crop::setCropPaint(QRectF &&rect) {
|
|||
_painterPath.addEllipse(_cropPaint);
|
||||
} else if (_data.cropType == EditorData::CropType::RoundedRect) {
|
||||
const auto radius = std::min(_cropPaint.width(), _cropPaint.height())
|
||||
* st::roundRadiusLarge / float64(st::defaultDialogRow.photoSize);
|
||||
* Ui::ForumUserpicRadiusMultiplier();
|
||||
_painterPath.addRoundedRect(_cropPaint, radius, radius);
|
||||
} else {
|
||||
_painterPath.addRect(_cropPaint);
|
||||
|
|
|
@ -20,10 +20,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_boxes.h"
|
||||
#include "styles/style_chat.h"
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace AdminLog {
|
||||
namespace {
|
||||
|
||||
|
@ -64,7 +60,7 @@ private:
|
|||
QRect _checkRect;
|
||||
|
||||
const not_null<UserData*> _user;
|
||||
std::shared_ptr<Data::CloudImageView> _userpic;
|
||||
Ui::PeerUserpicView _userpic;
|
||||
Ui::Text::String _name;
|
||||
QString _statusText;
|
||||
bool _statusOnline = false;
|
||||
|
|
|
@ -19,10 +19,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
struct ChatRestrictionsInfo;
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
@ -38,6 +34,7 @@ enum class PointState : char;
|
|||
namespace Ui {
|
||||
class PopupMenu;
|
||||
class ChatStyle;
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -278,9 +275,8 @@ private:
|
|||
std::map<not_null<const HistoryItem*>, not_null<Element*>> _itemsByData;
|
||||
base::flat_map<not_null<const HistoryItem*>, TimeId> _itemDates;
|
||||
base::flat_set<FullMsgId> _animatedStickersPlayed;
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
std::shared_ptr<Data::CloudImageView>> _userpics, _userpicsCache;
|
||||
base::flat_map<not_null<PeerData*>, Ui::PeerUserpicView> _userpics;
|
||||
base::flat_map<not_null<PeerData*>, Ui::PeerUserpicView> _userpicsCache;
|
||||
int _itemsTop = 0;
|
||||
int _itemsWidth = 0;
|
||||
int _itemsHeight = 0;
|
||||
|
|
|
@ -2262,7 +2262,7 @@ void History::loadUserpic() {
|
|||
|
||||
void History::paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Dialogs::Ui::PaintContext &context) const {
|
||||
peer->paintUserpic(
|
||||
p,
|
||||
|
|
|
@ -398,7 +398,7 @@ public:
|
|||
void loadUserpic() override;
|
||||
void paintUserpic(
|
||||
Painter &p,
|
||||
std::shared_ptr<Data::CloudImageView> &view,
|
||||
Ui::PeerUserpicView &view,
|
||||
const Dialogs::Ui::PaintContext &context) const override;
|
||||
|
||||
void refreshChatListNameSortKey();
|
||||
|
|
|
@ -1135,7 +1135,8 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
|||
|
||||
// paint the userpic if it intersects the painted rect
|
||||
if (userpicTop + st::msgPhotoSize > clip.top()) {
|
||||
if (const auto from = view->data()->displayFrom()) {
|
||||
const auto item = view->data();
|
||||
if (const auto from = item->displayFrom()) {
|
||||
Dialogs::Ui::PaintUserpic(
|
||||
p,
|
||||
from,
|
||||
|
@ -1146,28 +1147,25 @@ void HistoryInner::paintEvent(QPaintEvent *e) {
|
|||
width(),
|
||||
st::msgPhotoSize,
|
||||
context.paused);
|
||||
} else if (const auto info = view->data()->hiddenSenderInfo()) {
|
||||
} else if (const auto info = item->hiddenSenderInfo()) {
|
||||
if (info->customUserpic.empty()) {
|
||||
info->emptyUserpic.paint(
|
||||
info->emptyUserpic.paintCircle(
|
||||
p,
|
||||
st::historyPhotoLeft,
|
||||
userpicTop,
|
||||
width(),
|
||||
st::msgPhotoSize);
|
||||
} else {
|
||||
const auto painted = info->paintCustomUserpic(
|
||||
auto &userpic = _hiddenSenderUserpics[item->id];
|
||||
const auto valid = info->paintCustomUserpic(
|
||||
p,
|
||||
userpic,
|
||||
st::historyPhotoLeft,
|
||||
userpicTop,
|
||||
width(),
|
||||
st::msgPhotoSize);
|
||||
if (!painted) {
|
||||
const auto itemId = view->data()->fullId();
|
||||
auto &v = _sponsoredUserpics[itemId.msg];
|
||||
if (!info->customUserpic.isCurrentView(v)) {
|
||||
v = info->customUserpic.createView();
|
||||
info->customUserpic.load(&session(), itemId);
|
||||
}
|
||||
if (!valid) {
|
||||
info->customUserpic.load(&session(), item->fullId());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -20,7 +20,6 @@ struct ClickHandlerContext;
|
|||
|
||||
namespace Data {
|
||||
struct Group;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -51,6 +50,7 @@ class PopupMenu;
|
|||
enum class ReportReason;
|
||||
struct ChatPaintContext;
|
||||
class PathShiftGradient;
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Dialogs::Ui {
|
||||
|
@ -458,12 +458,9 @@ private:
|
|||
bool _isChatWide = false;
|
||||
|
||||
base::flat_set<not_null<const HistoryItem*>> _animatedStickersPlayed;
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
std::shared_ptr<Data::CloudImageView>> _userpics, _userpicsCache;
|
||||
base::flat_map<
|
||||
MsgId,
|
||||
std::shared_ptr<Data::CloudImageView>> _sponsoredUserpics;
|
||||
base::flat_map<not_null<PeerData*>, Ui::PeerUserpicView> _userpics;
|
||||
base::flat_map<not_null<PeerData*>, Ui::PeerUserpicView> _userpicsCache;
|
||||
base::flat_map<MsgId, Ui::PeerUserpicView> _hiddenSenderUserpics;
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
std::unique_ptr<VideoUserpic>> _videoUserpics;
|
||||
|
|
|
@ -144,22 +144,31 @@ ClickHandlerPtr HiddenSenderInfo::ForwardClickHandler() {
|
|||
|
||||
bool HiddenSenderInfo::paintCustomUserpic(
|
||||
Painter &p,
|
||||
Ui::PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size) const {
|
||||
const auto view = customUserpic.activeView();
|
||||
if (const auto image = view ? view->image() : nullptr) {
|
||||
const auto circled = Images::Option::RoundCircle;
|
||||
p.drawPixmap(
|
||||
x,
|
||||
y,
|
||||
image->pix(size, size, { .options = circled }));
|
||||
return true;
|
||||
} else {
|
||||
emptyUserpic.paint(p, x, y, outerWidth, size);
|
||||
return false;
|
||||
Expects(!customUserpic.empty());
|
||||
|
||||
auto valid = true;
|
||||
if (!customUserpic.isCurrentView(view.cloud)) {
|
||||
view.cloud = customUserpic.createView();
|
||||
valid = false;
|
||||
}
|
||||
const auto image = *view.cloud;
|
||||
if (image.isNull()) {
|
||||
emptyUserpic.paintCircle(p, x, y, outerWidth, size);
|
||||
return valid;
|
||||
}
|
||||
Ui::ValidateUserpicCache(
|
||||
view,
|
||||
image.isNull() ? nullptr : &image,
|
||||
image.isNull() ? &emptyUserpic : nullptr,
|
||||
size * style::DevicePixelRatio(),
|
||||
false);
|
||||
p.drawImage(QRect(x, y, size, size), view.cached);
|
||||
return valid;
|
||||
}
|
||||
|
||||
void HistoryMessageForwarded::create(const HistoryMessageVia *via) const {
|
||||
|
|
|
@ -19,6 +19,7 @@ class VoiceSeekClickHandler;
|
|||
namespace Ui {
|
||||
struct ChatPaintContext;
|
||||
class ChatStyle;
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Data {
|
||||
|
@ -94,6 +95,7 @@ public:
|
|||
[[nodiscard]] const Ui::Text::String &nameText() const;
|
||||
[[nodiscard]] bool paintCustomUserpic(
|
||||
Painter &p,
|
||||
Ui::PeerUserpicView &view,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
|
|
|
@ -139,12 +139,12 @@ rpl::producer<Ui::GroupCallBarContent> GroupCallBarContentByCall(
|
|||
state->someUserpicsNotLoaded = false;
|
||||
for (auto &userpic : state->userpics) {
|
||||
userpic.peer->loadUserpic();
|
||||
const auto pic = userpic.peer->genUserpic(
|
||||
auto image = userpic.peer->generateUserpicImage(
|
||||
userpic.view,
|
||||
userpicSize);
|
||||
userpic.uniqueKey = userpic.peer->userpicUniqueKey(userpic.view);
|
||||
state->current.users.push_back({
|
||||
.userpic = pic.toImage(),
|
||||
.userpic = std::move(image),
|
||||
.userpicKey = userpic.uniqueKey,
|
||||
.id = userpic.peer->id.value,
|
||||
.speaking = userpic.speaking,
|
||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/userpic_view.h"
|
||||
|
||||
namespace Ui {
|
||||
struct GroupCallBarContent;
|
||||
|
@ -15,7 +16,6 @@ struct GroupCallBarContent;
|
|||
|
||||
namespace Data {
|
||||
class GroupCall;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace style {
|
||||
|
@ -27,7 +27,7 @@ namespace HistoryView {
|
|||
struct UserpicInRow {
|
||||
not_null<PeerData*> peer;
|
||||
bool speaking = false;
|
||||
mutable std::shared_ptr<Data::CloudImageView> view;
|
||||
mutable Ui::PeerUserpicView view;
|
||||
mutable InMemoryKey uniqueKey;
|
||||
};
|
||||
|
||||
|
|
|
@ -2132,7 +2132,8 @@ void ListWidget::paintEvent(QPaintEvent *e) {
|
|||
|
||||
// paint the userpic if it intersects the painted rect
|
||||
if (userpicTop + st::msgPhotoSize > clip.top()) {
|
||||
if (const auto from = view->data()->displayFrom()) {
|
||||
const auto item = view->data();
|
||||
if (const auto from = item->displayFrom()) {
|
||||
from->paintUserpicLeft(
|
||||
p,
|
||||
_userpics[from],
|
||||
|
@ -2140,28 +2141,25 @@ void ListWidget::paintEvent(QPaintEvent *e) {
|
|||
userpicTop,
|
||||
view->width(),
|
||||
st::msgPhotoSize);
|
||||
} else if (const auto info = view->data()->hiddenSenderInfo()) {
|
||||
} else if (const auto info = item->hiddenSenderInfo()) {
|
||||
if (info->customUserpic.empty()) {
|
||||
info->emptyUserpic.paint(
|
||||
info->emptyUserpic.paintCircle(
|
||||
p,
|
||||
st::historyPhotoLeft,
|
||||
userpicTop,
|
||||
view->width(),
|
||||
st::msgPhotoSize);
|
||||
} else {
|
||||
const auto painted = info->paintCustomUserpic(
|
||||
auto &userpic = _hiddenSenderUserpics[item->id];
|
||||
const auto valid = info->paintCustomUserpic(
|
||||
p,
|
||||
userpic,
|
||||
st::historyPhotoLeft,
|
||||
userpicTop,
|
||||
view->width(),
|
||||
st::msgPhotoSize);
|
||||
if (!painted) {
|
||||
const auto itemId = view->data()->fullId();
|
||||
auto &v = _sponsoredUserpics[itemId.msg];
|
||||
if (!info->customUserpic.isCurrentView(v)) {
|
||||
v = info->customUserpic.createView();
|
||||
info->customUserpic.load(session, itemId);
|
||||
}
|
||||
if (!valid) {
|
||||
info->customUserpic.load(session, item->fullId());
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
|
|
@ -29,6 +29,7 @@ class PopupMenu;
|
|||
class ChatTheme;
|
||||
struct ChatPaintContext;
|
||||
enum class TouchScrollState;
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
|
@ -37,7 +38,6 @@ class SessionController;
|
|||
|
||||
namespace Data {
|
||||
struct Group;
|
||||
class CloudImageView;
|
||||
struct Reaction;
|
||||
struct AllowedReactions;
|
||||
} // namespace Data
|
||||
|
@ -637,12 +637,9 @@ private:
|
|||
ItemRevealAnimation> _itemRevealAnimations;
|
||||
int _itemsRevealHeight = 0;
|
||||
base::flat_set<FullMsgId> _animatedStickersPlayed;
|
||||
base::flat_map<
|
||||
not_null<PeerData*>,
|
||||
std::shared_ptr<Data::CloudImageView>> _userpics, _userpicsCache;
|
||||
base::flat_map<
|
||||
MsgId,
|
||||
std::shared_ptr<Data::CloudImageView>> _sponsoredUserpics;
|
||||
base::flat_map<not_null<PeerData*>, Ui::PeerUserpicView> _userpics;
|
||||
base::flat_map<not_null<PeerData*>, Ui::PeerUserpicView> _userpicsCache;
|
||||
base::flat_map<MsgId, Ui::PeerUserpicView> _hiddenSenderUserpics;
|
||||
|
||||
const std::unique_ptr<Ui::PathShiftGradient> _pathGradient;
|
||||
|
||||
|
|
|
@ -1105,10 +1105,10 @@ void Message::paintCommentsButton(
|
|||
auto &entry = list[i];
|
||||
const auto peer = entry.peer;
|
||||
auto &view = entry.view;
|
||||
const auto wasView = view.get();
|
||||
const auto wasView = view.cloud.get();
|
||||
if (views->recentRepliers[i] != peer->id
|
||||
|| peer->userpicUniqueKey(view) != entry.uniqueKey
|
||||
|| view.get() != wasView) {
|
||||
|| view.cloud.get() != wasView) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -86,12 +86,12 @@ rpl::producer<Ui::RequestsBarContent> RequestsBarContentByPeer(
|
|||
state->someUserpicsNotLoaded = false;
|
||||
for (auto &userpic : state->userpics) {
|
||||
userpic.peer->loadUserpic();
|
||||
const auto pic = userpic.peer->genUserpic(
|
||||
auto image = userpic.peer->generateUserpicImage(
|
||||
userpic.view,
|
||||
userpicSize);
|
||||
userpic.uniqueKey = userpic.peer->userpicUniqueKey(userpic.view);
|
||||
state->current.users.push_back({
|
||||
.userpic = pic.toImage(),
|
||||
.userpic = std::move(image),
|
||||
.userpicKey = userpic.uniqueKey,
|
||||
.id = userpic.peer->id.value,
|
||||
});
|
||||
|
|
|
@ -96,8 +96,8 @@ Contact::Contact(
|
|||
|
||||
Contact::~Contact() {
|
||||
history()->owner().unregisterContactView(_userId, _parent);
|
||||
if (_userpic) {
|
||||
_userpic = nullptr;
|
||||
if (!_userpic.null()) {
|
||||
_userpic = {};
|
||||
_parent->checkHeavyPart();
|
||||
}
|
||||
}
|
||||
|
@ -177,13 +177,13 @@ void Contact::draw(Painter &p, const PaintContext &context) const {
|
|||
if (_userId) {
|
||||
QRect rthumb(style::rtlrect(st.padding.left(), st.padding.top() - topMinus, st.thumbSize, st.thumbSize, paintw));
|
||||
if (_contact) {
|
||||
const auto was = (_userpic != nullptr);
|
||||
const auto was = !_userpic.null();
|
||||
_contact->paintUserpic(p, _userpic, rthumb.x(), rthumb.y(), st.thumbSize);
|
||||
if (!was && _userpic) {
|
||||
if (!was && !_userpic.null()) {
|
||||
history()->owner().registerHeavyViewPart(_parent);
|
||||
}
|
||||
} else {
|
||||
_photoEmpty->paint(p, st.padding.left(), st.padding.top() - topMinus, paintw, st.thumbSize);
|
||||
_photoEmpty->paintCircle(p, st.padding.left(), st.padding.top() - topMinus, paintw, st.thumbSize);
|
||||
}
|
||||
if (context.selected()) {
|
||||
PainterHighQualityEnabler hq(p);
|
||||
|
@ -197,7 +197,7 @@ void Contact::draw(Painter &p, const PaintContext &context) const {
|
|||
p.setPen(stm->msgFileThumbLinkFg);
|
||||
p.drawTextLeft(nameleft, linktop, paintw, _link, _linkw);
|
||||
} else {
|
||||
_photoEmpty->paint(p, st.padding.left(), st.padding.top() - topMinus, paintw, st.thumbSize);
|
||||
_photoEmpty->paintCircle(p, st.padding.left(), st.padding.top() - topMinus, paintw, st.thumbSize);
|
||||
}
|
||||
const auto namewidth = paintw - nameleft - nameright;
|
||||
|
||||
|
@ -232,11 +232,11 @@ TextState Contact::textState(QPoint point, StateRequest request) const {
|
|||
}
|
||||
|
||||
void Contact::unloadHeavyPart() {
|
||||
_userpic = nullptr;
|
||||
_userpic = {};
|
||||
}
|
||||
|
||||
bool Contact::hasHeavyPart() const {
|
||||
return (_userpic != nullptr);
|
||||
return !_userpic.null();
|
||||
}
|
||||
|
||||
} // namespace HistoryView
|
||||
|
|
|
@ -8,10 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "history/view/media/history_view_media.h"
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
#include "ui/userpic_view.h"
|
||||
|
||||
namespace Ui {
|
||||
class EmptyUserpic;
|
||||
|
@ -72,7 +69,7 @@ private:
|
|||
QString _fname, _lname, _phone;
|
||||
Ui::Text::String _name;
|
||||
std::unique_ptr<Ui::EmptyUserpic> _photoEmpty;
|
||||
mutable std::shared_ptr<Data::CloudImageView> _userpic;
|
||||
mutable Ui::PeerUserpicView _userpic;
|
||||
|
||||
ClickHandlerPtr _linkl;
|
||||
int _linkw = 0;
|
||||
|
|
|
@ -245,17 +245,16 @@ void Location::draw(Painter &p, const PaintContext &context) const {
|
|||
void Location::validateImageCache(
|
||||
QSize outer,
|
||||
Ui::BubbleRounding rounding) const {
|
||||
Expects(_media != nullptr);
|
||||
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
if (_imageCache.size() == (outer * ratio)
|
||||
&& _imageCacheRounding == rounding) {
|
||||
return;
|
||||
}
|
||||
const auto thumbnail = _media->image();
|
||||
if (!thumbnail) {
|
||||
&& _imageCacheRounding == rounding
|
||||
|| _media->isNull()) {
|
||||
return;
|
||||
}
|
||||
_imageCache = Images::Round(
|
||||
thumbnail->original().scaled(
|
||||
_media->scaled(
|
||||
outer * ratio,
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation),
|
||||
|
|
|
@ -12,7 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Data {
|
||||
class CloudImage;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace HistoryView {
|
||||
|
@ -81,7 +80,7 @@ private:
|
|||
[[nodiscard]] int fullHeight() const;
|
||||
|
||||
const not_null<Data::CloudImage*> _data;
|
||||
mutable std::shared_ptr<Data::CloudImageView> _media;
|
||||
mutable std::shared_ptr<QImage> _media;
|
||||
Ui::Text::String _title, _description;
|
||||
ClickHandlerPtr _link;
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ struct Photo::Streamed {
|
|||
::Media::Streaming::Instance instance;
|
||||
::Media::Streaming::FrameRequest frozenRequest;
|
||||
QImage frozenFrame;
|
||||
std::array<QImage, 4> roundingCorners;
|
||||
QImage roundingMask;
|
||||
};
|
||||
|
||||
|
@ -352,22 +353,66 @@ void Photo::draw(Painter &p, const PaintContext &context) const {
|
|||
}
|
||||
}
|
||||
|
||||
void Photo::validateUserpicImageCache(QSize size, bool forum) const {
|
||||
const auto forumValue = forum ? 1 : 0;
|
||||
const auto large = _dataMedia->image(PhotoSize::Large);
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto blurredValue = large ? 0 : 1;
|
||||
if (_imageCache.size() == (size * ratio)
|
||||
&& _imageCacheForum == forumValue
|
||||
&& _imageCacheBlurred == blurredValue) {
|
||||
return;
|
||||
}
|
||||
auto original = [&] {
|
||||
if (large) {
|
||||
return large->original();
|
||||
} else if (const auto thumbnail = _dataMedia->image(
|
||||
PhotoSize::Thumbnail)) {
|
||||
return thumbnail->original();
|
||||
} else if (const auto small = _dataMedia->image(
|
||||
PhotoSize::Small)) {
|
||||
return small->original();
|
||||
} else if (const auto blurred = _dataMedia->thumbnailInline()) {
|
||||
return blurred->original();
|
||||
} else {
|
||||
return Image::Empty()->original();
|
||||
}
|
||||
}();
|
||||
auto args = Images::PrepareArgs();
|
||||
if (blurredValue) {
|
||||
args = args.blurred();
|
||||
}
|
||||
original = Images::Prepare(std::move(original), size, args);
|
||||
if (forumValue) {
|
||||
original = Images::Round(
|
||||
std::move(original),
|
||||
Images::CornersMask(std::min(size.width(), size.height())
|
||||
* Ui::ForumUserpicRadiusMultiplier()
|
||||
* style::DevicePixelRatio()));
|
||||
} else {
|
||||
original = Images::Circle(std::move(original));
|
||||
}
|
||||
_imageCache = std::move(original);
|
||||
_imageCacheForum = forumValue;
|
||||
_imageCacheBlurred = blurredValue;
|
||||
}
|
||||
|
||||
void Photo::validateImageCache(
|
||||
QSize outer,
|
||||
std::optional<Ui::BubbleRounding> rounding) const {
|
||||
const auto large = _dataMedia->image(PhotoSize::Large);
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto shouldBeBlurred = !large;
|
||||
const auto blurredValue = large ? 0 : 1;
|
||||
if (_imageCache.size() == (outer * ratio)
|
||||
&& _imageCacheRounding == rounding
|
||||
&& _imageCacheBlurred == shouldBeBlurred) {
|
||||
&& _imageCacheBlurred == blurredValue) {
|
||||
return;
|
||||
}
|
||||
_imageCache = Images::Round(
|
||||
prepareImageCache(outer),
|
||||
MediaRoundingMask(rounding));
|
||||
_imageCacheRounding = rounding;
|
||||
_imageCacheBlurred = shouldBeBlurred;
|
||||
_imageCacheBlurred = blurredValue;
|
||||
}
|
||||
|
||||
QImage Photo::prepareImageCache(QSize outer) const {
|
||||
|
@ -405,17 +450,23 @@ void Photo::paintUserpicFrame(
|
|||
const auto rect = QRect(photoPosition, size);
|
||||
const auto st = context.st;
|
||||
const auto sti = context.imageStyle();
|
||||
const auto forum = _parent->data()->history()->isForum();
|
||||
|
||||
if (_streamed
|
||||
&& _streamed->instance.player().ready()
|
||||
&& !_streamed->instance.player().videoSize().isEmpty()) {
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
auto request = ::Media::Streaming::FrameRequest();
|
||||
request.outer = size * cIntRetinaFactor();
|
||||
request.resize = size * cIntRetinaFactor();
|
||||
const auto forum = _parent->data()->history()->isForum();
|
||||
request.outer = request.resize = size * ratio;
|
||||
if (forum) {
|
||||
const auto radius = int(std::min(size.width(), size.height())
|
||||
* Ui::ForumUserpicRadiusMultiplier()
|
||||
* ratio);
|
||||
if (_streamed->roundingCorners[0].width() != radius) {
|
||||
_streamed->roundingCorners = Images::CornersMask(radius);
|
||||
}
|
||||
request.rounding = Images::CornersMaskRef(
|
||||
Images::CornersMask(ImageRoundRadius::Large));
|
||||
_streamed->roundingCorners);
|
||||
} else {
|
||||
if (_streamed->roundingMask.size() != request.outer) {
|
||||
_streamed->roundingMask = Images::EllipseMask(size);
|
||||
|
@ -438,28 +489,8 @@ void Photo::paintUserpicFrame(
|
|||
}
|
||||
return;
|
||||
}
|
||||
const auto pix = [&] {
|
||||
const auto forum = _parent->data()->history()->isForum();
|
||||
const auto args = Images::PrepareArgs{
|
||||
.options = (forum
|
||||
? Images::Option::RoundLarge
|
||||
: Images::Option::RoundCircle),
|
||||
};
|
||||
if (const auto large = _dataMedia->image(PhotoSize::Large)) {
|
||||
return large->pix(size, args);
|
||||
} else if (const auto thumbnail = _dataMedia->image(
|
||||
PhotoSize::Thumbnail)) {
|
||||
return thumbnail->pix(size, args.blurred());
|
||||
} else if (const auto small = _dataMedia->image(
|
||||
PhotoSize::Small)) {
|
||||
return small->pix(size, args.blurred());
|
||||
} else if (const auto blurred = _dataMedia->thumbnailInline()) {
|
||||
return blurred->pix(size, args.blurred());
|
||||
} else {
|
||||
return QPixmap();
|
||||
}
|
||||
}();
|
||||
p.drawPixmap(rect, pix);
|
||||
validateUserpicImageCache(size, forum);
|
||||
p.drawImage(rect, _imageCache);
|
||||
|
||||
if (_data->videoCanBePlayed() && !_streamed) {
|
||||
const auto innerSize = st::msgFileLayout.thumbSize;
|
||||
|
|
|
@ -129,6 +129,7 @@ private:
|
|||
void validateImageCache(
|
||||
QSize outer,
|
||||
std::optional<Ui::BubbleRounding> rounding) const;
|
||||
void validateUserpicImageCache(QSize size, bool forum) const;
|
||||
[[nodiscard]] QImage prepareImageCache(QSize outer) const;
|
||||
|
||||
bool videoAutoplayEnabled() const;
|
||||
|
@ -150,8 +151,9 @@ private:
|
|||
mutable std::unique_ptr<Streamed> _streamed;
|
||||
mutable QImage _imageCache;
|
||||
mutable std::optional<Ui::BubbleRounding> _imageCacheRounding;
|
||||
int _serviceWidth = 0;
|
||||
mutable bool _imageCacheBlurred = false;
|
||||
int _serviceWidth : 30 = 0;
|
||||
mutable int _imageCacheForum : 1 = 0;
|
||||
mutable int _imageCacheBlurred : 1 = 0;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -181,6 +181,11 @@ struct Poll::CloseInformation {
|
|||
Ui::Animations::Basic radial;
|
||||
};
|
||||
|
||||
struct Poll::RecentVoter {
|
||||
not_null<UserData*> user;
|
||||
mutable Ui::PeerUserpicView userpic;
|
||||
};
|
||||
|
||||
template <typename Callback>
|
||||
Poll::SendingAnimation::SendingAnimation(
|
||||
const QByteArray &option,
|
||||
|
@ -886,9 +891,9 @@ void Poll::paintRecentVoters(
|
|||
|
||||
auto created = false;
|
||||
for (auto &recent : _recentVoters) {
|
||||
const auto was = (recent.userpic != nullptr);
|
||||
const auto was = !recent.userpic.null();
|
||||
recent.user->paintUserpic(p, recent.userpic, x, y, size);
|
||||
if (!was && recent.userpic) {
|
||||
if (!was && !recent.userpic.null()) {
|
||||
created = true;
|
||||
}
|
||||
const auto paintContent = [&](QPainter &p) {
|
||||
|
@ -1499,13 +1504,13 @@ void Poll::clickHandlerPressedChanged(
|
|||
|
||||
void Poll::unloadHeavyPart() {
|
||||
for (auto &recent : _recentVoters) {
|
||||
recent.userpic = nullptr;
|
||||
recent.userpic = {};
|
||||
}
|
||||
}
|
||||
|
||||
bool Poll::hasHeavyPart() const {
|
||||
for (auto &recent : _recentVoters) {
|
||||
if (recent.userpic) {
|
||||
if (!recent.userpic.null()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,10 +12,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_poll.h"
|
||||
#include "base/weak_ptr.h"
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class RippleAnimation;
|
||||
class FireworksAnimation;
|
||||
|
@ -75,11 +71,7 @@ private:
|
|||
struct SendingAnimation;
|
||||
struct Answer;
|
||||
struct CloseInformation;
|
||||
|
||||
struct RecentVoter {
|
||||
not_null<UserData*> user;
|
||||
mutable std::shared_ptr<Data::CloudImageView> userpic;
|
||||
};
|
||||
struct RecentVoter;
|
||||
|
||||
QSize countOptimalSize() override;
|
||||
QSize countCurrentSize(int newWidth) override;
|
||||
|
|
|
@ -524,9 +524,9 @@ void InlineList::resolveUserpicsImage(const Button &button) const {
|
|||
for (auto &entry : userpics->list) {
|
||||
const auto peer = entry.peer;
|
||||
auto &view = entry.view;
|
||||
const auto wasView = view.get();
|
||||
const auto wasView = view.cloud.get();
|
||||
if (peer->userpicUniqueKey(view) != entry.uniqueKey
|
||||
|| view.get() != wasView) {
|
||||
|| view.cloud.get() != wasView) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_message_reaction_id.h"
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
class Reactions;
|
||||
} // namespace Data
|
||||
|
||||
|
|
|
@ -879,9 +879,17 @@ void Video::prepareThumbnail(QSize size) const {
|
|||
}
|
||||
}
|
||||
}
|
||||
auto resultThumbnailImage = _documentMedia
|
||||
? nullptr
|
||||
: getResultThumb(fileOrigin());
|
||||
const auto resultThumbnail = Image(resultThumbnailImage
|
||||
? base::duplicate(*resultThumbnailImage)
|
||||
: QImage());
|
||||
const auto thumb = _documentMedia
|
||||
? _documentMedia->thumbnail()
|
||||
: getResultThumb(fileOrigin());
|
||||
: resultThumbnailImage
|
||||
? &resultThumbnail
|
||||
: nullptr;
|
||||
if (!thumb) {
|
||||
return;
|
||||
}
|
||||
|
@ -1245,7 +1253,7 @@ void Contact::prepareThumbnail(int width, int height) const {
|
|||
w = width;
|
||||
}
|
||||
}
|
||||
_thumb = thumb->pixNoCache(
|
||||
_thumb = Image(base::duplicate(*thumb)).pixNoCache(
|
||||
QSize(w, h) * style::DevicePixelRatio(),
|
||||
{
|
||||
.options = Images::Option::TransparentBackground,
|
||||
|
@ -1403,7 +1411,7 @@ void Article::prepareThumbnail(int width, int height) const {
|
|||
w = width;
|
||||
}
|
||||
}
|
||||
_thumb = thumb->pixNoCache(
|
||||
_thumb = Image(base::duplicate(*thumb)).pixNoCache(
|
||||
QSize(w, h) * style::DevicePixelRatio(),
|
||||
{
|
||||
.options = Images::Option::TransparentBackground,
|
||||
|
|
|
@ -142,7 +142,7 @@ bool ItemBase::hasResultThumb() const {
|
|||
|| !_result->_locationThumbnail.empty());
|
||||
}
|
||||
|
||||
Image *ItemBase::getResultThumb(Data::FileOrigin origin) const {
|
||||
QImage *ItemBase::getResultThumb(Data::FileOrigin origin) const {
|
||||
if (_result && !_thumbnail) {
|
||||
if (!_result->_thumbnail.empty()) {
|
||||
_thumbnail = _result->_thumbnail.createView();
|
||||
|
@ -152,7 +152,9 @@ Image *ItemBase::getResultThumb(Data::FileOrigin origin) const {
|
|||
_result->_locationThumbnail.load(_result->_session, origin);
|
||||
}
|
||||
}
|
||||
return _thumbnail->image();
|
||||
return (_thumbnail && !_thumbnail->isNull())
|
||||
? _thumbnail.get()
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
QPixmap ItemBase::getResultContactAvatar(int width, int height) const {
|
||||
|
|
|
@ -16,10 +16,6 @@ namespace Ui {
|
|||
class PathShiftGradient;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace InlineBots {
|
||||
|
||||
class Result;
|
||||
|
@ -126,7 +122,7 @@ protected:
|
|||
DocumentData *getResultDocument() const;
|
||||
PhotoData *getResultPhoto() const;
|
||||
bool hasResultThumb() const;
|
||||
Image *getResultThumb(Data::FileOrigin origin) const;
|
||||
QImage *getResultThumb(Data::FileOrigin origin) const;
|
||||
QPixmap getResultContactAvatar(int width, int height) const;
|
||||
int getResultDuration() const;
|
||||
QString getResultUrl() const;
|
||||
|
@ -148,7 +144,7 @@ protected:
|
|||
|
||||
private:
|
||||
not_null<Context*> _context;
|
||||
mutable std::shared_ptr<Data::CloudImageView> _thumbnail;
|
||||
mutable std::shared_ptr<QImage> _thumbnail;
|
||||
|
||||
};
|
||||
|
||||
|
|
|
@ -110,8 +110,9 @@ Session::Session(
|
|||
_user,
|
||||
Data::PeerUpdate::Flag::Photo
|
||||
) | rpl::start_with_next([=] {
|
||||
[[maybe_unused]] const auto image = _user->currentUserpic(
|
||||
_selfUserpicView);
|
||||
auto view = Ui::PeerUserpicView{ .cloud = _selfUserpicView };
|
||||
[[maybe_unused]] const auto image = _user->userpicCloudImage(view);
|
||||
_selfUserpicView = view.cloud;
|
||||
}, lifetime());
|
||||
|
||||
crl::on_main(this, [=] {
|
||||
|
|
|
@ -32,7 +32,6 @@ class Templates;
|
|||
namespace Data {
|
||||
class Session;
|
||||
class Changes;
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Storage {
|
||||
|
@ -216,7 +215,7 @@ private:
|
|||
|
||||
const std::unique_ptr<Support::Helper> _supportHelper;
|
||||
|
||||
std::shared_ptr<Data::CloudImageView> _selfUserpicView;
|
||||
std::shared_ptr<QImage> _selfUserpicView;
|
||||
rpl::variable<bool> _premiumPossible = false;
|
||||
|
||||
rpl::event_stream<bool> _termsLockChanges;
|
||||
|
|
|
@ -2827,14 +2827,16 @@ void OverlayWidget::initStreamingThumbnail() {
|
|||
|
||||
_touchbarDisplay.fire(TouchBarItemType::Video);
|
||||
|
||||
auto userpicImage = std::optional<Image>();
|
||||
const auto computePhotoThumbnail = [&] {
|
||||
const auto thumbnail = _photoMedia->image(Data::PhotoSize::Thumbnail);
|
||||
if (thumbnail) {
|
||||
return thumbnail;
|
||||
} else if (_peer && _peer->userpicPhotoId() == _photo->id) {
|
||||
if (const auto view = _peer->activeUserpicView()) {
|
||||
if (const auto image = view->image()) {
|
||||
return image;
|
||||
if (const auto view = _peer->activeUserpicView(); view.cloud) {
|
||||
if (!view.cloud->isNull()) {
|
||||
userpicImage.emplace(base::duplicate(*view.cloud));
|
||||
return &*userpicImage;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3455,8 +3457,11 @@ void OverlayWidget::validatePhotoCurrentImage() {
|
|||
&& !_message
|
||||
&& _peer
|
||||
&& _peer->hasUserpic()) {
|
||||
if (const auto view = _peer->activeUserpicView()) {
|
||||
validatePhotoImage(view->image(), true);
|
||||
if (const auto view = _peer->activeUserpicView(); view.cloud) {
|
||||
if (!view.cloud->isNull()) {
|
||||
auto image = Image(base::duplicate(*view.cloud));
|
||||
validatePhotoImage(&image, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (_staticContent.isNull()) {
|
||||
|
|
|
@ -23,6 +23,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "main/main_session.h"
|
||||
#include "lang/lang_keys.h"
|
||||
#include "base/weak_ptr.h"
|
||||
#include "window/notifications_utilities.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
#include <QtCore/QBuffer>
|
||||
|
@ -906,7 +907,7 @@ public:
|
|||
void showNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -1013,7 +1014,7 @@ Manager::Private::Private(not_null<Manager*> manager)
|
|||
void Manager::Private::showNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -1041,12 +1042,8 @@ void Manager::Private::showNotification(
|
|||
}
|
||||
|
||||
if (!options.hideNameAndPhoto) {
|
||||
const auto userpic = peer->isSelf()
|
||||
? Ui::EmptyUserpic::GenerateSavedMessages(st::notifyMacPhotoSize)
|
||||
: peer->isRepliesChat()
|
||||
? Ui::EmptyUserpic::GenerateRepliesMessages(st::notifyMacPhotoSize)
|
||||
: peer->genUserpic(userpicView, st::notifyMacPhotoSize);
|
||||
notification->setImage(userpic.toImage());
|
||||
notification->setImage(
|
||||
Window::Notifications::GenerateUserpic(peer, userpicView));
|
||||
}
|
||||
|
||||
auto i = _notifications.find(key);
|
||||
|
@ -1183,7 +1180,7 @@ Manager::~Manager() = default;
|
|||
void Manager::doShowNativeNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
|
@ -22,7 +22,7 @@ protected:
|
|||
void doShowNativeNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
|
@ -22,7 +22,7 @@ protected:
|
|||
void doShowNativeNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
|
@ -19,6 +19,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/empty_userpic.h"
|
||||
#include "main/main_session.h"
|
||||
#include "mainwindow.h"
|
||||
#include "window/notification_utilities.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
#include <thread>
|
||||
|
@ -189,7 +190,7 @@ public:
|
|||
void showNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -265,7 +266,7 @@ Manager::Private::Private(Manager *manager)
|
|||
void Manager::Private::showNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -302,12 +303,8 @@ void Manager::Private::showNotification(
|
|||
[notification setInformativeText:Q2NSString(msg)];
|
||||
if (!options.hideNameAndPhoto
|
||||
&& [notification respondsToSelector:@selector(setContentImage:)]) {
|
||||
auto userpic = peer->isSelf()
|
||||
? Ui::EmptyUserpic::GenerateSavedMessages(st::notifyMacPhotoSize)
|
||||
: peer->isRepliesChat()
|
||||
? Ui::EmptyUserpic::GenerateRepliesMessages(st::notifyMacPhotoSize)
|
||||
: peer->genUserpic(userpicView, st::notifyMacPhotoSize);
|
||||
NSImage *img = Q2NSImage(userpic.toImage());
|
||||
NSImage *img = Q2NSImage(
|
||||
Window::Notifications::GenerateUserpic(peer, userpicView));
|
||||
[notification setContentImage:img];
|
||||
}
|
||||
|
||||
|
@ -475,7 +472,7 @@ Manager::~Manager() = default;
|
|||
void Manager::doShowNativeNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
|
@ -84,7 +84,7 @@ QImage ArchiveUserpic(not_null<Data::Folder*> folder) {
|
|||
auto result = PrepareImage();
|
||||
Painter paint(&result);
|
||||
|
||||
auto view = std::shared_ptr<Data::CloudImageView>();
|
||||
auto view = Ui::PeerUserpicView();
|
||||
folder->paintUserpic(paint, 0, 0, result.width());
|
||||
return result;
|
||||
}
|
||||
|
@ -161,7 +161,7 @@ TimeId CalculateOnlineTill(not_null<PeerData*> peer) {
|
|||
@implementation PinnedDialogsPanel {
|
||||
struct Pin {
|
||||
PeerData *peer = nullptr;
|
||||
std::shared_ptr<Data::CloudImageView> userpicView = nullptr;
|
||||
Ui::PeerUserpicView userpicView;
|
||||
int index = -1;
|
||||
QImage userpic;
|
||||
QImage unreadBadge;
|
||||
|
|
|
@ -405,15 +405,13 @@ void Create(Window::Notifications::System *system) {
|
|||
#ifndef __MINGW32__
|
||||
class Manager::Private {
|
||||
public:
|
||||
using Type = Window::Notifications::CachedUserpics::Type;
|
||||
|
||||
explicit Private(Manager *instance, Type type);
|
||||
explicit Private(Manager *instance);
|
||||
bool init();
|
||||
|
||||
bool showNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -438,7 +436,7 @@ private:
|
|||
bool showNotificationInTryCatch(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -460,9 +458,8 @@ private:
|
|||
|
||||
};
|
||||
|
||||
Manager::Private::Private(Manager *instance, Type type)
|
||||
: _cachedUserpics(type)
|
||||
, _guarded(std::make_shared<Manager*>(instance)) {
|
||||
Manager::Private::Private(Manager *instance)
|
||||
: _guarded(std::make_shared<Manager*>(instance)) {
|
||||
ToastActivations(
|
||||
) | rpl::start_with_next([=](const ToastActivation &activation) {
|
||||
handleActivation(activation);
|
||||
|
@ -657,7 +654,7 @@ void Manager::Private::handleActivation(const ToastActivation &activation) {
|
|||
bool Manager::Private::showNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -692,7 +689,7 @@ std::wstring Manager::Private::ensureSendButtonIcon() {
|
|||
bool Manager::Private::showNotificationInTryCatch(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -870,7 +867,7 @@ void Manager::Private::tryHide(const ToastNotification ¬ification) {
|
|||
|
||||
Manager::Manager(Window::Notifications::System *system)
|
||||
: NativeManager(system)
|
||||
, _private(std::make_unique<Private>(this, Private::Type::Rounded)) {
|
||||
, _private(std::make_unique<Private>(this)) {
|
||||
}
|
||||
|
||||
bool Manager::init() {
|
||||
|
@ -890,7 +887,7 @@ Manager::~Manager() = default;
|
|||
void Manager::doShowNativeNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
|
@ -30,7 +30,7 @@ protected:
|
|||
void doShowNativeNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
|
@ -8,10 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#pragma once
|
||||
|
||||
#include "profile/profile_block_widget.h"
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
#include "ui/userpic_view.h"
|
||||
|
||||
namespace Ui {
|
||||
class RippleAnimation;
|
||||
|
@ -33,7 +30,7 @@ public:
|
|||
~Item();
|
||||
|
||||
const not_null<PeerData*> peer;
|
||||
std::shared_ptr<Data::CloudImageView> userpic;
|
||||
Ui::PeerUserpicView userpic;
|
||||
Ui::Text::String name;
|
||||
QString statusText;
|
||||
bool statusHasOnlineColor = false;
|
||||
|
|
|
@ -644,7 +644,7 @@ void SetupAccountsWrap(
|
|||
}
|
||||
|
||||
Ui::RpWidget userpic;
|
||||
std::shared_ptr<Data::CloudImageView> view;
|
||||
Ui::PeerUserpicView view;
|
||||
base::unique_qptr<Ui::PopupMenu> menu;
|
||||
};
|
||||
const auto state = raw->lifetime().make_state<State>(raw);
|
||||
|
|
|
@ -360,7 +360,7 @@ RoundImageCheckbox::RoundImageCheckbox(
|
|||
const style::RoundImageCheckbox &st,
|
||||
Fn<void()> updateCallback,
|
||||
PaintRoundImage &&paintRoundImage,
|
||||
Fn<ImageRoundRadius()> roundingRadius)
|
||||
Fn<std::optional<int>(int size)> roundingRadius)
|
||||
: _st(st)
|
||||
, _updateCallback(updateCallback)
|
||||
, _paintRoundImage(std::move(paintRoundImage))
|
||||
|
@ -390,8 +390,8 @@ void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) const {
|
|||
|
||||
if (selectionLevel > 0) {
|
||||
const auto radius = _roundingRadius
|
||||
? _roundingRadius()
|
||||
: ImageRoundRadius::Ellipse;
|
||||
? _roundingRadius(_st.imageRadius)
|
||||
: std::optional<int>();
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setOpacity(std::clamp(selectionLevel, 0., 1.));
|
||||
p.setBrush(Qt::NoBrush);
|
||||
|
@ -405,11 +405,10 @@ void RoundImageCheckbox::paint(Painter &p, int x, int y, int outerWidth) const {
|
|||
_st.imageRadius * 2,
|
||||
_st.imageRadius * 2,
|
||||
outerWidth);
|
||||
if (radius == ImageRoundRadius::Ellipse) {
|
||||
if (!radius) {
|
||||
p.drawEllipse(rect);
|
||||
} else {
|
||||
const auto pxRadius = st::roundRadiusLarge;
|
||||
p.drawRoundedRect(rect, pxRadius, pxRadius);
|
||||
p.drawRoundedRect(rect, *radius, *radius);
|
||||
}
|
||||
p.setOpacity(1.);
|
||||
}
|
||||
|
|
|
@ -52,7 +52,7 @@ public:
|
|||
const style::RoundImageCheckbox &st,
|
||||
Fn<void()> updateCallback,
|
||||
PaintRoundImage &&paintRoundImage,
|
||||
Fn<ImageRoundRadius()> roundingRadius = nullptr);
|
||||
Fn<std::optional<int>(int size)> roundingRadius = nullptr);
|
||||
|
||||
void paint(Painter &p, int x, int y, int outerWidth) const;
|
||||
float64 checkedAnimationRatio() const;
|
||||
|
@ -76,7 +76,7 @@ private:
|
|||
const style::RoundImageCheckbox &_st;
|
||||
Fn<void()> _updateCallback;
|
||||
PaintRoundImage _paintRoundImage;
|
||||
Fn<ImageRoundRadius()> _roundingRadius;
|
||||
Fn<std::optional<int>(int size)> _roundingRadius;
|
||||
|
||||
QPixmap _wideCache;
|
||||
Ui::Animations::Simple _selection;
|
||||
|
|
|
@ -193,7 +193,7 @@ void PaintInaccessibleAccountInner(
|
|||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] QPixmap Generate(int size, Fn<void(QPainter&)> callback) {
|
||||
[[nodiscard]] QImage Generate(int size, Fn<void(QPainter&)> callback) {
|
||||
auto result = QImage(
|
||||
QSize(size, size) * style::DevicePixelRatio(),
|
||||
QImage::Format_ARGB32_Premultiplied);
|
||||
|
@ -203,7 +203,7 @@ void PaintInaccessibleAccountInner(
|
|||
Painter p(&result);
|
||||
callback(p);
|
||||
}
|
||||
return Ui::PixmapFromImage(std::move(result));
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -286,7 +286,7 @@ void EmptyUserpic::paint(
|
|||
}
|
||||
}
|
||||
|
||||
void EmptyUserpic::paint(
|
||||
void EmptyUserpic::paintCircle(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
|
@ -304,9 +304,6 @@ void EmptyUserpic::paintRounded(
|
|||
int outerWidth,
|
||||
int size,
|
||||
int radius) const {
|
||||
if (!radius) {
|
||||
radius = st::roundRadiusSmall;
|
||||
}
|
||||
paint(p, x, y, outerWidth, size, [&] {
|
||||
p.drawRoundedRect(x, y, size, size, radius, radius);
|
||||
});
|
||||
|
@ -338,21 +335,6 @@ void EmptyUserpic::PaintSavedMessages(
|
|||
PaintSavedMessages(p, x, y, outerWidth, size, QBrush(bg), fg);
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintSavedMessagesRounded(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size) {
|
||||
auto bg = QLinearGradient(x, y, x, y + size);
|
||||
bg.setStops({
|
||||
{ 0., st::historyPeerSavedMessagesBg->c },
|
||||
{ 1., st::historyPeerSavedMessagesBg2->c }
|
||||
});
|
||||
const auto &fg = st::historyPeerUserpicFg;
|
||||
PaintSavedMessagesRounded(p, x, y, outerWidth, size, QBrush(bg), fg);
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintSavedMessages(
|
||||
QPainter &p,
|
||||
int x,
|
||||
|
@ -371,42 +353,12 @@ void EmptyUserpic::PaintSavedMessages(
|
|||
PaintSavedMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintSavedMessagesRounded(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size,
|
||||
QBrush bg,
|
||||
const style::color &fg) {
|
||||
x = style::RightToLeft() ? (outerWidth - x - size) : x;
|
||||
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setBrush(std::move(bg));
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(
|
||||
x,
|
||||
y,
|
||||
size,
|
||||
size,
|
||||
st::roundRadiusSmall,
|
||||
st::roundRadiusSmall);
|
||||
|
||||
PaintSavedMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
QPixmap EmptyUserpic::GenerateSavedMessages(int size) {
|
||||
QImage EmptyUserpic::GenerateSavedMessages(int size) {
|
||||
return Generate(size, [&](QPainter &p) {
|
||||
PaintSavedMessages(p, 0, 0, size, size);
|
||||
});
|
||||
}
|
||||
|
||||
QPixmap EmptyUserpic::GenerateSavedMessagesRounded(int size) {
|
||||
return Generate(size, [&](QPainter &p) {
|
||||
PaintSavedMessagesRounded(p, 0, 0, size, size);
|
||||
});
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintRepliesMessages(
|
||||
QPainter &p,
|
||||
int x,
|
||||
|
@ -422,21 +374,6 @@ void EmptyUserpic::PaintRepliesMessages(
|
|||
PaintRepliesMessages(p, x, y, outerWidth, size, QBrush(bg), fg);
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintRepliesMessagesRounded(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size) {
|
||||
auto bg = QLinearGradient(x, y, x, y + size);
|
||||
bg.setStops({
|
||||
{ 0., st::historyPeerSavedMessagesBg->c },
|
||||
{ 1., st::historyPeerSavedMessagesBg2->c }
|
||||
});
|
||||
const auto &fg = st::historyPeerUserpicFg;
|
||||
PaintRepliesMessagesRounded(p, x, y, outerWidth, size, QBrush(bg), fg);
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintRepliesMessages(
|
||||
QPainter &p,
|
||||
int x,
|
||||
|
@ -455,42 +392,12 @@ void EmptyUserpic::PaintRepliesMessages(
|
|||
PaintRepliesMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
void EmptyUserpic::PaintRepliesMessagesRounded(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size,
|
||||
QBrush bg,
|
||||
const style::color &fg) {
|
||||
x = style::RightToLeft() ? (outerWidth - x - size) : x;
|
||||
|
||||
PainterHighQualityEnabler hq(p);
|
||||
p.setBrush(bg);
|
||||
p.setPen(Qt::NoPen);
|
||||
p.drawRoundedRect(
|
||||
x,
|
||||
y,
|
||||
size,
|
||||
size,
|
||||
st::roundRadiusSmall,
|
||||
st::roundRadiusSmall);
|
||||
|
||||
PaintRepliesMessagesInner(p, x, y, size, fg);
|
||||
}
|
||||
|
||||
QPixmap EmptyUserpic::GenerateRepliesMessages(int size) {
|
||||
QImage EmptyUserpic::GenerateRepliesMessages(int size) {
|
||||
return Generate(size, [&](QPainter &p) {
|
||||
PaintRepliesMessages(p, 0, 0, size, size);
|
||||
});
|
||||
}
|
||||
|
||||
QPixmap EmptyUserpic::GenerateRepliesMessagesRounded(int size) {
|
||||
return Generate(size, [&](QPainter &p) {
|
||||
PaintRepliesMessagesRounded(p, 0, 0, size, size);
|
||||
});
|
||||
}
|
||||
|
||||
std::pair<uint64, uint64> EmptyUserpic::uniqueKey() const {
|
||||
const auto first = (uint64(0xFFFFFFFFU) << 32)
|
||||
| anim::getPremultiplied(_colors.color1->c);
|
||||
|
@ -510,7 +417,7 @@ QPixmap EmptyUserpic::generate(int size) {
|
|||
result.fill(Qt::transparent);
|
||||
{
|
||||
auto p = QPainter(&result);
|
||||
paint(p, 0, 0, size, size);
|
||||
paintCircle(p, 0, 0, size, size);
|
||||
}
|
||||
return Ui::PixmapFromImage(std::move(result));
|
||||
}
|
||||
|
|
|
@ -7,9 +7,11 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
*/
|
||||
#pragma once
|
||||
|
||||
#include "base/weak_ptr.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class EmptyUserpic {
|
||||
class EmptyUserpic final : public base::has_weak_ptr {
|
||||
public:
|
||||
struct BgColors {
|
||||
const style::color color1;
|
||||
|
@ -24,7 +26,7 @@ public:
|
|||
|
||||
EmptyUserpic(const BgColors &colors, const QString &name);
|
||||
|
||||
void paint(
|
||||
void paintCircle(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
|
@ -52,12 +54,6 @@ public:
|
|||
int y,
|
||||
int outerWidth,
|
||||
int size);
|
||||
static void PaintSavedMessagesRounded(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size);
|
||||
static void PaintSavedMessages(
|
||||
QPainter &p,
|
||||
int x,
|
||||
|
@ -66,16 +62,7 @@ public:
|
|||
int size,
|
||||
QBrush bg,
|
||||
const style::color &fg);
|
||||
static void PaintSavedMessagesRounded(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size,
|
||||
QBrush bg,
|
||||
const style::color &fg);
|
||||
[[nodiscard]] static QPixmap GenerateSavedMessages(int size);
|
||||
[[nodiscard]] static QPixmap GenerateSavedMessagesRounded(int size);
|
||||
[[nodiscard]] static QImage GenerateSavedMessages(int size);
|
||||
|
||||
static void PaintRepliesMessages(
|
||||
QPainter &p,
|
||||
|
@ -83,12 +70,6 @@ public:
|
|||
int y,
|
||||
int outerWidth,
|
||||
int size);
|
||||
static void PaintRepliesMessagesRounded(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size);
|
||||
static void PaintRepliesMessages(
|
||||
QPainter &p,
|
||||
int x,
|
||||
|
@ -97,16 +78,7 @@ public:
|
|||
int size,
|
||||
QBrush bg,
|
||||
const style::color &fg);
|
||||
static void PaintRepliesMessagesRounded(
|
||||
QPainter &p,
|
||||
int x,
|
||||
int y,
|
||||
int outerWidth,
|
||||
int size,
|
||||
QBrush bg,
|
||||
const style::color &fg);
|
||||
[[nodiscard]] static QPixmap GenerateRepliesMessages(int size);
|
||||
[[nodiscard]] static QPixmap GenerateRepliesMessagesRounded(int size);
|
||||
[[nodiscard]] static QImage GenerateRepliesMessages(int size);
|
||||
|
||||
~EmptyUserpic();
|
||||
|
||||
|
|
|
@ -354,7 +354,7 @@ void UserpicButton::setupPeerViewers() {
|
|||
) | rpl::filter([=] {
|
||||
return _waiting;
|
||||
}) | rpl::start_with_next([=] {
|
||||
if (!_userpicView || _userpicView->image()) {
|
||||
if (!Ui::PeerUserpicLoading(_userpicView)) {
|
||||
_waiting = false;
|
||||
startNewPhotoShowing();
|
||||
}
|
||||
|
@ -473,12 +473,17 @@ void UserpicButton::paintUserpicFrame(Painter &p, QPoint photoPosition) {
|
|||
: false;
|
||||
auto request = Media::Streaming::FrameRequest();
|
||||
auto size = QSize{ _st.photoSize, _st.photoSize };
|
||||
request.outer = size * cIntRetinaFactor();
|
||||
request.resize = size * cIntRetinaFactor();
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
request.outer = request.resize = size * ratio;
|
||||
const auto forum = _peer && _peer->isForum();
|
||||
if (forum) {
|
||||
request.rounding = Images::CornersMaskRef(
|
||||
Images::CornersMask(ImageRoundRadius::Large));
|
||||
const auto radius = int(_st.photoSize
|
||||
* Ui::ForumUserpicRadiusMultiplier()
|
||||
* ratio);
|
||||
if (_roundingCorners[0].width() != radius) {
|
||||
_roundingCorners = Images::CornersMask(radius);
|
||||
}
|
||||
request.rounding = Images::CornersMaskRef(_roundingCorners);
|
||||
} else {
|
||||
if (_ellipseMask.size() != request.outer) {
|
||||
_ellipseMask = Images::EllipseMask(size);
|
||||
|
@ -520,7 +525,7 @@ void UserpicButton::processPeerPhoto() {
|
|||
Expects(_peer != nullptr);
|
||||
|
||||
_userpicView = _peer->createUserpicView();
|
||||
_waiting = _userpicView && !_userpicView->image();
|
||||
_waiting = Ui::PeerUserpicLoading(_userpicView);
|
||||
if (_waiting) {
|
||||
_peer->loadUserpic();
|
||||
}
|
||||
|
@ -798,7 +803,7 @@ void UserpicButton::fillShape(QPainter &p, const style::color &color) const {
|
|||
p.setBrush(color);
|
||||
const auto size = _st.photoSize;
|
||||
if (_peer && _peer->isForum()) {
|
||||
const auto radius = st::roundRadiusLarge;
|
||||
const auto radius = size * Ui::ForumUserpicRadiusMultiplier();
|
||||
p.drawRoundedRect(0, 0, size, size, radius, radius);
|
||||
} else {
|
||||
p.drawEllipse(0, 0, size, size);
|
||||
|
@ -811,8 +816,8 @@ void UserpicButton::prepareUserpicPixmap() {
|
|||
}
|
||||
auto size = _st.photoSize;
|
||||
_userpicHasImage = _peer
|
||||
? (_peer->currentUserpic(_userpicView) || _role != Role::ChangePhoto)
|
||||
: false;
|
||||
&& (_peer->userpicCloudImage(_userpicView)
|
||||
|| _role != Role::ChangePhoto);
|
||||
_userpic = CreateSquarePixmap(size, [&](Painter &p) {
|
||||
if (_userpicHasImage) {
|
||||
_peer->paintUserpic(p, _userpicView, 0, 0, _st.photoSize);
|
||||
|
|
|
@ -11,15 +11,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/widgets/tooltip.h"
|
||||
#include "ui/effects/animations.h"
|
||||
#include "ui/effects/cross_line.h"
|
||||
#include "ui/userpic_view.h"
|
||||
#include "styles/style_window.h"
|
||||
#include "styles/style_widgets.h"
|
||||
|
||||
class PeerData;
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Window {
|
||||
class Controller;
|
||||
class SessionController;
|
||||
|
@ -159,7 +156,7 @@ private:
|
|||
::Window::SessionController *_controller = nullptr;
|
||||
::Window::Controller *_window = nullptr;
|
||||
PeerData *_peer = nullptr;
|
||||
std::shared_ptr<Data::CloudImageView> _userpicView;
|
||||
PeerUserpicView _userpicView;
|
||||
QString _cropTitle;
|
||||
Role _role = Role::ChangePhoto;
|
||||
bool _notShownYet = true;
|
||||
|
@ -169,28 +166,29 @@ private:
|
|||
bool _userpicCustom = false;
|
||||
bool _requestToUpload = false;
|
||||
InMemoryKey _userpicUniqueKey;
|
||||
Ui::Animations::Simple _a_appearance;
|
||||
Animations::Simple _a_appearance;
|
||||
QImage _result;
|
||||
QImage _ellipseMask;
|
||||
std::array<QImage, 4> _roundingCorners;
|
||||
std::unique_ptr<Media::Streaming::Instance> _streamed;
|
||||
PhotoData *_streamedPhoto = nullptr;
|
||||
|
||||
base::unique_qptr<Ui::PopupMenu> _menu;
|
||||
base::unique_qptr<PopupMenu> _menu;
|
||||
|
||||
bool _showSavedMessagesOnSelf = false;
|
||||
bool _canOpenPhoto = false;
|
||||
bool _cursorInChangeOverlay = false;
|
||||
bool _changeOverlayEnabled = false;
|
||||
Ui::Animations::Simple _changeOverlayShown;
|
||||
Animations::Simple _changeOverlayShown;
|
||||
|
||||
rpl::event_stream<QImage> _chosenImages;
|
||||
rpl::event_stream<> _uploadPhotoRequests;
|
||||
|
||||
};
|
||||
|
||||
class SilentToggle
|
||||
: public Ui::RippleButton
|
||||
, public Ui::AbstractTooltipShower {
|
||||
class SilentToggle final
|
||||
: public RippleButton
|
||||
, public AbstractTooltipShower {
|
||||
public:
|
||||
SilentToggle(QWidget *parent, not_null<ChannelData*> channel);
|
||||
|
||||
|
@ -218,7 +216,7 @@ private:
|
|||
not_null<ChannelData*> _channel;
|
||||
bool _checked = false;
|
||||
|
||||
Ui::Animations::Simple _crossLineAnimation;
|
||||
Animations::Simple _crossLineAnimation;
|
||||
|
||||
};
|
||||
|
||||
|
|
80
Telegram/SourceFiles/ui/userpic_view.cpp
Normal file
80
Telegram/SourceFiles/ui/userpic_view.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
/*
|
||||
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 "ui/userpic_view.h"
|
||||
|
||||
#include "ui/empty_userpic.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
|
||||
namespace Ui {
|
||||
|
||||
float64 ForumUserpicRadiusMultiplier() {
|
||||
return 0.3;
|
||||
}
|
||||
|
||||
bool PeerUserpicLoading(const PeerUserpicView &view) {
|
||||
return view.cloud && view.cloud->isNull();
|
||||
}
|
||||
|
||||
void ValidateUserpicCache(
|
||||
PeerUserpicView &view,
|
||||
const QImage *cloud,
|
||||
const EmptyUserpic *empty,
|
||||
int size,
|
||||
bool forum) {
|
||||
Expects(cloud != nullptr || empty != nullptr);
|
||||
|
||||
const auto full = QSize(size, size);
|
||||
const auto version = style::PaletteVersion();
|
||||
const auto forumValue = forum ? 1 : 0;
|
||||
const auto regenerate = (view.cached.size() != QSize(size, size))
|
||||
|| (view.forum != forumValue)
|
||||
|| (cloud && !view.empty.null())
|
||||
|| (empty && empty != view.empty.get())
|
||||
|| (empty && view.paletteVersion != version);
|
||||
if (!regenerate) {
|
||||
return;
|
||||
}
|
||||
view.empty = empty;
|
||||
view.forum = forumValue;
|
||||
view.paletteVersion = version;
|
||||
|
||||
if (cloud) {
|
||||
view.cached = cloud->scaled(
|
||||
full,
|
||||
Qt::IgnoreAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
if (forum) {
|
||||
view.cached = Images::Round(
|
||||
std::move(view.cached),
|
||||
Images::CornersMask(
|
||||
size * Ui::ForumUserpicRadiusMultiplier()));
|
||||
} else {
|
||||
view.cached = Images::Circle(std::move(view.cached));
|
||||
}
|
||||
} else {
|
||||
if (view.cached.size() != full) {
|
||||
view.cached = QImage(full, QImage::Format_ARGB32_Premultiplied);
|
||||
}
|
||||
view.cached.fill(Qt::transparent);
|
||||
|
||||
auto p = QPainter(&view.cached);
|
||||
if (forum) {
|
||||
empty->paintRounded(
|
||||
p,
|
||||
0,
|
||||
0,
|
||||
size,
|
||||
size,
|
||||
size * Ui::ForumUserpicRadiusMultiplier());
|
||||
} else {
|
||||
empty->paintCircle(p, 0, 0, size, size);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Ui
|
41
Telegram/SourceFiles/ui/userpic_view.h
Normal file
41
Telegram/SourceFiles/ui/userpic_view.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/*
|
||||
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 "base/weak_ptr.h"
|
||||
|
||||
#include <QtGui/QImage>
|
||||
|
||||
namespace Ui {
|
||||
|
||||
class EmptyUserpic;
|
||||
|
||||
[[nodiscard]] float64 ForumUserpicRadiusMultiplier();
|
||||
|
||||
struct PeerUserpicView {
|
||||
[[nodiscard]] bool null() const {
|
||||
return cached.isNull() && !cloud && empty.null();
|
||||
}
|
||||
|
||||
QImage cached;
|
||||
std::shared_ptr<QImage> cloud;
|
||||
base::weak_ptr<const EmptyUserpic> empty;
|
||||
int paletteVersion : 31 = 0;
|
||||
int forum : 1 = 0;
|
||||
};
|
||||
|
||||
[[nodiscard]] bool PeerUserpicLoading(const PeerUserpicView &view);
|
||||
|
||||
void ValidateUserpicCache(
|
||||
PeerUserpicView &view,
|
||||
const QImage *cloud,
|
||||
const EmptyUserpic *empty,
|
||||
int size,
|
||||
bool forum);
|
||||
|
||||
} // namespace Ui
|
|
@ -15,13 +15,16 @@ class History;
|
|||
|
||||
namespace Data {
|
||||
class Session;
|
||||
class CloudImageView;
|
||||
class ForumTopic;
|
||||
class Thread;
|
||||
struct ItemNotification;
|
||||
enum class ItemNotificationType;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Main {
|
||||
class Session;
|
||||
} // namespace Main
|
||||
|
@ -392,7 +395,7 @@ protected:
|
|||
virtual void doShowNativeNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
@ -413,7 +416,7 @@ protected:
|
|||
void doShowNativeNotification(
|
||||
not_null<PeerData*> peer,
|
||||
MsgId topicRootId,
|
||||
std::shared_ptr<Data::CloudImageView> &userpicView,
|
||||
Ui::PeerUserpicView &userpicView,
|
||||
MsgId msgId,
|
||||
const QString &title,
|
||||
const QString &subtitle,
|
||||
|
|
|
@ -660,7 +660,7 @@ Notification::Notification(
|
|||
auto position = computePosition(st::notifyMinHeight);
|
||||
updateGeometry(position.x(), position.y(), st::notifyWidth, st::notifyMinHeight);
|
||||
|
||||
_userpicLoaded = !_userpicView || (_userpicView->image() != nullptr);
|
||||
_userpicLoaded = !Ui::PeerUserpicLoading(_userpicView);
|
||||
updateNotifyDisplay();
|
||||
|
||||
_hideTimer.setSingleShot(true);
|
||||
|
@ -1004,7 +1004,7 @@ void Notification::updatePeerPhoto() {
|
|||
return;
|
||||
}
|
||||
_userpicView = _peer->createUserpicView();
|
||||
if (_userpicView && !_userpicView->image()) {
|
||||
if (Ui::PeerUserpicLoading(_userpicView)) {
|
||||
return;
|
||||
}
|
||||
_userpicLoaded = true;
|
||||
|
@ -1024,7 +1024,7 @@ void Notification::updatePeerPhoto() {
|
|||
st::notifyPhotoPos.y(),
|
||||
width(),
|
||||
st::notifyPhotoSize);
|
||||
_userpicView = nullptr;
|
||||
_userpicView = {};
|
||||
update();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,16 +11,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/effects/animations.h"
|
||||
#include "ui/text/text.h"
|
||||
#include "ui/rp_widget.h"
|
||||
#include "ui/userpic_view.h"
|
||||
#include "base/timer.h"
|
||||
#include "base/binary_guard.h"
|
||||
#include "base/object_ptr.h"
|
||||
|
||||
#include <QtCore/QTimer>
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
class RoundButton;
|
||||
|
@ -290,7 +287,7 @@ private:
|
|||
History *_history = nullptr;
|
||||
Data::ForumTopic *_topic = nullptr;
|
||||
MsgId _topicRootId = 0;
|
||||
std::shared_ptr<Data::CloudImageView> _userpicView;
|
||||
Ui::PeerUserpicView _userpicView;
|
||||
QString _author;
|
||||
Data::ReactionId _reaction;
|
||||
HistoryItem *_item = nullptr;
|
||||
|
|
|
@ -15,8 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/empty_userpic.h"
|
||||
#include "styles/style_window.h"
|
||||
|
||||
namespace Window {
|
||||
namespace Notifications {
|
||||
namespace Window::Notifications {
|
||||
namespace {
|
||||
|
||||
// Delete notify photo file after 1 minute of not using.
|
||||
|
@ -24,9 +23,16 @@ constexpr int kNotifyDeletePhotoAfterMs = 60000;
|
|||
|
||||
} // namespace
|
||||
|
||||
CachedUserpics::CachedUserpics(Type type)
|
||||
: _type(type)
|
||||
, _clearTimer([=] { clear(); }) {
|
||||
QImage GenerateUserpic(not_null<PeerData*> peer, Ui::PeerUserpicView &view) {
|
||||
return peer->isSelf()
|
||||
? Ui::EmptyUserpic::GenerateSavedMessages(st::notifyMacPhotoSize)
|
||||
: peer->isRepliesChat()
|
||||
? Ui::EmptyUserpic::GenerateRepliesMessages(st::notifyMacPhotoSize)
|
||||
: peer->generateUserpicImage(view, st::notifyMacPhotoSize);
|
||||
}
|
||||
|
||||
CachedUserpics::CachedUserpics()
|
||||
: _clearTimer([=] { clear(); }) {
|
||||
QDir().mkpath(cWorkingDir() + u"tdata/temp"_q);
|
||||
}
|
||||
|
||||
|
@ -37,14 +43,14 @@ CachedUserpics::~CachedUserpics() {
|
|||
}
|
||||
|
||||
// This works about 1200ms on Windows for a folder with one image O_o
|
||||
// base::Platform::DeleteDirectory(cWorkingDir() + u"tdata/temp"_q);
|
||||
//base::Platform::DeleteDirectory(cWorkingDir() + u"tdata/temp"_q);
|
||||
}
|
||||
}
|
||||
|
||||
QString CachedUserpics::get(
|
||||
const InMemoryKey &key,
|
||||
not_null<PeerData*> peer,
|
||||
std::shared_ptr<Data::CloudImageView> &view) {
|
||||
Ui::PeerUserpicView &view) {
|
||||
auto ms = crl::now();
|
||||
auto i = _images.find(key);
|
||||
if (i != _images.cend()) {
|
||||
|
@ -64,21 +70,7 @@ QString CachedUserpics::get(
|
|||
cWorkingDir(),
|
||||
QString::number(base::RandomValue<uint64>(), 16));
|
||||
if (key.first || key.second) {
|
||||
if (peer->isSelf()) {
|
||||
const auto method = (_type == Type::Rounded)
|
||||
? Ui::EmptyUserpic::GenerateSavedMessagesRounded
|
||||
: Ui::EmptyUserpic::GenerateSavedMessages;
|
||||
method(st::notifyMacPhotoSize).save(v.path, "PNG");
|
||||
} else if (peer->isRepliesChat()) {
|
||||
const auto method = (_type == Type::Rounded)
|
||||
? Ui::EmptyUserpic::GenerateRepliesMessagesRounded
|
||||
: Ui::EmptyUserpic::GenerateRepliesMessages;
|
||||
method(st::notifyMacPhotoSize).save(v.path, "PNG");
|
||||
} else if (_type == Type::Rounded) {
|
||||
peer->saveUserpicRounded(view, v.path, st::notifyMacPhotoSize);
|
||||
} else {
|
||||
peer->saveUserpic(view, v.path, st::notifyMacPhotoSize);
|
||||
}
|
||||
GenerateUserpic(peer, view).save(v.path, "PNG");
|
||||
} else {
|
||||
LogoNoMargin().save(v.path, "PNG");
|
||||
}
|
||||
|
@ -128,5 +120,4 @@ void CachedUserpics::clear() {
|
|||
}
|
||||
}
|
||||
|
||||
} // namespace Notifications
|
||||
} // namespace Window
|
||||
} // namespace Window::Notifications
|
||||
|
|
|
@ -10,34 +10,31 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "window/notifications_manager.h"
|
||||
#include "base/timer.h"
|
||||
|
||||
namespace Data {
|
||||
class CloudImageView;
|
||||
} // namespace Data
|
||||
namespace Ui {
|
||||
struct PeerUserpicView;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Window {
|
||||
namespace Notifications {
|
||||
namespace Window::Notifications {
|
||||
|
||||
[[nodiscard]] QImage GenerateUserpic(
|
||||
not_null<PeerData*> peer,
|
||||
Ui::PeerUserpicView &view);
|
||||
|
||||
class CachedUserpics : public QObject {
|
||||
public:
|
||||
enum class Type {
|
||||
Rounded,
|
||||
Circled,
|
||||
};
|
||||
|
||||
CachedUserpics(Type type);
|
||||
CachedUserpics();
|
||||
~CachedUserpics();
|
||||
|
||||
[[nodiscard]] QString get(
|
||||
const InMemoryKey &key,
|
||||
not_null<PeerData*> peer,
|
||||
std::shared_ptr<Data::CloudImageView> &view);
|
||||
Ui::PeerUserpicView &view);
|
||||
|
||||
private:
|
||||
void clear();
|
||||
void clearInMs(int ms);
|
||||
crl::time clear(crl::time ms);
|
||||
|
||||
Type _type = Type::Rounded;
|
||||
struct Image {
|
||||
crl::time until = 0;
|
||||
QString path;
|
||||
|
@ -49,5 +46,4 @@ private:
|
|||
|
||||
};
|
||||
|
||||
} // namesapce Notifications
|
||||
} // namespace Window
|
||||
} // namespace Window::Notifications
|
||||
|
|
|
@ -982,7 +982,7 @@ void Generator::paintUserpic(int x, int y, Row::Type type, int index, QString le
|
|||
image.fill(Qt::transparent);
|
||||
{
|
||||
Painter p(&image);
|
||||
userpic.paintRounded(p, 0, 0, size, size, size / 2);
|
||||
userpic.paintCircle(p, 0, 0, size, size);
|
||||
}
|
||||
_p->drawImage(rtl() ? (_rect.width() - x - size) : x, y, image);
|
||||
}
|
||||
|
|
|
@ -278,6 +278,8 @@ PRIVATE
|
|||
ui/empty_userpic.h
|
||||
ui/grouped_layout.cpp
|
||||
ui/grouped_layout.h
|
||||
ui/userpic_view.cpp
|
||||
ui/userpic_view.h
|
||||
ui/widgets/fields/special_fields.cpp
|
||||
ui/widgets/fields/special_fields.h
|
||||
ui/widgets/fields/time_part_input_with_placeholder.cpp
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit e8294bbc9c7f85e6909c3ed06fe03cfd39869613
|
||||
Subproject commit fd3531b70750ffe7ec2213a899409c08c388ce4c
|
|
@ -1 +1 @@
|
|||
Subproject commit 22ceaae4ed958d9711965fbe4c1385a7d8c60212
|
||||
Subproject commit 59a7b94ef4bb4d4cf6597d53bdacccbf5720e694
|
Loading…
Add table
Reference in a new issue