Loading app/src/main/java/app/fedilab/android/activities/HashTagActivity.java +177 −87 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.view.MenuItem; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; import androidx.lifecycle.ViewModelProvider; import androidx.localbroadcastmanager.content.LocalBroadcastManager; Loading Loading @@ -56,11 +57,14 @@ public class HashTagActivity extends BaseActivity { public static int position; private String tag; private boolean pinnedTag; private boolean followedTag; private boolean mutedTag; private Boolean pinnedTag; private Boolean followedTag; private Boolean mutedTag; private TagVM tagVM; private Filter fedilabFilter; private Filter.KeywordsAttributes keyword; private PinnedTimeline pinnedTimeline; private Pinned pinned; @Override protected void onCreate(Bundle savedInstanceState) { Loading @@ -75,9 +79,9 @@ public class HashTagActivity extends BaseActivity { } if (tag == null) finish(); pinnedTag = false; followedTag = false; mutedTag = false; pinnedTag = null; followedTag = null; mutedTag = null; setSupportActionBar(binding.toolbar); ActionBar actionBar = getSupportActionBar(); //Remove title Loading @@ -100,19 +104,24 @@ public class HashTagActivity extends BaseActivity { ReorderVM reorderVM = new ViewModelProvider(HashTagActivity.this).get(ReorderVM.class); reorderVM.getAllPinned().observe(HashTagActivity.this, pinned -> { if (pinned != null) { this.pinned = pinned; pinnedTag = false; if (pinned.pinnedTimelines != null) { for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) { if (pinnedTimeline.tagTimeline != null) { if (pinnedTimeline.tagTimeline.name.equalsIgnoreCase(tag)) { this.pinnedTimeline = pinnedTimeline; pinnedTag = true; invalidateOptionsMenu(); break; } } } invalidateOptionsMenu(); } } }); if (MainActivity.filterFetched && MainActivity.mainFilters != null) { mutedTag = false; for (Filter filter : MainActivity.mainFilters) { if (filter.title.equalsIgnoreCase(Helper.FEDILAB_MUTED_HASHTAGS)) { fedilabFilter = filter; Loading @@ -120,17 +129,14 @@ public class HashTagActivity extends BaseActivity { for (Filter.KeywordsAttributes keywordsAttributes : filter.keywords) { if (fetch.equalsIgnoreCase(keywordsAttributes.keyword)) { mutedTag = true; keyword = keywordsAttributes; invalidateOptionsMenu(); break; } } mutedTag = false; invalidateOptionsMenu(); break; } } } else { mutedTag = true; invalidateOptionsMenu(); } Bundle bundle = new Bundle(); Loading Loading @@ -158,6 +164,29 @@ public class HashTagActivity extends BaseActivity { finish(); return true; } else if (item.getItemId() == R.id.action_add_timeline) { if (pinnedTag) { AlertDialog.Builder unpinConfirm = new AlertDialog.Builder(HashTagActivity.this, Helper.dialogStyle()); unpinConfirm.setMessage(getString(R.string.unpin_timeline_description)); unpinConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); unpinConfirm.setPositiveButton(R.string.yes, (dialog, which) -> { pinned.pinnedTimelines.remove(pinnedTimeline); try { new Pinned(HashTagActivity.this).updatePinned(pinned); } catch (DBException e) { e.printStackTrace(); } pinnedTag = false; invalidateOptionsMenu(); Bundle b = new Bundle(); b.putBoolean(Helper.RECEIVE_REDRAW_TOPBAR, true); Intent intentBD = new Intent(Helper.BROADCAST_DATA); intentBD.putExtras(b); LocalBroadcastManager.getInstance(HashTagActivity.this).sendBroadcast(intentBD); dialog.dismiss(); }); unpinConfirm.show(); } else { new Thread(() -> { try { Pinned pinned = new Pinned(HashTagActivity.this).getPinned(currentAccount); Loading @@ -182,7 +211,7 @@ public class HashTagActivity extends BaseActivity { mainHandler.post(myRunnable); return; } PinnedTimeline pinnedTimeline = new PinnedTimeline(); pinnedTimeline = new PinnedTimeline(); pinnedTimeline.type = Timeline.TimeLineEnum.TAG; pinnedTimeline.position = pinned.pinnedTimelines.size(); pinnedTimeline.displayed = true; Loading @@ -208,15 +237,26 @@ public class HashTagActivity extends BaseActivity { e.printStackTrace(); } }).start(); } } else if (item.getItemId() == R.id.action_follow_tag) { if (!followedTag) { tagVM.follow(MainActivity.currentInstance, MainActivity.currentToken, tag).observe(this, returnedTag -> { if (returnedTag != null) { followedTag = returnedTag.following; invalidateOptionsMenu(); } }); } else { tagVM.unfollow(MainActivity.currentInstance, MainActivity.currentToken, tag).observe(this, returnedTag -> { if (returnedTag != null) { followedTag = returnedTag.following; invalidateOptionsMenu(); } }); } } else if (item.getItemId() == R.id.action_mute) { if (!mutedTag) { if (MainActivity.mainFilters == null || fedilabFilter == null) { MainActivity.mainFilters = new ArrayList<>(); Filter.FilterParams filterParams = new Filter.FilterParams(); Loading @@ -227,7 +267,6 @@ public class HashTagActivity extends BaseActivity { filterParams.context.add("public"); filterParams.context.add("thread"); filterParams.context.add("account"); String finalTag = tag; FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class); filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams) .observe(HashTagActivity.this, filter -> { Loading @@ -242,6 +281,9 @@ public class HashTagActivity extends BaseActivity { } else { muteTags(); } } else { unmuteTags(); } } Loading @@ -249,6 +291,24 @@ public class HashTagActivity extends BaseActivity { } private void unmuteTags() { String search = tag.startsWith("#") ? tag : "#" + tag; for (Filter.KeywordsAttributes keywordsAttributes : fedilabFilter.keywords) { if (search.equalsIgnoreCase(keywordsAttributes.keyword)) { keyword = keywordsAttributes; break; } } if (keyword != null && keyword.id != null) { FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class); filtersVM.removeKeyword(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, keyword.id); fedilabFilter.keywords.remove(keyword); mutedTag = false; invalidateOptionsMenu(); } } private void muteTags() { Filter.FilterParams filterParams = new Filter.FilterParams(); filterParams.id = fedilabFilter.id; Loading @@ -261,6 +321,7 @@ public class HashTagActivity extends BaseActivity { FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class); filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams) .observe(HashTagActivity.this, filter -> { fedilabFilter = filter; mutedTag = true; invalidateOptionsMenu(); }); Loading @@ -272,13 +333,42 @@ public class HashTagActivity extends BaseActivity { 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) { if (pinnedTag != null) { pin.setVisible(true); if (pinnedTag) { pin.setIcon(R.drawable.tag_pin_off); pin.setTitle(getString(R.string.unpin_tag)); } else { pin.setTitle(getString(R.string.unpin_tag)); pin.setIcon(R.drawable.tag_pin); } } else { pin.setVisible(false); } if (followedTag && follow != null) { if (followedTag != null) { follow.setVisible(true); if (followedTag) { follow.setTitle(getString(R.string.unfollow_tag)); follow.setIcon(R.drawable.tag_unfollow); } else { follow.setTitle(getString(R.string.follow_tag)); follow.setIcon(R.drawable.tag_follow); } } else { follow.setVisible(false); } mute.setVisible(!mutedTag); if (mutedTag != null) { mute.setVisible(true); if (mutedTag) { mute.setTitle(getString(R.string.unmute_tag_action)); mute.setIcon(R.drawable.tag_unmuted); } else { mute.setTitle(getString(R.string.mute_tag_action)); mute.setIcon(R.drawable.tag_muted); } } else { mute.setVisible(false); } return super.onCreateOptionsMenu(menu); } Loading app/src/main/java/app/fedilab/android/client/endpoints/MastodonFiltersService.java +1 −1 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ public interface MastodonFiltersService { ); //Remove a keyword for a filter @DELETE("filter_keywords/{id}") @DELETE("filters/keywords/{id}") Call<Void> removeKeywordFilter( @Header("Authorization") String token, @Path("id") String id Loading app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +0 −1 Original line number Diff line number Diff line Loading @@ -361,7 +361,6 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. if (timelineType != null) { slug = timelineType != Timeline.TimeLineEnum.ART ? timelineType.getValue() + (ident != null ? "|" + ident : "") : Timeline.TimeLineEnum.TAG.getValue() + (ident != null ? "|" + ident : ""); } LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(receive_action, new IntentFilter(Helper.RECEIVE_STATUS_ACTION)); binding = FragmentPaginationBinding.inflate(inflater, container, false); return binding.getRoot(); Loading app/src/main/java/app/fedilab/android/viewmodel/mastodon/FiltersVM.java +20 −0 Original line number Diff line number Diff line Loading @@ -212,4 +212,24 @@ public class FiltersVM extends AndroidViewModel { }).start(); } /** * Remove a filter * * @param id ID of the filter */ public void removeKeyword(@NonNull String instance, String token, @NonNull String id) { MastodonFiltersService mastodonAccountsService = initV2(instance); new Thread(() -> { Call<Void> removeFilterCall = mastodonAccountsService.removeKeywordFilter(token, id); if (removeFilterCall != null) { try { removeFilterCall.execute(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } } app/src/main/res/drawable/tag_follow.xml 0 → 100644 +9 −0 Original line number Diff line number Diff line <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:fillColor="#FF000000" android:pathData="M21.41,11.58L12.41,2.58C12.04,2.21 11.53,2 11,2H4A2,2 0,0 0,2 4V11C2,11.53 2.21,12.04 2.59,12.41L3,12.81C3.9,12.27 4.94,12 6,12A6,6 0,0 1,12 18C12,19.06 11.72,20.09 11.18,21L11.58,21.4C11.95,21.78 12.47,22 13,22C13.53,22 14.04,21.79 14.41,21.41L21.41,14.41C21.79,14.04 22,13.53 22,13C22,12.47 21.79,11.96 21.41,11.58M5.5,7A1.5,1.5 0,0 1,4 5.5A1.5,1.5 0,0 1,5.5 4A1.5,1.5 0,0 1,7 5.5A1.5,1.5 0,0 1,5.5 7M10,19H7V22H5V19H2V17H5V14H7V17H10V19Z" /> </vector> Loading
app/src/main/java/app/fedilab/android/activities/HashTagActivity.java +177 −87 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.view.MenuItem; import androidx.annotation.NonNull; import androidx.appcompat.app.ActionBar; import androidx.appcompat.app.AlertDialog; import androidx.lifecycle.ViewModelProvider; import androidx.localbroadcastmanager.content.LocalBroadcastManager; Loading Loading @@ -56,11 +57,14 @@ public class HashTagActivity extends BaseActivity { public static int position; private String tag; private boolean pinnedTag; private boolean followedTag; private boolean mutedTag; private Boolean pinnedTag; private Boolean followedTag; private Boolean mutedTag; private TagVM tagVM; private Filter fedilabFilter; private Filter.KeywordsAttributes keyword; private PinnedTimeline pinnedTimeline; private Pinned pinned; @Override protected void onCreate(Bundle savedInstanceState) { Loading @@ -75,9 +79,9 @@ public class HashTagActivity extends BaseActivity { } if (tag == null) finish(); pinnedTag = false; followedTag = false; mutedTag = false; pinnedTag = null; followedTag = null; mutedTag = null; setSupportActionBar(binding.toolbar); ActionBar actionBar = getSupportActionBar(); //Remove title Loading @@ -100,19 +104,24 @@ public class HashTagActivity extends BaseActivity { ReorderVM reorderVM = new ViewModelProvider(HashTagActivity.this).get(ReorderVM.class); reorderVM.getAllPinned().observe(HashTagActivity.this, pinned -> { if (pinned != null) { this.pinned = pinned; pinnedTag = false; if (pinned.pinnedTimelines != null) { for (PinnedTimeline pinnedTimeline : pinned.pinnedTimelines) { if (pinnedTimeline.tagTimeline != null) { if (pinnedTimeline.tagTimeline.name.equalsIgnoreCase(tag)) { this.pinnedTimeline = pinnedTimeline; pinnedTag = true; invalidateOptionsMenu(); break; } } } invalidateOptionsMenu(); } } }); if (MainActivity.filterFetched && MainActivity.mainFilters != null) { mutedTag = false; for (Filter filter : MainActivity.mainFilters) { if (filter.title.equalsIgnoreCase(Helper.FEDILAB_MUTED_HASHTAGS)) { fedilabFilter = filter; Loading @@ -120,17 +129,14 @@ public class HashTagActivity extends BaseActivity { for (Filter.KeywordsAttributes keywordsAttributes : filter.keywords) { if (fetch.equalsIgnoreCase(keywordsAttributes.keyword)) { mutedTag = true; keyword = keywordsAttributes; invalidateOptionsMenu(); break; } } mutedTag = false; invalidateOptionsMenu(); break; } } } else { mutedTag = true; invalidateOptionsMenu(); } Bundle bundle = new Bundle(); Loading Loading @@ -158,6 +164,29 @@ public class HashTagActivity extends BaseActivity { finish(); return true; } else if (item.getItemId() == R.id.action_add_timeline) { if (pinnedTag) { AlertDialog.Builder unpinConfirm = new AlertDialog.Builder(HashTagActivity.this, Helper.dialogStyle()); unpinConfirm.setMessage(getString(R.string.unpin_timeline_description)); unpinConfirm.setNegativeButton(R.string.cancel, (dialog, which) -> dialog.dismiss()); unpinConfirm.setPositiveButton(R.string.yes, (dialog, which) -> { pinned.pinnedTimelines.remove(pinnedTimeline); try { new Pinned(HashTagActivity.this).updatePinned(pinned); } catch (DBException e) { e.printStackTrace(); } pinnedTag = false; invalidateOptionsMenu(); Bundle b = new Bundle(); b.putBoolean(Helper.RECEIVE_REDRAW_TOPBAR, true); Intent intentBD = new Intent(Helper.BROADCAST_DATA); intentBD.putExtras(b); LocalBroadcastManager.getInstance(HashTagActivity.this).sendBroadcast(intentBD); dialog.dismiss(); }); unpinConfirm.show(); } else { new Thread(() -> { try { Pinned pinned = new Pinned(HashTagActivity.this).getPinned(currentAccount); Loading @@ -182,7 +211,7 @@ public class HashTagActivity extends BaseActivity { mainHandler.post(myRunnable); return; } PinnedTimeline pinnedTimeline = new PinnedTimeline(); pinnedTimeline = new PinnedTimeline(); pinnedTimeline.type = Timeline.TimeLineEnum.TAG; pinnedTimeline.position = pinned.pinnedTimelines.size(); pinnedTimeline.displayed = true; Loading @@ -208,15 +237,26 @@ public class HashTagActivity extends BaseActivity { e.printStackTrace(); } }).start(); } } else if (item.getItemId() == R.id.action_follow_tag) { if (!followedTag) { tagVM.follow(MainActivity.currentInstance, MainActivity.currentToken, tag).observe(this, returnedTag -> { if (returnedTag != null) { followedTag = returnedTag.following; invalidateOptionsMenu(); } }); } else { tagVM.unfollow(MainActivity.currentInstance, MainActivity.currentToken, tag).observe(this, returnedTag -> { if (returnedTag != null) { followedTag = returnedTag.following; invalidateOptionsMenu(); } }); } } else if (item.getItemId() == R.id.action_mute) { if (!mutedTag) { if (MainActivity.mainFilters == null || fedilabFilter == null) { MainActivity.mainFilters = new ArrayList<>(); Filter.FilterParams filterParams = new Filter.FilterParams(); Loading @@ -227,7 +267,6 @@ public class HashTagActivity extends BaseActivity { filterParams.context.add("public"); filterParams.context.add("thread"); filterParams.context.add("account"); String finalTag = tag; FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class); filtersVM.addFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams) .observe(HashTagActivity.this, filter -> { Loading @@ -242,6 +281,9 @@ public class HashTagActivity extends BaseActivity { } else { muteTags(); } } else { unmuteTags(); } } Loading @@ -249,6 +291,24 @@ public class HashTagActivity extends BaseActivity { } private void unmuteTags() { String search = tag.startsWith("#") ? tag : "#" + tag; for (Filter.KeywordsAttributes keywordsAttributes : fedilabFilter.keywords) { if (search.equalsIgnoreCase(keywordsAttributes.keyword)) { keyword = keywordsAttributes; break; } } if (keyword != null && keyword.id != null) { FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class); filtersVM.removeKeyword(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, keyword.id); fedilabFilter.keywords.remove(keyword); mutedTag = false; invalidateOptionsMenu(); } } private void muteTags() { Filter.FilterParams filterParams = new Filter.FilterParams(); filterParams.id = fedilabFilter.id; Loading @@ -261,6 +321,7 @@ public class HashTagActivity extends BaseActivity { FiltersVM filtersVM = new ViewModelProvider(HashTagActivity.this).get(FiltersVM.class); filtersVM.editFilter(BaseMainActivity.currentInstance, BaseMainActivity.currentToken, filterParams) .observe(HashTagActivity.this, filter -> { fedilabFilter = filter; mutedTag = true; invalidateOptionsMenu(); }); Loading @@ -272,13 +333,42 @@ public class HashTagActivity extends BaseActivity { 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) { if (pinnedTag != null) { pin.setVisible(true); if (pinnedTag) { pin.setIcon(R.drawable.tag_pin_off); pin.setTitle(getString(R.string.unpin_tag)); } else { pin.setTitle(getString(R.string.unpin_tag)); pin.setIcon(R.drawable.tag_pin); } } else { pin.setVisible(false); } if (followedTag && follow != null) { if (followedTag != null) { follow.setVisible(true); if (followedTag) { follow.setTitle(getString(R.string.unfollow_tag)); follow.setIcon(R.drawable.tag_unfollow); } else { follow.setTitle(getString(R.string.follow_tag)); follow.setIcon(R.drawable.tag_follow); } } else { follow.setVisible(false); } mute.setVisible(!mutedTag); if (mutedTag != null) { mute.setVisible(true); if (mutedTag) { mute.setTitle(getString(R.string.unmute_tag_action)); mute.setIcon(R.drawable.tag_unmuted); } else { mute.setTitle(getString(R.string.mute_tag_action)); mute.setIcon(R.drawable.tag_muted); } } else { mute.setVisible(false); } return super.onCreateOptionsMenu(menu); } Loading
app/src/main/java/app/fedilab/android/client/endpoints/MastodonFiltersService.java +1 −1 Original line number Diff line number Diff line Loading @@ -96,7 +96,7 @@ public interface MastodonFiltersService { ); //Remove a keyword for a filter @DELETE("filter_keywords/{id}") @DELETE("filters/keywords/{id}") Call<Void> removeKeywordFilter( @Header("Authorization") String token, @Path("id") String id Loading
app/src/main/java/app/fedilab/android/ui/fragment/timeline/FragmentMastodonTimeline.java +0 −1 Original line number Diff line number Diff line Loading @@ -361,7 +361,6 @@ public class FragmentMastodonTimeline extends Fragment implements StatusAdapter. if (timelineType != null) { slug = timelineType != Timeline.TimeLineEnum.ART ? timelineType.getValue() + (ident != null ? "|" + ident : "") : Timeline.TimeLineEnum.TAG.getValue() + (ident != null ? "|" + ident : ""); } LocalBroadcastManager.getInstance(requireActivity()).registerReceiver(receive_action, new IntentFilter(Helper.RECEIVE_STATUS_ACTION)); binding = FragmentPaginationBinding.inflate(inflater, container, false); return binding.getRoot(); Loading
app/src/main/java/app/fedilab/android/viewmodel/mastodon/FiltersVM.java +20 −0 Original line number Diff line number Diff line Loading @@ -212,4 +212,24 @@ public class FiltersVM extends AndroidViewModel { }).start(); } /** * Remove a filter * * @param id ID of the filter */ public void removeKeyword(@NonNull String instance, String token, @NonNull String id) { MastodonFiltersService mastodonAccountsService = initV2(instance); new Thread(() -> { Call<Void> removeFilterCall = mastodonAccountsService.removeKeywordFilter(token, id); if (removeFilterCall != null) { try { removeFilterCall.execute(); } catch (Exception e) { e.printStackTrace(); } } }).start(); } }
app/src/main/res/drawable/tag_follow.xml 0 → 100644 +9 −0 Original line number Diff line number Diff line <vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="24dp" android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> <path android:fillColor="#FF000000" android:pathData="M21.41,11.58L12.41,2.58C12.04,2.21 11.53,2 11,2H4A2,2 0,0 0,2 4V11C2,11.53 2.21,12.04 2.59,12.41L3,12.81C3.9,12.27 4.94,12 6,12A6,6 0,0 1,12 18C12,19.06 11.72,20.09 11.18,21L11.58,21.4C11.95,21.78 12.47,22 13,22C13.53,22 14.04,21.79 14.41,21.41L21.41,14.41C21.79,14.04 22,13.53 22,13C22,12.47 21.79,11.96 21.41,11.58M5.5,7A1.5,1.5 0,0 1,4 5.5A1.5,1.5 0,0 1,5.5 4A1.5,1.5 0,0 1,7 5.5A1.5,1.5 0,0 1,5.5 7M10,19H7V22H5V19H2V17H5V14H7V17H10V19Z" /> </vector>