Added ability to share QR code from channels.

This commit is contained in:
23rd 2024-09-10 11:34:55 +03:00
parent fdcbe3cf3a
commit 925c9239bd
4 changed files with 43 additions and 29 deletions

View file

@ -1035,6 +1035,22 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
result.text->setContextCopyText(contextCopyText); result.text->setContextCopyText(contextCopyText);
return result; return result;
}; };
const auto fitLabelToButton = [&](
not_null<Ui::RpWidget*> button,
not_null<Ui::FlatLabel*> label) {
const auto parent = label->parentWidget();
result->sizeValue() | rpl::start_with_next([=] {
const auto s = parent->size();
button->moveToRight(
0,
(s.height() - button->height()) / 2);
label->resizeToWidth(
s.width()
- label->geometry().left()
- st::lineWidth * 2
- button->width());
}, button->lifetime());
};
if (const auto user = _peer->asUser()) { if (const auto user = _peer->asUser()) {
const auto controller = _controller->parentController(); const auto controller = _controller->parentController();
if (user->session().supportMode()) { if (user->session().supportMode()) {
@ -1103,25 +1119,12 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
usernameLine.text->setContextMenuHook(hook); usernameLine.text->setContextMenuHook(hook);
usernameLine.subtext->setContextMenuHook(hook); usernameLine.subtext->setContextMenuHook(hook);
if (user) { if (user) {
const auto usernameLabel = usernameLine.text;
const auto parent = usernameLabel->parentWidget();
const auto copyUsername = Ui::CreateChild<Ui::IconButton>( const auto copyUsername = Ui::CreateChild<Ui::IconButton>(
parent, usernameLine.text->parentWidget(),
user->isBot() user->isBot()
? st::infoProfileLabeledButtonCopy ? st::infoProfileLabeledButtonCopy
: st::infoProfileLabeledButtonQr); : st::infoProfileLabeledButtonQr);
result->sizeValue( fitLabelToButton(copyUsername, usernameLine.text);
) | rpl::start_with_next([=] {
const auto s = parent->size();
copyUsername->moveToRight(
0,
(s.height() - copyUsername->height()) / 2);
usernameLabel->resizeToWidth(
s.width()
- usernameLabel->geometry().left()
- st::lineWidth * 2
- copyUsername->width());
}, copyUsername->lifetime());
copyUsername->setClickedCallback([=] { copyUsername->setClickedCallback([=] {
if (!user->isBot()) { if (!user->isBot()) {
controller->show(Box([=](not_null<Ui::GenericBox*> box) { controller->show(Box([=](not_null<Ui::GenericBox*> box) {
@ -1187,7 +1190,7 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
: text) + addToLink, : text) + addToLink,
(addToLink.isEmpty() ? link.url : (text + addToLink))); (addToLink.isEmpty() ? link.url : (text + addToLink)));
}); });
auto linkLine = addInfoOneLine( const auto linkLine = addInfoOneLine(
(topicRootId (topicRootId
? tr::lng_info_link_label(Ui::Text::WithEntities) ? tr::lng_info_link_label(Ui::Text::WithEntities)
: UsernamesSubtext(_peer, tr::lng_info_link_label())), : UsernamesSubtext(_peer, tr::lng_info_link_label())),
@ -1200,6 +1203,18 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
addToLink); addToLink);
linkLine.text->overrideLinkClickHandler(linkCallback); linkLine.text->overrideLinkClickHandler(linkCallback);
linkLine.subtext->overrideLinkClickHandler(linkCallback); linkLine.subtext->overrideLinkClickHandler(linkCallback);
{
const auto qr = Ui::CreateChild<Ui::IconButton>(
linkLine.text->parentWidget(),
st::infoProfileLabeledButtonQr);
fitLabelToButton(qr, linkLine.text);
qr->setClickedCallback([=, peer = _peer] {
controller->show(Box([=](not_null<Ui::GenericBox*> box) {
Ui::FillPeerQrBox(box, peer);
}));
return false;
});
}
if (const auto channel = _topic ? nullptr : _peer->asChannel()) { if (const auto channel = _topic ? nullptr : _peer->asChannel()) {
auto locationText = LocationValue( auto locationText = LocationValue(

View file

@ -154,11 +154,11 @@ rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user) {
} }
rpl::producer<TextWithEntities> UsernameValue( rpl::producer<TextWithEntities> UsernameValue(
not_null<UserData*> user, not_null<PeerData*> peer,
bool primary) { bool primary) {
return (primary return (primary
? PlainPrimaryUsernameValue(user) ? PlainPrimaryUsernameValue(peer)
: (PlainUsernameValue(user) | rpl::type_erased()) : (PlainUsernameValue(peer) | rpl::type_erased())
) | rpl::map([](QString &&username) { ) | rpl::map([](QString &&username) {
return username.isEmpty() return username.isEmpty()
? QString() ? QString()

View file

@ -57,7 +57,7 @@ rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
[[nodiscard]] rpl::producer<TextWithEntities> PhoneOrHiddenValue( [[nodiscard]] rpl::producer<TextWithEntities> PhoneOrHiddenValue(
not_null<UserData*> user); not_null<UserData*> user);
[[nodiscard]] rpl::producer<TextWithEntities> UsernameValue( [[nodiscard]] rpl::producer<TextWithEntities> UsernameValue(
not_null<UserData*> user, not_null<PeerData*> peer,
bool primary = false); bool primary = false);
[[nodiscard]] rpl::producer<std::vector<TextWithEntities>> UsernamesValue( [[nodiscard]] rpl::producer<std::vector<TextWithEntities>> UsernamesValue(
not_null<PeerData*> peer); not_null<PeerData*> peer);

View file

@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "data/data_cloud_themes.h" #include "data/data_cloud_themes.h"
#include "data/data_peer.h" #include "data/data_peer.h"
#include "data/data_session.h" #include "data/data_session.h"
#include "data/data_user.h"
#include "info/channel_statistics/boosts/giveaway/boost_badge.h" // InfiniteRadialAnimationWidget. #include "info/channel_statistics/boosts/giveaway/boost_badge.h" // InfiniteRadialAnimationWidget.
#include "info/profile/info_profile_values.h" #include "info/profile/info_profile_values.h"
#include "lang/lang_keys.h" #include "lang/lang_keys.h"
@ -22,12 +21,12 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "ui/image/image_prepare.h" #include "ui/image/image_prepare.h"
#include "ui/layers/generic_box.h" #include "ui/layers/generic_box.h"
#include "ui/painter.h" #include "ui/painter.h"
#include "ui/widgets/continuous_sliders.h"
#include "ui/rect.h" #include "ui/rect.h"
#include "ui/ui_utility.h" #include "ui/ui_utility.h"
#include "ui/vertical_list.h" #include "ui/vertical_list.h"
#include "ui/widgets/box_content_divider.h" #include "ui/widgets/box_content_divider.h"
#include "ui/widgets/buttons.h" #include "ui/widgets/buttons.h"
#include "ui/widgets/continuous_sliders.h"
#include "ui/wrap/vertical_layout.h" #include "ui/wrap/vertical_layout.h"
#include "window/window_controller.h" #include "window/window_controller.h"
#include "window/window_session_controller.h" #include "window/window_session_controller.h"
@ -386,9 +385,9 @@ void FillPeerQrBox(
userpic, userpic,
state->font, state->font,
state->userpicToggled.value(), state->userpicToggled.value(),
Info::Profile::UsernameValue(peer->asUser()), Info::Profile::UsernameValue(peer, true),
Info::Profile::LinkValue(peer) | rpl::map([](const auto &link) { Info::Profile::LinkValue(peer, true) | rpl::map([](const auto &link) {
return link.url; return link.text;
}), }),
state->bgs.value()); state->bgs.value());
@ -719,12 +718,12 @@ void FillPeerQrBox(
: 0; : 0;
const auto font = createFont(scale); const auto font = createFont(scale);
using namespace Info::Profile;
const auto username = rpl::variable<TextWithEntities>( const auto username = rpl::variable<TextWithEntities>(
Info::Profile::UsernameValue( UsernameValue(peer, true)).current().text.toUpper();
peer->asUser())).current().text.toUpper();
const auto link = rpl::variable<QString>( const auto link = rpl::variable<QString>(
Info::Profile::LinkValue(peer) | rpl::map([](const auto &l) { LinkValue(peer, true) | rpl::map([](const auto &l) {
return l.url; return l.text;
})); }));
const auto textWidth = font->width(username); const auto textWidth = font->width(username);
const auto top = Ui::GrabWidget( const auto top = Ui::GrabWidget(