Loading app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +48 −7 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.text.style.URLSpan; import android.util.Patterns; import android.view.LayoutInflater; import android.view.View; import android.webkit.URLUtil; import android.widget.Toast; import androidx.annotation.NonNull; Loading Loading @@ -286,19 +287,25 @@ public class SpannableHelper { private static void makeLinks(Context context, SpannableStringBuilder content, String url, int start, int end) { String newUrl = url; String newURL = Helper.transformURL(context, url); boolean validUrl = URLUtil.isValidUrl(url) && url.length() == (end - start); if (validUrl) { newUrl = Helper.transformURL(context, url); } //If URL has been transformed if (newURL.compareTo(url) != 0) { content.replace(start, end, newURL); end = start + newURL.length(); url = newURL; if (validUrl && newUrl.compareTo(url) != 0) { content.replace(start, end, newUrl); end = start + newUrl.length(); url = newUrl; } if (url.length() > 30 && (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("gimini://"))) { if (url.length() > 30 && (validUrl || url.startsWith("gimini://"))) { newUrl = url.substring(0, 30); newUrl += "…"; content.replace(start, end, newUrl); } int matchEnd = start + newUrl.length(); int matchEnd = validUrl ? start + newUrl.length() : end; String finalUrl = url; if (content.length() < matchEnd) { matchEnd = content.length(); Loading Loading @@ -439,6 +446,8 @@ public class SpannableHelper { textView.setTag(CLICKABLE_SPAN); Pattern link = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w._-]*[0-9]*)(/[0-9]+)?$"); Matcher matcherLink = link.matcher(finalUrl); Pattern linkLong = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w_.-]+@[a-zA-Z0-9][a-zA-Z0-9.-]{1,61}[a-zA-Z0-9](?:\\.[a-zA-Z]{2,})+)(/[0-9]+)?$"); Matcher matcherLinkLong = linkLong.matcher(finalUrl); if (matcherLink.find() && !finalUrl.contains("medium.com")) { if (matcherLink.group(3) != null && Objects.requireNonNull(matcherLink.group(3)).length() > 0) { //It's a toot CrossActionHelper.fetchRemoteStatus(context, currentAccount, finalUrl, new CrossActionHelper.Callback() { Loading @@ -460,6 +469,38 @@ public class SpannableHelper { public void federatedStatus(Status status) { } @Override public void federatedAccount(Account account) { Intent intent = new Intent(context, ProfileActivity.class); Bundle b = new Bundle(); b.putSerializable(Helper.ARG_ACCOUNT, account); intent.putExtras(b); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } }); } } else if (matcherLinkLong.find() && !finalUrl.contains("medium.com")) { if (matcherLinkLong.group(3) != null && Objects.requireNonNull(matcherLinkLong.group(3)).length() > 0) { //It's a toot CrossActionHelper.fetchRemoteStatus(context, currentAccount, finalUrl, new CrossActionHelper.Callback() { @Override public void federatedStatus(Status status) { Intent intent = new Intent(context, ContextActivity.class); intent.putExtra(Helper.ARG_STATUS, status); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } @Override public void federatedAccount(Account account) { } }); } else if (matcherLinkLong.group(2) != null) {//It's an account CrossActionHelper.fetchRemoteAccount(context, currentAccount, matcherLinkLong.group(2), new CrossActionHelper.Callback() { @Override public void federatedStatus(Status status) { } @Override public void federatedAccount(Account account) { Intent intent = new Intent(context, ProfileActivity.class); Loading app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +3 −0 Original line number Diff line number Diff line Loading @@ -1743,6 +1743,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> statusDraft.statusReplyList = new ArrayList<>(); statusToDeal.text = statusSource.text; statusToDeal.spoiler_text = statusSource.spoiler_text; if (statusToDeal.spoiler_text != null && statusToDeal.spoiler_text.length() > 0) { statusToDeal.spoilerChecked = true; } statusDraft.statusDraftList.add(statusToDeal); intent.putExtra(Helper.ARG_STATUS_DRAFT, statusDraft); intent.putExtra(Helper.ARG_EDIT_STATUS_ID, statusToDeal.id); Loading app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +5 −0 Original line number Diff line number Diff line Loading @@ -366,6 +366,11 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. if (acctArray.length > 1) { remoteInstance = acctArray[1]; } if (remoteInstance != null && remoteInstance.equalsIgnoreCase(currentInstance)) { checkRemotely = false; } else if (remoteInstance == null) { checkRemotely = false; } } if (tagTimeline != null) { ident = "@T@" + tagTimeline.name; Loading src/fdroid/fastlane/metadata/android/en/changelogs/462.txt 0 → 100644 +20 −0 Original line number Diff line number Diff line Added: - Add Bubble timeline support in extra-features with filters - Allow to display public profiles by default to get all messages (Settings > Interface) - Glitch: Allow to post messages locally (Can be turned off in Settings) - Pixelfed: Custom layout to display Media fully (Also works for other software when there are media) - Allow to align left action buttons in messages Changed: - Full rework on links in messages (also mentions and tags) - Add pinned tag in "any" to avoid to lose it when renaming timeline Fixed: - Links to messages not handled by the app - CW when editing a message - Fix push notifications with several accounts - Fix quotes with tags/mentions - Fix notifications - Fix sending multiple media - Fix crashes No newline at end of file Loading
app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +48 −7 Original line number Diff line number Diff line Loading @@ -41,6 +41,7 @@ import android.text.style.URLSpan; import android.util.Patterns; import android.view.LayoutInflater; import android.view.View; import android.webkit.URLUtil; import android.widget.Toast; import androidx.annotation.NonNull; Loading Loading @@ -286,19 +287,25 @@ public class SpannableHelper { private static void makeLinks(Context context, SpannableStringBuilder content, String url, int start, int end) { String newUrl = url; String newURL = Helper.transformURL(context, url); boolean validUrl = URLUtil.isValidUrl(url) && url.length() == (end - start); if (validUrl) { newUrl = Helper.transformURL(context, url); } //If URL has been transformed if (newURL.compareTo(url) != 0) { content.replace(start, end, newURL); end = start + newURL.length(); url = newURL; if (validUrl && newUrl.compareTo(url) != 0) { content.replace(start, end, newUrl); end = start + newUrl.length(); url = newUrl; } if (url.length() > 30 && (url.startsWith("http://") || url.startsWith("https://") || url.startsWith("gimini://"))) { if (url.length() > 30 && (validUrl || url.startsWith("gimini://"))) { newUrl = url.substring(0, 30); newUrl += "…"; content.replace(start, end, newUrl); } int matchEnd = start + newUrl.length(); int matchEnd = validUrl ? start + newUrl.length() : end; String finalUrl = url; if (content.length() < matchEnd) { matchEnd = content.length(); Loading Loading @@ -439,6 +446,8 @@ public class SpannableHelper { textView.setTag(CLICKABLE_SPAN); Pattern link = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w._-]*[0-9]*)(/[0-9]+)?$"); Matcher matcherLink = link.matcher(finalUrl); Pattern linkLong = Pattern.compile("https?://([\\da-z.-]+\\.[a-z.]{2,10})/(@[\\w_.-]+@[a-zA-Z0-9][a-zA-Z0-9.-]{1,61}[a-zA-Z0-9](?:\\.[a-zA-Z]{2,})+)(/[0-9]+)?$"); Matcher matcherLinkLong = linkLong.matcher(finalUrl); if (matcherLink.find() && !finalUrl.contains("medium.com")) { if (matcherLink.group(3) != null && Objects.requireNonNull(matcherLink.group(3)).length() > 0) { //It's a toot CrossActionHelper.fetchRemoteStatus(context, currentAccount, finalUrl, new CrossActionHelper.Callback() { Loading @@ -460,6 +469,38 @@ public class SpannableHelper { public void federatedStatus(Status status) { } @Override public void federatedAccount(Account account) { Intent intent = new Intent(context, ProfileActivity.class); Bundle b = new Bundle(); b.putSerializable(Helper.ARG_ACCOUNT, account); intent.putExtras(b); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } }); } } else if (matcherLinkLong.find() && !finalUrl.contains("medium.com")) { if (matcherLinkLong.group(3) != null && Objects.requireNonNull(matcherLinkLong.group(3)).length() > 0) { //It's a toot CrossActionHelper.fetchRemoteStatus(context, currentAccount, finalUrl, new CrossActionHelper.Callback() { @Override public void federatedStatus(Status status) { Intent intent = new Intent(context, ContextActivity.class); intent.putExtra(Helper.ARG_STATUS, status); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); context.startActivity(intent); } @Override public void federatedAccount(Account account) { } }); } else if (matcherLinkLong.group(2) != null) {//It's an account CrossActionHelper.fetchRemoteAccount(context, currentAccount, matcherLinkLong.group(2), new CrossActionHelper.Callback() { @Override public void federatedStatus(Status status) { } @Override public void federatedAccount(Account account) { Intent intent = new Intent(context, ProfileActivity.class); Loading
app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +3 −0 Original line number Diff line number Diff line Loading @@ -1743,6 +1743,9 @@ public class StatusAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> statusDraft.statusReplyList = new ArrayList<>(); statusToDeal.text = statusSource.text; statusToDeal.spoiler_text = statusSource.spoiler_text; if (statusToDeal.spoiler_text != null && statusToDeal.spoiler_text.length() > 0) { statusToDeal.spoilerChecked = true; } statusDraft.statusDraftList.add(statusToDeal); intent.putExtra(Helper.ARG_STATUS_DRAFT, statusDraft); intent.putExtra(Helper.ARG_EDIT_STATUS_ID, statusToDeal.id); Loading
app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +5 −0 Original line number Diff line number Diff line Loading @@ -366,6 +366,11 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. if (acctArray.length > 1) { remoteInstance = acctArray[1]; } if (remoteInstance != null && remoteInstance.equalsIgnoreCase(currentInstance)) { checkRemotely = false; } else if (remoteInstance == null) { checkRemotely = false; } } if (tagTimeline != null) { ident = "@T@" + tagTimeline.name; Loading
src/fdroid/fastlane/metadata/android/en/changelogs/462.txt 0 → 100644 +20 −0 Original line number Diff line number Diff line Added: - Add Bubble timeline support in extra-features with filters - Allow to display public profiles by default to get all messages (Settings > Interface) - Glitch: Allow to post messages locally (Can be turned off in Settings) - Pixelfed: Custom layout to display Media fully (Also works for other software when there are media) - Allow to align left action buttons in messages Changed: - Full rework on links in messages (also mentions and tags) - Add pinned tag in "any" to avoid to lose it when renaming timeline Fixed: - Links to messages not handled by the app - CW when editing a message - Fix push notifications with several accounts - Fix quotes with tags/mentions - Fix notifications - Fix sending multiple media - Fix crashes No newline at end of file