diff --git a/components/common/CommonPaginator.vue b/components/common/CommonPaginator.vue
index 8bf06c2e..1191f17d 100644
--- a/components/common/CommonPaginator.vue
+++ b/components/common/CommonPaginator.vue
@@ -17,7 +17,7 @@ const {
   virtualScroller?: boolean
   stream?: Promise<WsEvents>
   eventType?: 'notification' | 'update'
-  preprocess?: (items: T[]) => U[]
+  preprocess?: (items: (U | T)[]) => U[]
 }>()
 
 defineSlots<{
diff --git a/components/notification/NotificationPaginator.vue b/components/notification/NotificationPaginator.vue
index 2e071e36..7e2fcbaa 100644
--- a/components/notification/NotificationPaginator.vue
+++ b/components/notification/NotificationPaginator.vue
@@ -23,7 +23,7 @@ const groupId = (item: mastodon.v1.Notification): string => {
   return JSON.stringify(id)
 }
 
-function preprocess(items: mastodon.v1.Notification[]): NotificationSlot[] {
+function groupItems(items: mastodon.v1.Notification[]): NotificationSlot[] {
   const results: NotificationSlot[] = []
 
   let id = 0
@@ -108,6 +108,28 @@ function preprocess(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
+      for (const like of group.likes) {
+        if (like.reblog)
+          flattenedNotifications.push(like.reblog)
+        if (like.favourite)
+          flattenedNotifications.push(like.favourite)
+      }
+    }
+    else if (item.type === 'grouped-follow') {
+      flattenedNotifications.push(...item.items)
+    }
+    else {
+      flattenedNotifications.push(item)
+    }
+  }
+  return groupItems(flattenedNotifications)
+}
+
 const { clearNotifications } = useNotifications()
 const { formatNumber } = useHumanReadableNumber()
 </script>
diff --git a/composables/paginator.ts b/composables/paginator.ts
index 62861b0c..90950cc2 100644
--- a/composables/paginator.ts
+++ b/composables/paginator.ts
@@ -5,7 +5,7 @@ export function usePaginator<T, P, U = T>(
   paginator: Paginator<T[], P>,
   stream?: Promise<WsEvents>,
   eventType: 'notification' | 'update' = 'update',
-  preprocess: (items: T[]) => U[] = items => items as unknown as U[],
+  preprocess: (items: (T | U)[]) => U[] = items => items as unknown as U[],
   buffer = 10,
 ) {
   const state = ref<PaginatorState>(isMastoInitialised.value ? 'idle' : 'loading')
@@ -64,14 +64,14 @@ export function usePaginator<T, P, U = T>(
     try {
       const result = await paginator.next()
 
-      if (result.value?.length) {
-        const preprocessedItems = preprocess([...nextItems.value, ...result.value]) as any
+      if (!result.done && result.value.length) {
+        const preprocessedItems = preprocess([...nextItems.value, ...result.value] as (U | T)[])
         const itemsToShowCount
           = preprocessedItems.length < buffer
             ? preprocessedItems.length
             : preprocessedItems.length - buffer
-        nextItems.value = preprocessedItems.slice(itemsToShowCount)
-        items.value.push(...preprocessedItems.slice(0, itemsToShowCount))
+        ;(nextItems.value as U[]) = preprocessedItems.slice(itemsToShowCount)
+        ;(items.value as U[]).push(...preprocessedItems.slice(0, itemsToShowCount))
         state.value = 'idle'
       }
       else {