Skip to content
This repository was archived by the owner on May 30, 2025. It is now read-only.

Commit b0f9ce0

Browse files
committed
implement deleting notifications
1 parent e17b6e8 commit b0f9ce0

16 files changed

Lines changed: 124 additions & 23 deletions

‎mastodon/src/main/java/org/joinmastodon/android/GlobalUserPreferences.java‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public class GlobalUserPreferences{
2626
public static boolean disableMarquee;
2727
public static boolean disableSwipe;
2828
public static boolean voteButtonForSingleChoice;
29+
public static boolean enableDeleteNotifications;
2930
public static ThemePreference theme;
3031
public static ColorPreference color;
3132

@@ -55,6 +56,7 @@ public static void load(){
5556
disableMarquee=prefs.getBoolean("disableMarquee", false);
5657
disableSwipe=prefs.getBoolean("disableSwipe", false);
5758
voteButtonForSingleChoice=prefs.getBoolean("voteButtonForSingleChoice", true);
59+
enableDeleteNotifications=prefs.getBoolean("enableDeleteNotifications", false);
5860
theme=ThemePreference.values()[prefs.getInt("theme", 0)];
5961
recentLanguages=fromJson(prefs.getString("recentLanguages", "{}"), recentLanguagesType, new HashMap<>());
6062

@@ -79,6 +81,7 @@ public static void save(){
7981
.putBoolean("alwaysExpandContentWarnings", alwaysExpandContentWarnings)
8082
.putBoolean("disableMarquee", disableMarquee)
8183
.putBoolean("disableSwipe", disableSwipe)
84+
.putBoolean("enableDeleteNotifications", enableDeleteNotifications)
8285
.putInt("theme", theme.ordinal())
8386
.putString("color", color.name())
8487
.putString("recentLanguages", gson.toJson(recentLanguages))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package org.joinmastodon.android.api.requests.notifications;
2+
3+
import com.google.gson.reflect.TypeToken;
4+
5+
import org.joinmastodon.android.api.ApiUtils;
6+
import org.joinmastodon.android.api.MastodonAPIRequest;
7+
import org.joinmastodon.android.model.Notification;
8+
9+
import java.util.EnumSet;
10+
import java.util.List;
11+
12+
public class DismissNotification extends MastodonAPIRequest<Object>{
13+
public DismissNotification(String id){
14+
super(HttpMethod.POST, "/notifications/" + (id != null ? id + "/dismiss" : "clear"), Object.class);
15+
setRequestBody(new Object());
16+
}
17+
}

‎mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsFragment.java‎

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,15 +74,25 @@ public void onAttach(Activity activity){
7474
@Override
7575
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater){
7676
inflater.inflate(R.menu.notifications, menu);
77+
menu.findItem(R.id.clear_notifications).setVisible(GlobalUserPreferences.enableDeleteNotifications);
7778
}
7879

7980
@Override
8081
public boolean onOptionsItemSelected(MenuItem item) {
81-
if (item.getItemId() != R.id.follow_requests) return false;
82-
Bundle args=new Bundle();
83-
args.putString("account", accountID);
84-
Nav.go(getActivity(), FollowRequestsListFragment.class, args);
85-
return true;
82+
if (item.getItemId() == R.id.follow_requests) {
83+
Bundle args=new Bundle();
84+
args.putString("account", accountID);
85+
Nav.go(getActivity(), FollowRequestsListFragment.class, args);
86+
return true;
87+
} else if (item.getItemId() == R.id.clear_notifications) {
88+
UiUtils.confirmDeleteNotification(getActivity(), accountID, null, ()->{
89+
for (int i = 0; i < tabViews.length; i++) {
90+
getFragmentForPage(i).reload();
91+
}
92+
});
93+
return true;
94+
}
95+
return false;
8696
}
8797

8898
@Override

‎mastodon/src/main/java/org/joinmastodon/android/fragments/NotificationsListFragment.java‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import android.app.Activity;
44
import android.os.Bundle;
5+
import android.view.Menu;
6+
import android.view.MenuInflater;
57
import android.view.View;
68

79
import com.squareup.otto.Subscribe;
@@ -10,7 +12,6 @@
1012
import org.joinmastodon.android.R;
1113
import org.joinmastodon.android.api.requests.markers.SaveMarkers;
1214
import org.joinmastodon.android.api.session.AccountSessionManager;
13-
import org.joinmastodon.android.events.NotificationDeletedEvent;
1415
import org.joinmastodon.android.events.PollUpdatedEvent;
1516
import org.joinmastodon.android.events.RemoveAccountPostsEvent;
1617
import org.joinmastodon.android.model.Notification;
@@ -78,9 +79,9 @@ protected List<StatusDisplayItem> buildDisplayItems(Notification n){
7879
case FAVORITE -> getString(R.string.user_favorited);
7980
case POLL -> getString(R.string.poll_ended);
8081
};
81-
HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, null, extraText) : null;
82+
HeaderStatusDisplayItem titleItem=extraText!=null ? new HeaderStatusDisplayItem(n.id, n.account, n.createdAt, this, accountID, null, extraText, n) : null;
8283
if(n.status!=null){
83-
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, titleItem!=null, titleItem==null);
84+
ArrayList<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, n.status, accountID, n, knownAccounts, titleItem!=null, titleItem==null, n);
8485
if(titleItem!=null){
8586
for(StatusDisplayItem item:items){
8687
if(item instanceof ImageStatusDisplayItem imgItem){
@@ -210,7 +211,7 @@ public void onRemoveAccountPostsEvent(RemoveAccountPostsEvent ev){
210211
}
211212
}
212213

213-
private void removeNotification(Notification n){
214+
public void removeNotification(Notification n){
214215
data.remove(n);
215216
preloadedData.remove(n);
216217
int index=-1;

‎mastodon/src/main/java/org/joinmastodon/android/fragments/SettingsFragment.java‎

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,11 @@ public void onCreate(Bundle savedInstanceState){
105105
items.add(new ColorPalettePicker());
106106

107107
items.add(new HeaderItem(R.string.settings_behavior));
108+
items.add(new SwitchItem(R.string.sk_settings_show_federated_timeline, R.drawable.ic_fluent_earth_24_regular, GlobalUserPreferences.showFederatedTimeline, i->{
109+
GlobalUserPreferences.showFederatedTimeline=i.checked;
110+
GlobalUserPreferences.save();
111+
needAppRestart=true;
112+
}));
108113
items.add(new SwitchItem(R.string.settings_gif, R.drawable.ic_fluent_gif_24_regular, GlobalUserPreferences.playGifs, i->{
109114
GlobalUserPreferences.playGifs=i.checked;
110115
GlobalUserPreferences.save();
@@ -126,6 +131,11 @@ public void onCreate(Bundle savedInstanceState){
126131
GlobalUserPreferences.save();
127132
needAppRestart=true;
128133
}));
134+
items.add(new SwitchItem(R.string.sk_enable_delete_notifications, R.drawable.ic_fluent_delete_24_regular, GlobalUserPreferences.enableDeleteNotifications, i->{
135+
GlobalUserPreferences.enableDeleteNotifications=i.checked;
136+
GlobalUserPreferences.save();
137+
needAppRestart=true;
138+
}));
129139

130140
items.add(new HeaderItem(R.string.home_timeline));
131141
items.add(new SwitchItem(R.string.sk_settings_show_replies, R.drawable.ic_fluent_chat_multiple_24_regular, GlobalUserPreferences.showReplies, i->{
@@ -140,11 +150,6 @@ public void onCreate(Bundle savedInstanceState){
140150
GlobalUserPreferences.loadNewPosts=i.checked;
141151
GlobalUserPreferences.save();
142152
}));
143-
items.add(new SwitchItem(R.string.sk_settings_show_federated_timeline, R.drawable.ic_fluent_earth_24_regular, GlobalUserPreferences.showFederatedTimeline, i->{
144-
GlobalUserPreferences.showFederatedTimeline=i.checked;
145-
GlobalUserPreferences.save();
146-
needAppRestart=true;
147-
}));
148153

149154
items.add(new HeaderItem(R.string.settings_notifications));
150155
items.add(notificationPolicyItem=new NotificationPolicyItem());

‎mastodon/src/main/java/org/joinmastodon/android/fragments/StatusEditHistoryFragment.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ public void onSuccess(List<Status> result){
5454

5555
@Override
5656
protected List<StatusDisplayItem> buildDisplayItems(Status s){
57-
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false);
57+
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false, null);
5858
int idx=data.indexOf(s);
5959
if(idx>=0){
6060
String date=UiUtils.DATE_TIME_FORMATTER.format(s.createdAt.atZone(ZoneId.systemDefault()));

‎mastodon/src/main/java/org/joinmastodon/android/fragments/StatusListFragment.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ public abstract class StatusListFragment extends BaseStatusListFragment<Status>{
2929
protected EventListener eventListener=new EventListener();
3030

3131
protected List<StatusDisplayItem> buildDisplayItems(Status s){
32-
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false, true);
32+
return StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, false, true, null);
3333
}
3434

3535
@Override

‎mastodon/src/main/java/org/joinmastodon/android/fragments/discover/SearchFragment.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ protected List<StatusDisplayItem> buildDisplayItems(SearchResult s){
7575
return switch(s.type){
7676
case ACCOUNT -> Collections.singletonList(new AccountStatusDisplayItem(s.id, this, s.account));
7777
case HASHTAG -> Collections.singletonList(new HashtagStatusDisplayItem(s.id, this, s.hashtag));
78-
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, false, true);
78+
case STATUS -> StatusDisplayItem.buildItems(this, s.status, accountID, s, knownAccounts, false, true, null);
7979
};
8080
}
8181

‎mastodon/src/main/java/org/joinmastodon/android/fragments/report/ReportAddPostsChoiceFragment.java‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ protected RecyclerView.Adapter getAdapter(){
237237

238238
@Override
239239
protected List<StatusDisplayItem> buildDisplayItems(Status s){
240-
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false);
240+
List<StatusDisplayItem> items=StatusDisplayItem.buildItems(this, s, accountID, s, knownAccounts, true, false, null);
241241
for(StatusDisplayItem item:items){
242242
if(item instanceof ImageStatusDisplayItem isdi){
243243
isdi.horizontalInset=V.dp(40+32);

‎mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/HeaderStatusDisplayItem.java‎

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,22 @@
1919
import android.widget.TextView;
2020
import android.widget.Toast;
2121

22+
import androidx.recyclerview.widget.RecyclerView;
23+
2224
import org.joinmastodon.android.GlobalUserPreferences;
2325
import org.joinmastodon.android.R;
2426
import org.joinmastodon.android.api.requests.accounts.GetAccountRelationships;
2527
import org.joinmastodon.android.api.requests.statuses.GetStatusSourceText;
2628
import org.joinmastodon.android.api.session.AccountSessionManager;
2729
import org.joinmastodon.android.fragments.BaseStatusListFragment;
2830
import org.joinmastodon.android.fragments.ComposeFragment;
31+
import org.joinmastodon.android.fragments.NotificationsListFragment;
2932
import org.joinmastodon.android.fragments.ProfileFragment;
3033
import org.joinmastodon.android.fragments.ThreadFragment;
3134
import org.joinmastodon.android.fragments.report.ReportReasonChoiceFragment;
3235
import org.joinmastodon.android.model.Account;
3336
import org.joinmastodon.android.model.Attachment;
37+
import org.joinmastodon.android.model.Notification;
3438
import org.joinmastodon.android.model.Relationship;
3539
import org.joinmastodon.android.model.Status;
3640
import org.joinmastodon.android.ui.text.HtmlParser;
@@ -62,15 +66,17 @@ public class HeaderStatusDisplayItem extends StatusDisplayItem{
6266
private boolean hasVisibilityToggle;
6367
boolean needBottomPadding;
6468
private String extraText;
69+
private Notification notification;
6570

66-
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID, Status status, String extraText){
71+
public HeaderStatusDisplayItem(String parentID, Account user, Instant createdAt, BaseStatusListFragment parentFragment, String accountID, Status status, String extraText, Notification notification){
6772
super(parentID, parentFragment);
6873
this.user=user;
6974
this.createdAt=createdAt;
7075
avaRequest=new UrlImageLoaderRequest(GlobalUserPreferences.playGifs ? user.avatar : user.avatarStatic, V.dp(50), V.dp(50));
7176
this.accountID=accountID;
7277
parsedName=new SpannableStringBuilder(user.displayName);
7378
this.status=status;
79+
this.notification=notification;
7480
HtmlParser.parseCustomEmoji(parsedName, user.emojis);
7581
emojiHelper.setText(parsedName);
7682
if(status!=null){
@@ -107,7 +113,7 @@ public ImageLoaderRequest getImageRequest(int index){
107113

108114
public static class Holder extends StatusDisplayItem.Holder<HeaderStatusDisplayItem> implements ImageLoaderViewHolder{
109115
private final TextView name, username, timestamp, extraText;
110-
private final ImageView avatar, more, visibility;
116+
private final ImageView avatar, more, visibility, deleteNotification;
111117
private final PopupMenu optionsMenu;
112118
private Relationship relationship;
113119
private APIRequest<?> currentRelationshipRequest;
@@ -127,12 +133,18 @@ public Holder(Activity activity, ViewGroup parent){
127133
avatar=findViewById(R.id.avatar);
128134
more=findViewById(R.id.more);
129135
visibility=findViewById(R.id.visibility);
136+
deleteNotification=findViewById(R.id.delete_notification);
130137
extraText=findViewById(R.id.extra_text);
131138
avatar.setOnClickListener(this::onAvaClick);
132139
avatar.setOutlineProvider(roundCornersOutline);
133140
avatar.setClipToOutline(true);
134141
more.setOnClickListener(this::onMoreClick);
135142
visibility.setOnClickListener(v->item.parentFragment.onVisibilityIconClick(this));
143+
deleteNotification.setOnClickListener(v->UiUtils.confirmDeleteNotification(activity, item.parentFragment.getAccountID(), item.notification, ()->{
144+
if (item.parentFragment instanceof NotificationsListFragment fragment) {
145+
fragment.removeNotification(item.notification);
146+
}
147+
}));
136148

137149
optionsMenu=new PopupMenu(activity, more);
138150
optionsMenu.inflate(R.menu.post);
@@ -226,6 +238,7 @@ public void onBind(HeaderStatusDisplayItem item){
226238
else
227239
timestamp.setText(item.parentFragment.getString(R.string.edited_timestamp, UiUtils.formatRelativeTimestamp(itemView.getContext(), item.status.editedAt)));
228240
visibility.setVisibility(item.hasVisibilityToggle && !item.inset ? View.VISIBLE : View.GONE);
241+
deleteNotification.setVisibility(GlobalUserPreferences.enableDeleteNotifications && item.notification!=null ? View.VISIBLE : View.GONE);
229242
if(item.hasVisibilityToggle){
230243
visibility.setImageResource(item.status.spoilerRevealed ? R.drawable.ic_visibility_off : R.drawable.ic_visibility);
231244
visibility.setContentDescription(item.parentFragment.getString(item.status.spoilerRevealed ? R.string.hide_content : R.string.reveal_content));

0 commit comments

Comments
 (0)