Allow accepting video userpic suggestions.

This commit is contained in:
John Preston 2022-12-14 12:20:01 +04:00
parent 446f0f1653
commit 9513aaa768
16 changed files with 287 additions and 149 deletions

View File

@ -1211,6 +1211,17 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_profile_suggest_photo" = "Suggest Profile Photo"; "lng_profile_suggest_photo" = "Suggest Profile Photo";
"lng_profile_set_photo_for" = "Set Profile Photo"; "lng_profile_set_photo_for" = "Set Profile Photo";
"lng_profile_photo_reset" = "Reset to Original"; "lng_profile_photo_reset" = "Reset to Original";
"lng_profile_set_for_done" = "You will now always see this photo for {user}'s account.";
"lng_profile_suggest_sure" = "You can suggest {user} to set this photo for their page.";
"lng_profile_suggest_button" = "Suggest";
"lng_profile_set_personal_sure" = "Only you will see this photo and it will replace any photo {user} sets for themselves.";
"lng_profile_accept_photo_sure" = "{user} suggests you to use this profile photo for your Telegram account.";
"lng_profile_set_photo_button" = "Set Photo";
"lng_profile_accept_video_sure" = "{user} suggests you to use this profile video for your Telegram account.";
"lng_profile_set_video_button" = "Set Video";
"lng_profile_changed_photo_title" = "Photo updated";
"lng_profile_changed_photo_about" = "You can change it in {link}.";
"lng_profile_changed_photo_link" = "Settings";
"lng_media_type_photos" = "Photos"; "lng_media_type_photos" = "Photos";
"lng_media_type_gifs" = "GIFs"; "lng_media_type_gifs" = "GIFs";
"lng_media_type_videos" = "Videos"; "lng_media_type_videos" = "Videos";
@ -1569,6 +1580,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"lng_action_suggested_photo_me" = "You suggested {user} to use this profile photo."; "lng_action_suggested_photo_me" = "You suggested {user} to use this profile photo.";
"lng_action_suggested_photo" = "{user} suggests you to use this profile photo."; "lng_action_suggested_photo" = "{user} suggests you to use this profile photo.";
"lng_action_suggested_photo_button" = "View Photo"; "lng_action_suggested_photo_button" = "View Photo";
"lng_action_suggested_video_me" = "You suggested {user} to use this profile video.";
"lng_action_suggested_video" = "{user} suggests you to use this profile video.";
"lng_action_suggested_video_button" = "View Video";
"lng_action_attach_menu_bot_allowed" = "You allowed this bot to message you when you added it in the attachment menu."; "lng_action_attach_menu_bot_allowed" = "You allowed this bot to message you when you added it in the attachment menu.";
"lng_action_topic_created_inside" = "Topic created"; "lng_action_topic_created_inside" = "Topic created";
"lng_action_topic_closed_inside" = "Topic closed"; "lng_action_topic_closed_inside" = "Topic closed";

View File

@ -13,6 +13,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "base/unixtime.h" #include "base/unixtime.h"
#include "data/data_channel.h" #include "data/data_channel.h"
#include "data/data_chat.h" #include "data/data_chat.h"
#include "data/data_file_origin.h"
#include "data/data_peer.h" #include "data/data_peer.h"
#include "data/data_photo.h" #include "data/data_photo.h"
#include "data/data_session.h" #include "data/data_session.h"
@ -121,16 +122,32 @@ void PeerPhoto::uploadFallback(not_null<PeerData*> peer, QImage &&image) {
upload(peer, std::move(image), UploadType::Fallback); upload(peer, std::move(image), UploadType::Fallback);
} }
void PeerPhoto::updateSelf(not_null<PhotoData*> photo) { void PeerPhoto::updateSelf(
_api.request(MTPphotos_UpdateProfilePhoto( not_null<PhotoData*> photo,
MTP_flags(0), Data::FileOrigin origin) {
photo->mtpInput() const auto send = [=](auto resend) -> void {
)).done([=](const MTPphotos_Photo &result) { const auto usedFileReference = photo->fileReference();
result.match([&](const MTPDphotos_photo &data) { _api.request(MTPphotos_UpdateProfilePhoto(
_session->data().processPhoto(data.vphoto()); MTP_flags(0),
_session->data().processUsers(data.vusers()); photo->mtpInput()
}); )).done([=](const MTPphotos_Photo &result) {
}).send(); result.match([&](const MTPDphotos_photo &data) {
_session->data().processPhoto(data.vphoto());
_session->data().processUsers(data.vusers());
});
}).fail([=](const MTP::Error &error) {
if (error.code() == 400
&& error.type().startsWith(u"FILE_REFERENCE_"_q)) {
photo->session().api().refreshFileReference(origin, [=](
const auto &) {
if (photo->fileReference() != usedFileReference) {
resend(resend);
}
});
}
}).send();
};
send(send);
} }
void PeerPhoto::upload( void PeerPhoto::upload(

View File

@ -13,6 +13,10 @@ class ApiWrap;
class PeerData; class PeerData;
class UserData; class UserData;
namespace Data {
struct FileOrigin;
} // namespace Data
namespace Main { namespace Main {
class Session; class Session;
} // namespace Main } // namespace Main
@ -26,7 +30,9 @@ public:
void upload(not_null<PeerData*> peer, QImage &&image); void upload(not_null<PeerData*> peer, QImage &&image);
void uploadFallback(not_null<PeerData*> peer, QImage &&image); void uploadFallback(not_null<PeerData*> peer, QImage &&image);
void updateSelf(not_null<PhotoData*> photo); void updateSelf(
not_null<PhotoData*> photo,
Data::FileOrigin origin);
void suggest(not_null<PeerData*> peer, QImage &&image); void suggest(not_null<PeerData*> peer, QImage &&image);
void clear(not_null<PhotoData*> photo); void clear(not_null<PhotoData*> photo);
void clearPersonal(not_null<UserData*> user); void clearPersonal(not_null<UserData*> user);

View File

@ -28,6 +28,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_premium_limits.h" #include "data/data_premium_limits.h"
#include "data/stickers/data_stickers.h" #include "data/stickers/data_stickers.h"
#include "data/stickers/data_custom_emoji.h" #include "data/stickers/data_custom_emoji.h"
#include "editor/editor_layer_widget.h"
#include "editor/photo_editor.h"
#include "editor/photo_editor_layer_widget.h" #include "editor/photo_editor_layer_widget.h"
#include "history/history_drag_area.h" #include "history/history_drag_area.h"
#include "history/history_item.h" #include "history/history_item.h"
@ -453,13 +455,18 @@ void EditCaptionBox::setupPhotoEditorEventHandler() {
rebuildPreview(); rebuildPreview();
}; };
const auto fileImage = std::make_shared<Image>(*large); const auto fileImage = std::make_shared<Image>(*large);
auto editor = base::make_unique_q<Editor::PhotoEditor>(
this,
&controller->window(),
fileImage,
Editor::PhotoModifications());
const auto raw = editor.get();
auto layer = std::make_unique<Editor::LayerWidget>(
this,
std::move(editor));
Editor::InitEditorLayer(layer.get(), raw, std::move(callback));
controller->showLayer( controller->showLayer(
std::make_unique<Editor::LayerWidget>( std::move(layer),
this,
&controller->window(),
fileImage,
Editor::PhotoModifications(),
std::move(callback)),
Ui::LayerOption::KeepOther); Ui::LayerOption::KeepOther);
} }
}, lifetime()); }, lifetime());

View File

@ -95,6 +95,8 @@ struct FileReferenceAccumulator {
data.vaction().match( data.vaction().match(
[&](const MTPDmessageActionChatEditPhoto &data) { [&](const MTPDmessageActionChatEditPhoto &data) {
push(data.vphoto()); push(data.vphoto());
}, [&](const MTPDmessageActionSuggestProfilePhoto &data) {
push(data.vphoto());
}, [](const auto &data) { }, [](const auto &data) {
}); });
}, [](const MTPDmessageEmpty &data) { }, [](const MTPDmessageEmpty &data) {

View File

@ -0,0 +1,50 @@
/*
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 "editor/editor_layer_widget.h"
#include <QtGui/QGuiApplication>
namespace Editor {
LayerWidget::LayerWidget(
not_null<QWidget*> parent,
base::unique_qptr<Ui::RpWidget> content)
: Ui::LayerWidget(parent)
, _content(std::move(content)) {
_content->setParent(this);
_content->show();
paintRequest(
) | rpl::start_with_next([=](const QRect &clip) {
auto p = QPainter(this);
p.fillRect(clip, st::photoEditorBg);
}, lifetime());
sizeValue(
) | rpl::start_with_next([=](const QSize &size) {
_content->resize(size);
}, lifetime());
}
void LayerWidget::parentResized() {
resizeToWidth(parentWidget()->width());
}
void LayerWidget::keyPressEvent(QKeyEvent *e) {
QGuiApplication::sendEvent(_content.get(), e);
}
int LayerWidget::resizeGetHeight(int newWidth) {
return parentWidget()->height();
}
bool LayerWidget::closeByOutsideClick() const {
return false;
}
} // namespace Editor

View File

@ -0,0 +1,42 @@
/*
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 "ui/layers/layer_widget.h"
#include "ui/image/image.h"
#include "editor/photo_editor_common.h"
#include "base/unique_qptr.h"
enum class ImageRoundRadius;
namespace Window {
class Controller;
class SessionController;
} // namespace Window
namespace Editor {
class LayerWidget final : public Ui::LayerWidget {
public:
LayerWidget(
not_null<QWidget*> parent,
base::unique_qptr<Ui::RpWidget> content);
void parentResized() override;
bool closeByOutsideClick() const override;
protected:
void keyPressEvent(QKeyEvent *e) override;
int resizeGetHeight(int newWidth) override;
private:
const base::unique_qptr<Ui::RpWidget> _content;
};
} // namespace Editor

View File

@ -15,6 +15,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "editor/photo_editor_controls.h" #include "editor/photo_editor_controls.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "ui/layers/layer_widget.h"
#include "styles/style_editor.h" #include "styles/style_editor.h"
namespace Editor { namespace Editor {
@ -46,7 +47,7 @@ constexpr auto kPrecision = 100000;
} // namespace } // namespace
PhotoEditor::PhotoEditor( PhotoEditor::PhotoEditor(
not_null<Ui::RpWidget*> parent, not_null<QWidget*> parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
std::shared_ptr<Image> photo, std::shared_ptr<Image> photo,
PhotoModifications modifications, PhotoModifications modifications,
@ -174,7 +175,7 @@ PhotoEditor::PhotoEditor(
}, lifetime()); }, lifetime());
} }
void PhotoEditor::handleKeyPress(not_null<QKeyEvent*> e) { void PhotoEditor::keyPressEvent(QKeyEvent *e) {
if (!_colorPicker->preventHandleKeyPress()) { if (!_colorPicker->preventHandleKeyPress()) {
_content->handleKeyPress(e) || _controls->handleKeyPress(e); _content->handleKeyPress(e) || _controls->handleKeyPress(e);
} }
@ -193,4 +194,24 @@ rpl::producer<> PhotoEditor::cancelRequests() const {
return _cancel.events(); return _cancel.events();
} }
void InitEditorLayer(
not_null<Ui::LayerWidget*> layer,
not_null<PhotoEditor*> editor,
Fn<void(PhotoModifications)> doneCallback) {
editor->cancelRequests(
) | rpl::start_with_next([=] {
layer->closeLayer();
}, editor->lifetime());
const auto weak = Ui::MakeWeak(layer.get());
editor->doneRequests(
) | rpl::start_with_next([=, done = std::move(doneCallback)](
const PhotoModifications &mods) {
done(mods);
if (const auto strong = weak.data()) {
strong->closeLayer();
}
}, editor->lifetime());
}
} // namespace Editor } // namespace Editor

View File

@ -8,11 +8,14 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#pragma once #pragma once
#include "ui/rp_widget.h" #include "ui/rp_widget.h"
#include "ui/image/image.h"
#include "base/unique_qptr.h" #include "base/unique_qptr.h"
#include "editor/photo_editor_common.h" #include "editor/photo_editor_common.h"
#include "editor/photo_editor_inner_common.h" #include "editor/photo_editor_inner_common.h"
#include "ui/image/image.h"
namespace Ui {
class LayerWidget;
} // namespace Ui
namespace Window { namespace Window {
class Controller; class Controller;
@ -28,19 +31,18 @@ struct Controllers;
class PhotoEditor final : public Ui::RpWidget { class PhotoEditor final : public Ui::RpWidget {
public: public:
PhotoEditor( PhotoEditor(
not_null<Ui::RpWidget*> parent, not_null<QWidget*> parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
std::shared_ptr<Image> photo, std::shared_ptr<Image> photo,
PhotoModifications modifications, PhotoModifications modifications,
EditorData data = EditorData()); EditorData data = EditorData());
void save(); void save();
rpl::producer<PhotoModifications> doneRequests() const; [[nodiscard]] rpl::producer<PhotoModifications> doneRequests() const;
rpl::producer<> cancelRequests() const; [[nodiscard]] rpl::producer<> cancelRequests() const;
void handleKeyPress(not_null<QKeyEvent*> e);
private: private:
void keyPressEvent(QKeyEvent *e) override;
PhotoModifications _modifications; PhotoModifications _modifications;
@ -59,4 +61,9 @@ private:
}; };
void InitEditorLayer(
not_null<Ui::LayerWidget*> layer,
not_null<PhotoEditor*> editor,
Fn<void(PhotoModifications)> doneCallback);
} // namespace Editor } // namespace Editor

View File

@ -8,12 +8,15 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "editor/photo_editor_layer_widget.h" #include "editor/photo_editor_layer_widget.h"
#include "ui/boxes/confirm_box.h" // InformBox #include "ui/boxes/confirm_box.h" // InformBox
#include "editor/editor_layer_widget.h"
#include "editor/photo_editor.h" #include "editor/photo_editor.h"
#include "storage/storage_media_prepare.h" #include "storage/storage_media_prepare.h"
#include "ui/chat/attach/attach_prepare.h" #include "ui/chat/attach/attach_prepare.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include <QtGui/QGuiApplication>
namespace Editor { namespace Editor {
namespace { namespace {
@ -22,7 +25,7 @@ constexpr auto kProfilePhotoSize = 640;
} // namespace } // namespace
void OpenWithPreparedFile( void OpenWithPreparedFile(
not_null<Ui::RpWidget*> parent, not_null<QWidget*> parent,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
not_null<Ui::PreparedFile*> file, not_null<Ui::PreparedFile*> file,
int previewWidth, int previewWidth,
@ -54,18 +57,19 @@ void OpenWithPreparedFile(
}; };
auto copy = image->data; auto copy = image->data;
const auto fileImage = std::make_shared<Image>(std::move(copy)); const auto fileImage = std::make_shared<Image>(std::move(copy));
controller->showLayer( auto editor = base::make_unique_q<PhotoEditor>(
std::make_unique<LayerWidget>( parent,
parent, &controller->window(),
&controller->window(), fileImage,
fileImage, image->modifications);
image->modifications, const auto raw = editor.get();
std::move(callback)), auto layer = std::make_unique<LayerWidget>(parent, std::move(editor));
Ui::LayerOption::KeepOther); InitEditorLayer(layer.get(), raw, std::move(callback));
controller->showLayer(std::move(layer), Ui::LayerOption::KeepOther);
} }
void PrepareProfilePhoto( void PrepareProfilePhoto(
not_null<Ui::RpWidget*> parent, not_null<QWidget*> parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
ImageRoundRadius radius, ImageRoundRadius radius,
Fn<void(QImage &&image)> &&doneCallback, Fn<void(QImage &&image)> &&doneCallback,
@ -112,24 +116,25 @@ void PrepareProfilePhoto(
minSide); minSide);
}(); }();
controller->showLayer( auto editor = base::make_unique_q<PhotoEditor>(
std::make_unique<LayerWidget>( parent,
parent, controller,
controller, fileImage,
fileImage, PhotoModifications{ .crop = std::move(crop) },
PhotoModifications{ .crop = std::move(crop) }, EditorData{
std::move(applyModifications), .cropType = (radius == ImageRoundRadius::Ellipse
EditorData{ ? EditorData::CropType::Ellipse
.cropType = (radius == ImageRoundRadius::Ellipse : EditorData::CropType::RoundedRect),
? EditorData::CropType::Ellipse .keepAspectRatio = true,
: EditorData::CropType::RoundedRect), });
.keepAspectRatio = true, const auto raw = editor.get();
}), auto layer = std::make_unique<LayerWidget>(parent, std::move(editor));
Ui::LayerOption::KeepOther); InitEditorLayer(layer.get(), raw, std::move(applyModifications));
controller->showLayer(std::move(layer), Ui::LayerOption::KeepOther);
} }
void PrepareProfilePhotoFromFile( void PrepareProfilePhotoFromFile(
not_null<Ui::RpWidget*> parent, not_null<QWidget*> parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
ImageRoundRadius radius, ImageRoundRadius radius,
Fn<void(QImage &&image)> &&doneCallback) { Fn<void(QImage &&image)> &&doneCallback) {
@ -158,60 +163,4 @@ void PrepareProfilePhotoFromFile(
crl::guard(parent, callback)); crl::guard(parent, callback));
} }
LayerWidget::LayerWidget(
not_null<Ui::RpWidget*> parent,
not_null<Window::Controller*> window,
std::shared_ptr<Image> photo,
PhotoModifications modifications,
Fn<void(PhotoModifications)> &&doneCallback,
EditorData data)
: Ui::LayerWidget(parent)
, _content(base::make_unique_q<PhotoEditor>(
this,
window,
photo,
std::move(modifications),
std::move(data))) {
paintRequest(
) | rpl::start_with_next([=](const QRect &clip) {
auto p = QPainter(this);
p.fillRect(clip, st::photoEditorBg);
}, lifetime());
_content->cancelRequests(
) | rpl::start_with_next([=] {
closeLayer();
}, lifetime());
const auto weak = Ui::MakeWeak(_content.get());
_content->doneRequests(
) | rpl::start_with_next([=, done = std::move(doneCallback)](
const PhotoModifications &mods) {
done(mods);
if (weak) closeLayer();
}, lifetime());
sizeValue(
) | rpl::start_with_next([=](const QSize &size) {
_content->resize(size);
}, lifetime());
}
void LayerWidget::parentResized() {
resizeToWidth(parentWidget()->width());
}
void LayerWidget::keyPressEvent(QKeyEvent *e) {
_content->handleKeyPress(e);
}
int LayerWidget::resizeGetHeight(int newWidth) {
return parentWidget()->height();
}
bool LayerWidget::closeByOutsideClick() const {
return false;
}
} // namespace Editor } // namespace Editor

View File

@ -6,16 +6,15 @@ For license and copyright information please follow this link:
https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
*/ */
#pragma once #pragma once
//
#include "ui/layers/layer_widget.h" //#include "ui/image/image.h"
//#include "editor/photo_editor_common.h"
#include "base/unique_qptr.h" //#include "base/unique_qptr.h"
#include "editor/photo_editor_common.h"
#include "ui/image/image.h"
enum class ImageRoundRadius; enum class ImageRoundRadius;
namespace Ui { namespace Ui {
class RpWidget;
struct PreparedFile; struct PreparedFile;
} // namespace Ui } // namespace Ui
@ -27,47 +26,23 @@ class SessionController;
namespace Editor { namespace Editor {
void OpenWithPreparedFile( void OpenWithPreparedFile(
not_null<Ui::RpWidget*> parent, not_null<QWidget*> parent,
not_null<Window::SessionController*> controller, not_null<Window::SessionController*> controller,
not_null<Ui::PreparedFile*> file, not_null<Ui::PreparedFile*> file,
int previewWidth, int previewWidth,
Fn<void()> &&doneCallback); Fn<void()> &&doneCallback);
void PrepareProfilePhoto( void PrepareProfilePhoto(
not_null<Ui::RpWidget*> parent, not_null<QWidget*> parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
ImageRoundRadius radius, ImageRoundRadius radius,
Fn<void(QImage &&image)> &&doneCallback, Fn<void(QImage &&image)> &&doneCallback,
QImage &&image); QImage &&image);
void PrepareProfilePhotoFromFile( void PrepareProfilePhotoFromFile(
not_null<Ui::RpWidget*> parent, not_null<QWidget*> parent,
not_null<Window::Controller*> controller, not_null<Window::Controller*> controller,
ImageRoundRadius radius, ImageRoundRadius radius,
Fn<void(QImage &&image)> &&doneCallback); Fn<void(QImage &&image)> &&doneCallback);
class PhotoEditor;
class LayerWidget : public Ui::LayerWidget {
public:
LayerWidget(
not_null<Ui::RpWidget*> parent,
not_null<Window::Controller*> window,
std::shared_ptr<Image> photo,
PhotoModifications modifications,
Fn<void(PhotoModifications)> &&doneCallback,
EditorData data = EditorData());
void parentResized() override;
bool closeByOutsideClick() const override;
protected:
void keyPressEvent(QKeyEvent *e) override;
int resizeGetHeight(int newWidth) override;
private:
const base::unique_qptr<PhotoEditor> _content;
};
} // namespace Editor } // namespace Editor

View File

@ -3884,6 +3884,12 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
auto prepareSuggestProfilePhoto = [this](const MTPDmessageActionSuggestProfilePhoto &action) { auto prepareSuggestProfilePhoto = [this](const MTPDmessageActionSuggestProfilePhoto &action) {
auto result = PreparedServiceText{}; auto result = PreparedServiceText{};
const auto isSelf = (_from->id == _from->session().userPeerId()); const auto isSelf = (_from->id == _from->session().userPeerId());
const auto isVideo = action.vphoto().match([&](const MTPDphoto &data) {
return data.vvideo_sizes().has_value()
&& !data.vvideo_sizes()->v.isEmpty();
}, [](const MTPDphotoEmpty &) {
return false;
});
const auto peer = isSelf ? history()->peer : _from; const auto peer = isSelf ? history()->peer : _from;
const auto user = peer->asUser(); const auto user = peer->asUser();
const auto name = (user && !user->firstName.isEmpty()) const auto name = (user && !user->firstName.isEmpty())
@ -3891,8 +3897,12 @@ void HistoryItem::setServiceMessageByAction(const MTPmessageAction &action) {
: peer->name(); : peer->name();
result.links.push_back(peer->createOpenLink()); result.links.push_back(peer->createOpenLink());
result.text = (isSelf result.text = (isSelf
? tr::lng_action_suggested_photo_me ? (isVideo
: tr::lng_action_suggested_photo)( ? tr::lng_action_suggested_video_me
: tr::lng_action_suggested_photo_me)
: (isVideo
? tr::lng_action_suggested_video
: tr::lng_action_suggested_photo))(
tr::now, tr::now,
lt_user, lt_user,
Ui::Text::Link(name, 1), // Link 1. Ui::Text::Link(name, 1), // Link 1.

View File

@ -22,6 +22,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
#include "main/main_session.h" #include "main/main_session.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
#include "ui/boxes/confirm_box.h"
#include "ui/painter.h" #include "ui/painter.h"
#include "mainwidget.h" #include "mainwidget.h"
#include "apiwrap.h" #include "apiwrap.h"
@ -56,7 +57,11 @@ QString UserpicSuggestion::title() {
} }
QString UserpicSuggestion::button() { QString UserpicSuggestion::button() {
return tr::lng_action_suggested_photo_button(tr::now); return _photo.getPhoto()->hasVideo()
? (_photo.parent()->data()->out()
? tr::lng_action_suggested_video_button(tr::now)
: tr::lng_profile_set_video_button(tr::now))
: tr::lng_action_suggested_photo_button(tr::now);
} }
QString UserpicSuggestion::subtitle() { QString UserpicSuggestion::subtitle() {
@ -67,6 +72,7 @@ ClickHandlerPtr UserpicSuggestion::createViewLink() {
const auto out = _photo.parent()->data()->out(); const auto out = _photo.parent()->data()->out();
const auto photo = _photo.getPhoto(); const auto photo = _photo.getPhoto();
const auto itemId = _photo.parent()->data()->fullId(); const auto itemId = _photo.parent()->data()->fullId();
const auto peer = _photo.parent()->data()->history()->peer;
const auto show = crl::guard(&_photo, [=](FullMsgId id) { const auto show = crl::guard(&_photo, [=](FullMsgId id) {
_photo.showPhoto(id); _photo.showPhoto(id);
}); });
@ -76,7 +82,29 @@ ClickHandlerPtr UserpicSuggestion::createViewLink() {
const auto media = photo->activeMediaView(); const auto media = photo->activeMediaView();
if (media->loaded()) { if (media->loaded()) {
if (out) { if (out) {
PhotoOpenClickHandler(photo, show, itemId).onClick(context); PhotoOpenClickHandler(photo, show, itemId).onClick(
context);
} else if (photo->hasVideo()) {
const auto user = peer->asUser();
const auto name = (user && !user->firstName.isEmpty())
? user->firstName
: peer->name();
const auto done = [=] {
using namespace Settings;
const auto session = &photo->session();
auto &peerPhotos = session->api().peerPhoto();
peerPhotos.updateSelf(photo, itemId);
controller->showSettings(Information::Id());
};
controller->show(Ui::MakeConfirmBox({
.text = tr::lng_profile_accept_video_sure(
tr::now,
lt_user,
name),
.confirmed = done,
.confirmText = tr::lng_profile_set_video_button(
tr::now),
}));
} else { } else {
const auto original = std::make_shared<QImage>( const auto original = std::make_shared<QImage>(
media->image(Data::PhotoSize::Large)->original()); media->image(Data::PhotoSize::Large)->original());
@ -88,7 +116,7 @@ ClickHandlerPtr UserpicSuggestion::createViewLink() {
auto &peerPhotos = session->api().peerPhoto(); auto &peerPhotos = session->api().peerPhoto();
if (original->size() == image.size() if (original->size() == image.size()
&& original->constBits() == image.constBits()) { && original->constBits() == image.constBits()) {
peerPhotos.updateSelf(photo); peerPhotos.updateSelf(photo, itemId);
} else { } else {
peerPhotos.upload(user, std::move(image)); peerPhotos.upload(user, std::move(image));
} }

View File

@ -140,6 +140,8 @@ UserpicButton::UserpicButton(
, _role(role) { , _role(role) {
Expects(_role == Role::ChangePhoto || _role == Role::ChoosePhoto); Expects(_role == Role::ChangePhoto || _role == Role::ChoosePhoto);
showCustom({});
_waiting = false;
prepare(); prepare();
} }
@ -157,7 +159,9 @@ UserpicButton::UserpicButton(
, _peer(peer) , _peer(peer)
, _role(role) , _role(role)
, _source(source) { , _source(source) {
if (_source != Source::Custom) { if (_source == Source::Custom) {
showCustom({});
} else {
processPeerPhoto(); processPeerPhoto();
setupPeerViewers(); setupPeerViewers();
} }
@ -175,7 +179,9 @@ UserpicButton::UserpicButton(
, _source(Source::PeerPhoto) { , _source(Source::PeerPhoto) {
Expects(_role != Role::OpenPhoto); Expects(_role != Role::OpenPhoto);
if (_source != Source::Custom) { if (_source == Source::Custom) {
showCustom({});
} else {
processPeerPhoto(); processPeerPhoto();
setupPeerViewers(); setupPeerViewers();
} }
@ -813,7 +819,9 @@ void UserpicButton::onStateChanged(
} }
void UserpicButton::showCustom(QImage &&image) { void UserpicButton::showCustom(QImage &&image) {
grabOldUserpic(); if (!_notShownYet) {
grabOldUserpic();
}
clearStreaming(); clearStreaming();
_sourceLifetime.destroy(); _sourceLifetime.destroy();

View File

@ -73,6 +73,8 @@ PRIVATE
editor/controllers/undo_controller.h editor/controllers/undo_controller.h
editor/editor_crop.cpp editor/editor_crop.cpp
editor/editor_crop.h editor/editor_crop.h
editor/editor_layer_widget.cpp
editor/editor_layer_widget.h
editor/photo_editor_common.cpp editor/photo_editor_common.cpp
editor/photo_editor_common.h editor/photo_editor_common.h
editor/photo_editor_inner_common.h editor/photo_editor_inner_common.h

@ -1 +1 @@
Subproject commit b178a5d15f4e422f4497e9c0334fe340df9d6046 Subproject commit 07d9420c19c008f9b49faaabde3e7d2139255961