Skip to content
This repository was archived by the owner on Oct 28, 2024. It is now read-only.

Commit b0f9ce0

Browse files
committed
implement deleting notifications
1 parent e17b6e8 commit b0f9ce0

16 files changed

+124
-23
lines changed

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

+3
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))
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

+15-5
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

+5-4
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

+10-5
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

+1-1
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

+1-1
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

+1-1
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

+1-1
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

+15-2
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));

mastodon/src/main/java/org/joinmastodon/android/ui/displayitems/StatusDisplayItem.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
import org.joinmastodon.android.model.Account;
1515
import org.joinmastodon.android.model.Attachment;
1616
import org.joinmastodon.android.model.DisplayItemsParent;
17+
import org.joinmastodon.android.model.Notification;
1718
import org.joinmastodon.android.model.Poll;
1819
import org.joinmastodon.android.model.Status;
1920
import org.joinmastodon.android.ui.PhotoLayoutHelper;
@@ -73,7 +74,7 @@ public static BindableViewHolder<? extends StatusDisplayItem> createViewHolder(T
7374
};
7475
}
7576

76-
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter){
77+
public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment fragment, Status status, String accountID, DisplayItemsParent parentObject, Map<String, Account> knownAccounts, boolean inset, boolean addFooter, Notification notification){
7778
String parentID=parentObject.getID();
7879
ArrayList<StatusDisplayItem> items=new ArrayList<>();
7980
Status statusForContent=status.getContentStatus();
@@ -92,7 +93,7 @@ public static ArrayList<StatusDisplayItem> buildItems(BaseStatusListFragment fra
9293
}));
9394
}
9495
HeaderStatusDisplayItem header;
95-
items.add(header=new HeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null));
96+
items.add(header=new HeaderStatusDisplayItem(parentID, statusForContent.account, statusForContent.createdAt, fragment, accountID, statusForContent, null, notification));
9697
if(!TextUtils.isEmpty(statusForContent.content))
9798
items.add(new TextStatusDisplayItem(parentID, HtmlParser.parse(statusForContent.content, statusForContent.emojis, statusForContent.mentions, statusForContent.tags, accountID), fragment, statusForContent));
9899
else

mastodon/src/main/java/org/joinmastodon/android/ui/utils/UiUtils.java

+21
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
import org.joinmastodon.android.api.requests.accounts.SetDomainBlocked;
5050
import org.joinmastodon.android.api.requests.accounts.AuthorizeFollowRequest;
5151
import org.joinmastodon.android.api.requests.accounts.RejectFollowRequest;
52+
import org.joinmastodon.android.api.requests.notifications.DismissNotification;
5253
import org.joinmastodon.android.api.requests.statuses.DeleteStatus;
5354
import org.joinmastodon.android.api.requests.statuses.GetStatusByID;
5455
import org.joinmastodon.android.api.requests.statuses.SetStatusPinned;
@@ -66,6 +67,7 @@
6667
import org.joinmastodon.android.model.Account;
6768
import org.joinmastodon.android.model.Emoji;
6869
import org.joinmastodon.android.model.ListTimeline;
70+
import org.joinmastodon.android.model.Notification;
6971
import org.joinmastodon.android.model.Relationship;
7072
import org.joinmastodon.android.model.Status;
7173
import org.joinmastodon.android.ui.M3AlertDialogBuilder;
@@ -463,6 +465,25 @@ public void onError(ErrorResponse error) {
463465
);
464466
}
465467

