Open link in browser when a post/account links to itself

closes #739
This commit is contained in:
Grishka
2023-11-15 18:17:08 +03:00
parent a438f633be
commit cbe243fc9e
9 changed files with 35 additions and 16 deletions

View File

@@ -516,7 +516,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
// noinspection SetTextI18n
username.setText('@'+account.acct+(isSelf ? ('@'+AccountSessionManager.getInstance().getAccount(accountID).domain) : ""));
}
CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
CharSequence parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account);
if(TextUtils.isEmpty(parsedBio)){
bio.setVisibility(View.GONE);
}else{
@@ -551,7 +551,7 @@ public class ProfileFragment extends LoaderFragment implements OnBackPressedList
fields.add(joined);
for(AccountField field:account.fields){
field.parsedValue=ssb=HtmlParser.parse(field.value, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
field.parsedValue=ssb=HtmlParser.parse(field.value, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account);
field.valueEmojis=ssb.getSpans(0, ssb.length(), CustomEmojiSpan.class);
ssb=new SpannableStringBuilder(field.name);
HtmlParser.parseCustomEmoji(ssb, account.emojis);

View File

@@ -271,7 +271,7 @@ public class SignupFragment extends ToolbarFragment{
@Override
public void tail(Node node, int depth){
if(node instanceof Element){
ssb.setSpan(new LinkSpan("", SignupFragment.this::onGoBackLinkClick, LinkSpan.Type.CUSTOM, null, null), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new LinkSpan("", SignupFragment.this::onGoBackLinkClick, LinkSpan.Type.CUSTOM, null, null, null), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
ssb.setSpan(new TypefaceSpan("sans-serif-medium"), spanStart, ssb.length(), Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
}
}

View File

@@ -30,7 +30,7 @@ public class AccountViewModel{
parsedName=HtmlParser.parseCustomEmoji(account.displayName, account.emojis);
else
parsedName=account.displayName;
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID);
parsedBio=HtmlParser.parse(account.note, account.emojis, Collections.emptyList(), Collections.emptyList(), accountID, account);
SpannableStringBuilder ssb=new SpannableStringBuilder(parsedName);
ssb.append(parsedBio);
emojiHelper.setText(ssb);

View File

@@ -102,7 +102,7 @@ public class LinkCardStatusDisplayItem extends StatusDisplayItem{
}
private void onClick(View v){
UiUtils.openURL(itemView.getContext(), item.parentFragment.getAccountID(), item.status.card.url);
UiUtils.openURL(itemView.getContext(), item.parentFragment.getAccountID(), item.status.card.url, item.status);
}
}
}

View File

@@ -135,7 +135,7 @@ public abstract class StatusDisplayItem{
}
if(!TextUtils.isEmpty(statusForContent.content)){
SpannableStringBuilder parsedText=HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID);
SpannableStringBuilder parsedText=HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID, statusForContent);
if(filtered){
HtmlParser.applyFilterHighlights(fragment.getActivity(), parsedText, status.filtered);
}

View File

@@ -59,7 +59,7 @@ public class TextStatusDisplayItem extends StatusDisplayItem{
public void setTranslatedText(String text){
Status statusForContent=status.getContentStatus();
translatedText=HtmlParser.parse(text, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, parentFragment.getAccountID());
translatedText=HtmlParser.parse(text, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, parentFragment.getAccountID(), statusForContent);
translationEmojiHelper.setText(translatedText);
}

View File

@@ -68,7 +68,7 @@ public class HtmlParser{
* @param emojis Custom emojis that are present in source as <code>:code:</code>
* @return a spanned string
*/
public static SpannableStringBuilder parse(String source, List<Emoji> emojis, List<Mention> mentions, List<Hashtag> tags, String accountID){
public static SpannableStringBuilder parse(String source, List<Emoji> emojis, List<Mention> mentions, List<Hashtag> tags, String accountID, Object parentObject){
class SpanInfo{
public Object span;
public int start;
@@ -120,7 +120,7 @@ public class HtmlParser{
}else{
linkType=LinkSpan.Type.URL;
}
openSpans.add(new SpanInfo(new LinkSpan(href, null, linkType, accountID, linkObject), ssb.length(), el));
openSpans.add(new SpanInfo(new LinkSpan(href, null, linkType, accountID, linkObject, parentObject), ssb.length(), el));
}
case "br" -> ssb.append('\n');
case "span" -> {
@@ -216,7 +216,7 @@ public class HtmlParser{
String url=matcher.group(3);
if(TextUtils.isEmpty(matcher.group(4)))
url="http://"+url;
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null, null), matcher.start(3), matcher.end(3), 0);
ssb.setSpan(new LinkSpan(url, null, LinkSpan.Type.URL, null, null, null), matcher.start(3), matcher.end(3), 0);
}while(matcher.find()); // Find more URLs
return ssb;
}

View File

@@ -15,13 +15,15 @@ public class LinkSpan extends CharacterStyle {
private Type type;
private String accountID;
private Object linkObject;
private Object parentObject;
public LinkSpan(String link, OnLinkClickListener listener, Type type, String accountID, Object linkObject){
public LinkSpan(String link, OnLinkClickListener listener, Type type, String accountID, Object linkObject, Object parentObject){
this.listener=listener;
this.link=link;
this.type=type;
this.accountID=accountID;
this.linkObject=linkObject;
this.parentObject=parentObject;
}
public int getColor(){
@@ -36,7 +38,7 @@ public class LinkSpan extends CharacterStyle {
public void onClick(Context context){
switch(getType()){
case URL -> UiUtils.openURL(context, accountID, link);
case URL -> UiUtils.openURL(context, accountID, link, parentObject);
case MENTION -> UiUtils.openProfileByID(context, accountID, link);
case HASHTAG -> {
if(linkObject instanceof Hashtag ht)

View File

@@ -83,6 +83,7 @@ import java.time.format.FormatStyle;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.stream.Collectors;
@@ -616,9 +617,15 @@ public class UiUtils{
return GlobalUserPreferences.theme==GlobalUserPreferences.ThemePreference.DARK;
}
public static void openURL(Context context, String accountID, String url){
public static void openURL(Context context, String accountID, String url, Object parentObject){
String objectURL=null;
if(parentObject instanceof Status s){
objectURL=s.url;
}else if(parentObject instanceof Account a){
objectURL=a.url;
}
Uri uri=Uri.parse(url);
if(accountID!=null && "https".equals(uri.getScheme())){
if(accountID!=null && "https".equals(uri.getScheme()) && !Objects.equals(url, objectURL)){
List<String> path=uri.getPathSegments();
if(AccountSessionManager.getInstance().getAccount(accountID).domain.equalsIgnoreCase(uri.getAuthority()) && path.size()==2 && path.get(0).matches("^@[a-zA-Z0-9_]+$") && path.get(1).matches("^[0-9]+$")){
// Match URLs like https://mastodon.social/@Gargron/108132679274083591
@@ -649,10 +656,20 @@ public class UiUtils{
Bundle args=new Bundle();
args.putString("account", accountID);
if(result.statuses!=null && !result.statuses.isEmpty()){
args.putParcelable("status", Parcels.wrap(result.statuses.get(0)));
Status s=result.statuses.get(0);
if(parentObject instanceof Status status && s.id.equals(status.id)){
launchWebBrowser(context, url);
return;
}
args.putParcelable("status", Parcels.wrap(s));
Nav.go((Activity)context, ThreadFragment.class, args);
}else if(result.accounts!=null && !result.accounts.isEmpty()){
args.putParcelable("profileAccount", Parcels.wrap(result.accounts.get(0)));
Account a=result.accounts.get(0);
if(parentObject instanceof Account account && a.id.equals(account.id)){
launchWebBrowser(context, url);
return;
}
args.putParcelable("profileAccount", Parcels.wrap(a));
Nav.go((Activity)context, ProfileFragment.class, args);
}else{
launchWebBrowser(context, url);