Loading app/src/main/java/app/fedilab/android/BaseMainActivity.java +3 −0 Original line number Diff line number Diff line Loading @@ -66,7 +66,9 @@ import androidx.navigation.ui.NavigationUI; import androidx.preference.PreferenceManager; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.gif.GifDrawable; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; import com.google.android.material.snackbar.Snackbar; Loading Loading @@ -652,6 +654,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt Helper.loadPP(headerMainBinding.accountProfilePicture, account); Glide.with(BaseMainActivity.this) .load(account.mastodon_account.header) .apply(new RequestOptions().transform(new CenterCrop())) .into(new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { Loading app/src/main/java/app/fedilab/android/client/entities/app/StatusCache.java +16 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,22 @@ public class StatusCache { return idReturned; } /** * update a status if presents in db * * @param statusCache {@link StatusCache} * @throws DBException exception with database */ public void updateIfExists(StatusCache statusCache) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } boolean exists = statusExist(statusCache); if (exists) { updateStatus(statusCache); } } /** * Check if a status exists in db * Loading app/src/main/java/app/fedilab/android/helper/Helper.java +6 −0 Original line number Diff line number Diff line Loading @@ -282,6 +282,10 @@ public class Helper { "(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,10}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); public static final Pattern aLink = Pattern.compile("<a((?!href).)*href=\"([^\"]*)\"[^>]*(((?!</a).)*)</a>"); public static final Pattern imgPattern = Pattern.compile("<img [^>]*src=\"([^\"]+)\"[^>]*>"); // --- Static Map of patterns used in spannable status content public static final Map<PatternType, Pattern> patternHashMap; public static final int NOTIFICATION_MEDIA = 451; Loading Loading @@ -679,6 +683,8 @@ public class Helper { } else { Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (!url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://") && !url.toLowerCase().startsWith("gemini://")) url = "http://" + url; intent.setData(Uri.parse(url)); try { context.startActivity(intent); Loading app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +35 −10 Original line number Diff line number Diff line Loading @@ -103,6 +103,20 @@ public class SpannableHelper { if (text == null) { return null; } Matcher matcherALink = Helper.aLink.matcher(text); //We stock details HashMap<String, String> urlDetails = new HashMap<>(); while (matcherALink.find()) { String urlText = matcherALink.group(3); String url = matcherALink.group(2); if (urlText != null) { urlText = urlText.substring(1); } if (url != null && urlText != null && !url.equals(urlText) && !urlText.contains("<span")) { urlDetails.put(url, urlText); text = text.replaceAll(Pattern.quote(matcherALink.group()), Matcher.quoteReplacement(url)); } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) initialContent = new SpannableString(Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY)); else Loading @@ -110,8 +124,10 @@ public class SpannableHelper { SpannableStringBuilder content = new SpannableStringBuilder(initialContent); URLSpan[] urls = content.getSpans(0, (content.length() - 1), URLSpan.class); for (URLSpan span : urls) for (URLSpan span : urls) { content.removeSpan(span); } //--- EMOJI ---- SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); boolean disableGif = sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_GIF), false); Loading Loading @@ -184,14 +200,15 @@ public class SpannableHelper { } //--- URLs ---- Matcher matcherALink = Patterns.WEB_URL.matcher(content); Matcher matcherLink = Patterns.WEB_URL.matcher(content); int offSetTruncate = 0; while (matcherALink.find()) { int matchStart = matcherALink.start() - offSetTruncate; int matchEnd = matchStart + matcherALink.group().length(); while (matcherLink.find()) { int matchStart = matcherLink.start() - offSetTruncate; int matchEnd = matchStart + matcherLink.group().length(); if (matchEnd > content.toString().length()) { matchEnd = content.toString().length(); } if (content.toString().length() < matchEnd || matchStart < 0 || matchStart > matchEnd) { continue; } Loading @@ -202,20 +219,27 @@ public class SpannableHelper { content.replace(matchStart, matchEnd, newURL); offSetTruncate += (newURL.length() - url.length()); matchEnd = matchStart + newURL.length(); //The transformed URL was in the list of URLs having a different names if (urlDetails.containsKey(url)) { urlDetails.put(newURL, urlDetails.get(url)); } } //Truncate URL if needed //TODO: add an option to disable truncated URLs String urlText = newURL; if (newURL.length() > 30) { if (newURL.length() > 30 && !urlDetails.containsKey(urlText)) { urlText = urlText.substring(0, 30); urlText += "…"; content.replace(matchStart, matchEnd, urlText); matchEnd = matchStart + 31; offSetTruncate += (newURL.length() - urlText.length()); } else if (urlDetails.containsKey(urlText) && urlDetails.get(urlText) != null) { urlText = urlDetails.get(urlText); if (urlText != null) { content.replace(matchStart, matchEnd, urlText); matchEnd = matchStart + urlText.length(); offSetTruncate += (newURL.length() - urlText.length()); } if (!urlText.startsWith("http")) { continue; } if (matchEnd <= content.length() && matchEnd >= matchStart) { Loading Loading @@ -409,6 +433,7 @@ public class SpannableHelper { Pattern pattern = entry.getValue(); Matcher matcher = pattern.matcher(content); while (matcher.find()) { int matchStart = matcher.start(); int matchEnd = matcher.end(); String word = content.toString().substring(matchStart, matchEnd); Loading app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +104 −127 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
app/src/main/java/app/fedilab/android/BaseMainActivity.java +3 −0 Original line number Diff line number Diff line Loading @@ -66,7 +66,9 @@ import androidx.navigation.ui.NavigationUI; import androidx.preference.PreferenceManager; import com.bumptech.glide.Glide; import com.bumptech.glide.load.resource.bitmap.CenterCrop; import com.bumptech.glide.load.resource.gif.GifDrawable; import com.bumptech.glide.request.RequestOptions; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.transition.Transition; import com.google.android.material.snackbar.Snackbar; Loading Loading @@ -652,6 +654,7 @@ public abstract class BaseMainActivity extends BaseActivity implements NetworkSt Helper.loadPP(headerMainBinding.accountProfilePicture, account); Glide.with(BaseMainActivity.this) .load(account.mastodon_account.header) .apply(new RequestOptions().transform(new CenterCrop())) .into(new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { Loading
app/src/main/java/app/fedilab/android/client/entities/app/StatusCache.java +16 −0 Original line number Diff line number Diff line Loading @@ -117,6 +117,22 @@ public class StatusCache { return idReturned; } /** * update a status if presents in db * * @param statusCache {@link StatusCache} * @throws DBException exception with database */ public void updateIfExists(StatusCache statusCache) throws DBException { if (db == null) { throw new DBException("db is null. Wrong initialization."); } boolean exists = statusExist(statusCache); if (exists) { updateStatus(statusCache); } } /** * Check if a status exists in db * Loading
app/src/main/java/app/fedilab/android/helper/Helper.java +6 −0 Original line number Diff line number Diff line Loading @@ -282,6 +282,10 @@ public class Helper { "(?i)\\b((?:[a-z][\\w-]+:(?:/{1,3}|[a-z0-9%])|www\\d{0,3}[.]|[a-z0-9.\\-]+[.][a-z]{2,10}/)(?:[^\\s()<>]+|\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\))+(?:\\(([^\\s()<>]+|(\\([^\\s()<>]+\\)))*\\)|[^\\s`!()\\[\\]{};:'\".,<>?«»“”‘’]))", Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL); public static final Pattern aLink = Pattern.compile("<a((?!href).)*href=\"([^\"]*)\"[^>]*(((?!</a).)*)</a>"); public static final Pattern imgPattern = Pattern.compile("<img [^>]*src=\"([^\"]+)\"[^>]*>"); // --- Static Map of patterns used in spannable status content public static final Map<PatternType, Pattern> patternHashMap; public static final int NOTIFICATION_MEDIA = 451; Loading Loading @@ -679,6 +683,8 @@ public class Helper { } else { Intent intent = new Intent(Intent.ACTION_VIEW); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (!url.toLowerCase().startsWith("http://") && !url.toLowerCase().startsWith("https://") && !url.toLowerCase().startsWith("gemini://")) url = "http://" + url; intent.setData(Uri.parse(url)); try { context.startActivity(intent); Loading
app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +35 −10 Original line number Diff line number Diff line Loading @@ -103,6 +103,20 @@ public class SpannableHelper { if (text == null) { return null; } Matcher matcherALink = Helper.aLink.matcher(text); //We stock details HashMap<String, String> urlDetails = new HashMap<>(); while (matcherALink.find()) { String urlText = matcherALink.group(3); String url = matcherALink.group(2); if (urlText != null) { urlText = urlText.substring(1); } if (url != null && urlText != null && !url.equals(urlText) && !urlText.contains("<span")) { urlDetails.put(url, urlText); text = text.replaceAll(Pattern.quote(matcherALink.group()), Matcher.quoteReplacement(url)); } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) initialContent = new SpannableString(Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY)); else Loading @@ -110,8 +124,10 @@ public class SpannableHelper { SpannableStringBuilder content = new SpannableStringBuilder(initialContent); URLSpan[] urls = content.getSpans(0, (content.length() - 1), URLSpan.class); for (URLSpan span : urls) for (URLSpan span : urls) { content.removeSpan(span); } //--- EMOJI ---- SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(context); boolean disableGif = sharedpreferences.getBoolean(context.getString(R.string.SET_DISABLE_GIF), false); Loading Loading @@ -184,14 +200,15 @@ public class SpannableHelper { } //--- URLs ---- Matcher matcherALink = Patterns.WEB_URL.matcher(content); Matcher matcherLink = Patterns.WEB_URL.matcher(content); int offSetTruncate = 0; while (matcherALink.find()) { int matchStart = matcherALink.start() - offSetTruncate; int matchEnd = matchStart + matcherALink.group().length(); while (matcherLink.find()) { int matchStart = matcherLink.start() - offSetTruncate; int matchEnd = matchStart + matcherLink.group().length(); if (matchEnd > content.toString().length()) { matchEnd = content.toString().length(); } if (content.toString().length() < matchEnd || matchStart < 0 || matchStart > matchEnd) { continue; } Loading @@ -202,20 +219,27 @@ public class SpannableHelper { content.replace(matchStart, matchEnd, newURL); offSetTruncate += (newURL.length() - url.length()); matchEnd = matchStart + newURL.length(); //The transformed URL was in the list of URLs having a different names if (urlDetails.containsKey(url)) { urlDetails.put(newURL, urlDetails.get(url)); } } //Truncate URL if needed //TODO: add an option to disable truncated URLs String urlText = newURL; if (newURL.length() > 30) { if (newURL.length() > 30 && !urlDetails.containsKey(urlText)) { urlText = urlText.substring(0, 30); urlText += "…"; content.replace(matchStart, matchEnd, urlText); matchEnd = matchStart + 31; offSetTruncate += (newURL.length() - urlText.length()); } else if (urlDetails.containsKey(urlText) && urlDetails.get(urlText) != null) { urlText = urlDetails.get(urlText); if (urlText != null) { content.replace(matchStart, matchEnd, urlText); matchEnd = matchStart + urlText.length(); offSetTruncate += (newURL.length() - urlText.length()); } if (!urlText.startsWith("http")) { continue; } if (matchEnd <= content.length() && matchEnd >= matchStart) { Loading Loading @@ -409,6 +433,7 @@ public class SpannableHelper { Pattern pattern = entry.getValue(); Matcher matcher = pattern.matcher(content); while (matcher.find()) { int matchStart = matcher.start(); int matchEnd = matcher.end(); String word = content.toString().substring(matchStart, matchEnd); Loading
app/src/main/java/app/fedilab/android/ui/drawer/StatusAdapter.java +104 −127 File changed.Preview size limit exceeded, changes collapsed. Show changes