468+
public static void confirmDeleteNotification(Activity activity, String accountID, Notification notification, Runnable callback) {
469+
showConfirmationAlert(activity,
470+
notification == null ? R.string.sk_delete_all_notifications : R.string.sk_delete_notification,
471+
notification == null ? R.string.sk_delete_all_notifications_confirm : R.string.sk_delete_notification_confirm,
472+
notification == null ? R.string.sk_delete_all_notifications_confirm_action : R.string.sk_delete_notification_confirm_action,
473+
()-> new DismissNotification(notification != null ? notification.id : null).setCallback(new Callback<>() {
474+
@Override
475+
public void onSuccess(Object o) {
476+
callback.run();
477+
}
478+
479+
@Override
480+
public void onError(ErrorResponse error) {
481+
error.showToast(activity);
482+
}
483+
}).exec(accountID)
484+
);
485+
}
486+
466487
public static void setRelationshipToActionButton(Relationship relationship, Button button){
467488
setRelationshipToActionButton(relationship, button, false);
468489
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<vector xmlns:android="http://schemas.android.com/apk/res/android" android:width="20dp" android:height="20dp" android:viewportWidth="20" android:viewportHeight="20">
2+
<path android:pathData="M8.5 4h3c0-0.828-0.672-1.5-1.5-1.5S8.5 3.172 8.5 4zm-1 0c0-1.38 1.12-2.5 2.5-2.5s2.5 1.12 2.5 2.5h5C17.776 4 18 4.224 18 4.5S17.776 5 17.5 5h-1.054l-1.194 10.344C15.077 16.858 13.796 18 12.272 18H7.728c-1.524 0-2.805-1.142-2.98-2.656L3.554 5H2.5C2.224 5 2 4.776 2 4.5S2.224 4 2.5 4h5zM9 8c0-0.276-0.224-0.5-0.5-0.5S8 7.724 8 8v6c0 0.276 0.224 0.5 0.5 0.5S9 14.276 9 14V8zm2.5-0.5C11.224 7.5 11 7.724 11 8v6c0 0.276 0.224 0.5 0.5 0.5S12 14.276 12 14V8c0-0.276-0.224-0.5-0.5-0.5z" android:fillColor="@color/fluent_default_icon_tint"/>
3+
</vector>

mastodon/src/main/res/layout/display_item_header.xml

+15-1
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,26 @@
2222
android:tint="?android:textColorSecondary" />
2323

2424
<ImageView
25-
android:id="@+id/visibility"
25+
android:id="@+id/delete_notification"
2626
android:layout_width="36dp"
2727
android:layout_height="36dp"
2828
android:layout_marginTop="-6dp"
2929
android:layout_marginRight="6dp"
3030
android:layout_toLeftOf="@id/more"
31+
android:visibility="gone"
32+
android:background="?android:selectableItemBackgroundBorderless"
33+
android:contentDescription="@string/sk_delete_notification"
34+
android:scaleType="center"
35+
android:src="@drawable/ic_fluent_delete_20_filled"
36+
android:tint="?android:textColorSecondary" />
37+
38+
<ImageView
39+
android:id="@+id/visibility"
40+
android:layout_width="36dp"
41+
android:layout_height="36dp"
42+
android:layout_marginTop="-6dp"
43+
android:layout_marginRight="6dp"
44+
android:layout_toLeftOf="@id/delete_notification"
3145
android:background="?android:selectableItemBackgroundBorderless"
3246
android:scaleType="center"
3347
android:src="@drawable/ic_visibility"

mastodon/src/main/res/menu/notifications.xml

+6
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,10 @@
66
android:showAsAction="always"
77
android:visible="false"
88
android:title="@string/sk_follow_requests" />
9+
<item
10+
android:id="@+id/clear_notifications"
11+
android:icon="@drawable/ic_fluent_delete_24_regular"
12+
android:showAsAction="always"
13+
android:visible="false"
14+
android:title="@string/sk_delete_all_notifications" />
915
</menu>

mastodon/src/main/res/values/strings_sk.xml

+7
Original file line numberDiff line numberDiff line change
@@ -70,4 +70,11 @@
7070
<string name="sk_settings_rules">Rules</string>
7171
<string name="sk_settings_about">About the app</string>
7272
<string name="sk_settings_donate">Donate</string>
73+
<string name="sk_delete_notification">Delete notification</string>
74+
<string name="sk_delete_notification_confirm_action">Delete notification</string>
75+
<string name="sk_delete_notification_confirm">Are you sure you want to delete this notification?</string>
76+
<string name="sk_delete_all_notifications">Delete all notifications</string>
77+
<string name="sk_delete_all_notifications_confirm_action">Delete all</string>
78+
<string name="sk_delete_all_notifications_confirm">Are you sure you want to delete this notification?</string>
79+
<string name="sk_enable_delete_notifications">Enable deleting notifications</string>
7380
</resources>

0 commit comments

Comments
 (0)