Fix an issue with links

This commit is contained in:
Thomas 2020-06-08 17:09:16 +02:00
parent 255ee6076d
commit b18a1c971e
1 changed files with 161 additions and 160 deletions

View File

@ -66,6 +66,7 @@ import java.util.ArrayList;
import java.util.Date; import java.util.Date;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Objects; import java.util.Objects;
@ -420,7 +421,7 @@ public class Status implements Parcelable {
Matcher matcher; Matcher matcher;
Pattern linkPattern = Pattern.compile("<a((?!href).)*href=\"([^\"]*)\"[^>]*(((?!</a).)*)</a>"); Pattern linkPattern = Pattern.compile("<a((?!href).)*href=\"([^\"]*)\"[^>]*(((?!</a).)*)</a>");
matcher = linkPattern.matcher(spannableString); matcher = linkPattern.matcher(spannableString);
HashMap<String, String> targetedURL = new HashMap<>(); LinkedHashMap<String, String> targetedURL = new LinkedHashMap<>();
HashMap<String, Account> accountsMentionUnknown = new HashMap<>(); HashMap<String, Account> accountsMentionUnknown = new HashMap<>();
String liveInstance = Helper.getLiveInstance(context); String liveInstance = Helper.getLiveInstance(context);
int i = 1; int i = 1;
@ -553,9 +554,9 @@ public class Status implements Parcelable {
} }
if (accountsMentionUnknown.size() > 0) { if (accountsMentionUnknown.size() > 0) {
Iterator it = accountsMentionUnknown.entrySet().iterator(); Iterator<Map.Entry<String, Account>> it = accountsMentionUnknown.entrySet().iterator();
while (it.hasNext()) { while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next(); Map.Entry<String, Account> pair = (Map.Entry<String, Account>) it.next();
String key = (String) pair.getKey(); String key = (String) pair.getKey();
Account account = (Account) pair.getValue(); Account account = (Account) pair.getValue();
String targetedAccount = "@" + account.getAcct(); String targetedAccount = "@" + account.getAcct();
@ -603,182 +604,182 @@ public class Status implements Parcelable {
} }
} }
if (targetedURL.size() > 0) { if (targetedURL.size() > 0) {
Iterator it = targetedURL.entrySet().iterator(); Iterator<Map.Entry<String, String>> it = targetedURL.entrySet().iterator();
int endPosition = 0; int endPosition = 0;
while (it.hasNext()) { while (it.hasNext()) {
Map.Entry pair = (Map.Entry) it.next(); Map.Entry<String, String> pair = (Map.Entry<String, String>) it.next();
String key = ((String) pair.getKey()).split("\\|")[0]; String key = ((String) pair.getKey()).split("\\|")[0];
String url = (String) pair.getValue(); String url = (String) pair.getValue();
if (spannableStringT.toString().toLowerCase().contains(key.toLowerCase())) { if (spannableStringT.toString().toLowerCase().contains(key.toLowerCase())) {
//Accounts can be mentioned several times so we have to loop //Accounts can be mentioned several times so we have to loop
int startPosition = spannableStringT.toString().toLowerCase().indexOf(key.toLowerCase(), endPosition); int startPosition = spannableStringT.toString().toLowerCase().indexOf(key.toLowerCase(), endPosition);
if (startPosition < 0) { if (startPosition > 0) {
startPosition = 0;
}
endPosition = startPosition + key.length();
if (key.contains("") && !key.endsWith("")) {
key = key.split("")[0] + "";
SpannableStringBuilder ssb = new SpannableStringBuilder();
ssb.append(spannableStringT, 0, spannableStringT.length());
if (ssb.length() >= endPosition) {
ssb.replace(startPosition, endPosition, key);
}
spannableStringT = SpannableString.valueOf(ssb);
endPosition = startPosition + key.length(); endPosition = startPosition + key.length();
} if (key.contains("") && !key.endsWith("")) {
if (endPosition <= spannableStringT.toString().length() && endPosition >= startPosition) { key = key.split("")[0] + "";
spannableStringT.setSpan(new LongClickableSpan() { SpannableStringBuilder ssb = new SpannableStringBuilder();
@Override ssb.append(spannableStringT, 0, spannableStringT.length());
public void onClick(@NonNull View textView) { if (ssb.length() >= endPosition) {
String finalUrl = url; ssb.replace(startPosition, endPosition, key);
Pattern link = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w._-]*[0-9]*)(/[0-9]+)?$"); }
Matcher matcherLink = link.matcher(url); spannableStringT = SpannableString.valueOf(ssb);
if (matcherLink.find() && !url.contains("medium.com")) { endPosition = startPosition + key.length();
if (matcherLink.group(3) != null && Objects.requireNonNull(matcherLink.group(3)).length() > 0) { //It's a toot }
CrossActions.doCrossConversation(context, finalUrl); if (endPosition <= spannableStringT.toString().length() && endPosition >= startPosition) {
} else {//It's an account spannableStringT.setSpan(new LongClickableSpan() {
Account account = new Account(); @Override
String acct = matcherLink.group(2); public void onClick(@NonNull View textView) {
if (acct != null) { String finalUrl = url;
if (acct.startsWith("@")) Pattern link = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w._-]*[0-9]*)(/[0-9]+)?$");
acct = acct.substring(1); Matcher matcherLink = link.matcher(url);
account.setAcct(acct); if (matcherLink.find() && !url.contains("medium.com")) {
account.setInstance(matcherLink.group(1)); if (matcherLink.group(3) != null && Objects.requireNonNull(matcherLink.group(3)).length() > 0) { //It's a toot
CrossActions.doCrossProfile(context, account); CrossActions.doCrossConversation(context, finalUrl);
} else {//It's an account
Account account = new Account();
String acct = matcherLink.group(2);
if (acct != null) {
if (acct.startsWith("@"))
acct = acct.substring(1);
account.setAcct(acct);
account.setInstance(matcherLink.group(1));
CrossActions.doCrossProfile(context, account);
}
} }
}
} else {
link = Pattern.compile("(https?://[\\da-z.-]+\\.[a-z.]{2,10})/videos/watch/(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})$");
matcherLink = link.matcher(url);
if (matcherLink.find()) { //Peertubee video
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
String url = matcherLink.group(1) + "/videos/watch/" + matcherLink.group(2);
b.putString("peertubeLinkToFetch", url);
b.putString("peertube_instance", Objects.requireNonNull(matcherLink.group(1)).replace("https://", "").replace("http://", ""));
b.putString("video_id", matcherLink.group(2));
intent.putExtras(b);
context.startActivity(intent);
} else { } else {
if (!url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://")) link = Pattern.compile("(https?://[\\da-z.-]+\\.[a-z.]{2,10})/videos/watch/(\\w{8}-\\w{4}-\\w{4}-\\w{4}-\\w{12})$");
finalUrl = "http://" + url; matcherLink = link.matcher(url);
Helper.openBrowser(context, finalUrl); if (matcherLink.find()) { //Peertubee video
Intent intent = new Intent(context, PeertubeActivity.class);
Bundle b = new Bundle();
String url = matcherLink.group(1) + "/videos/watch/" + matcherLink.group(2);
b.putString("peertubeLinkToFetch", url);
b.putString("peertube_instance", Objects.requireNonNull(matcherLink.group(1)).replace("https://", "").replace("http://", ""));
b.putString("video_id", matcherLink.group(2));
intent.putExtras(b);
context.startActivity(intent);
} else {
if (!url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://"))
finalUrl = "http://" + url;
Helper.openBrowser(context, finalUrl);
}
} }
} }
}
@Override @Override
public void onLongClick(@NonNull View textView) { public void onLongClick(@NonNull View textView) {
PopupMenu popup = new PopupMenu(context, textView); PopupMenu popup = new PopupMenu(context, textView);
popup.getMenuInflater() popup.getMenuInflater()
.inflate(R.menu.links_popup, popup.getMenu()); .inflate(R.menu.links_popup, popup.getMenu());
int style; int style;
if (theme == Helper.THEME_DARK) { if (theme == Helper.THEME_DARK) {
style = R.style.DialogDark; style = R.style.DialogDark;
} else if (theme == Helper.THEME_BLACK) { } else if (theme == Helper.THEME_BLACK) {
style = R.style.DialogBlack; style = R.style.DialogBlack;
} else { } else {
style = R.style.Dialog; style = R.style.Dialog;
} }
popup.setOnMenuItemClickListener(item -> { popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.action_show_link: case R.id.action_show_link:
AlertDialog.Builder builder = new AlertDialog.Builder(context, style); AlertDialog.Builder builder = new AlertDialog.Builder(context, style);
builder.setMessage(url); builder.setMessage(url);
builder.setTitle(context.getString(R.string.display_full_link)); builder.setTitle(context.getString(R.string.display_full_link));
builder.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss()) builder.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
.show(); .show();
break; break;
case R.id.action_share_link: case R.id.action_share_link:
Intent sendIntent = new Intent(Intent.ACTION_SEND); Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via)); sendIntent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via));
sendIntent.putExtra(Intent.EXTRA_TEXT, url); sendIntent.putExtra(Intent.EXTRA_TEXT, url);
sendIntent.setType("text/plain"); sendIntent.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent, context.getString(R.string.share_with))); context.startActivity(Intent.createChooser(sendIntent, context.getString(R.string.share_with)));
break; break;
case R.id.action_open_other_app:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
try {
context.startActivity(intent);
} catch (Exception e) {
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
}
break;
case R.id.action_copy_link:
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip = ClipData.newPlainText(Helper.CLIP_BOARD, url);
if (clipboard != null) {
clipboard.setPrimaryClip(clip);
Toasty.info(context, context.getString(R.string.clipboard_url), Toast.LENGTH_LONG).show();
}
break;
case R.id.action_unshorten:
Thread thread = new Thread() {
@Override
public void run() {
String response = new HttpsConnection(context, null).checkUrl(url);
Handler mainHandler = new Handler(context.getMainLooper());
Runnable myRunnable = () -> {
AlertDialog.Builder builder1 = new AlertDialog.Builder(context, style);
if (response != null) {
builder1.setMessage(context.getString(R.string.redirect_detected, url, response));
builder1.setNegativeButton(R.string.copy_link, (dialog, which) -> {
ClipboardManager clipboard1 = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip1 = ClipData.newPlainText(Helper.CLIP_BOARD, response);
if (clipboard1 != null) {
clipboard1.setPrimaryClip(clip1);
Toasty.info(context, context.getString(R.string.clipboard_url), Toast.LENGTH_LONG).show();
}
dialog.dismiss();
});
builder1.setNeutralButton(R.string.share_link, (dialog, which) -> {
Intent sendIntent1 = new Intent(Intent.ACTION_SEND);
sendIntent1.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via));
sendIntent1.putExtra(Intent.EXTRA_TEXT, url);
sendIntent1.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent1, context.getString(R.string.share_with)));
dialog.dismiss();
});
} else {
builder1.setMessage(R.string.no_redirect);
}
builder1.setTitle(context.getString(R.string.check_redirect));
builder1.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
.show();
};
mainHandler.post(myRunnable);
case R.id.action_open_other_app:
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
try {
context.startActivity(intent);
} catch (Exception e) {
Toasty.error(context, context.getString(R.string.toast_error), Toast.LENGTH_LONG).show();
} }
}; break;
thread.start(); case R.id.action_copy_link:
break; ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
} ClipData clip = ClipData.newPlainText(Helper.CLIP_BOARD, url);
return true; if (clipboard != null) {
}); clipboard.setPrimaryClip(clip);
popup.setOnDismissListener(menu -> BaseActivity.canShowActionMode = true); Toasty.info(context, context.getString(R.string.clipboard_url), Toast.LENGTH_LONG).show();
popup.show(); }
textView.clearFocus(); break;
BaseActivity.canShowActionMode = false; case R.id.action_unshorten:
} Thread thread = new Thread() {
@Override
public void run() {
String response = new HttpsConnection(context, null).checkUrl(url);
Handler mainHandler = new Handler(context.getMainLooper());
Runnable myRunnable = () -> {
AlertDialog.Builder builder1 = new AlertDialog.Builder(context, style);
if (response != null) {
builder1.setMessage(context.getString(R.string.redirect_detected, url, response));
builder1.setNegativeButton(R.string.copy_link, (dialog, which) -> {
ClipboardManager clipboard1 = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
ClipData clip1 = ClipData.newPlainText(Helper.CLIP_BOARD, response);
if (clipboard1 != null) {
clipboard1.setPrimaryClip(clip1);
Toasty.info(context, context.getString(R.string.clipboard_url), Toast.LENGTH_LONG).show();
}
dialog.dismiss();
});
builder1.setNeutralButton(R.string.share_link, (dialog, which) -> {
Intent sendIntent1 = new Intent(Intent.ACTION_SEND);
sendIntent1.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via));
sendIntent1.putExtra(Intent.EXTRA_TEXT, url);
sendIntent1.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent1, context.getString(R.string.share_with)));
dialog.dismiss();
});
} else {
builder1.setMessage(R.string.no_redirect);
}
builder1.setTitle(context.getString(R.string.check_redirect));
builder1.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
.show();
};
mainHandler.post(myRunnable);
}
};
thread.start();
break;
}
return true;
});
popup.setOnDismissListener(menu -> BaseActivity.canShowActionMode = true);
popup.show();
textView.clearFocus();
BaseActivity.canShowActionMode = false;
}
@Override @Override
public void updateDrawState(@NonNull TextPaint ds) { public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds); super.updateDrawState(ds);
ds.setUnderlineText(false); ds.setUnderlineText(false);
ds.setColor(link_color); ds.setColor(link_color);
} }
}, },
startPosition, endPosition, startPosition, endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE); Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
} }
} }
it.remove(); it.remove();
} }