Show additional information in userpic suggest / accept.
This commit is contained in:
parent
076f0e0800
commit
2364b0ad4e
12 changed files with 256 additions and 117 deletions
|
@ -31,11 +31,25 @@ photoEditorButtonIconFgOver: mediaviewPipControlsFgOver;
|
|||
photoEditorButtonIconFgActive: lightButtonFg;
|
||||
photoEditorButtonIconFgInactive: mediaviewPipPlaybackInactive;
|
||||
|
||||
photoEditorButtonBarHeight: 50px;
|
||||
photoEditorButtonBarWidth: windowMinWidth;
|
||||
photoEditorButtonBarHeight: 48px;
|
||||
photoEditorButtonBarWidth: 422px;
|
||||
photoEditorButtonBarPadding: margins(2px, 0px, 2px, 0px);
|
||||
photoEditorTextButtonPadding: margins(22px, 0px, 22px, 0px);
|
||||
|
||||
photoEditorButtonStyle: TextStyle(semiboldTextStyle) {
|
||||
font: font(14px semibold);
|
||||
linkFont: font(14px semibold);
|
||||
linkFontOver: font(14px semibold underline);
|
||||
}
|
||||
photoEditorButtonTextTop: 15px;
|
||||
|
||||
photoEditorAbout: FlatLabel(defaultFlatLabel) {
|
||||
textFg: mediaviewCaptionFg;
|
||||
minWidth: 240px;
|
||||
align: align(top);
|
||||
}
|
||||
photoEditorAboutMargin: margins(10px, 22px, 10px, 0px);
|
||||
|
||||
photoEditorRotateButton: IconButton(defaultIconButton) {
|
||||
width: photoEditorButtonBarHeight;
|
||||
height: photoEditorButtonBarHeight;
|
||||
|
@ -43,7 +57,7 @@ photoEditorRotateButton: IconButton(defaultIconButton) {
|
|||
icon: icon {{ "photo_editor/rotate", photoEditorButtonIconFg }};
|
||||
iconOver: icon {{ "photo_editor/rotate", photoEditorButtonIconFgOver }};
|
||||
|
||||
rippleAreaPosition: point(5px, 5px);
|
||||
rippleAreaPosition: point(4px, 4px);
|
||||
rippleAreaSize: 40px;
|
||||
ripple: RippleAnimation(defaultRippleAnimation) {
|
||||
color: shadowFg;
|
||||
|
|
|
@ -67,11 +67,12 @@ PhotoEditor::PhotoEditor(
|
|||
photo,
|
||||
_modifications,
|
||||
_controllers,
|
||||
std::move(data)))
|
||||
data))
|
||||
, _controls(base::make_unique_q<PhotoEditorControls>(
|
||||
this,
|
||||
_controllers,
|
||||
_modifications))
|
||||
_modifications,
|
||||
data))
|
||||
, _colorPicker(std::make_unique<ColorPicker>(
|
||||
this,
|
||||
Deserialize(Core::App().settings().photoEditorBrush()))) {
|
||||
|
@ -81,12 +82,18 @@ PhotoEditor::PhotoEditor(
|
|||
if (size.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const auto geometry = QRect(QPoint(), size);
|
||||
const auto contentRect = geometry - st::photoEditorContentMargins;
|
||||
_content->setGeometry(contentRect);
|
||||
const auto contentBottom = contentRect.top() + contentRect.height();
|
||||
const auto controlsRect = geometry
|
||||
- style::margins(0, contentBottom, 0, 0);
|
||||
_content->setGeometry(rect() - st::photoEditorContentMargins);
|
||||
}, lifetime());
|
||||
|
||||
_content->innerRect(
|
||||
) | rpl::start_with_next([=](QRect inner) {
|
||||
if (inner.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
const auto innerTop = _content->y() + inner.top();
|
||||
const auto skip = st::photoEditorCropPointSize;
|
||||
const auto controlsRect = rect()
|
||||
- style::margins(0, innerTop + inner.height() + skip, 0, 0);
|
||||
_controls->setGeometry(controlsRect);
|
||||
}, lifetime());
|
||||
|
||||
|
|
|
@ -30,6 +30,8 @@ struct EditorData {
|
|||
RoundedRect,
|
||||
};
|
||||
|
||||
TextWithEntities about;
|
||||
QString confirm;
|
||||
CropType cropType = CropType::Rect;
|
||||
bool keepAspectRatio = false;
|
||||
};
|
||||
|
|
|
@ -80,6 +80,8 @@ PhotoEditorContent::PhotoEditorContent(
|
|||
mods.angle,
|
||||
mods.flipped, imageSizeF);
|
||||
_paint->applyTransform(geometry, mods.angle, mods.flipped);
|
||||
|
||||
_innerRect = geometry;
|
||||
}, lifetime());
|
||||
|
||||
paintRequest(
|
||||
|
|
|
@ -37,6 +37,10 @@ public:
|
|||
|
||||
void setupDragArea();
|
||||
|
||||
[[nodiscard]] rpl::producer<QRect> innerRect() const {
|
||||
return _innerRect.value();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
const QSize _photoSize;
|
||||
|
@ -44,6 +48,7 @@ private:
|
|||
const base::unique_qptr<Crop> _crop;
|
||||
const std::shared_ptr<Image> _photo;
|
||||
|
||||
rpl::variable<QRect> _innerRect;
|
||||
rpl::variable<PhotoModifications> _modifications;
|
||||
rpl::event_stream<int> _keyPresses;
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "lang/lang_keys.h"
|
||||
#include "ui/image/image_prepare.h"
|
||||
#include "ui/widgets/buttons.h"
|
||||
#include "ui/widgets/labels.h"
|
||||
#include "ui/wrap/fade_wrap.h"
|
||||
#include "ui/painter.h"
|
||||
#include "styles/style_editor.h"
|
||||
|
||||
|
@ -55,7 +57,7 @@ EdgeButton::EdgeButton(
|
|||
const style::RippleAnimation &st)
|
||||
: Ui::RippleButton(parent, st)
|
||||
, _fg(fg)
|
||||
, _text(st::semiboldTextStyle, text)
|
||||
, _text(st::photoEditorButtonStyle, text)
|
||||
, _width(_text.maxWidth()
|
||||
+ st::photoEditorTextButtonPadding.left()
|
||||
+ st::photoEditorTextButtonPadding.right())
|
||||
|
@ -78,7 +80,7 @@ void EdgeButton::init() {
|
|||
paintRipple(p, _rippleRect.x(), _rippleRect.y());
|
||||
|
||||
p.setPen(_fg);
|
||||
const auto textTop = (height() - _text.minHeight()) / 2;
|
||||
const auto textTop = st::photoEditorButtonTextTop;
|
||||
_text.draw(p, 0, textTop, width(), style::al_center);
|
||||
}, lifetime());
|
||||
}
|
||||
|
@ -122,25 +124,49 @@ ButtonBar::ButtonBar(
|
|||
sizeValue(
|
||||
) | rpl::start_with_next([=](const QSize &size) {
|
||||
const auto children = RpWidget::children();
|
||||
if (children.empty()) {
|
||||
return;
|
||||
}
|
||||
const auto widgets = ranges::views::all(
|
||||
children
|
||||
) | ranges::views::filter([](not_null<const QObject*> object) {
|
||||
return object->isWidgetType();
|
||||
}) | ranges::views::transform([](not_null<QObject*> object) {
|
||||
return static_cast<Ui::RpWidget*>(object.get());
|
||||
return static_cast<QWidget*>(object.get());
|
||||
}) | ranges::to_vector;
|
||||
if (widgets.size() < 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
const auto residualWidth = size.width()
|
||||
- ranges::accumulate(widgets, 0, ranges::plus(), &QWidget::width);
|
||||
const auto step = residualWidth / float(widgets.size() - 1);
|
||||
const auto layout = [&](bool symmetrical) {
|
||||
auto widths = widgets | ranges::views::transform(
|
||||
&QWidget::width
|
||||
) | ranges::to_vector;
|
||||
const auto count = int(widths.size());
|
||||
const auto middle = count / 2;
|
||||
if (symmetrical) {
|
||||
for (auto i = 0; i != middle; ++i) {
|
||||
const auto j = count - i - 1;
|
||||
widths[i] = widths[j] = std::max(widths[i], widths[j]);
|
||||
}
|
||||
}
|
||||
const auto residualWidth = size.width()
|
||||
- ranges::accumulate(widths, 0);
|
||||
if (symmetrical && residualWidth < 0) {
|
||||
return false;
|
||||
}
|
||||
const auto step = residualWidth / float(count - 1);
|
||||
|
||||
auto left = 0.;
|
||||
for (const auto &widget : widgets) {
|
||||
widget->moveToLeft(int(left), 0);
|
||||
left += widget->width() + step;
|
||||
auto left = 0.;
|
||||
auto &&ints = ranges::views::ints(0, ranges::unreachable);
|
||||
auto &&list = ranges::views::zip(widgets, widths, ints);
|
||||
for (const auto &[widget, width, index] : list) {
|
||||
widget->move(int((index >= middle)
|
||||
? (left + width - widget->width())
|
||||
: left), 0);
|
||||
left += width + step;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
if (!layout(true)) {
|
||||
layout(false);
|
||||
}
|
||||
|
||||
auto result = QImage(
|
||||
|
@ -165,37 +191,45 @@ PhotoEditorControls::PhotoEditorControls(
|
|||
not_null<Ui::RpWidget*> parent,
|
||||
std::shared_ptr<Controllers> controllers,
|
||||
const PhotoModifications modifications,
|
||||
bool doneControls)
|
||||
const EditorData &data)
|
||||
: RpWidget(parent)
|
||||
, _bg(st::roundedBg)
|
||||
, _buttonHeight(st::photoEditorButtonBarHeight)
|
||||
, _transformButtons(base::make_unique_q<ButtonBar>(this, _bg))
|
||||
, _paintTopButtons(base::make_unique_q<ButtonBar>(this, _bg))
|
||||
, _paintBottomButtons(base::make_unique_q<ButtonBar>(this, _bg))
|
||||
, _about(data.about.empty()
|
||||
? nullptr
|
||||
: base::make_unique_q<Ui::FadeWrap<Ui::FlatLabel>>(
|
||||
this,
|
||||
object_ptr<Ui::FlatLabel>(
|
||||
this,
|
||||
rpl::single(data.about),
|
||||
st::photoEditorAbout)))
|
||||
, _transformCancel(base::make_unique_q<EdgeButton>(
|
||||
_transformButtons,
|
||||
tr::lng_cancel(tr::now),
|
||||
_buttonHeight,
|
||||
true,
|
||||
_bg,
|
||||
st::activeButtonFg,
|
||||
st::mediaviewCaptionFg,
|
||||
st::photoEditorRotateButton.ripple))
|
||||
, _rotateButton(base::make_unique_q<Ui::IconButton>(
|
||||
_transformButtons,
|
||||
st::photoEditorRotateButton))
|
||||
, _flipButton(base::make_unique_q<Ui::IconButton>(
|
||||
_transformButtons,
|
||||
st::photoEditorFlipButton))
|
||||
, _rotateButton(base::make_unique_q<Ui::IconButton>(
|
||||
_transformButtons,
|
||||
st::photoEditorRotateButton))
|
||||
, _paintModeButton(base::make_unique_q<Ui::IconButton>(
|
||||
_transformButtons,
|
||||
st::photoEditorPaintModeButton))
|
||||
, _transformDone(base::make_unique_q<EdgeButton>(
|
||||
_transformButtons,
|
||||
tr::lng_box_done(tr::now),
|
||||
(data.confirm.isEmpty() ? tr::lng_box_done(tr::now) : data.confirm),
|
||||
_buttonHeight,
|
||||
false,
|
||||
_bg,
|
||||
st::lightButtonFg,
|
||||
st::mediaviewTextLinkFg,
|
||||
st::photoEditorRotateButton.ripple))
|
||||
, _paintCancel(base::make_unique_q<EdgeButton>(
|
||||
_paintBottomButtons,
|
||||
|
@ -203,7 +237,7 @@ PhotoEditorControls::PhotoEditorControls(
|
|||
_buttonHeight,
|
||||
true,
|
||||
_bg,
|
||||
st::activeButtonFg,
|
||||
st::mediaviewCaptionFg,
|
||||
st::photoEditorRotateButton.ripple))
|
||||
, _undoButton(base::make_unique_q<Ui::IconButton>(
|
||||
_paintTopButtons,
|
||||
|
@ -225,19 +259,9 @@ PhotoEditorControls::PhotoEditorControls(
|
|||
_buttonHeight,
|
||||
false,
|
||||
_bg,
|
||||
st::lightButtonFg,
|
||||
st::mediaviewTextLinkFg,
|
||||
st::photoEditorRotateButton.ripple)) {
|
||||
|
||||
{
|
||||
const auto &padding = st::photoEditorButtonBarPadding;
|
||||
const auto w = st::photoEditorButtonBarWidth
|
||||
- padding.left()
|
||||
- padding.right();
|
||||
_transformButtons->resize(w, _buttonHeight);
|
||||
_paintBottomButtons->resize(w, _buttonHeight);
|
||||
_paintTopButtons->resize(w, _buttonHeight);
|
||||
}
|
||||
|
||||
{
|
||||
const auto icon = &st::photoEditorPaintIconActive;
|
||||
_paintModeButtonActive->setIconOverride(icon, icon);
|
||||
|
@ -250,6 +274,14 @@ PhotoEditorControls::PhotoEditorControls(
|
|||
return;
|
||||
}
|
||||
|
||||
const auto &padding = st::photoEditorButtonBarPadding;
|
||||
const auto w = std::min(st::photoEditorButtonBarWidth, size.width())
|
||||
- padding.left()
|
||||
- padding.right();
|
||||
_transformButtons->resize(w, _buttonHeight);
|
||||
_paintBottomButtons->resize(w, _buttonHeight);
|
||||
_paintTopButtons->resize(w, _buttonHeight);
|
||||
|
||||
const auto buttonsTop = bottomButtonsTop();
|
||||
|
||||
const auto ¤t = _transformButtons->isHidden()
|
||||
|
@ -259,6 +291,16 @@ PhotoEditorControls::PhotoEditorControls(
|
|||
current->moveToLeft(
|
||||
(size.width() - current->width()) / 2,
|
||||
buttonsTop);
|
||||
|
||||
if (_about) {
|
||||
const auto &margin = st::photoEditorAboutMargin;
|
||||
const auto skip = st::photoEditorCropPointSize;
|
||||
_about->resizeToWidth(
|
||||
size.width() - margin.left() - margin.right());
|
||||
_about->moveToLeft(
|
||||
(size.width() - _about->width()) / 2,
|
||||
margin.top() - skip);
|
||||
}
|
||||
}, lifetime());
|
||||
|
||||
_mode.changes(
|
||||
|
@ -413,6 +455,9 @@ void PhotoEditorControls::showAnimated(
|
|||
const auto duration = st::photoEditorBarAnimationDuration;
|
||||
|
||||
const auto isTransform = (mode == Mode::Transform);
|
||||
if (_about) {
|
||||
_about->toggle(isTransform, animated);
|
||||
}
|
||||
|
||||
const auto buttonsLeft = (width() - _transformButtons->width()) / 2;
|
||||
const auto buttonsTop = bottomButtonsTop();
|
||||
|
|
|
@ -15,6 +15,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
|
||||
namespace Ui {
|
||||
class IconButton;
|
||||
class FlatLabel;
|
||||
template <typename Widget>
|
||||
class FadeWrap;
|
||||
} // namespace Ui
|
||||
|
||||
namespace Editor {
|
||||
|
@ -22,6 +25,7 @@ namespace Editor {
|
|||
class EdgeButton;
|
||||
class ButtonBar;
|
||||
struct Controllers;
|
||||
struct EditorData;
|
||||
|
||||
class PhotoEditorControls final : public Ui::RpWidget {
|
||||
public:
|
||||
|
@ -29,7 +33,7 @@ public:
|
|||
not_null<Ui::RpWidget*> parent,
|
||||
std::shared_ptr<Controllers> controllers,
|
||||
const PhotoModifications modifications,
|
||||
bool doneControls = true);
|
||||
const EditorData &data);
|
||||
|
||||
[[nodiscard]] rpl::producer<int> rotateRequests() const;
|
||||
[[nodiscard]] rpl::producer<> flipRequests() const;
|
||||
|
@ -58,9 +62,11 @@ private:
|
|||
const base::unique_qptr<ButtonBar> _paintTopButtons;
|
||||
const base::unique_qptr<ButtonBar> _paintBottomButtons;
|
||||
|
||||
const base::unique_qptr<Ui::FadeWrap<Ui::FlatLabel>> _about;
|
||||
|
||||
const base::unique_qptr<EdgeButton> _transformCancel;
|
||||
const base::unique_qptr<Ui::IconButton> _rotateButton;
|
||||
const base::unique_qptr<Ui::IconButton> _flipButton;
|
||||
const base::unique_qptr<Ui::IconButton> _rotateButton;
|
||||
const base::unique_qptr<Ui::IconButton> _paintModeButton;
|
||||
const base::unique_qptr<EdgeButton> _transformDone;
|
||||
|
||||
|
|
|
@ -71,7 +71,7 @@ void OpenWithPreparedFile(
|
|||
void PrepareProfilePhoto(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
ImageRoundRadius radius,
|
||||
EditorData data,
|
||||
Fn<void(QImage &&image)> &&doneCallback,
|
||||
QImage &&image) {
|
||||
const auto resizeToMinSize = [=](
|
||||
|
@ -121,12 +121,7 @@ void PrepareProfilePhoto(
|
|||
controller,
|
||||
fileImage,
|
||||
PhotoModifications{ .crop = std::move(crop) },
|
||||
EditorData{
|
||||
.cropType = (radius == ImageRoundRadius::Ellipse
|
||||
? EditorData::CropType::Ellipse
|
||||
: EditorData::CropType::RoundedRect),
|
||||
.keepAspectRatio = true,
|
||||
});
|
||||
data);
|
||||
const auto raw = editor.get();
|
||||
auto layer = std::make_unique<LayerWidget>(parent, std::move(editor));
|
||||
InitEditorLayer(layer.get(), raw, std::move(applyModifications));
|
||||
|
@ -136,7 +131,7 @@ void PrepareProfilePhoto(
|
|||
void PrepareProfilePhotoFromFile(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
ImageRoundRadius radius,
|
||||
EditorData data,
|
||||
Fn<void(QImage &&image)> &&doneCallback) {
|
||||
const auto callback = [=, done = std::move(doneCallback)](
|
||||
const FileDialog::OpenResult &result) mutable {
|
||||
|
@ -152,7 +147,7 @@ void PrepareProfilePhotoFromFile(
|
|||
PrepareProfilePhoto(
|
||||
parent,
|
||||
controller,
|
||||
radius,
|
||||
data,
|
||||
std::move(done),
|
||||
std::move(image));
|
||||
};
|
||||
|
|
|
@ -25,6 +25,8 @@ class SessionController;
|
|||
|
||||
namespace Editor {
|
||||
|
||||
struct EditorData;
|
||||
|
||||
void OpenWithPreparedFile(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Window::SessionController*> controller,
|
||||
|
@ -35,14 +37,14 @@ void OpenWithPreparedFile(
|
|||
void PrepareProfilePhoto(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
ImageRoundRadius radius,
|
||||
EditorData data,
|
||||
Fn<void(QImage &&image)> &&doneCallback,
|
||||
QImage &&image);
|
||||
|
||||
void PrepareProfilePhotoFromFile(
|
||||
not_null<QWidget*> parent,
|
||||
not_null<Window::Controller*> controller,
|
||||
ImageRoundRadius radius,
|
||||
EditorData data,
|
||||
Fn<void(QImage &&image)> &&doneCallback);
|
||||
|
||||
} // namespace Editor
|
||||
|
|
|
@ -14,6 +14,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_photo_media.h"
|
||||
#include "data/data_file_click_handler.h"
|
||||
#include "data/data_session.h"
|
||||
#include "editor/photo_editor_common.h"
|
||||
#include "editor/photo_editor_layer_widget.h"
|
||||
#include "history/history.h"
|
||||
#include "history/history_item.h"
|
||||
|
@ -31,7 +32,71 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "styles/style_chat.h"
|
||||
|
||||
namespace HistoryView {
|
||||
namespace {
|
||||
|
||||
void ShowUserpicSuggestion(
|
||||
not_null<Window::SessionController*> controller,
|
||||
const std::shared_ptr<Data::PhotoMedia> &media,
|
||||
const FullMsgId itemId,
|
||||
not_null<PeerData*> peer) {
|
||||
const auto photo = media->owner();
|
||||
const auto from = peer->asUser();
|
||||
const auto name = (from && !from->firstName.isEmpty())
|
||||
? from->firstName
|
||||
: peer->name();
|
||||
if (photo->hasVideo()) {
|
||||
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 {
|
||||
const auto original = std::make_shared<QImage>(
|
||||
media->image(Data::PhotoSize::Large)->original());
|
||||
const auto callback = [=](QImage &&image) {
|
||||
using namespace Settings;
|
||||
const auto session = &photo->session();
|
||||
const auto user = session->user();
|
||||
UpdatePhotoLocally(user, image);
|
||||
auto &peerPhotos = session->api().peerPhoto();
|
||||
if (original->size() == image.size()
|
||||
&& original->constBits() == image.constBits()) {
|
||||
peerPhotos.updateSelf(photo, itemId);
|
||||
} else {
|
||||
peerPhotos.upload(user, std::move(image));
|
||||
}
|
||||
controller->showSettings(Information::Id());
|
||||
};
|
||||
using namespace Editor;
|
||||
PrepareProfilePhoto(
|
||||
controller->content(),
|
||||
&controller->window(),
|
||||
{
|
||||
.about = { tr::lng_profile_accept_photo_sure(
|
||||
tr::now,
|
||||
lt_user,
|
||||
name) },
|
||||
.confirm = tr::lng_profile_set_photo_button(tr::now),
|
||||
.cropType = EditorData::CropType::Ellipse,
|
||||
.keepAspectRatio = true,
|
||||
},
|
||||
callback,
|
||||
base::duplicate(*original));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
UserpicSuggestion::UserpicSuggestion(
|
||||
not_null<Element*> parent,
|
||||
not_null<PeerData*> chat,
|
||||
|
@ -84,50 +149,8 @@ ClickHandlerPtr UserpicSuggestion::createViewLink() {
|
|||
if (out) {
|
||||
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 {
|
||||
const auto original = std::make_shared<QImage>(
|
||||
media->image(Data::PhotoSize::Large)->original());
|
||||
const auto callback = [=](QImage &&image) {
|
||||
using namespace Settings;
|
||||
const auto session = &photo->session();
|
||||
const auto user = session->user();
|
||||
UpdatePhotoLocally(user, image);
|
||||
auto &peerPhotos = session->api().peerPhoto();
|
||||
if (original->size() == image.size()
|
||||
&& original->constBits() == image.constBits()) {
|
||||
peerPhotos.updateSelf(photo, itemId);
|
||||
} else {
|
||||
peerPhotos.upload(user, std::move(image));
|
||||
}
|
||||
controller->showSettings(Information::Id());
|
||||
};
|
||||
Editor::PrepareProfilePhoto(
|
||||
controller->content(),
|
||||
&controller->window(),
|
||||
ImageRoundRadius::Ellipse,
|
||||
callback,
|
||||
base::duplicate(*original));
|
||||
ShowUserpicSuggestion(controller, media, itemId, peer);
|
||||
}
|
||||
} else if (!photo->loading()) {
|
||||
PhotoSaveClickHandler(photo, itemId).onClick(context);
|
||||
|
|
|
@ -25,6 +25,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "data/data_session.h"
|
||||
#include "data/data_user.h"
|
||||
#include "data/data_user_photos.h" // UserPhotosViewer.
|
||||
#include "editor/photo_editor_common.h"
|
||||
#include "editor/photo_editor_layer_widget.h"
|
||||
#include "history/admin_log/history_admin_log_item.h"
|
||||
#include "history/history.h"
|
||||
|
@ -1134,10 +1135,15 @@ object_ptr<Ui::RpWidget> ProfilePhotoPrivacyController::setupBelowWidget(
|
|||
base::call_delayed(
|
||||
st::settingsButton.ripple.hideDuration,
|
||||
crl::guard(container, [=] {
|
||||
Editor::PrepareProfilePhotoFromFile(
|
||||
using namespace Editor;
|
||||
PrepareProfilePhotoFromFile(
|
||||
container,
|
||||
&controller->window(),
|
||||
ImageRoundRadius::Ellipse,
|
||||
{
|
||||
.confirm = tr::lng_profile_set_photo_button(tr::now),
|
||||
.cropType = EditorData::CropType::Ellipse,
|
||||
.keepAspectRatio = true,
|
||||
},
|
||||
[=](QImage &&image) {
|
||||
state->updatePhoto(std::move(image), true);
|
||||
state->hiddenByUser = false;
|
||||
|
|
|
@ -22,7 +22,9 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
|||
#include "calls/calls_instance.h"
|
||||
#include "core/application.h"
|
||||
#include "ui/layers/generic_box.h"
|
||||
#include "ui/text/text_utilities.h"
|
||||
#include "ui/painter.h"
|
||||
#include "editor/photo_editor_common.h"
|
||||
#include "editor/photo_editor_layer_widget.h"
|
||||
#include "media/streaming/media_streaming_instance.h"
|
||||
#include "media/streaming/media_streaming_player.h"
|
||||
|
@ -70,22 +72,29 @@ void CameraBox(
|
|||
}
|
||||
}, box->lifetime());
|
||||
|
||||
auto done = [=, done = std::move(doneCallback)](QImage &&image) {
|
||||
auto done = [=, done = std::move(doneCallback)]() mutable {
|
||||
using namespace Editor;
|
||||
auto callback = [=, done = std::move(done)](QImage &&image) {
|
||||
box->closeBox();
|
||||
done(std::move(image));
|
||||
};
|
||||
PrepareProfilePhoto(
|
||||
box,
|
||||
controller,
|
||||
{
|
||||
.confirm = tr::lng_profile_set_photo_button(tr::now),
|
||||
.cropType = ((peer && peer->isForum())
|
||||
? EditorData::CropType::RoundedRect
|
||||
: EditorData::CropType::Ellipse),
|
||||
.keepAspectRatio = true,
|
||||
},
|
||||
std::move(callback),
|
||||
track->frame(FrameRequest()).mirrored(true, false));
|
||||
box->closeBox();
|
||||
done(std::move(image));
|
||||
};
|
||||
|
||||
box->setTitle(tr::lng_profile_camera_title());
|
||||
box->addButton(tr::lng_continue(), [=, done = std::move(done)]() mutable {
|
||||
Editor::PrepareProfilePhoto(
|
||||
box,
|
||||
controller,
|
||||
((peer && peer->isForum())
|
||||
? ImageRoundRadius::Large
|
||||
: ImageRoundRadius::Ellipse),
|
||||
std::move(done),
|
||||
track->frame(FrameRequest()).mirrored(true, false));
|
||||
});
|
||||
box->addButton(tr::lng_continue(), std::move(done));
|
||||
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||
}
|
||||
|
||||
|
@ -260,12 +269,35 @@ void UserpicButton::choosePhotoLocally() {
|
|||
base::call_delayed(
|
||||
_st.changeButton.ripple.hideDuration,
|
||||
crl::guard(this, [=] {
|
||||
Editor::PrepareProfilePhotoFromFile(
|
||||
using namespace Editor;
|
||||
const auto user = _peer ? _peer->asUser() : nullptr;
|
||||
const auto name = (user && !user->firstName.isEmpty())
|
||||
? user->firstName
|
||||
: _peer->name();
|
||||
const auto phrase = (type == ChosenType::Suggest)
|
||||
? &tr::lng_profile_suggest_sure
|
||||
: (_peer->isUser() && !_peer->isSelf())
|
||||
? &tr::lng_profile_set_personal_sure
|
||||
: nullptr;
|
||||
PrepareProfilePhotoFromFile(
|
||||
this,
|
||||
_window,
|
||||
((_peer && _peer->isForum())
|
||||
? ImageRoundRadius::Large
|
||||
: ImageRoundRadius::Ellipse),
|
||||
{
|
||||
.about = (phrase
|
||||
? (*phrase)(
|
||||
tr::now,
|
||||
lt_user,
|
||||
Ui::Text::Bold(name),
|
||||
Ui::Text::WithEntities)
|
||||
: TextWithEntities()),
|
||||
.confirm = ((type == ChosenType::Suggest)
|
||||
? tr::lng_profile_suggest_button(tr::now)
|
||||
: tr::lng_profile_set_photo_button(tr::now)),
|
||||
.cropType = ((_peer && _peer->isForum())
|
||||
? EditorData::CropType::RoundedRect
|
||||
: EditorData::CropType::Ellipse),
|
||||
.keepAspectRatio = true,
|
||||
},
|
||||
callback(type));
|
||||
}));
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue