fix: group follow notification

append current group before push a single item
zio/stable
三咲智子 2023-01-09 20:23:15 +08:00
parent efe7d639c1
commit 83db9f0c38
No known key found for this signature in database
GPG Key ID: 69992F2250DFD93E
4 changed files with 37 additions and 52 deletions

View File

@ -1,4 +1,4 @@
<script setup lang="ts" generic="T, O">
<script setup lang="ts" generic="T, O, U = T">
// @ts-expect-error missing types
import { DynamicScroller } from 'vue-virtual-scroller'
import 'vue-virtual-scroller/dist/vue-virtual-scroller.css'
@ -22,20 +22,20 @@ const {
// until the next pagination to avoid border effect between pages when reordering
// and grouping items
buffer?: number
preprocess?: (items: T[]) => any[]
preprocess?: (items: T[]) => U[]
}>()
defineSlots<{
default: {
items: T[]
item: T
items: U[]
item: U
index: number
active?: boolean
older?: T
newer?: T // newer is undefined when index === 0
older?: U
newer?: U // newer is undefined when index === 0
}
items: {
items: T[]
items: U[]
}
updater: {
number: number

View File

@ -1,12 +1,9 @@
<script setup lang="ts">
import { mastodon } from 'masto'
import type { Paginator, WsEvents } from 'masto'
// type used in <template>
// eslint-disable-next-line @typescript-eslint/consistent-type-imports
import type { GroupedAccountLike, GroupedLikeNotifications, GroupedNotifications, NotificationSlot } from '~/types'
import type { Paginator, WsEvents, mastodon } from 'masto'
import type { GroupedAccountLike, NotificationSlot } from '~/types'
const { paginator, stream } = defineProps<{
paginator: Paginator<NotificationSlot[], mastodon.v1.ListNotificationsParams>
paginator: Paginator<mastodon.v1.Notification[], mastodon.v1.ListNotificationsParams>
stream?: Promise<WsEvents>
}>()
@ -26,7 +23,7 @@ const groupId = (item: mastodon.v1.Notification): string => {
return JSON.stringify(id)
}
function groupItems(items: mastodon.v1.Notification[]): NotificationSlot[] {
function preprocess(items: mastodon.v1.Notification[]): NotificationSlot[] {
const results: NotificationSlot[] = []
let id = 0
@ -43,21 +40,31 @@ function groupItems(items: mastodon.v1.Notification[]): NotificationSlot[] {
// This normally happens when you transfer an account, if not, show
// a big profile card for each follow
if (group[0].type === 'follow') {
const toGroup = []
let groups: mastodon.v1.Notification[] = []
function newGroup() {
if (groups.length > 0) {
results.push({
id: `grouped-${id++}`,
type: 'grouped-follow',
items: groups,
})
groups = []
}
}
for (const item of group) {
const hasHeader = !item.account.header.endsWith('/original/missing.png')
if (hasHeader && (item.account.followersCount > 250 || (group.length === 1 && item.account.followersCount > 25)))
if (hasHeader && (item.account.followersCount > 250 || (group.length === 1 && item.account.followersCount > 25))) {
newGroup()
results.push(item)
else
toGroup.push(item)
}
if (toGroup.length > 0) {
results.push({
id: `grouped-${id++}`,
type: `grouped-${group[0].type}`,
items: toGroup,
})
}
else {
groups.push(item)
}
}
newGroup()
return
}
@ -101,28 +108,6 @@ function groupItems(items: mastodon.v1.Notification[]): NotificationSlot[] {
return results
}
function preprocess(items: NotificationSlot[]): NotificationSlot[] {
const flattenedNotifications: mastodon.v1.Notification[] = []
for (const item of items) {
if (item.type === 'grouped-reblogs-and-favourites') {
const group = item as GroupedLikeNotifications
for (const like of group.likes) {
if (like.reblog)
flattenedNotifications.push(like.reblog)
if (like.favourite)
flattenedNotifications.push(like.favourite)
}
}
else if (item.type.startsWith('grouped-')) {
flattenedNotifications.push(...(item as GroupedNotifications).items)
}
else {
flattenedNotifications.push(item as mastodon.v1.Notification)
}
}
return groupItems(flattenedNotifications)
}
const { clearNotifications } = useNotifications()
const { formatNumber } = useHumanReadableNumber()
</script>
@ -143,12 +128,12 @@ const { formatNumber } = useHumanReadableNumber()
/>
<NotificationGroupedLikes
v-else-if="item.type === 'grouped-reblogs-and-favourites'"
:group="item as GroupedLikeNotifications"
:group="item"
border="b base"
/>
<NotificationCard
v-else
:notification="item as mastodon.v1.Notification"
:notification="item"
hover:bg-active
border="b base"
/>

View File

@ -1,11 +1,11 @@
import type { Paginator, WsEvents } from 'masto'
import type { PaginatorState } from '~/types'
export function usePaginator<T, P>(
export function usePaginator<T, P, U = T>(
paginator: Paginator<T[], P>,
stream?: Promise<WsEvents>,
eventType: 'notification' | 'update' = 'update',
preprocess: (items: T[]) => T[] = (items: T[]) => items,
preprocess: (items: T[]) => U[] = (items: T[]) => items as unknown as U[],
buffer = 10,
) {
const state = ref<PaginatorState>(isMastoInitialised.value ? 'idle' : 'loading')

View File

@ -29,7 +29,7 @@ export type PaginatorState = 'idle' | 'loading' | 'done' | 'error'
export interface GroupedNotifications {
id: string
type: Exclude<string, 'grouped-reblogs-and-favourites'>
type: 'grouped-follow'
items: mastodon.v1.Notification[]
}