More click-to-copy in profile
This commit is contained in:
parent
f8c18a4820
commit
901f41a1b7
6 changed files with 171 additions and 67 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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": "Имя пользователя скопировано."
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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()) {
|
||||||
|
|
@ -275,21 +298,64 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
|
||||||
user->session().supportHelper().infoLabelValue(user),
|
user->session().supportHelper().infoLabelValue(user),
|
||||||
user->session().supportHelper().infoTextValue(user));
|
user->session().supportHelper().infoTextValue(user));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
});
|
||||||
|
|
||||||
addInfoOneLine(
|
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(
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue