Grouped Notifications UI (#30440)
Co-authored-by: Eugen Rochko <eugen@zeonfederated.com> Co-authored-by: Claire <claire.github-309c@sitedethib.com>
This commit is contained in:
		
					parent
					
						
							
								7d090b2ab6
							
						
					
				
			
			
				commit
				
					
						f587ff643f
					
				
			
		
					 65 changed files with 3329 additions and 131 deletions
				
			
		
							
								
								
									
										207
									
								
								app/javascript/mastodon/models/notification_group.ts
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										207
									
								
								app/javascript/mastodon/models/notification_group.ts
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,207 @@ | |||
| import type { | ||||
|   ApiAccountRelationshipSeveranceEventJSON, | ||||
|   ApiAccountWarningJSON, | ||||
|   BaseNotificationGroupJSON, | ||||
|   ApiNotificationGroupJSON, | ||||
|   ApiNotificationJSON, | ||||
|   NotificationType, | ||||
|   NotificationWithStatusType, | ||||
| } from 'mastodon/api_types/notifications'; | ||||
| import type { ApiReportJSON } from 'mastodon/api_types/reports'; | ||||
| 
 | ||||
| // Maximum number of avatars displayed in a notification group
 | ||||
| // This corresponds to the max lenght of `group.sampleAccountIds`
 | ||||
| export const NOTIFICATIONS_GROUP_MAX_AVATARS = 8; | ||||
| 
 | ||||
| interface BaseNotificationGroup | ||||
|   extends Omit<BaseNotificationGroupJSON, 'sample_accounts'> { | ||||
|   sampleAccountIds: string[]; | ||||
| } | ||||
| 
 | ||||
| interface BaseNotificationWithStatus<Type extends NotificationWithStatusType> | ||||
|   extends BaseNotificationGroup { | ||||
|   type: Type; | ||||
|   statusId: string; | ||||
| } | ||||
| 
 | ||||
| interface BaseNotification<Type extends NotificationType> | ||||
|   extends BaseNotificationGroup { | ||||
|   type: Type; | ||||
| } | ||||
| 
 | ||||
| export type NotificationGroupFavourite = | ||||
|   BaseNotificationWithStatus<'favourite'>; | ||||
| export type NotificationGroupReblog = BaseNotificationWithStatus<'reblog'>; | ||||
| export type NotificationGroupStatus = BaseNotificationWithStatus<'status'>; | ||||
| export type NotificationGroupMention = BaseNotificationWithStatus<'mention'>; | ||||
| export type NotificationGroupPoll = BaseNotificationWithStatus<'poll'>; | ||||
| export type NotificationGroupUpdate = BaseNotificationWithStatus<'update'>; | ||||
| export type NotificationGroupFollow = BaseNotification<'follow'>; | ||||
| export type NotificationGroupFollowRequest = BaseNotification<'follow_request'>; | ||||
| export type NotificationGroupAdminSignUp = BaseNotification<'admin.sign_up'>; | ||||
| 
 | ||||
| export type AccountWarningAction = | ||||
|   | 'none' | ||||
|   | 'disable' | ||||
|   | 'mark_statuses_as_sensitive' | ||||
|   | 'delete_statuses' | ||||
|   | 'sensitive' | ||||
|   | 'silence' | ||||
|   | 'suspend'; | ||||
| export interface AccountWarning | ||||
|   extends Omit<ApiAccountWarningJSON, 'target_account'> { | ||||
|   targetAccountId: string; | ||||
| } | ||||
| 
 | ||||
| export interface NotificationGroupModerationWarning | ||||
|   extends BaseNotification<'moderation_warning'> { | ||||
|   moderationWarning: AccountWarning; | ||||
| } | ||||
| 
 | ||||
| type AccountRelationshipSeveranceEvent = | ||||
|   ApiAccountRelationshipSeveranceEventJSON; | ||||
| export interface NotificationGroupSeveredRelationships | ||||
|   extends BaseNotification<'severed_relationships'> { | ||||
|   event: AccountRelationshipSeveranceEvent; | ||||
| } | ||||
| 
 | ||||
| interface Report extends Omit<ApiReportJSON, 'target_account'> { | ||||
|   targetAccountId: string; | ||||
| } | ||||
| 
 | ||||
| export interface NotificationGroupAdminReport | ||||
|   extends BaseNotification<'admin.report'> { | ||||
|   report: Report; | ||||
| } | ||||
| 
 | ||||
| export type NotificationGroup = | ||||
|   | NotificationGroupFavourite | ||||
|   | NotificationGroupReblog | ||||
|   | NotificationGroupStatus | ||||
|   | NotificationGroupMention | ||||
|   | NotificationGroupPoll | ||||
|   | NotificationGroupUpdate | ||||
|   | NotificationGroupFollow | ||||
|   | NotificationGroupFollowRequest | ||||
|   | NotificationGroupModerationWarning | ||||
|   | NotificationGroupSeveredRelationships | ||||
|   | NotificationGroupAdminSignUp | ||||
|   | NotificationGroupAdminReport; | ||||
| 
 | ||||
| function createReportFromJSON(reportJSON: ApiReportJSON): Report { | ||||
|   const { target_account, ...report } = reportJSON; | ||||
|   return { | ||||
|     targetAccountId: target_account.id, | ||||
|     ...report, | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| function createAccountWarningFromJSON( | ||||
|   warningJSON: ApiAccountWarningJSON, | ||||
| ): AccountWarning { | ||||
|   const { target_account, ...warning } = warningJSON; | ||||
|   return { | ||||
|     targetAccountId: target_account.id, | ||||
|     ...warning, | ||||
|   }; | ||||
| } | ||||
| 
 | ||||
| function createAccountRelationshipSeveranceEventFromJSON( | ||||
|   eventJson: ApiAccountRelationshipSeveranceEventJSON, | ||||
| ): AccountRelationshipSeveranceEvent { | ||||
|   return eventJson; | ||||
| } | ||||
| 
 | ||||
| export function createNotificationGroupFromJSON( | ||||
|   groupJson: ApiNotificationGroupJSON, | ||||
| ): NotificationGroup { | ||||
|   const { sample_accounts, ...group } = groupJson; | ||||
|   const sampleAccountIds = sample_accounts.map((account) => account.id); | ||||
| 
 | ||||
|   switch (group.type) { | ||||
|     case 'favourite': | ||||
|     case 'reblog': | ||||
|     case 'status': | ||||
|     case 'mention': | ||||
|     case 'poll': | ||||
|     case 'update': { | ||||
|       const { status, ...groupWithoutStatus } = group; | ||||
|       return { | ||||
|         statusId: status.id, | ||||
|         sampleAccountIds, | ||||
|         ...groupWithoutStatus, | ||||
|       }; | ||||
|     } | ||||
|     case 'admin.report': { | ||||
|       const { report, ...groupWithoutTargetAccount } = group; | ||||
|       return { | ||||
|         report: createReportFromJSON(report), | ||||
|         sampleAccountIds, | ||||
|         ...groupWithoutTargetAccount, | ||||
|       }; | ||||
|     } | ||||
|     case 'severed_relationships': | ||||
|       return { | ||||
|         ...group, | ||||
|         event: createAccountRelationshipSeveranceEventFromJSON(group.event), | ||||
|         sampleAccountIds, | ||||
|       }; | ||||
| 
 | ||||
|     case 'moderation_warning': { | ||||
|       const { moderation_warning, ...groupWithoutModerationWarning } = group; | ||||
|       return { | ||||
|         ...groupWithoutModerationWarning, | ||||
|         moderationWarning: createAccountWarningFromJSON(moderation_warning), | ||||
|         sampleAccountIds, | ||||
|       }; | ||||
|     } | ||||
|     default: | ||||
|       return { | ||||
|         sampleAccountIds, | ||||
|         ...group, | ||||
|       }; | ||||
|   } | ||||
| } | ||||
| 
 | ||||
| export function createNotificationGroupFromNotificationJSON( | ||||
|   notification: ApiNotificationJSON, | ||||
| ) { | ||||
|   const group = { | ||||
|     sampleAccountIds: [notification.account.id], | ||||
|     group_key: notification.group_key, | ||||
|     notifications_count: 1, | ||||
|     type: notification.type, | ||||
|     most_recent_notification_id: notification.id, | ||||
|     page_min_id: notification.id, | ||||
|     page_max_id: notification.id, | ||||
|     latest_page_notification_at: notification.created_at, | ||||
|   } as NotificationGroup; | ||||
| 
 | ||||
|   switch (notification.type) { | ||||
|     case 'favourite': | ||||
|     case 'reblog': | ||||
|     case 'status': | ||||
|     case 'mention': | ||||
|     case 'poll': | ||||
|     case 'update': | ||||
|       return { ...group, statusId: notification.status.id }; | ||||
|     case 'admin.report': | ||||
|       return { ...group, report: createReportFromJSON(notification.report) }; | ||||
|     case 'severed_relationships': | ||||
|       return { | ||||
|         ...group, | ||||
|         event: createAccountRelationshipSeveranceEventFromJSON( | ||||
|           notification.event, | ||||
|         ), | ||||
|       }; | ||||
|     case 'moderation_warning': | ||||
|       return { | ||||
|         ...group, | ||||
|         moderationWarning: createAccountWarningFromJSON( | ||||
|           notification.moderation_warning, | ||||
|         ), | ||||
|       }; | ||||
|     default: | ||||
|       return group; | ||||
|   } | ||||
| } | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue