More click-to-copy in profile

This commit is contained in:
Eric Kotato 2020-06-28 03:23:15 +03:00
parent f8c18a4820
commit 901f41a1b7
6 changed files with 171 additions and 67 deletions

View file

@ -2533,4 +2533,13 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
"ktg_settings_monospace_large_bubbles" = "Expand bubbles with monospace"; "ktg_settings_monospace_large_bubbles" = "Expand bubbles with monospace";
"ktg_bot_id_copied" = "Bot ID copied to clipboard.";
"ktg_user_id_copied" = "User ID copied to clipboard.";
"ktg_group_id_copied" = "Group ID copied to clipboard.";
"ktg_supergroup_id_copied" = "Supergroup ID copied to clipboard.";
"ktg_channel_id_copied" = "Channel ID copied to clipboard.";
"ktg_phone_copied" = "Phone copied to clipboard.";
"ktg_mention_copied" = "Username copied to clipboard.";
// Keys finished // Keys finished

View file

@ -132,5 +132,12 @@
"many": "{count} дней", "many": "{count} дней",
"other": "{count} дней" "other": "{count} дней"
}, },
"ktg_settings_monospace_large_bubbles": "Расширять моноширинные сообщения" "ktg_settings_monospace_large_bubbles": "Расширять моноширинные сообщения",
"ktg_bot_id_copied": "ID бота скопирован.",
"ktg_user_id_copied": "ID пользователя скопирован.",
"ktg_group_id_copied": "ID группы скопирован.",
"ktg_supergroup_id_copied": "ID супергруппы скопирован.",
"ktg_channel_id_copied": "ID канала скопирован.",
"ktg_phone_copied": "Номер телефона скопирован.",
"ktg_mention_copied": "Имя пользователя скопировано."
} }

View file

@ -376,6 +376,12 @@ infoLabeledOneLine: FlatLabel(defaultFlatLabel) {
lineHeight: 19px; lineHeight: 19px;
} }
} }
infoLabeledOneLineInline: FlatLabel(infoLabeledOneLine) {
palette: TextPalette(defaultTextPalette) {
linkFg: windowFg;
}
}
infoLabelSkip: 2px; infoLabelSkip: 2px;
infoLabel: FlatLabel(infoLabeledOneLine) { infoLabel: FlatLabel(infoLabeledOneLine) {
textFg: windowSubTextFg; textFg: windowSubTextFg;

View file

@ -48,6 +48,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
#include "facades.h" #include "facades.h"
#include "styles/style_info.h" #include "styles/style_info.h"
#include "styles/style_boxes.h" #include "styles/style_boxes.h"
#include "app.h"
#include <QtGui/QGuiApplication> #include <QtGui/QGuiApplication>
#include <QtGui/QClipboard> #include <QtGui/QClipboard>
@ -255,19 +256,41 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
result->setContextCopyText(contextCopyText); result->setContextCopyText(contextCopyText);
return result; return result;
}; };
auto addInfoOneLineInline = [&](
rpl::producer<QString> &&label,
rpl::producer<TextWithEntities> &&text,
const QString &contextCopyText) {
auto result = addInfoLine(
std::move(label),
std::move(text),
st::infoLabeledOneLineInline);
result->setContextCopyText(contextCopyText);
return result;
};
if (const auto user = _peer->asUser()) { if (const auto user = _peer->asUser()) {
if (cShowChatId() != 0) { if (cShowChatId() != 0) {
if (user->isBot()) { auto idDrawableText = IDValue(
addInfoOneLine( user
tr::ktg_profile_bot_id(), ) | rpl::map([](TextWithEntities &&text) {
IDValue(user), return Ui::Text::Link(text.text);
tr::ktg_profile_copy_id(tr::now)); });
} else { auto idInfo = addInfoOneLineInline(
addInfoOneLine( (user->isBot()
tr::ktg_profile_user_id(), ? tr::ktg_profile_bot_id()
IDValue(user), : tr::ktg_profile_user_id()),
tr::ktg_profile_copy_id(tr::now)); std::move(idDrawableText),
} tr::ktg_profile_copy_id(tr::now));
idInfo->setClickHandlerFilter([user](auto&&...) {
const auto idText = IDString(user);
if (!idText.isEmpty()) {
QGuiApplication::clipboard()->setText(idText);
Ui::Toast::Show(user->isBot()
? tr::ktg_bot_id_copied(tr::now)
: tr::ktg_user_id_copied(tr::now));
}
return false;
});
} }
if (user->session().supportMode()) { if (user->session().supportMode()) {
@ -276,20 +299,63 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
user->session().supportHelper().infoTextValue(user)); user->session().supportHelper().infoTextValue(user));
} }
addInfoOneLine( auto phoneDrawableText = rpl::combine(
PhoneValue(user),
UsernameValue(user),
AboutValue(user),
tr::lng_info_mobile_hidden()
) | rpl::map([](
const TextWithEntities &phone,
const TextWithEntities &username,
const TextWithEntities &bio,
const QString &hidden) {
return (phone.text.isEmpty() && username.text.isEmpty() && bio.text.isEmpty())
? Ui::Text::WithEntities(hidden)
: Ui::Text::Link(phone.text);
});
auto phoneInfo = addInfoOneLineInline(
tr::lng_info_mobile_label(), tr::lng_info_mobile_label(),
PhoneOrHiddenValue(user), std::move(phoneDrawableText),
tr::lng_profile_copy_phone(tr::now)); tr::lng_profile_copy_phone(tr::now));
phoneInfo->setClickHandlerFilter([user](auto&&...) {
const auto phoneText = user->phone();
if (!phoneText.isEmpty()) {
QGuiApplication::clipboard()->setText(App::formatPhone(phoneText));
Ui::Toast::Show(tr::ktg_phone_copied(tr::now));
}
return false;
});
if (user->isBot()) { if (user->isBot()) {
addInfoLine(tr::lng_info_about_label(), AboutValue(user)); addInfoLine(tr::lng_info_about_label(), AboutValue(user));
} else { } else {
addInfoLine(tr::lng_info_bio_label(), AboutValue(user)); addInfoLine(tr::lng_info_bio_label(), AboutValue(user));
} }
addInfoOneLine(
auto usernameDrawableText = UsernameValue(
user
) | rpl::map([](TextWithEntities &&username) {
return username.text.isEmpty()
? TextWithEntities()
: Ui::Text::Link(username.text);
});
auto usernameInfo = addInfoOneLineInline(
tr::lng_info_username_label(), tr::lng_info_username_label(),
UsernameValue(user), std::move(usernameDrawableText),
tr::lng_context_copy_mention(tr::now)); tr::lng_context_copy_mention(tr::now));
usernameInfo->setClickHandlerFilter([user](auto&&...) {
const auto usernameText = user->userName();
if (!usernameText.isEmpty()) {
QGuiApplication::clipboard()->setText('@' + usernameText);
Ui::Toast::Show(tr::ktg_mention_copied(tr::now));
}
return false;
});
const auto window = &_controller->parentController()->window(); const auto window = &_controller->parentController()->window();
AddMainButton( AddMainButton(
result, result,
@ -299,22 +365,32 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
tracker); tracker);
} else { } else {
if (cShowChatId() != 0) { if (cShowChatId() != 0) {
if (_peer->isChat()) { auto idDrawableText = IDValue(
addInfoOneLine( _peer
tr::ktg_profile_group_id(), ) | rpl::map([](TextWithEntities &&text) {
IDValue(_peer), return Ui::Text::Link(text.text);
tr::ktg_profile_copy_id(tr::now)); });
} else if (_peer->isMegagroup()) { auto idInfo = addInfoOneLineInline(
addInfoOneLine( (_peer->isChat()
tr::ktg_profile_supergroup_id(), ? tr::ktg_profile_group_id()
IDValue(_peer), : _peer->isMegagroup()
tr::ktg_profile_copy_id(tr::now)); ? tr::ktg_profile_supergroup_id()
} else { : tr::ktg_profile_channel_id()),
addInfoOneLine( std::move(idDrawableText),
tr::ktg_profile_channel_id(), tr::ktg_profile_copy_id(tr::now));
IDValue(_peer),
tr::ktg_profile_copy_id(tr::now)); idInfo->setClickHandlerFilter([peer = _peer](auto&&...) {
} const auto idText = IDString(peer);
if (!idText.isEmpty()) {
QGuiApplication::clipboard()->setText(idText);
Ui::Toast::Show(peer->isChat()
? tr::ktg_group_id_copied(tr::now)
: peer->isMegagroup()
? tr::ktg_supergroup_id_copied(tr::now)
: tr::ktg_channel_id_copied(tr::now));
}
return false;
});
} }
auto linkText = LinkValue( auto linkText = LinkValue(

View file

@ -47,7 +47,7 @@ auto PlainUsernameValue(not_null<PeerData*> peer) {
} // namespace } // namespace
rpl::producer<TextWithEntities> IDValue(not_null<PeerData*> peer) { QString IDString(not_null<PeerData*> peer) {
auto resultId = QString::number(peer->bareId()); auto resultId = QString::number(peer->bareId());
if (cShowChatId() == 2) { if (cShowChatId() == 2) {
@ -58,7 +58,11 @@ rpl::producer<TextWithEntities> IDValue(not_null<PeerData*> peer) {
} }
} }
return rpl::single(resultId) | Ui::Text::ToWithEntities(); return resultId;
}
rpl::producer<TextWithEntities> IDValue(not_null<PeerData*> peer) {
return rpl::single(IDString(peer)) | Ui::Text::ToWithEntities();
} }
rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) { rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
@ -79,39 +83,6 @@ rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user) {
}) | Ui::Text::ToWithEntities(); }) | Ui::Text::ToWithEntities();
} }
rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user) {
return rpl::combine(
PhoneValue(user),
PlainUsernameValue(user),
PlainBioValue(user),
tr::lng_info_mobile_hidden()
) | rpl::map([](
const TextWithEntities &phone,
const QString &username,
const QString &bio,
const QString &hidden) {
return (phone.text.isEmpty() && username.isEmpty() && bio.isEmpty())
? Ui::Text::WithEntities(hidden)
: phone;
});
}
rpl::producer<TextWithEntities> BioValue(not_null<UserData*> user) {
return PlainBioValue(user)
| ToSingleLine()
| Ui::Text::ToWithEntities();
}
rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
return PlainUsernameValue(
user
) | rpl::map([](QString &&username) {
return username.isEmpty()
? QString()
: ('@' + username);
}) | Ui::Text::ToWithEntities();
}
rpl::producer<QString> PlainAboutValue(not_null<PeerData*> peer) { rpl::producer<QString> PlainAboutValue(not_null<PeerData*> peer) {
/* /*
if (const auto user = peer->asUser()) { if (const auto user = peer->asUser()) {
@ -142,6 +113,39 @@ rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
}); });
} }
rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user) {
return rpl::combine(
PhoneValue(user),
PlainUsernameValue(user),
PlainAboutValue(user),
tr::lng_info_mobile_hidden()
) | rpl::map([](
const TextWithEntities &phone,
const QString &username,
const QString &bio,
const QString &hidden) {
return (phone.text.isEmpty() && username.isEmpty() && bio.isEmpty())
? Ui::Text::WithEntities(hidden)
: phone;
});
}
rpl::producer<TextWithEntities> BioValue(not_null<UserData*> user) {
return PlainBioValue(user)
| ToSingleLine()
| Ui::Text::ToWithEntities();
}
rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
return PlainUsernameValue(
user
) | rpl::map([](QString &&username) {
return username.isEmpty()
? QString()
: ('@' + username);
}) | Ui::Text::ToWithEntities();
}
rpl::producer<QString> LinkValue(not_null<PeerData*> peer) { rpl::producer<QString> LinkValue(not_null<PeerData*> peer) {
return PlainUsernameValue( return PlainUsernameValue(
peer peer

View file

@ -35,6 +35,8 @@ inline auto ToSingleLine() {
rpl::producer<not_null<PeerData*>> MigratedOrMeValue( rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
not_null<PeerData*> peer); not_null<PeerData*> peer);
QString IDString(not_null<PeerData*> peer);
rpl::producer<TextWithEntities> IDValue(not_null<PeerData*> peer); rpl::producer<TextWithEntities> IDValue(not_null<PeerData*> peer);
rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer); rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer);
rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user); rpl::producer<TextWithEntities> PhoneValue(not_null<UserData*> user);