Loading app/src/main/java/app/fedilab/android/activities/HashTagActivity.java +43 −0 Original line number Diff line number Diff line Loading @@ -34,7 +34,9 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import java.util.ArrayList; import java.util.List; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; import app.fedilab.android.client.entities.api.Filter; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Pinned; import app.fedilab.android.client.entities.app.PinnedTimeline; Loading @@ -46,6 +48,7 @@ import app.fedilab.android.exception.DBException; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.ui.fragment.timeline.FragmentMastodonTimeline; import app.fedilab.android.viewmodel.mastodon.FiltersVM; import app.fedilab.android.viewmodel.mastodon.ReorderVM; import app.fedilab.android.viewmodel.mastodon.TagVM; import es.dmoral.toasty.Toasty; Loading @@ -58,7 +61,9 @@ public class HashTagActivity extends BaseActivity { private String tag; private boolean pinnedTag; private boolean followedTag; private boolean mutedTag; private TagVM tagVM; private Filter fedilabFilter; @Override protected void onCreate(Bundle savedInstanceState) { Loading @@ -75,6 +80,7 @@ public class HashTagActivity extends BaseActivity { finish(); pinnedTag = false; followedTag = false; mutedTag = true; setSupportActionBar(binding.toolbar); ActionBar actionBar = getSupportActionBar(); //Remove title Loading Loading @@ -110,6 +116,26 @@ public class HashTagActivity extends BaseActivity { } } }); if (MainActivity.filterFetched && MainActivity.mainFilters != null) { for (Filter filter : MainActivity.mainFilters) { if (filter.title.equalsIgnoreCase(Helper.FEDILAB_MUTED_HASHTAGS)) { fedilabFilter = filter; String fetch = tag.startsWith("#") ? tag : "#" + tag; for (Filter.KeywordsAttributes keywordsAttributes : filter.keywords) { if (fetch.equalsIgnoreCase(keywordsAttributes.keyword)) { mutedTag = true; invalidateOptionsMenu(); break; } } mutedTag = false; invalidateOptionsMenu(); break; } } } else { mutedTag = true; } Bundle bundle = new Bundle(); bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TAG); Loading Loading @@ -194,6 +220,21 @@ public class HashTagActivity extends BaseActivity { invalidateOptionsMenu(); } }); } else if (item.getItemId() == R.id.action_mute) { Filter.FilterParams filterParams = new Filter.FilterParams(); filterParams.id = fedilabFilter.id; filterParams.keywords = new ArrayList<>(); Filter.KeywordsParams keywordsParams = new Filter.KeywordsParams(); keywordsParams.whole_word = true; keywordsParams.keyword = tag.startsWith("#") ? tag : "#" + tag; filterParams.keywords.add(keywordsParams); filterParams.context = fedilabFilter.context; FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class); filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams) .observe(HashTagActivity.this, filter -> { mutedTag = true; invalidateOptionsMenu(); }); } return super.onOptionsItemSelected(item); Loading @@ -205,12 +246,14 @@ public class HashTagActivity extends BaseActivity { getMenuInflater().inflate(R.menu.menu_hashtag, menu); MenuItem pin = menu.findItem(R.id.action_add_timeline); MenuItem follow = menu.findItem(R.id.action_follow_tag); MenuItem mute = menu.findItem(R.id.action_mute); if (pinnedTag && pin != null) { pin.setVisible(false); } if (followedTag && follow != null) { follow.setVisible(false); } mute.setVisible(!mutedTag); return super.onCreateOptionsMenu(menu); } Loading app/src/main/java/app/fedilab/android/helper/Helper.java +1 −1 Original line number Diff line number Diff line Loading @@ -240,7 +240,7 @@ public class Helper { public static final String ARG_ACCOUNT_ID = "ARG_ACCOUNT_ID"; public static final String ARG_ADMIN_DOMAINBLOCK = "ARG_ADMIN_DOMAINBLOCK"; public static final String ARG_ADMIN_DOMAINBLOCK_DELETE = "ARG_ADMIN_DOMAINBLOCK_DELETE"; public static final String FEDILAB_MUTED_HASHTAGS = "Fedilab muted hashtags"; public static final String ARG_REPORT = "ARG_REPORT"; public static final String ARG_ACCOUNT_MENTION = "ARG_ACCOUNT_MENTION"; public static final String ARG_MINIFIED = "ARG_MINIFIED"; Loading app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +75 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelStoreOwner; import androidx.preference.PreferenceManager; import com.bumptech.glide.Glide; Loading @@ -65,17 +68,21 @@ import java.util.regex.Pattern; import javax.net.ssl.HttpsURLConnection; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; import app.fedilab.android.activities.ContextActivity; import app.fedilab.android.activities.HashTagActivity; import app.fedilab.android.activities.MainActivity; import app.fedilab.android.activities.ProfileActivity; import app.fedilab.android.client.entities.api.Account; import app.fedilab.android.client.entities.api.Announcement; import app.fedilab.android.client.entities.api.Attachment; import app.fedilab.android.client.entities.api.Emoji; import app.fedilab.android.client.entities.api.Filter; import app.fedilab.android.client.entities.api.Mention; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.databinding.PopupLinksBinding; import app.fedilab.android.viewmodel.mastodon.FiltersVM; import es.dmoral.toasty.Toasty; public class SpannableHelper { Loading Loading @@ -764,7 +771,47 @@ public class SpannableHelper { if (matchStart >= 0 && matchEnd <= content.toString().length() && matchEnd >= matchStart) { URLSpan[] span = content.getSpans(matchStart, matchEnd, URLSpan.class); content.removeSpan(span); content.setSpan(new ClickableSpan() { content.setSpan(new LongClickableSpan() { @Override public void onLongClick(View textView) { textView.setTag(CLICKABLE_SPAN); if (patternType == Helper.PatternType.TAG && BaseMainActivity.filterFetched && MainActivity.mainFilters != null) { String tag = word.trim(); if (!tag.startsWith("#")) { tag = "#" + tag; } Filter fedilabFilter = null; for (Filter filter : MainActivity.mainFilters) { if (filter.title.equals(Helper.FEDILAB_MUTED_HASHTAGS)) { fedilabFilter = filter; break; } } //Filter for Fedilab doesn't exist we have to create it if (fedilabFilter == null) { Filter.FilterParams filterParams = new Filter.FilterParams(); filterParams.title = Helper.FEDILAB_MUTED_HASHTAGS; filterParams.filter_action = "hide"; filterParams.context = new ArrayList<>(); filterParams.context.add("home"); filterParams.context.add("public"); filterParams.context.add("thread"); filterParams.context.add("account"); String finalTag = tag; FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class); filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams) .observe((LifecycleOwner) context, filter -> { if (filter != null) { MainActivity.mainFilters.add(filter); addTagToFilter(context, finalTag, filter); } }); } else { addTagToFilter(context, tag, fedilabFilter); } } } @Override public void onClick(@NonNull View textView) { textView.setTag(CLICKABLE_SPAN); Loading Loading @@ -848,12 +895,39 @@ public class SpannableHelper { ds.setUnderlineText(false); ds.setColor(linkColor); } }, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } } } } public static void addTagToFilter(Context context, String tag, Filter filter) { for (Filter.KeywordsAttributes keywords : filter.keywords) { if (keywords.keyword.equalsIgnoreCase(tag)) { return; } } AlertDialog.Builder builder = new AlertDialog.Builder(context, Helper.dialogStyle()); builder.setMessage(context.getString(R.string.mute_tag, tag)); builder .setPositiveButton(R.string.yes, (dialog, which) -> { Filter.FilterParams filterParams = new Filter.FilterParams(); filterParams.id = filter.id; filterParams.keywords = new ArrayList<>(); Filter.KeywordsParams keywordsParams = new Filter.KeywordsParams(); keywordsParams.whole_word = true; keywordsParams.keyword = tag; filterParams.keywords.add(keywordsParams); filterParams.context = filter.context; FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class); filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams); dialog.dismiss(); }) .setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss()) .show(); } /** * Convert HTML content to text. Also, it handles click on link * This needs to be run asynchronously Loading app/src/main/res/drawable/ic_baseline_volume_mute_24.xml +1 −1 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ android:width="24dp" android:height="24dp" android:autoMirrored="true" android:tint="?attr/colorControlNormal" android:tint="#FFFFFF" android:viewportWidth="24" android:viewportHeight="24"> <path Loading app/src/main/res/menu/menu_hashtag.xml +5 −0 Original line number Diff line number Diff line Loading @@ -11,4 +11,9 @@ android:icon="@drawable/ic_baseline_add_24" android:title="@string/add_instances" app:showAsAction="ifRoom" /> <item android:id="@+id/action_mute" android:icon="@drawable/ic_baseline_volume_mute_24" android:title="@string/mute_tag" app:showAsAction="ifRoom" /> </menu> No newline at end of file Loading
app/src/main/java/app/fedilab/android/activities/HashTagActivity.java +43 −0 Original line number Diff line number Diff line Loading @@ -34,7 +34,9 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import java.util.ArrayList; import java.util.List; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; import app.fedilab.android.client.entities.api.Filter; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.client.entities.app.Pinned; import app.fedilab.android.client.entities.app.PinnedTimeline; Loading @@ -46,6 +48,7 @@ import app.fedilab.android.exception.DBException; import app.fedilab.android.helper.Helper; import app.fedilab.android.helper.ThemeHelper; import app.fedilab.android.ui.fragment.timeline.FragmentMastodonTimeline; import app.fedilab.android.viewmodel.mastodon.FiltersVM; import app.fedilab.android.viewmodel.mastodon.ReorderVM; import app.fedilab.android.viewmodel.mastodon.TagVM; import es.dmoral.toasty.Toasty; Loading @@ -58,7 +61,9 @@ public class HashTagActivity extends BaseActivity { private String tag; private boolean pinnedTag; private boolean followedTag; private boolean mutedTag; private TagVM tagVM; private Filter fedilabFilter; @Override protected void onCreate(Bundle savedInstanceState) { Loading @@ -75,6 +80,7 @@ public class HashTagActivity extends BaseActivity { finish(); pinnedTag = false; followedTag = false; mutedTag = true; setSupportActionBar(binding.toolbar); ActionBar actionBar = getSupportActionBar(); //Remove title Loading Loading @@ -110,6 +116,26 @@ public class HashTagActivity extends BaseActivity { } } }); if (MainActivity.filterFetched && MainActivity.mainFilters != null) { for (Filter filter : MainActivity.mainFilters) { if (filter.title.equalsIgnoreCase(Helper.FEDILAB_MUTED_HASHTAGS)) { fedilabFilter = filter; String fetch = tag.startsWith("#") ? tag : "#" + tag; for (Filter.KeywordsAttributes keywordsAttributes : filter.keywords) { if (fetch.equalsIgnoreCase(keywordsAttributes.keyword)) { mutedTag = true; invalidateOptionsMenu(); break; } } mutedTag = false; invalidateOptionsMenu(); break; } } } else { mutedTag = true; } Bundle bundle = new Bundle(); bundle.putSerializable(Helper.ARG_TIMELINE_TYPE, Timeline.TimeLineEnum.TAG); Loading Loading @@ -194,6 +220,21 @@ public class HashTagActivity extends BaseActivity { invalidateOptionsMenu(); } }); } else if (item.getItemId() == R.id.action_mute) { Filter.FilterParams filterParams = new Filter.FilterParams(); filterParams.id = fedilabFilter.id; filterParams.keywords = new ArrayList<>(); Filter.KeywordsParams keywordsParams = new Filter.KeywordsParams(); keywordsParams.whole_word = true; keywordsParams.keyword = tag.startsWith("#") ? tag : "#" + tag; filterParams.keywords.add(keywordsParams); filterParams.context = fedilabFilter.context; FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class); filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams) .observe(HashTagActivity.this, filter -> { mutedTag = true; invalidateOptionsMenu(); }); } return super.onOptionsItemSelected(item); Loading @@ -205,12 +246,14 @@ public class HashTagActivity extends BaseActivity { getMenuInflater().inflate(R.menu.menu_hashtag, menu); MenuItem pin = menu.findItem(R.id.action_add_timeline); MenuItem follow = menu.findItem(R.id.action_follow_tag); MenuItem mute = menu.findItem(R.id.action_mute); if (pinnedTag && pin != null) { pin.setVisible(false); } if (followedTag && follow != null) { follow.setVisible(false); } mute.setVisible(!mutedTag); return super.onCreateOptionsMenu(menu); } Loading
app/src/main/java/app/fedilab/android/helper/Helper.java +1 −1 Original line number Diff line number Diff line Loading @@ -240,7 +240,7 @@ public class Helper { public static final String ARG_ACCOUNT_ID = "ARG_ACCOUNT_ID"; public static final String ARG_ADMIN_DOMAINBLOCK = "ARG_ADMIN_DOMAINBLOCK"; public static final String ARG_ADMIN_DOMAINBLOCK_DELETE = "ARG_ADMIN_DOMAINBLOCK_DELETE"; public static final String FEDILAB_MUTED_HASHTAGS = "Fedilab muted hashtags"; public static final String ARG_REPORT = "ARG_REPORT"; public static final String ARG_ACCOUNT_MENTION = "ARG_ACCOUNT_MENTION"; public static final String ARG_MINIFIED = "ARG_MINIFIED"; Loading
app/src/main/java/app/fedilab/android/helper/SpannableHelper.java +75 −1 Original line number Diff line number Diff line Loading @@ -46,6 +46,9 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.appcompat.app.AlertDialog; import androidx.core.content.ContextCompat; import androidx.lifecycle.LifecycleOwner; import androidx.lifecycle.ViewModelProvider; import androidx.lifecycle.ViewModelStoreOwner; import androidx.preference.PreferenceManager; import com.bumptech.glide.Glide; Loading @@ -65,17 +68,21 @@ import java.util.regex.Pattern; import javax.net.ssl.HttpsURLConnection; import app.fedilab.android.BaseMainActivity; import app.fedilab.android.R; import app.fedilab.android.activities.ContextActivity; import app.fedilab.android.activities.HashTagActivity; import app.fedilab.android.activities.MainActivity; import app.fedilab.android.activities.ProfileActivity; import app.fedilab.android.client.entities.api.Account; import app.fedilab.android.client.entities.api.Announcement; import app.fedilab.android.client.entities.api.Attachment; import app.fedilab.android.client.entities.api.Emoji; import app.fedilab.android.client.entities.api.Filter; import app.fedilab.android.client.entities.api.Mention; import app.fedilab.android.client.entities.api.Status; import app.fedilab.android.databinding.PopupLinksBinding; import app.fedilab.android.viewmodel.mastodon.FiltersVM; import es.dmoral.toasty.Toasty; public class SpannableHelper { Loading Loading @@ -764,7 +771,47 @@ public class SpannableHelper { if (matchStart >= 0 && matchEnd <= content.toString().length() && matchEnd >= matchStart) { URLSpan[] span = content.getSpans(matchStart, matchEnd, URLSpan.class); content.removeSpan(span); content.setSpan(new ClickableSpan() { content.setSpan(new LongClickableSpan() { @Override public void onLongClick(View textView) { textView.setTag(CLICKABLE_SPAN); if (patternType == Helper.PatternType.TAG && BaseMainActivity.filterFetched && MainActivity.mainFilters != null) { String tag = word.trim(); if (!tag.startsWith("#")) { tag = "#" + tag; } Filter fedilabFilter = null; for (Filter filter : MainActivity.mainFilters) { if (filter.title.equals(Helper.FEDILAB_MUTED_HASHTAGS)) { fedilabFilter = filter; break; } } //Filter for Fedilab doesn't exist we have to create it if (fedilabFilter == null) { Filter.FilterParams filterParams = new Filter.FilterParams(); filterParams.title = Helper.FEDILAB_MUTED_HASHTAGS; filterParams.filter_action = "hide"; filterParams.context = new ArrayList<>(); filterParams.context.add("home"); filterParams.context.add("public"); filterParams.context.add("thread"); filterParams.context.add("account"); String finalTag = tag; FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class); filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams) .observe((LifecycleOwner) context, filter -> { if (filter != null) { MainActivity.mainFilters.add(filter); addTagToFilter(context, finalTag, filter); } }); } else { addTagToFilter(context, tag, fedilabFilter); } } } @Override public void onClick(@NonNull View textView) { textView.setTag(CLICKABLE_SPAN); Loading Loading @@ -848,12 +895,39 @@ public class SpannableHelper { ds.setUnderlineText(false); ds.setColor(linkColor); } }, matchStart, matchEnd, Spanned.SPAN_INCLUSIVE_EXCLUSIVE); } } } } public static void addTagToFilter(Context context, String tag, Filter filter) { for (Filter.KeywordsAttributes keywords : filter.keywords) { if (keywords.keyword.equalsIgnoreCase(tag)) { return; } } AlertDialog.Builder builder = new AlertDialog.Builder(context, Helper.dialogStyle()); builder.setMessage(context.getString(R.string.mute_tag, tag)); builder .setPositiveButton(R.string.yes, (dialog, which) -> { Filter.FilterParams filterParams = new Filter.FilterParams(); filterParams.id = filter.id; filterParams.keywords = new ArrayList<>(); Filter.KeywordsParams keywordsParams = new Filter.KeywordsParams(); keywordsParams.whole_word = true; keywordsParams.keyword = tag; filterParams.keywords.add(keywordsParams); filterParams.context = filter.context; FiltersVM filtersVM = new ViewModelProvider((ViewModelStoreOwner) context).get(FiltersVM.class); filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams); dialog.dismiss(); }) .setNegativeButton(R.string.no, (dialog, which) -> dialog.dismiss()) .show(); } /** * Convert HTML content to text. Also, it handles click on link * This needs to be run asynchronously Loading
app/src/main/res/drawable/ic_baseline_volume_mute_24.xml +1 −1 Original line number Diff line number Diff line Loading @@ -2,7 +2,7 @@ android:width="24dp" android:height="24dp" android:autoMirrored="true" android:tint="?attr/colorControlNormal" android:tint="#FFFFFF" android:viewportWidth="24" android:viewportHeight="24"> <path Loading
app/src/main/res/menu/menu_hashtag.xml +5 −0 Original line number Diff line number Diff line Loading @@ -11,4 +11,9 @@ android:icon="@drawable/ic_baseline_add_24" android:title="@string/add_instances" app:showAsAction="ifRoom" /> <item android:id="@+id/action_mute" android:icon="@drawable/ic_baseline_volume_mute_24" android:title="@string/mute_tag" app:showAsAction="ifRoom" /> </menu> No newline at end of file