mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-04-15 21:57:10 +02:00
Allow uploading chat wallpapers from file.
This commit is contained in:
parent
9130735ed6
commit
0b25d19e3b
7 changed files with 224 additions and 79 deletions
|
@ -10,11 +10,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lang/lang_keys.h"
|
||||
#include "ui/effects/round_checkbox.h"
|
||||
#include "ui/image/image.h"
|
||||
#include "ui/chat/attach/attach_extensions.h"
|
||||
#include "ui/chat/chat_theme.h"
|
||||
#include "ui/ui_utility.h"
|
||||
#include "main/main_session.h"
|
||||
#include "apiwrap.h"
|
||||
#include "mtproto/sender.h"
|
||||
#include "core/file_utilities.h"
|
||||
#include "data/data_peer.h"
|
||||
#include "data/data_session.h"
|
||||
#include "data/data_file_origin.h"
|
||||
|
@ -174,6 +176,10 @@ void BackgroundBox::prepare() {
|
|||
st::infoIconMediaPhoto,
|
||||
st::infoSharedMediaButtonIconPosition);
|
||||
|
||||
button->setClickedCallback([=] {
|
||||
chooseFromFile();
|
||||
});
|
||||
|
||||
Settings::AddSkip(container);
|
||||
Settings::AddDivider(container);
|
||||
|
||||
|
@ -196,6 +202,55 @@ void BackgroundBox::prepare() {
|
|||
}, _inner->lifetime());
|
||||
}
|
||||
|
||||
void BackgroundBox::chooseFromFile() {
|
||||
const auto filterStart = _forPeer
|
||||
? u"Image files (*"_q
|
||||
: u"Theme files (*.tdesktop-theme *.tdesktop-palette *"_q;
|
||||
auto filters = QStringList(
|
||||
filterStart
|
||||
+ Ui::ImageExtensions().join(u" *"_q)
|
||||
+ u")"_q);
|
||||
filters.push_back(FileDialog::AllFilesFilter());
|
||||
const auto callback = [=](const FileDialog::OpenResult &result) {
|
||||
if (result.paths.isEmpty() && result.remoteContent.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_forPeer && !result.paths.isEmpty()) {
|
||||
const auto filePath = result.paths.front();
|
||||
const auto hasExtension = [&](QLatin1String extension) {
|
||||
return filePath.endsWith(extension, Qt::CaseInsensitive);
|
||||
};
|
||||
if (hasExtension(qstr(".tdesktop-theme"))
|
||||
|| hasExtension(qstr(".tdesktop-palette"))) {
|
||||
Window::Theme::Apply(filePath);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto image = Images::Read({
|
||||
.path = result.paths.isEmpty() ? QString() : result.paths.front(),
|
||||
.content = result.remoteContent,
|
||||
.forceOpaque = true,
|
||||
}).image;
|
||||
if (image.isNull() || image.width() <= 0 || image.height() <= 0) {
|
||||
return;
|
||||
}
|
||||
auto local = Data::CustomWallPaper();
|
||||
local.setLocalImageAsThumbnail(std::make_shared<Image>(
|
||||
std::move(image)));
|
||||
_controller->show(Box<BackgroundPreviewBox>(
|
||||
_controller,
|
||||
local,
|
||||
BackgroundPreviewArgs{ _forPeer }));
|
||||
};
|
||||
FileDialog::GetOpenPath(
|
||||
this,
|
||||
tr::lng_choose_image(tr::now),
|
||||
filters.join(u";;"_q),
|
||||
crl::guard(this, callback));
|
||||
}
|
||||
|
||||
bool BackgroundBox::hasDefaultForPeer() const {
|
||||
Expects(_forPeer != nullptr);
|
||||
|
||||
|
|
|
@ -39,6 +39,8 @@ private:
|
|||
void removePaper(const Data::WallPaper &paper);
|
||||
void resetForPeer();
|
||||
|
||||
void chooseFromFile();
|
||||
|
||||
const not_null<Window::SessionController*> _controller;
|
||||
|
||||
QPointer<Inner> _inner;
|
||||
|
|
|
@ -35,6 +35,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "boxes/background_preview_box.h"
|
||||
#include "window/window_session_controller.h"
|
||||
#include "settings/settings_common.h"
|
||||
#include "storage/file_upload.h"
|
||||
#include "storage/localimageloader.h"
|
||||
#include "styles/style_chat.h"
|
||||
#include "styles/style_layers.h"
|
||||
#include "styles/style_boxes.h"
|
||||
|
@ -275,18 +277,82 @@ void BackgroundPreviewBox::createBlurCheckbox() {
|
|||
}
|
||||
|
||||
void BackgroundPreviewBox::apply() {
|
||||
const auto weak = Ui::MakeWeak(this);
|
||||
if (_forPeer) {
|
||||
applyForPeer();
|
||||
} else {
|
||||
applyForEveryone();
|
||||
}
|
||||
if (weak) {
|
||||
closeBox();
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::applyForPeer() {
|
||||
void BackgroundPreviewBox::uploadForPeer() {
|
||||
Expects(_forPeer != nullptr);
|
||||
|
||||
if (_uploadId) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto session = &_controller->session();
|
||||
const auto ready = Window::Theme::PrepareWallPaper(
|
||||
session->mainDcId(),
|
||||
_paper.localThumbnail()->original());
|
||||
const auto documentId = ready.id;
|
||||
_uploadId = FullMsgId(
|
||||
session->userPeerId(),
|
||||
session->data().nextLocalMessageId());
|
||||
session->uploader().uploadMedia(_uploadId, ready);
|
||||
if (_uploadLifetime) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto document = session->data().document(documentId);
|
||||
document->uploadingData = std::make_unique<Data::UploadState>(
|
||||
document->size);
|
||||
|
||||
session->uploader().documentProgress(
|
||||
) | rpl::start_with_next([=](const FullMsgId &fullId) {
|
||||
if (fullId != _uploadId) {
|
||||
return;
|
||||
}
|
||||
_uploadProgress = document->uploading()
|
||||
? ((document->uploadingData->offset * 100)
|
||||
/ document->uploadingData->size)
|
||||
: 0.;
|
||||
update(radialRect());
|
||||
}, _uploadLifetime);
|
||||
|
||||
session->uploader().documentReady(
|
||||
) | rpl::start_with_next([=](const Storage::UploadedMedia &data) {
|
||||
if (data.fullId != _uploadId) {
|
||||
return;
|
||||
}
|
||||
_uploadProgress = 1.;
|
||||
_uploadLifetime.destroy();
|
||||
update(radialRect());
|
||||
session->api().request(MTPaccount_UploadWallPaper(
|
||||
MTP_flags(MTPaccount_UploadWallPaper::Flag::f_for_chat),
|
||||
data.info.file,
|
||||
MTP_string("image/jpeg"),
|
||||
_paper.mtpSettings()
|
||||
)).done([=](const MTPWallPaper &result) {
|
||||
result.match([&](const MTPDwallPaper &data) {
|
||||
session->data().documentConvert(
|
||||
session->data().document(documentId),
|
||||
data.vdocument());
|
||||
}, [&](const MTPDwallPaperNoFile &data) {
|
||||
LOG(("API Error: "
|
||||
"Got wallPaperNoFile after account.UploadWallPaper."));
|
||||
});
|
||||
if (const auto paper = Data::WallPaper::Create(session, result)) {
|
||||
setExistingForPeer(*paper);
|
||||
}
|
||||
}).send();
|
||||
}, _uploadLifetime);
|
||||
|
||||
_uploadProgress = 0.;
|
||||
_radial.start(_uploadProgress);
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::setExistingForPeer(const Data::WallPaper &paper) {
|
||||
Expects(_forPeer != nullptr);
|
||||
|
||||
const auto api = &_controller->session().api();
|
||||
|
@ -296,17 +362,27 @@ void BackgroundPreviewBox::applyForPeer() {
|
|||
| (_fromMessageId ? Flag() : Flag::f_wallpaper)
|
||||
| Flag::f_settings),
|
||||
_forPeer->input,
|
||||
_paper.mtpInput(&_controller->session()),
|
||||
_paper.mtpSettings(),
|
||||
paper.mtpInput(&_controller->session()),
|
||||
paper.mtpSettings(),
|
||||
MTP_int(_fromMessageId.msg)
|
||||
)).done([=](const MTPUpdates &result) {
|
||||
api->applyUpdates(result);
|
||||
}).send();
|
||||
|
||||
_forPeer->setWallPaper(_paper);
|
||||
_forPeer->setWallPaper(paper);
|
||||
_controller->finishChatThemeEdit(_forPeer);
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::applyForPeer() {
|
||||
Expects(_forPeer != nullptr);
|
||||
|
||||
if (Data::IsCustomWallPaper(_paper)) {
|
||||
uploadForPeer();
|
||||
} else {
|
||||
setExistingForPeer(_paper);
|
||||
}
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::applyForEveryone() {
|
||||
const auto install = (_paper.id() != Window::Theme::Background()->id())
|
||||
&& Data::IsCloudWallPaper(_paper);
|
||||
|
@ -317,6 +393,7 @@ void BackgroundPreviewBox::applyForEveryone() {
|
|||
_paper.mtpSettings()
|
||||
)).send();
|
||||
}
|
||||
closeBox();
|
||||
}
|
||||
|
||||
void BackgroundPreviewBox::share() {
|
||||
|
@ -441,14 +518,11 @@ void BackgroundPreviewBox::paintTexts(Painter &p, crl::time ms) {
|
|||
}
|
||||
|
||||
void BackgroundPreviewBox::radialAnimationCallback(crl::time now) {
|
||||
Expects(_paper.document() != nullptr);
|
||||
|
||||
const auto document = _paper.document();
|
||||
const auto wasAnimating = _radial.animating();
|
||||
const auto updated = _radial.update(
|
||||
_media->progress(),
|
||||
!document->loading(),
|
||||
now);
|
||||
const auto updated = _uploadId
|
||||
? _radial.update(_uploadProgress, !_uploadLifetime, now)
|
||||
: _radial.update(_media->progress(), !document->loading(), now);
|
||||
if ((wasAnimating || _radial.animating())
|
||||
&& (!anim::Disabled() || updated)) {
|
||||
update(radialRect());
|
||||
|
|
|
@ -61,6 +61,8 @@ private:
|
|||
void apply();
|
||||
void applyForPeer();
|
||||
void applyForEveryone();
|
||||
void uploadForPeer();
|
||||
void setExistingForPeer(const Data::WallPaper &paper);
|
||||
void share();
|
||||
void radialAnimationCallback(crl::time now);
|
||||
QRect radialRect() const;
|
||||
|
@ -96,4 +98,8 @@ private:
|
|||
std::optional<QColor> _serviceBg;
|
||||
object_ptr<Ui::Checkbox> _blur = { nullptr };
|
||||
|
||||
FullMsgId _uploadId;
|
||||
float64 _uploadProgress = 0.;
|
||||
rpl::lifetime _uploadLifetime;
|
||||
|
||||
};
|
||||
|
|
|
@ -329,9 +329,12 @@ void ThemeDocument::prepareThumbnailFrom(
|
|||
tw = th = 1;
|
||||
}
|
||||
const auto ratio = style::DevicePixelRatio();
|
||||
const auto resizeTo = _serviceWidth
|
||||
? QSize(tw, th).scaled(_pixw, _pixh, Qt::KeepAspectRatioByExpanding)
|
||||
: QSize(_pixw, (_pixw * th) / tw);
|
||||
original = Images::Prepare(
|
||||
std::move(original),
|
||||
QSize(_pixw, (_pixw * th) / tw) * ratio,
|
||||
resizeTo * ratio,
|
||||
{ .options = options, .outer = { _pixw, _pixh } });
|
||||
if (isPattern) {
|
||||
original = Ui::PreparePatternImage(
|
||||
|
|
|
@ -457,70 +457,6 @@ void ClearApplying() {
|
|||
GlobalApplying = Applying();
|
||||
}
|
||||
|
||||
SendMediaReady PrepareWallPaper(MTP::DcId dcId, const QImage &image) {
|
||||
PreparedPhotoThumbs thumbnails;
|
||||
QVector<MTPPhotoSize> sizes;
|
||||
|
||||
QByteArray jpeg;
|
||||
QBuffer jpegBuffer(&jpeg);
|
||||
image.save(&jpegBuffer, "JPG", 87);
|
||||
|
||||
const auto scaled = [&](int size) {
|
||||
return image.scaled(
|
||||
size,
|
||||
size,
|
||||
Qt::KeepAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
};
|
||||
const auto push = [&](const char *type, QImage &&image) {
|
||||
sizes.push_back(MTP_photoSize(
|
||||
MTP_string(type),
|
||||
MTP_int(image.width()),
|
||||
MTP_int(image.height()), MTP_int(0)));
|
||||
thumbnails.emplace(
|
||||
type[0],
|
||||
PreparedPhotoThumb{ .image = std::move(image) });
|
||||
};
|
||||
push("s", scaled(320));
|
||||
|
||||
const auto filename = u"wallpaper.jpg"_q;
|
||||
auto attributes = QVector<MTPDocumentAttribute>(
|
||||
1,
|
||||
MTP_documentAttributeFilename(MTP_string(filename)));
|
||||
attributes.push_back(MTP_documentAttributeImageSize(
|
||||
MTP_int(image.width()),
|
||||
MTP_int(image.height())));
|
||||
const auto id = base::RandomValue<DocumentId>();
|
||||
const auto document = MTP_document(
|
||||
MTP_flags(0),
|
||||
MTP_long(id),
|
||||
MTP_long(0),
|
||||
MTP_bytes(),
|
||||
MTP_int(base::unixtime::now()),
|
||||
MTP_string("image/jpeg"),
|
||||
MTP_long(jpeg.size()),
|
||||
MTP_vector<MTPPhotoSize>(sizes),
|
||||
MTPVector<MTPVideoSize>(),
|
||||
MTP_int(dcId),
|
||||
MTP_vector<MTPDocumentAttribute>(attributes));
|
||||
|
||||
return SendMediaReady(
|
||||
SendMediaType::ThemeFile,
|
||||
QString(), // filepath
|
||||
filename,
|
||||
jpeg.size(),
|
||||
jpeg,
|
||||
id,
|
||||
0,
|
||||
QString(),
|
||||
PeerId(),
|
||||
MTP_photoEmpty(MTP_long(0)),
|
||||
thumbnails,
|
||||
document,
|
||||
QByteArray(),
|
||||
0);
|
||||
}
|
||||
|
||||
void ClearEditingPalette() {
|
||||
QFile(EditingPalettePath()).remove();
|
||||
}
|
||||
|
@ -1565,5 +1501,69 @@ bool ReadPaletteValues(const QByteArray &content, Fn<bool(QLatin1String name, QL
|
|||
};
|
||||
}
|
||||
|
||||
SendMediaReady PrepareWallPaper(MTP::DcId dcId, const QImage &image) {
|
||||
PreparedPhotoThumbs thumbnails;
|
||||
QVector<MTPPhotoSize> sizes;
|
||||
|
||||
QByteArray jpeg;
|
||||
QBuffer jpegBuffer(&jpeg);
|
||||
image.save(&jpegBuffer, "JPG", 87);
|
||||
|
||||
const auto scaled = [&](int size) {
|
||||
return image.scaled(
|
||||
size,
|
||||
size,
|
||||
Qt::KeepAspectRatio,
|
||||
Qt::SmoothTransformation);
|
||||
};
|
||||
const auto push = [&](const char *type, QImage &&image) {
|
||||
sizes.push_back(MTP_photoSize(
|
||||
MTP_string(type),
|
||||
MTP_int(image.width()),
|
||||
MTP_int(image.height()), MTP_int(0)));
|
||||
thumbnails.emplace(
|
||||
type[0],
|
||||
PreparedPhotoThumb{ .image = std::move(image) });
|
||||
};
|
||||
push("s", scaled(320));
|
||||
|
||||
const auto filename = u"wallpaper.jpg"_q;
|
||||
auto attributes = QVector<MTPDocumentAttribute>(
|
||||
1,
|
||||
MTP_documentAttributeFilename(MTP_string(filename)));
|
||||
attributes.push_back(MTP_documentAttributeImageSize(
|
||||
MTP_int(image.width()),
|
||||
MTP_int(image.height())));
|
||||
const auto id = base::RandomValue<DocumentId>();
|
||||
const auto document = MTP_document(
|
||||
MTP_flags(0),
|
||||
MTP_long(id),
|
||||
MTP_long(0),
|
||||
MTP_bytes(),
|
||||
MTP_int(base::unixtime::now()),
|
||||
MTP_string("image/jpeg"),
|
||||
MTP_long(jpeg.size()),
|
||||
MTP_vector<MTPPhotoSize>(sizes),
|
||||
MTPVector<MTPVideoSize>(),
|
||||
MTP_int(dcId),
|
||||
MTP_vector<MTPDocumentAttribute>(attributes));
|
||||
|
||||
return SendMediaReady(
|
||||
SendMediaType::ThemeFile,
|
||||
QString(), // filepath
|
||||
filename,
|
||||
jpeg.size(),
|
||||
jpeg,
|
||||
id,
|
||||
0,
|
||||
QString(),
|
||||
PeerId(),
|
||||
MTP_photoEmpty(MTP_long(0)),
|
||||
thumbnails,
|
||||
document,
|
||||
QByteArray(),
|
||||
0);
|
||||
}
|
||||
|
||||
} // namespace Theme
|
||||
} // namespace Window
|
||||
|
|
|
@ -12,6 +12,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "ui/style/style_core_palette.h"
|
||||
|
||||
class QFileSystemWatcher;
|
||||
struct SendMediaReady;
|
||||
|
||||
namespace style {
|
||||
struct colorizer;
|
||||
|
@ -296,6 +297,10 @@ private:
|
|||
|
||||
};
|
||||
|
||||
[[nodiscard]] SendMediaReady PrepareWallPaper(
|
||||
MTP::DcId dcId,
|
||||
const QImage &image);
|
||||
|
||||
[[nodiscard]] ChatBackground *Background();
|
||||
|
||||
bool ReadPaletteValues(
|
||||
|
|
Loading…
Add table
Reference in a new issue