2
0
mirror of https://github.com/kotatogram/kotatogram-desktop synced 2025-09-05 09:05:14 +00:00

Use Data::CloudImage for userpics.

This commit is contained in:
John Preston
2020-05-28 18:32:10 +04:00
parent 249f7813c1
commit f066e0f05a
55 changed files with 748 additions and 284 deletions

View File

@@ -33,6 +33,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "history/history.h"
#include "history/view/history_view_element.h"
#include "history/history_item.h"
#include "storage/file_download.h"
#include "facades.h"
#include "app.h"
@@ -108,8 +109,7 @@ void PeerClickHandler::onClick(ClickContext context) const {
PeerData::PeerData(not_null<Data::Session*> owner, PeerId id)
: id(id)
, _owner(owner)
, _userpicEmpty(createEmptyUserpic()) {
, _owner(owner) {
_nameText.setText(st::msgNameStyle, QString(), Ui::NameTextOptions());
}
@@ -145,7 +145,8 @@ void PeerData::updateNameDelayed(
}
name = newName;
_nameText.setText(st::msgNameStyle, name, Ui::NameTextOptions());
refreshEmptyUserpic();
_userpicEmpty = nullptr;
Notify::PeerUpdate update(this);
if (nameVersion++ > 1) {
update.flags |= UpdateFlag::NameChanged;
@@ -175,28 +176,22 @@ void PeerData::updateNameDelayed(
}
}
std::unique_ptr<Ui::EmptyUserpic> PeerData::createEmptyUserpic() const {
return std::make_unique<Ui::EmptyUserpic>(
Data::PeerUserpicColor(id),
name);
}
void PeerData::refreshEmptyUserpic() const {
_userpicEmpty = useEmptyUserpic() ? createEmptyUserpic() : nullptr;
not_null<Ui::EmptyUserpic*> PeerData::ensureEmptyUserpic() const {
if (!_userpicEmpty) {
_userpicEmpty = std::make_unique<Ui::EmptyUserpic>(
Data::PeerUserpicColor(id),
name);
}
return _userpicEmpty.get();
}
ClickHandlerPtr PeerData::createOpenLink() {
return std::make_shared<PeerClickHandler>(this);
}
void PeerData::setUserpic(
PhotoId photoId,
const StorageImageLocation &location,
ImagePtr userpic) {
void PeerData::setUserpic(PhotoId photoId, const ImageLocation &location) {
_userpicPhotoId = photoId;
_userpic = userpic;
_userpicLocation = location;
refreshEmptyUserpic();
_userpic.set(&session(), ImageWithLocation{ .location = location });
}
void PeerData::setUserpicPhoto(const MTPPhoto &data) {
@@ -213,80 +208,109 @@ void PeerData::setUserpicPhoto(const MTPPhoto &data) {
}
}
ImagePtr PeerData::currentUserpic() const {
if (_userpic) {
_userpic->load(userpicOrigin());
if (_userpic->loaded()) {
if (!useEmptyUserpic()) {
_userpicEmpty = nullptr;
}
return _userpic;
}
Image *PeerData::currentUserpic(
std::shared_ptr<Data::CloudImageView> &view) const {
if (!_userpic.isCurrentView(view)) {
view = _userpic.createView();
_userpic.load(&session(), userpicOrigin());
}
if (!_userpicEmpty) {
refreshEmptyUserpic();
const auto image = view ? view->image() : nullptr;
if (image) {
_userpicEmpty = nullptr;
}
return ImagePtr();
return image;
}
void PeerData::paintUserpic(Painter &p, int x, int y, int size) const {
if (auto userpic = currentUserpic()) {
void PeerData::paintUserpic(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const {
if (const auto userpic = currentUserpic(view)) {
p.drawPixmap(x, y, userpic->pixCircled(userpicOrigin(), size, size));
} else {
_userpicEmpty->paint(p, x, y, x + size + x, size);
ensureEmptyUserpic()->paint(p, x, y, x + size + x, size);
}
}
void PeerData::paintUserpicRounded(Painter &p, int x, int y, int size) const {
if (auto userpic = currentUserpic()) {
void PeerData::paintUserpicRounded(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const {
if (const auto userpic = currentUserpic(view)) {
p.drawPixmap(x, y, userpic->pixRounded(userpicOrigin(), size, size, ImageRoundRadius::Small));
} else {
_userpicEmpty->paintRounded(p, x, y, x + size + x, size);
ensureEmptyUserpic()->paintRounded(p, x, y, x + size + x, size);
}
}
void PeerData::paintUserpicSquare(Painter &p, int x, int y, int size) const {
if (auto userpic = currentUserpic()) {
void PeerData::paintUserpicSquare(
Painter &p,
std::shared_ptr<Data::CloudImageView> &view,
int x,
int y,
int size) const {
if (const auto userpic = currentUserpic(view)) {
p.drawPixmap(x, y, userpic->pix(userpicOrigin(), size, size));
} else {
_userpicEmpty->paintSquare(p, x, y, x + size + x, size);
ensureEmptyUserpic()->paintSquare(p, x, y, x + size + x, size);
}
}
void PeerData::loadUserpic() {
_userpic->load(userpicOrigin());
_userpic.load(&session(), userpicOrigin());
}
bool PeerData::userpicLoaded() const {
return _userpic->loaded();
bool PeerData::hasUserpic() const {
return !_userpic.empty();
}
bool PeerData::useEmptyUserpic() const {
return !_userpicLocation.valid()
|| !_userpic
|| !_userpic->loaded();
std::shared_ptr<Data::CloudImageView> PeerData::activeUserpicView() {
return _userpic.empty() ? nullptr : _userpic.activeView();
}
InMemoryKey PeerData::userpicUniqueKey() const {
if (useEmptyUserpic()) {
if (!_userpicEmpty) {
refreshEmptyUserpic();
}
return _userpicEmpty->uniqueKey();
std::shared_ptr<Data::CloudImageView> PeerData::createUserpicView() {
if (_userpic.empty()) {
return nullptr;
}
return inMemoryKey(_userpicLocation);
auto result = _userpic.createView();
_userpic.load(&session(), userpicPhotoOrigin());
return result;
}
void PeerData::saveUserpic(const QString &path, int size) const {
genUserpic(size).save(path, "PNG");
bool PeerData::useEmptyUserpic(
std::shared_ptr<Data::CloudImageView> &view) const {
return !currentUserpic(view);
}
void PeerData::saveUserpicRounded(const QString &path, int size) const {
genUserpicRounded(size).save(path, "PNG");
InMemoryKey PeerData::userpicUniqueKey(
std::shared_ptr<Data::CloudImageView> &view) const {
return useEmptyUserpic(view)
? ensureEmptyUserpic()->uniqueKey()
: inMemoryKey(_userpic.location());
}
QPixmap PeerData::genUserpic(int size) const {
if (auto userpic = currentUserpic()) {
void PeerData::saveUserpic(
std::shared_ptr<Data::CloudImageView> &view,
const QString &path,
int size) const {
genUserpic(view, size).save(path, "PNG");
}
void PeerData::saveUserpicRounded(
std::shared_ptr<Data::CloudImageView> &view,
const QString &path,
int size) const {
genUserpicRounded(view, size).save(path, "PNG");
}
QPixmap PeerData::genUserpic(
std::shared_ptr<Data::CloudImageView> &view,
int size) const {
if (const auto userpic = currentUserpic(view)) {
return userpic->pixCircled(userpicOrigin(), size, size);
}
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
@@ -294,13 +318,15 @@ QPixmap PeerData::genUserpic(int size) const {
result.fill(Qt::transparent);
{
Painter p(&result);
paintUserpic(p, 0, 0, size);
paintUserpic(p, view, 0, 0, size);
}
return App::pixmapFromImageInPlace(std::move(result));
}
QPixmap PeerData::genUserpicRounded(int size) const {
if (auto userpic = currentUserpic()) {
QPixmap PeerData::genUserpicRounded(
std::shared_ptr<Data::CloudImageView> &view,
int size) const {
if (auto userpic = currentUserpic(view)) {
return userpic->pixRounded(userpicOrigin(), size, size, ImageRoundRadius::Small);
}
auto result = QImage(QSize(size, size) * cIntRetinaFactor(), QImage::Format_ARGB32_Premultiplied);
@@ -308,7 +334,7 @@ QPixmap PeerData::genUserpicRounded(int size) const {
result.fill(Qt::transparent);
{
Painter p(&result);
paintUserpicRounded(p, 0, 0, size);
paintUserpicRounded(p, view, 0, 0, size);
}
return App::pixmapFromImageInPlace(std::move(result));
}
@@ -327,49 +353,42 @@ void PeerData::updateUserpic(
PhotoId photoId,
MTP::DcId dcId,
const MTPFileLocation &location) {
const auto size = kUserpicSize;
const auto loc = location.match([&](
setUserpicChecked(photoId, location.match([&](
const MTPDfileLocationToBeDeprecated &deprecated) {
return StorageImageLocation(
StorageFileLocation(
return ImageLocation(
{ StorageFileLocation(
dcId,
isSelf() ? peerToUser(id) : 0,
MTP_inputPeerPhotoFileLocation(
MTP_flags(0),
input,
deprecated.vvolume_id(),
deprecated.vlocal_id())),
size,
size);
});
setUserpicChecked(photoId, loc, Images::Create(loc));
deprecated.vlocal_id())) },
kUserpicSize,
kUserpicSize);
}));
}
void PeerData::clearUserpic() {
const auto photoId = PhotoId(0);
const auto loc = StorageImageLocation();
const auto photo = [&] {
if (isNotificationsUser()) {
auto image = Core::App().logoNoMargin().scaledToWidth(
kUserpicSize,
Qt::SmoothTransformation);
return _userpic
? _userpic
: Images::Create(std::move(image), "PNG");
}
return ImagePtr();
}();
setUserpicChecked(photoId, loc, photo);
//const auto photo = [&] { // #TODO optimize
// if (isNotificationsUser()) {
// auto image = Core::App().logoNoMargin().scaledToWidth(
// kUserpicSize,
// Qt::SmoothTransformation);
// return _userpic
// ? _userpic
// : Images::Create(std::move(image), "PNG");
// }
// return ImagePtr();
//}();
setUserpicChecked(PhotoId(), ImageLocation());
}
void PeerData::setUserpicChecked(
PhotoId photoId,
const StorageImageLocation &location,
ImagePtr userpic) {
if (_userpicPhotoId != photoId
|| _userpic.get() != userpic.get()
|| _userpicLocation != location) {
setUserpic(photoId, location, userpic);
const ImageLocation &location) {
if (_userpicPhotoId != photoId || _userpic.location() != location) {
setUserpic(photoId, location);
Notify::peerUpdatedDelayed(this, UpdateFlag::PhotoChanged);
//if (const auto channel = asChannel()) { // #feed
// if (const auto feed = channel->feed()) {