diff options
Diffstat (limited to 'app/src/main/java/app/fedilab')
40 files changed, 967 insertions, 331 deletions
diff --git a/app/src/main/java/app/fedilab/android/activities/BaseActivity.java b/app/src/main/java/app/fedilab/android/activities/BaseActivity.java index be483f80e..2f2b870f8 100644 --- a/app/src/main/java/app/fedilab/android/activities/BaseActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/BaseActivity.java @@ -83,6 +83,10 @@ public class BaseActivity extends AppCompatActivity { setTheme(R.style.BlackAppTheme); currentThemeId = R.style.BlackAppTheme; break; + case "DRACULA": + setTheme(R.style.DraculaAppTheme); + currentThemeId = R.style.DraculaAppTheme; + break; } break; } @@ -113,6 +117,11 @@ public class BaseActivity extends AppCompatActivity { setTheme(R.style.BlackAppTheme); currentThemeId = R.style.BlackAppTheme; break; + case "DRACULA": + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); + setTheme(R.style.DraculaAppTheme); + currentThemeId = R.style.DraculaAppTheme; + break; } } super.onCreate(savedInstanceState); diff --git a/app/src/main/java/app/fedilab/android/activities/BaseAlertDialogActivity.java b/app/src/main/java/app/fedilab/android/activities/BaseAlertDialogActivity.java index 220526dc5..48b51a25b 100644 --- a/app/src/main/java/app/fedilab/android/activities/BaseAlertDialogActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/BaseAlertDialogActivity.java @@ -76,6 +76,9 @@ public class BaseAlertDialogActivity extends AppCompatActivity { case "BLACK": setTheme(R.style.BlackAlertDialog); break; + case "DRACULA": + setTheme(R.style.DraculaAlertDialog); + break; } break; } @@ -101,6 +104,10 @@ public class BaseAlertDialogActivity extends AppCompatActivity { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); setTheme(R.style.BlackAlertDialog); break; + case "DRACULA": + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); + setTheme(R.style.DraculaAlertDialog); + break; } } super.onCreate(savedInstanceState); diff --git a/app/src/main/java/app/fedilab/android/activities/BaseBarActivity.java b/app/src/main/java/app/fedilab/android/activities/BaseBarActivity.java index dce372699..e8f0111e4 100644 --- a/app/src/main/java/app/fedilab/android/activities/BaseBarActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/BaseBarActivity.java @@ -75,6 +75,9 @@ public class BaseBarActivity extends AppCompatActivity { case "BLACK": setTheme(R.style.BlackAppThemeBar); break; + case "DRACULA": + setTheme(R.style.DraculaAppThemeBar); + break; } break; } @@ -101,6 +104,10 @@ public class BaseBarActivity extends AppCompatActivity { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); setTheme(R.style.BlackAppThemeBar); break; + case "DRACULA": + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); + setTheme(R.style.DraculaAppThemeBar); + break; } } super.onCreate(savedInstanceState); diff --git a/app/src/main/java/app/fedilab/android/activities/BaseTransparentActivity.java b/app/src/main/java/app/fedilab/android/activities/BaseTransparentActivity.java index 12f89e809..77f2df730 100644 --- a/app/src/main/java/app/fedilab/android/activities/BaseTransparentActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/BaseTransparentActivity.java @@ -75,6 +75,9 @@ public class BaseTransparentActivity extends AppCompatActivity { case "BLACK": setTheme(R.style.TransparentBlack); break; + case "DRACULA": + setTheme(R.style.TransparentDracula); + break; } break; } @@ -101,6 +104,10 @@ public class BaseTransparentActivity extends AppCompatActivity { AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); setTheme(R.style.TransparentBlack); break; + case "DRACULA": + AppCompatDelegate.setDefaultNightMode(AppCompatDelegate.MODE_NIGHT_YES); + setTheme(R.style.TransparentDracula); + break; } } super.onCreate(savedInstanceState); diff --git a/app/src/main/java/app/fedilab/android/activities/FollowedTagActivity.java b/app/src/main/java/app/fedilab/android/activities/FollowedTagActivity.java index 8dbd904d8..bd5732e3a 100644 --- a/app/src/main/java/app/fedilab/android/activities/FollowedTagActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/FollowedTagActivity.java @@ -108,7 +108,7 @@ public class FollowedTagActivity extends BaseBarActivity implements FollowedTagA fragmentMastodonTimeline.onDestroyView(); } invalidateOptionsMenu(); - setTitle(R.string.action_lists); + setTitle(R.string.followed_tags); }); if (tagList.size() == 0) { binding.notContent.setVisibility(View.VISIBLE); @@ -177,7 +177,7 @@ public class FollowedTagActivity extends BaseBarActivity implements FollowedTagA fragmentMastodonTimeline.onDestroyView(); } }); - setTitle(R.string.action_lists); + setTitle(R.string.followed_tags); invalidateOptionsMenu(); } else { super.onBackPressed(); diff --git a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java index 01afc9cee..5c34875e6 100644 --- a/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/ProfileActivity.java @@ -25,6 +25,7 @@ import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.res.ColorStateList; +import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.text.SpannableString; @@ -262,6 +263,7 @@ public class ProfileActivity extends BaseActivity { }); boolean disableGif = sharedpreferences.getBoolean(getString(R.string.SET_DISABLE_GIF), false); String targetedUrl = disableGif ? account.avatar_static : account.avatar; + // MastodonHelper.loadPPMastodon(binding.accountPp, account); Glide.with(ProfileActivity.this) .asDrawable() .dontTransform() @@ -271,6 +273,11 @@ public class ProfileActivity extends BaseActivity { public void onResourceReady(@NonNull final Drawable resource, Transition<? super Drawable> transition) { binding.profilePicture.setImageDrawable(resource); binding.accountPp.setImageDrawable(resource); + if (resource instanceof Animatable) { + binding.profilePicture.animate(); + binding.accountPp.animate(); + ((Animatable) resource).start(); + } ActivityCompat.startPostponedEnterTransition(ProfileActivity.this); } @@ -390,7 +397,7 @@ public class ProfileActivity extends BaseActivity { TextView.BufferType.SPANNABLE); binding.accountNote.setMovementMethod(LinkMovementMethod.getInstance()); - //MastodonHelper.loadPPMastodon(binding.accountPp, account); + binding.accountPp.setOnClickListener(v -> { Intent intent = new Intent(ProfileActivity.this, MediaActivity.class); Bundle b = new Bundle(); @@ -935,13 +942,11 @@ public class ProfileActivity extends BaseActivity { builderInner.setTitle(stringArrayConf[0]); builderInner.setNeutralButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); - builderInner.setNegativeButton(R.string.keep_notifications, (dialog, which) -> { - accountsVM.mute(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, target, false, 0) - .observe(ProfileActivity.this, relationShip -> { - this.relationship = relationShip; - updateAccount(); - }); - }); + builderInner.setNegativeButton(R.string.keep_notifications, (dialog, which) -> accountsVM.mute(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, target, false, 0) + .observe(ProfileActivity.this, relationShip -> { + this.relationship = relationShip; + updateAccount(); + })); builderInner.setPositiveButton(R.string.action_mute, (dialog, which) -> { accountsVM.mute(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, target, true, 0) .observe(ProfileActivity.this, relationShip -> { diff --git a/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java b/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java index 5b27f224b..2e6584a83 100644 --- a/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java +++ b/app/src/main/java/app/fedilab/android/activities/SearchResultTabActivity.java @@ -130,9 +130,10 @@ public class SearchResultTabActivity extends BaseBarActivity { search = query.trim(); ScreenSlidePagerAdapter mPagerAdapter = new ScreenSlidePagerAdapter(getSupportFragmentManager()); binding.searchViewpager.setAdapter(mPagerAdapter); - searchView.clearFocus(); setTitle(search); searchView.setIconified(true); + searchView.setQuery(search, false); + searchView.clearFocus(); binding.searchTabLayout.selectTab(initial); return false; } diff --git a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt index 955b615cf..32edbad45 100644 --- a/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt +++ b/app/src/main/java/app/fedilab/android/activities/SettingsActivity.kt @@ -36,6 +36,7 @@ class SettingsActivity : BaseBarActivity() { val navController = findNavController(R.id.fragment_container) appBarConfiguration = AppBarConfiguration.Builder().build() setupActionBarWithNavController(navController, appBarConfiguration) + } diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Account.java b/app/src/main/java/app/fedilab/android/client/entities/api/Account.java index 9ece81820..7a2bd1f29 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Account.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Account.java @@ -85,7 +85,7 @@ public class Account implements Serializable { if (display_name == null || display_name.isEmpty()) { display_name = username; } - return SpannableHelper.convert(context, display_name, null, this, null, false, viewWeakReference); + return SpannableHelper.convert(context, display_name, null, this, null, false, false, viewWeakReference); } public synchronized Spannable getSpanDisplayName(Activity activity, WeakReference<View> viewWeakReference) { @@ -96,11 +96,11 @@ public class Account implements Serializable { } public synchronized Spannable getSpanDisplayNameTitle(Context context, WeakReference<View> viewWeakReference, String title) { - return SpannableHelper.convert(context, title, null, this, null, false, viewWeakReference); + return SpannableHelper.convert(context, title, null, this, null, false, false, viewWeakReference); } public synchronized Spannable getSpanNote(Context context, WeakReference<View> viewWeakReference) { - return SpannableHelper.convert(context, note, null, this, null, true, viewWeakReference); + return SpannableHelper.convert(context, note, null, this, null, true, true, viewWeakReference); } public static class AccountParams implements Serializable { diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Announcement.java b/app/src/main/java/app/fedilab/android/client/entities/api/Announcement.java index b015313fd..808ac6e5d 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Announcement.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Announcement.java @@ -56,7 +56,7 @@ public class Announcement { public synchronized Spannable getSpanContent(Context context, WeakReference<View> viewWeakReference) { - return SpannableHelper.convert(context, content, null, null, this, true, viewWeakReference); + return SpannableHelper.convert(context, content, null, null, this, true, false, viewWeakReference); } } diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Attachment.java b/app/src/main/java/app/fedilab/android/client/entities/api/Attachment.java index c4a2b9aba..f569a2422 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Attachment.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Attachment.java @@ -51,6 +51,8 @@ public class Attachment implements Serializable { public String focus = null; public String translation = null; + public float measuredWidth = -1.f; + public static class Meta implements Serializable { @SerializedName("focus") public Focus focus; diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Field.java b/app/src/main/java/app/fedilab/android/client/entities/api/Field.java index 0fdbb3a66..af574ee32 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Field.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Field.java @@ -47,7 +47,7 @@ public class Field implements Serializable { if (verified_at != null && value != null) { value_span = new ForegroundColorSpan(ContextCompat.getColor(context, R.color.verified_text)); } - Spannable spannable = SpannableHelper.convert(context, value, null, account, null, true, viewWeakReference); + Spannable spannable = SpannableHelper.convert(context, value, null, account, null, true, true, viewWeakReference); if (value_span != null && spannable != null) { spannable.setSpan(value_span, 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } @@ -57,7 +57,7 @@ public class Field implements Serializable { public synchronized Spannable getLabelSpan(Context context, Account account, WeakReference<View> viewWeakReference) { - Spannable spannable = SpannableHelper.convert(context, name, null, account, null, true, viewWeakReference); + Spannable spannable = SpannableHelper.convert(context, name, null, account, null, true, true, viewWeakReference); if (name_span != null && spannable != null) { spannable.setSpan(name_span, 0, spannable.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); } diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Poll.java b/app/src/main/java/app/fedilab/android/client/entities/api/Poll.java index 3bf9c4791..cf0d1d8b9 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Poll.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Poll.java @@ -61,7 +61,7 @@ public class Poll implements Serializable { public transient Spannable span_title; public Spannable getSpanTitle(Context context, Status status, WeakReference<View> viewWeakReference) { - span_title = SpannableHelper.convert(context, title, status, null, null, false, viewWeakReference); + span_title = SpannableHelper.convert(context, title, status, null, null, false, false, viewWeakReference); return span_title; } } diff --git a/app/src/main/java/app/fedilab/android/client/entities/api/Status.java b/app/src/main/java/app/fedilab/android/client/entities/api/Status.java index e3c753055..7c39f4874 100644 --- a/app/src/main/java/app/fedilab/android/client/entities/api/Status.java +++ b/app/src/main/java/app/fedilab/android/client/entities/api/Status.java @@ -115,6 +115,10 @@ public class Status implements Serializable, Cloneable { public transient boolean submitted = false; public transient boolean spoilerChecked = false; public Filter filteredByApp; + public transient Spannable contentSpan; + public transient Spannable contentSpoilerSpan; + public transient Spannable contentTranslateSpan; + @Override public boolean equals(@Nullable Object obj) { boolean same = false; @@ -124,17 +128,29 @@ public class Status implements Serializable, Cloneable { return same; } - public synchronized Spannable getSpanContent(Context context, WeakReference<View> viewWeakReference) { - return SpannableHelper.convert(context, content, this, null, null, true, viewWeakReference); + public synchronized Spannable getSpanContent(Context context, WeakReference<View> viewWeakReference, Callback callback) { + if (contentSpan == null) { + contentSpan = SpannableHelper.convert(context, content, this, null, null, true, false, viewWeakReference, callback); + } + return contentSpan; } + public synchronized Spannable getSpanSpoiler(Context context, WeakReference<View> viewWeakReference, Callback callback) { + if (contentSpoilerSpan == null) { + contentSpoilerSpan = SpannableHelper.convert(context, spoiler_text, this, null, null, true, false, viewWeakReference, callback); + } + return contentSpoilerSpan; + } - public synchronized Spannable getSpanSpoiler(Context context, WeakReference<View> viewWeakReference) { - return SpannableHelper.convert(context, spoiler_text, this, null, null, true, viewWeakReference); + public synchronized Spannable getSpanTranslate(Context context, WeakReference<View> viewWeakReference, Callback callback) { + if (contentTranslateSpan == null) { + contentTranslateSpan = SpannableHelper.convert(context, translationContent, this, null, null, true, false, viewWeakReference, callback); + } + return contentTranslateSpan; } - public synchronized Spannable getSpanTranslate(Context context, WeakReference<View> viewWeakReference) { - return SpannableHelper.convert(context, translationContent, this, null, null, true, viewWeakReference); + public interface Callback { + void emojiFetched(); } @NonNull diff --git a/app/src/main/java/app/fedilab/android/helper/CustomEmoji.java b/app/src/main/java/app/fedilab/android/helper/CustomEmoji.java index 108351115..f121afc18 100644 --- a/app/src/main/java/app/fedilab/android/helper/CustomEmoji.java +++ b/app/src/main/java/app/fedilab/android/helper/CustomEmoji.java @@ -6,6 +6,7 @@ import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.drawable.Animatable; import android.graphics.drawable.Drawable; +import android.text.SpannableStringBuilder; import android.text.style.ReplacementSpan; import android.view.View; @@ -13,26 +14,53 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.preference.PreferenceManager; +import com.bumptech.glide.Glide; import com.bumptech.glide.request.target.CustomTarget; import com.bumptech.glide.request.target.Target; import com.bumptech.glide.request.transition.Transition; import java.lang.ref.WeakReference; +import java.util.List; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import app.fedilab.android.R; +import app.fedilab.android.client.entities.api.Emoji; +import app.fedilab.android.client.entities.api.Status; public class CustomEmoji extends ReplacementSpan { private final float scale; private final WeakReference<View> viewWeakReference; private Drawable imageDrawable; - + private boolean callbackCalled; CustomEmoji(WeakReference<View> viewWeakReference) { Context mContext = viewWeakReference.get().getContext(); this.viewWeakReference = viewWeakReference; SharedPreferences sharedpreferences = PreferenceManager.getDefaultSharedPreferences(mContext); scale = sharedpreferences.getFloat(mContext.getString(R.string.SET_FONT_SCALE), 1.1f); + callbackCalled = false; + } + + public SpannableStringBuilder makeEmoji(SpannableStringBuilder content, List<Emoji> emojiList, boolean animate, Status.Callback callback) { + if (emojiList != null && emojiList.size() > 0) { + int count = 1; + for (Emoji emoji : emojiList) { + Matcher matcher = Pattern.compile(":" + emoji.shortcode + ":", Pattern.LITERAL) + .matcher(content); + while (matcher.find()) { + CustomEmoji customEmoji = new CustomEmoji(new WeakReference<>(viewWeakReference.get())); + content.setSpan(customEmoji, matcher.start(), matcher.end(), 0); + Glide.with(viewWeakReference.get()) + .asDrawable() + .load(animate ? emoji.url : emoji.static_url) + .into(customEmoji.getTarget(animate, count == emojiList.size() && !callbackCalled ? callback : null)); + } + count++; + } + } + return content; } @Override @@ -61,7 +89,7 @@ public class CustomEmoji extends ReplacementSpan { } } - public Target<Drawable> getTarget(boolean animate) { + public Target<Drawable> getTarget(boolean animate, Status.Callback callback) { return new CustomTarget<Drawable>() { @Override public void onResourceReady(@NonNull Drawable resource, @Nullable Transition<? super Drawable> transition) { @@ -97,6 +125,10 @@ public class CustomEmoji extends ReplacementSpan { if (view != null) { view.invalidate(); } + if (callback != null && !callbackCalled) { + callbackCalled = true; + callback.emojiFetched(); + } } @Override diff --git a/app/src/main/java/app/fedilab/android/helper/Helper.java b/app/src/main/java/app/fedilab/android/helper/Helper.java index c8af7befc..8b10a8740 100644 --- a/app/src/main/java/app/fedilab/android/helper/Helper.java +++ b/app/src/main/java/app/fedilab/android/helper/Helper.java @@ -323,7 +323,7 @@ public class Helper { Pattern.CASE_INSENSITIVE | Pattern.MULTILINE | Pattern.DOTALL);*/ - public static final Pattern hashtagPattern = Pattern.compile("(#[\\w_A-zÀ-ÿ]+)"); + public static final Pattern hashtagPattern = Pattern.compile("(^|\\s+|[.,;?!-]+)(#[\\w_A-zÀ-ÿ]+)"); public static final Pattern groupPattern = Pattern.compile("(![\\w_]+)"); public static final Pattern mentionPattern = Pattern.compile("(@[\\w_.-]+[\\w])"); public static final Pattern mentionLongPattern = Pattern.c |