Highlight internal links in Bio.
This commit is contained in:
		
							parent
							
								
									600cf83c3f
								
							
						
					
					
						commit
						c35b6e1209
					
				
					 4 changed files with 44 additions and 39 deletions
				
			
		| 
						 | 
					@ -267,11 +267,10 @@ object_ptr<Ui::RpWidget> DetailsFiller::setupInfo() {
 | 
				
			||||||
			tr::lng_info_mobile_label(),
 | 
								tr::lng_info_mobile_label(),
 | 
				
			||||||
			PhoneOrHiddenValue(user),
 | 
								PhoneOrHiddenValue(user),
 | 
				
			||||||
			tr::lng_profile_copy_phone(tr::now));
 | 
								tr::lng_profile_copy_phone(tr::now));
 | 
				
			||||||
		if (user->isBot()) {
 | 
							auto label = user->isBot()
 | 
				
			||||||
			addInfoLine(tr::lng_info_about_label(), AboutValue(user));
 | 
								? tr::lng_info_about_label()
 | 
				
			||||||
		} else {
 | 
								: tr::lng_info_bio_label();
 | 
				
			||||||
			addInfoLine(tr::lng_info_bio_label(), BioValue(user));
 | 
							addInfoLine(std::move(label), AboutValue(user));
 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		addInfoOneLine(
 | 
							addInfoOneLine(
 | 
				
			||||||
			tr::lng_info_username_label(),
 | 
								tr::lng_info_username_label(),
 | 
				
			||||||
			UsernameValue(user),
 | 
								UsernameValue(user),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
 | 
				
			||||||
#include "info/profile/info_profile_values.h"
 | 
					#include "info/profile/info_profile_values.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "core/application.h"
 | 
					#include "core/application.h"
 | 
				
			||||||
 | 
					#include "core/local_url_handlers.h"
 | 
				
			||||||
#include "main/main_session.h"
 | 
					#include "main/main_session.h"
 | 
				
			||||||
#include "ui/wrap/slide_wrap.h"
 | 
					#include "ui/wrap/slide_wrap.h"
 | 
				
			||||||
#include "ui/text/text_utilities.h"
 | 
					#include "ui/text/text_utilities.h"
 | 
				
			||||||
| 
						 | 
					@ -29,12 +30,12 @@ namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
using UpdateFlag = Data::PeerUpdate::Flag;
 | 
					using UpdateFlag = Data::PeerUpdate::Flag;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
auto PlainBioValue(not_null<UserData*> user) {
 | 
					auto PlainAboutValue(not_null<PeerData*> peer) {
 | 
				
			||||||
	return user->session().changes().peerFlagsValue(
 | 
						return peer->session().changes().peerFlagsValue(
 | 
				
			||||||
		user,
 | 
							peer,
 | 
				
			||||||
		UpdateFlag::About
 | 
							UpdateFlag::About
 | 
				
			||||||
	) | rpl::map([=] {
 | 
						) | rpl::map([=] {
 | 
				
			||||||
		return user->about();
 | 
							return peer->about();
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,6 +48,24 @@ auto PlainUsernameValue(not_null<PeerData*> peer) {
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void StripExternalLinks(TextWithEntities &text) {
 | 
				
			||||||
 | 
						const auto local = [](const QString &url) {
 | 
				
			||||||
 | 
							return Core::TryConvertUrlToLocal(url).startsWith(qstr("tg://"));
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						const auto notLocal = [&](const EntityInText &entity) {
 | 
				
			||||||
 | 
							if (entity.type() == EntityType::CustomUrl) {
 | 
				
			||||||
 | 
								return !local(entity.data());
 | 
				
			||||||
 | 
							} else if (entity.type() == EntityType::Url) {
 | 
				
			||||||
 | 
								return !local(text.text.mid(entity.offset(), entity.length()));
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								return false;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						};
 | 
				
			||||||
 | 
						text.entities.erase(
 | 
				
			||||||
 | 
							ranges::remove_if(text.entities, notLocal),
 | 
				
			||||||
 | 
							text.entities.end());
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
} // namespace
 | 
					} // namespace
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
 | 
					rpl::producer<TextWithEntities> NameValue(not_null<PeerData*> peer) {
 | 
				
			||||||
| 
						 | 
					@ -71,25 +90,19 @@ rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user) {
 | 
				
			||||||
	return rpl::combine(
 | 
						return rpl::combine(
 | 
				
			||||||
		PhoneValue(user),
 | 
							PhoneValue(user),
 | 
				
			||||||
		PlainUsernameValue(user),
 | 
							PlainUsernameValue(user),
 | 
				
			||||||
		PlainBioValue(user),
 | 
							PlainAboutValue(user),
 | 
				
			||||||
		tr::lng_info_mobile_hidden()
 | 
							tr::lng_info_mobile_hidden()
 | 
				
			||||||
	) | rpl::map([](
 | 
						) | rpl::map([](
 | 
				
			||||||
			const TextWithEntities &phone,
 | 
								const TextWithEntities &phone,
 | 
				
			||||||
			const QString &username,
 | 
								const QString &username,
 | 
				
			||||||
			const QString &bio,
 | 
								const QString &about,
 | 
				
			||||||
			const QString &hidden) {
 | 
								const QString &hidden) {
 | 
				
			||||||
		return (phone.text.isEmpty() && username.isEmpty() && bio.isEmpty())
 | 
							return (phone.text.isEmpty() && username.isEmpty() && about.isEmpty())
 | 
				
			||||||
			? Ui::Text::WithEntities(hidden)
 | 
								? Ui::Text::WithEntities(hidden)
 | 
				
			||||||
			: phone;
 | 
								: phone;
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rpl::producer<TextWithEntities> BioValue(not_null<UserData*> user) {
 | 
					 | 
				
			||||||
	return PlainBioValue(user)
 | 
					 | 
				
			||||||
		| ToSingleLine()
 | 
					 | 
				
			||||||
		| Ui::Text::ToWithEntities();
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
 | 
					rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
 | 
				
			||||||
	return PlainUsernameValue(
 | 
						return PlainUsernameValue(
 | 
				
			||||||
		user
 | 
							user
 | 
				
			||||||
| 
						 | 
					@ -100,32 +113,26 @@ rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user) {
 | 
				
			||||||
	}) | Ui::Text::ToWithEntities();
 | 
						}) | Ui::Text::ToWithEntities();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rpl::producer<QString> PlainAboutValue(not_null<PeerData*> peer) {
 | 
					 | 
				
			||||||
	if (const auto user = peer->asUser()) {
 | 
					 | 
				
			||||||
		if (!user->isBot()) {
 | 
					 | 
				
			||||||
			return rpl::single(QString());
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	return peer->session().changes().peerFlagsValue(
 | 
					 | 
				
			||||||
		peer,
 | 
					 | 
				
			||||||
		UpdateFlag::About
 | 
					 | 
				
			||||||
	) | rpl::map([=] {
 | 
					 | 
				
			||||||
		return peer->about();
 | 
					 | 
				
			||||||
	});
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
 | 
					rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer) {
 | 
				
			||||||
	auto flags = TextParseLinks
 | 
						auto flags = TextParseLinks | TextParseMentions;
 | 
				
			||||||
		| TextParseMentions
 | 
						const auto user = peer->asUser();
 | 
				
			||||||
		| TextParseHashtags;
 | 
						const auto isBot = user && user->isBot();
 | 
				
			||||||
	if (peer->isUser()) {
 | 
						if (!user) {
 | 
				
			||||||
		flags |= TextParseBotCommands;
 | 
							flags |= TextParseHashtags;
 | 
				
			||||||
 | 
						} else if (isBot) {
 | 
				
			||||||
 | 
							flags |= TextParseHashtags | TextParseBotCommands;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						const auto stripExternal = peer->isChat()
 | 
				
			||||||
 | 
							|| peer->isMegagroup()
 | 
				
			||||||
 | 
							|| (user && !isBot);
 | 
				
			||||||
	return PlainAboutValue(
 | 
						return PlainAboutValue(
 | 
				
			||||||
		peer
 | 
							peer
 | 
				
			||||||
	) | Ui::Text::ToWithEntities(
 | 
						) | Ui::Text::ToWithEntities(
 | 
				
			||||||
	) | rpl::map([=](TextWithEntities &&text) {
 | 
						) | rpl::map([=](TextWithEntities &&text) {
 | 
				
			||||||
		TextUtilities::ParseEntities(text, flags);
 | 
							TextUtilities::ParseEntities(text, flags);
 | 
				
			||||||
 | 
							if (stripExternal) {
 | 
				
			||||||
 | 
								StripExternalLinks(text);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return std::move(text);
 | 
							return std::move(text);
 | 
				
			||||||
	});
 | 
						});
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -37,7 +37,6 @@ rpl::producer<not_null<PeerData*>> MigratedOrMeValue(
 | 
				
			||||||
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);
 | 
				
			||||||
rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user);
 | 
					rpl::producer<TextWithEntities> PhoneOrHiddenValue(not_null<UserData*> user);
 | 
				
			||||||
rpl::producer<TextWithEntities> BioValue(not_null<UserData*> user);
 | 
					 | 
				
			||||||
rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user);
 | 
					rpl::producer<TextWithEntities> UsernameValue(not_null<UserData*> user);
 | 
				
			||||||
rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer);
 | 
					rpl::producer<TextWithEntities> AboutValue(not_null<PeerData*> peer);
 | 
				
			||||||
rpl::producer<QString> LinkValue(not_null<PeerData*> peer);
 | 
					rpl::producer<QString> LinkValue(not_null<PeerData*> peer);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -346,7 +346,7 @@ BioManager SetupBio(
 | 
				
			||||||
			std::move(done));
 | 
								std::move(done));
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	Info::Profile::BioValue(
 | 
						Info::Profile::AboutValue(
 | 
				
			||||||
		self
 | 
							self
 | 
				
			||||||
	) | rpl::start_with_next([=](const TextWithEntities &text) {
 | 
						) | rpl::start_with_next([=](const TextWithEntities &text) {
 | 
				
			||||||
		const auto wasChanged = (*current != bio->getLastText());
 | 
							const auto wasChanged = (*current != bio->getLastText());
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue