Display only unseen notifications in the notification center and remove the past notifications section from the list

This commit is contained in:
pa
2026-02-21 19:05:46 +09:00
parent 472508248e
commit e2f6fbfc85
3 changed files with 28 additions and 57 deletions

View File

@@ -124,6 +124,16 @@ export const useNotificationStore = defineStore('Notification', () => {
(n) => getNotificationCategory(n.type) === 'other'
)
);
const unseenSet = computed(() => new Set(unseenNotifications.value));
const unseenFriendNotifications = computed(() =>
friendNotifications.value.filter((n) => unseenSet.value.has(n.id))
);
const unseenGroupNotifications = computed(() =>
groupNotifications.value.filter((n) => unseenSet.value.has(n.id))
);
const unseenOtherNotifications = computed(() =>
otherNotifications.value.filter((n) => unseenSet.value.has(n.id))
);
const hasUnseenNotifications = computed(
() => unseenNotifications.value.length > 0
);
@@ -2703,6 +2713,9 @@ export const useNotificationStore = defineStore('Notification', () => {
friendNotifications,
groupNotifications,
otherNotifications,
unseenFriendNotifications,
unseenGroupNotifications,
unseenOtherNotifications,
hasUnseenNotifications,
getNotificationCategory,
isNotificationExpired,

View File

@@ -10,43 +10,40 @@
<TabsList class="mr-4 ml-2 mt-2 grid w-auto grid-cols-3">
<TabsTrigger value="friend">
{{ t('side_panel.notification_center.tab_friend') }}
<span v-if="activeCount.friend" class="ml-1 text-xs text-muted-foreground">
({{ activeCount.friend }})
<span v-if="unseenFriendNotifications.length" class="ml-1 text-xs text-muted-foreground">
({{ unseenFriendNotifications.length }})
</span>
</TabsTrigger>
<TabsTrigger value="group">
{{ t('side_panel.notification_center.tab_group') }}
<span v-if="activeCount.group" class="ml-1 text-xs text-muted-foreground">
({{ activeCount.group }})
<span v-if="unseenGroupNotifications.length" class="ml-1 text-xs text-muted-foreground">
({{ unseenGroupNotifications.length }})
</span>
</TabsTrigger>
<TabsTrigger value="other">
{{ t('side_panel.notification_center.tab_other') }}
<span v-if="activeCount.other" class="ml-1 text-xs text-muted-foreground">
({{ activeCount.other }})
<span v-if="unseenOtherNotifications.length" class="ml-1 text-xs text-muted-foreground">
({{ unseenOtherNotifications.length }})
</span>
</TabsTrigger>
</TabsList>
<TabsContent value="friend" class="mt-0 min-h-0 flex-1 overflow-hidden">
<NotificationList
:notifications="friendNotifications"
:unseen-ids="unseenNotifications"
:notifications="unseenFriendNotifications"
@show-invite-response="showSendInviteResponseDialog"
@show-invite-request-response="showSendInviteRequestResponseDialog"
@navigate-to-table="navigateToTable" />
</TabsContent>
<TabsContent value="group" class="mt-0 min-h-0 flex-1 overflow-hidden">
<NotificationList
:notifications="groupNotifications"
:unseen-ids="unseenNotifications"
:notifications="unseenGroupNotifications"
@show-invite-response="showSendInviteResponseDialog"
@show-invite-request-response="showSendInviteRequestResponseDialog"
@navigate-to-table="navigateToTable" />
</TabsContent>
<TabsContent value="other" class="mt-0 min-h-0 flex-1 overflow-hidden">
<NotificationList
:notifications="otherNotifications"
:unseen-ids="unseenNotifications"
:notifications="unseenOtherNotifications"
@show-invite-response="showSendInviteResponseDialog"
@show-invite-request-response="showSendInviteRequestResponseDialog"
@navigate-to-table="navigateToTable" />
@@ -65,7 +62,7 @@
<script setup>
import { Sheet, SheetContent, SheetHeader, SheetTitle } from '@/components/ui/sheet';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
import { computed, ref } from 'vue';
import { ref } from 'vue';
import { storeToRefs } from 'pinia';
import { useI18n } from 'vue-i18n';
import { useRouter } from 'vue-router';
@@ -81,22 +78,11 @@
const { refreshInviteMessageTableData } = useInviteStore();
const { clearInviteImageUpload } = useGalleryStore();
const {
isNotificationCenterOpen,
friendNotifications,
groupNotifications,
otherNotifications,
unseenNotifications
} = storeToRefs(useNotificationStore());
const { isNotificationCenterOpen, unseenFriendNotifications, unseenGroupNotifications, unseenOtherNotifications } =
storeToRefs(useNotificationStore());
const activeTab = ref('friend');
const activeCount = computed(() => ({
friend: friendNotifications.value.length,
group: groupNotifications.value.length,
other: otherNotifications.value.length
}));
// Dialog state
const sendInviteResponseDialog = ref({
messageSlot: {},

View File

@@ -6,7 +6,7 @@
v-for="n in activeNotifications"
:key="n.id || n.type + n.created_at"
:notification="n"
:is-unseen="unseenIds.includes(n.id)"
:is-unseen="true"
@show-invite-response="$emit('show-invite-response', $event)"
@show-invite-request-response="$emit('show-invite-request-response', $event)" />
</div>
@@ -14,22 +14,6 @@
{{ t('side_panel.notification_center.no_new_notifications') }}
</div>
<template v-if="expiredNotifications.length">
<div class="flex items-center gap-2 px-4 py-2">
<Separator class="flex-1" />
<span class="shrink-0 text-[10px] text-muted-foreground uppercase tracking-wider">
{{ t('side_panel.notification_center.past_notifications') }}
</span>
<Separator class="flex-1" />
</div>
<div class="flex flex-col gap-0.5 px-2 pb-2">
<NotificationItem
v-for="n in expiredNotifications"
:key="n.id || n.type + n.created_at"
:notification="n"
:is-unseen="false" />
</div>
</template>
<div class="flex justify-center py-3">
<Button
variant="ghost"
@@ -45,7 +29,6 @@
<script setup>
import { Button } from '@/components/ui/button';
import { Separator } from '@/components/ui/separator';
import { computed } from 'vue';
import { useI18n } from 'vue-i18n';
@@ -54,8 +37,7 @@
import NotificationItem from './NotificationItem.vue';
const props = defineProps({
notifications: { type: Array, required: true },
unseenIds: { type: Array, default: () => [] }
notifications: { type: Array, required: true }
});
defineEmits(['show-invite-response', 'show-invite-request-response', 'navigate-to-table']);
@@ -71,15 +53,5 @@
return Number.isFinite(ts) ? ts : 0;
}
const sortedNotifications = computed(() => [...props.notifications].sort((a, b) => getTs(b) - getTs(a)));
const activeNotifications = computed(() =>
sortedNotifications.value.filter((n) => getTs(n) > dayjs().subtract(1, 'week').valueOf())
);
const MAX_EXPIRED = 20;
const expiredNotifications = computed(() =>
sortedNotifications.value.filter((n) => getTs(n) <= dayjs().subtract(1, 'week').valueOf()).slice(0, MAX_EXPIRED)
);
const activeNotifications = computed(() => [...props.notifications].sort((a, b) => getTs(b) - getTs(a)));
</script>