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:
@@ -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()) {
|
||||
|
Reference in New Issue
Block a user