Commit b18a1c97 authored by Thomas's avatar Thomas
Browse files

Fix an issue with links

parent 255ee607
Pipeline #310849 passed with stage
in 8 minutes and 31 seconds
......@@ -66,6 +66,7 @@ import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
......@@ -420,7 +421,7 @@ public class Status implements Parcelable {
Matcher matcher;
Pattern linkPattern = Pattern.compile("<a((?!href).)*href=\"([^\"]*)\"[^>]*(((?!</a).)*)</a>");
matcher = linkPattern.matcher(spannableString);
HashMap<String, String> targetedURL = new HashMap<>();
LinkedHashMap<String, String> targetedURL = new LinkedHashMap<>();
HashMap<String, Account> accountsMentionUnknown = new HashMap<>();
String liveInstance = Helper.getLiveInstance(context);
int i = 1;
......@@ -553,9 +554,9 @@ public class Status implements Parcelable {
}
if (accountsMentionUnknown.size() > 0) {
Iterator it = accountsMentionUnknown.entrySet().iterator();
Iterator<Map.Entry<String, Account>> it = accountsMentionUnknown.entrySet().iterator();
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();
Account account = (Account) pair.getValue();
String targetedAccount = "@" + account.getAcct();
......@@ -603,182 +604,182 @@ public class Status implements Parcelable {
}
}
if (targetedURL.size() > 0) {
Iterator it = targetedURL.entrySet().iterator();
Iterator<Map.Entry<String, String>> it = targetedURL.entrySet().iterator();
int endPosition = 0;
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 url = (String) pair.getValue();
if (spannableStringT.toString().toLowerCase().contains(key.toLowerCase())) {
//Accounts can be mentioned several times so we have to loop
int startPosition = spannableStringT.toString().toLowerCase().indexOf(key.toLowerCase(), endPosition);
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);
if (startPosition > 0) {
endPosition = startPosition + key.length();
}
if (endPosition <= spannableStringT.toString().length() && endPosition >= startPosition) {
spannableStringT.setSpan(new LongClickableSpan() {
@Override
public void onClick(@NonNull View textView) {
String finalUrl = url;
Pattern link = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w._-]*[0-9]*)(/[0-9]+)?$");
Matcher matcherLink = link.matcher(url);
if (matcherLink.find() && !url.contains("medium.com")) {
if (matcherLink.group(3) != null && Objects.requireNonNull(matcherLink.group(3)).length() > 0) { //It's a toot
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);
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();
}
if (endPosition <= spannableStringT.toString().length() && endPosition >= startPosition) {
spannableStringT.setSpan(new LongClickableSpan() {
@Override
public void onClick(@NonNull View textView) {
String finalUrl = url;
Pattern link = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w._-]*[0-9]*)(/[0-9]+)?$");
Matcher matcherLink = link.matcher(url);
if (matcherLink.find() && !url.contains("medium.com")) {
if (matcherLink.group(3) != null && Objects.requireNonNull(matcherLink.group(3)).length() > 0) { //It's a toot
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 {
if (!url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://"))
finalUrl = "http://" + url;
Helper.openBrowser(context, finalUrl);
}
}
}
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 {
if (!url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://"))
finalUrl = "http://" + url;
Helper.openBrowser(context, finalUrl);
}
@Override
public void onLongClick(@NonNull View textView) {
PopupMenu popup = new PopupMenu(context, textView);
popup.getMenuInflater()
.inflate(R.menu.links_popup, popup.getMenu());
int style;
if (theme == Helper.THEME_DARK) {
style = R.style.DialogDark;
} else if (theme == Helper.THEME_BLACK) {
style = R.style.DialogBlack;
} else {
style = R.style.Dialog;
}
}
popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case R.id.action_show_link:
AlertDialog.Builder builder = new AlertDialog.Builder(context, style);
builder.setMessage(url);
builder.setTitle(context.getString(R.string.display_full_link));
builder.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
.show();
break;
case R.id.action_share_link:
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via));
sendIntent.putExtra(Intent.EXTRA_TEXT, url);
sendIntent.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent, context.getString(R.string.share_with)));
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);
}
};
thread.start();
break;
@Override
public void onLongClick(@NonNull View textView) {
PopupMenu popup = new PopupMenu(context, textView);
popup.getMenuInflater()
.inflate(R.menu.links_popup, popup.getMenu());
int style;
if (theme == Helper.THEME_DARK) {
style = R.style.DialogDark;
} else if (theme == Helper.THEME_BLACK) {
style = R.style.DialogBlack;
} else {
style = R.style.Dialog;
}
return true;
});
popup.setOnDismissListener(menu -> BaseActivity.canShowActionMode = true);
popup.show();
textView.clearFocus();
BaseActivity.canShowActionMode = false;
}
popup.setOnMenuItemClickListener(item -> {
switch (item.getItemId()) {
case R.id.action_show_link:
AlertDialog.Builder builder = new AlertDialog.Builder(context, style);
builder.setMessage(url);
builder.setTitle(context.getString(R.string.display_full_link));
builder.setPositiveButton(R.string.close, (dialog, which) -> dialog.dismiss())
.show();
break;
case R.id.action_share_link:
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, context.getString(R.string.shared_via));
sendIntent.putExtra(Intent.EXTRA_TEXT, url);
sendIntent.setType("text/plain");
context.startActivity(Intent.createChooser(sendIntent, context.getString(R.string.share_with)));
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);
}
};
thread.start();
break;
}
return true;
});
popup.setOnDismissListener(menu -> BaseActivity.canShowActionMode = true);
popup.show();
textView.clearFocus();
BaseActivity.canShowActionMode = false;
}
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(link_color);
}
},
startPosition, endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
@Override
public void updateDrawState(@NonNull TextPaint ds) {
super.updateDrawState(ds);
ds.setUnderlineText(false);
ds.setColor(link_color);
}
},
startPosition, endPosition,
Spanned.SPAN_INCLUSIVE_EXCLUSIVE);
}
}
}
it.remove();
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment