Add `moderation_warning` notifications (AND-175)

This commit is contained in:
Grishka 2024-09-21 11:09:36 +03:00
parent 9e201f3c00
commit 1dc9adafc7
9 changed files with 83 additions and 6 deletions

View File

@ -282,6 +282,8 @@ public class CacheController{
group.mostRecentNotificationId=group.pageMaxId=group.pageMinId=n.id;
group.latestPageNotificationAt=n.createdAt;
group.sampleAccountIds=List.of(n.account.id);
group.event=n.event;
group.moderationWarning=n.moderationWarning;
if(n.status!=null)
group.statusId=n.status.id;
NotificationViewModel nvm=new NotificationViewModel();

View File

@ -36,7 +36,7 @@ public abstract class BaseNotificationsListFragment extends BaseStatusListFragme
else
titleItem=null;
}else{
if(n.notification.type==NotificationType.SEVERED_RELATIONSHIPS)
if(n.notification.type==NotificationType.SEVERED_RELATIONSHIPS || n.notification.type==NotificationType.MODERATION_WARNING)
titleItem=new NotificationWithButtonStatusDisplayItem(n.getID(), this, n, accountID);
else
titleItem=new NotificationHeaderStatusDisplayItem(n.getID(), this, n, accountID);

View File

@ -0,0 +1,32 @@
package org.joinmastodon.android.model;
import com.google.gson.annotations.SerializedName;
import org.joinmastodon.android.api.RequiredField;
import org.parceler.Parcel;
@Parcel
public class AccountWarning extends BaseModel{
@RequiredField
public String id;
@RequiredField
public Action action=Action.NONE;
public String text;
public enum Action{
@SerializedName("none")
NONE,
@SerializedName("disable")
DISABLE,
@SerializedName("mark_statuses_as_sensitive")
MARK_STATUSES_AS_SENSITIVE,
@SerializedName("delete_statuses")
DELETE_STATUSES,
@SerializedName("sensitive")
SENSITIVE,
@SerializedName("silence")
SILENCE,
@SerializedName("suspend")
SUSPEND
}
}

View File

@ -19,6 +19,7 @@ public class Notification extends BaseModel implements DisplayItemsParent{
public Account account;
public Status status;
public RelationshipSeveranceEvent event;
public AccountWarning moderationWarning;
@Override
public void postprocess() throws ObjectValidationException{
@ -34,7 +35,9 @@ public class Notification extends BaseModel implements DisplayItemsParent{
event=null;
}
}
if(type!=NotificationType.SEVERED_RELATIONSHIPS && account==null){
if(moderationWarning!=null)
moderationWarning.postprocess();
if(type!=NotificationType.SEVERED_RELATIONSHIPS && type!=NotificationType.MODERATION_WARNING && account==null){
throw new ObjectValidationException("account must be present for type "+type);
}
}

View File

@ -22,7 +22,7 @@ public class NotificationGroup extends BaseModel{
public List<String> sampleAccountIds;
public String statusId;
public RelationshipSeveranceEvent event;
// TODO moderation_warning
public AccountWarning moderationWarning;
@Override
@ -36,7 +36,9 @@ public class NotificationGroup extends BaseModel{
event=null;
}
}
if(type!=NotificationType.SEVERED_RELATIONSHIPS && sampleAccountIds.isEmpty()){
if(moderationWarning!=null)
moderationWarning.postprocess();
if(type!=NotificationType.SEVERED_RELATIONSHIPS && type!=NotificationType.MODERATION_WARNING && sampleAccountIds.isEmpty()){
throw new ObjectValidationException("sample_account_ids must be present for type "+type);
}
}

View File

@ -22,7 +22,9 @@ public enum NotificationType{
@SerializedName("update")
UPDATE,
@SerializedName("severed_relationships")
SEVERED_RELATIONSHIPS;
SEVERED_RELATIONSHIPS,
@SerializedName("moderation_warning")
MODERATION_WARNING;
public boolean canBeGrouped(){
return this==REBLOG || this==FAVORITE;

View File

@ -13,6 +13,7 @@ import android.widget.TextView;
import org.joinmastodon.android.R;
import org.joinmastodon.android.api.session.AccountSessionManager;
import org.joinmastodon.android.fragments.BaseStatusListFragment;
import org.joinmastodon.android.model.AccountWarning;
import org.joinmastodon.android.model.NotificationType;
import org.joinmastodon.android.model.RelationshipSeveranceEvent;
import org.joinmastodon.android.model.viewmodel.NotificationViewModel;
@ -29,9 +30,9 @@ public class NotificationWithButtonStatusDisplayItem extends StatusDisplayItem{
public NotificationWithButtonStatusDisplayItem(String parentID, BaseStatusListFragment<?> parentFragment, NotificationViewModel notification, String accountID){
super(parentID, parentFragment);
this.notification=notification;
String localDomain=AccountSessionManager.get(accountID).domain;
if(notification.notification.type==NotificationType.SEVERED_RELATIONSHIPS){
RelationshipSeveranceEvent event=notification.notification.event;
String localDomain=AccountSessionManager.get(accountID).domain;
if(event!=null){
text=switch(event.type){
case ACCOUNT_SUSPENSION -> replacePlaceholdersWithBoldStrings(parentFragment.getString(R.string.relationship_severance_account_suspension,
@ -48,6 +49,23 @@ public class NotificationWithButtonStatusDisplayItem extends StatusDisplayItem{
}
buttonText=parentFragment.getString(R.string.relationship_severance_learn_more);
buttonAction=()->UiUtils.launchWebBrowser(parentFragment.getActivity(), "https://"+localDomain+"/severed_relationships");
}else if(notification.notification.type==NotificationType.MODERATION_WARNING){
AccountWarning warning=notification.notification.moderationWarning;
if(warning!=null){
text=parentFragment.getString(switch(warning.action){
case NONE -> R.string.moderation_warning_action_none;
case DISABLE -> R.string.moderation_warning_action_disable;
case MARK_STATUSES_AS_SENSITIVE -> R.string.moderation_warning_action_mark_statuses_as_sensitive;
case DELETE_STATUSES -> R.string.moderation_warning_action_delete_statuses;
case SENSITIVE -> R.string.moderation_warning_action_sensitive;
case SILENCE -> R.string.moderation_warning_action_silence;
case SUSPEND -> R.string.moderation_warning_action_suspend;
});
buttonAction=()->UiUtils.launchWebBrowser(parentFragment.getActivity(), "https://"+localDomain+"/disputes/strikes/"+warning.id);
}else{
text="???";
}
buttonText=parentFragment.getString(R.string.moderation_warning_learn_more);
}
}
@ -86,6 +104,7 @@ public class NotificationWithButtonStatusDisplayItem extends StatusDisplayItem{
public void onBind(NotificationWithButtonStatusDisplayItem item){
icon.setImageResource(switch(item.notification.notification.type){
case SEVERED_RELATIONSHIPS -> R.drawable.ic_heart_broken_fill1_24px;
case MODERATION_WARNING -> R.drawable.ic_gavel_24px;
default -> throw new IllegalStateException("Unexpected value: " + item.notification.notification.type);
});
icon.setImageTintList(ColorStateList.valueOf(UiUtils.getThemeColor(itemView.getContext(), R.attr.colorM3Outline)));

View File

@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="@android:color/white"
android:pathData="M160,840L160,760L640,760L640,840L160,840ZM386,646L160,420L244,334L472,560L386,646ZM640,392L414,164L500,80L726,306L640,392ZM824,800L302,278L358,222L880,744L824,800Z"/>
</vector>

View File

@ -808,4 +808,12 @@
<!-- %1$s is the domain that was blocked, %2$,d is the follower count, %3$s is the `x_accounts` plural string -->
<string name="relationship_severance_user_domain_block">You have blocked %1$s, removing %2$,d of your followers and %3$s you follow.</string>
<string name="relationship_severance_learn_more">Learn more</string>
<string name="moderation_warning_action_none">Your account has received a moderation warning.</string>
<string name="moderation_warning_action_disable">Your account has been disabled.</string>
<string name="moderation_warning_action_mark_statuses_as_sensitive">Some of your posts have been marked as sensitive.</string>
<string name="moderation_warning_action_delete_statuses">Some of your posts have been removed.</string>
<string name="moderation_warning_action_sensitive">Your posts will be marked as sensitive from now on.</string>
<string name="moderation_warning_action_silence">Your account has been limited.</string>
<string name="moderation_warning_action_suspend">Your account has been suspended.</string>
<string name="moderation_warning_learn_more">Learn more</string>
</resources>