{original.senderUserId !== currentUser.value?.id &&
- !original.$isExpired ? (
+ !isNotificationExpired(original) ? (
{original.type === 'friendRequest' ? (
diff --git a/src/views/Sidebar/components/NotificationCenterSheet.vue b/src/views/Sidebar/components/NotificationCenterSheet.vue
index ec8b43ec..1000bdb4 100644
--- a/src/views/Sidebar/components/NotificationCenterSheet.vue
+++ b/src/views/Sidebar/components/NotificationCenterSheet.vue
@@ -92,9 +92,9 @@
const activeTab = ref('friend');
const activeCount = computed(() => ({
- friend: friendNotifications.value.filter((n) => !n.$isExpired).length,
- group: groupNotifications.value.filter((n) => !n.$isExpired).length,
- other: otherNotifications.value.filter((n) => !n.$isExpired).length
+ friend: friendNotifications.value.length,
+ group: groupNotifications.value.length,
+ other: otherNotifications.value.length
}));
// Dialog state
diff --git a/src/views/Sidebar/components/NotificationItem.vue b/src/views/Sidebar/components/NotificationItem.vue
index a8b797f2..ddeab284 100644
--- a/src/views/Sidebar/components/NotificationItem.vue
+++ b/src/views/Sidebar/components/NotificationItem.vue
@@ -1,8 +1,5 @@
- -
+
-
@@ -18,7 +15,7 @@
{{ typeLabel }}
@@ -33,7 +30,7 @@
{{ relativeTime }}
-
+
{
const n = props.notification;
@@ -224,6 +223,7 @@
const showDecline = computed(() => {
const type = props.notification.type;
+ const link = props.notification.link;
return (
type !== 'requestInviteResponse' &&
type !== 'inviteResponse' &&
@@ -232,7 +232,8 @@
type !== 'groupChange' &&
!type?.includes('group.') &&
!type?.includes('moderation.') &&
- !type?.includes('instance.')
+ !type?.includes('instance.') &&
+ !link?.startsWith('economy.')
);
});
@@ -242,13 +243,18 @@
const n = props.notification;
const type = n.type;
if (type === 'friendRequest' || type === 'ignoredFriendRequest') return false;
- if (type?.includes('group.') || type?.includes('moderation.') || type?.includes('instance.')) return false;
- if (n.link?.startsWith('economy.')) return false;
- // For active notifications, group.queueReady is handled separately
- if (!n.$isExpired && type === 'group.queueReady') return false;
return true;
});
+ const isSeen = computed(() => {
+ const n = props.notification;
+ if (typeof n.seen === 'boolean') {
+ return n.seen;
+ }
+ // Fallback for v1 notifications without seen property
+ return !props.isUnseen;
+ });
+
const canInvite = computed(() => {
const location = lastLocation.value?.location;
return Boolean(location) && isGameRunning.value && checkCanInvite(location);
@@ -284,27 +290,6 @@
notificationStore.sendNotificationResponse(props.notification.id, props.notification.responses, response.type);
}
- function openNotificationLink(link) {
- if (!link) return;
- const data = link.split(':');
- if (!data.length) return;
- switch (data[0]) {
- case 'group':
- groupStore.showGroupDialog(data[1]);
- break;
- case 'user':
- userStore.showUserDialog(data[1]);
- break;
- case 'event': {
- const ids = data[1].split(',');
- if (ids.length >= 2) {
- groupStore.showGroupDialog(ids[0]);
- }
- break;
- }
- }
- }
-
function openSender() {
const userId = props.notification.senderUserId;
if (!userId) return;
@@ -314,4 +299,36 @@
userStore.showUserDialog(userId);
}
}
+
+ onMounted(() => {
+ // Mark as seen
+ if (isNotificationExpired(props.notification) || isSeen.value) {
+ return;
+ }
+ const params = { notificationId: props.notification.id };
+ if (!props.notification.version || props.notification.version < 2) {
+ notificationRequest.seeNotification({ notificationId: props.notification.id }).then((args) => {
+ console.log('Marked notification-v1 as seen:', args.json);
+ notificationStore.handleNotificationSee(props.notification.id);
+ });
+ return;
+ }
+ notificationRequest
+ .seeNotificationV2(params)
+ .then((args) => {
+ console.log('Marked notification-v2 as seen:', args.json);
+ const newArgs = {
+ params,
+ json: {
+ ...args.json,
+ seen: true
+ }
+ };
+ notificationStore.handleNotificationV2Update(newArgs);
+ })
+ .catch((err) => {
+ console.error('Failed to mark notification-v2 as seen:', err);
+ handleNotificationV2Hide(props.notification.id);
+ });
+ });
diff --git a/src/views/Sidebar/components/NotificationList.vue b/src/views/Sidebar/components/NotificationList.vue
index 54f00e41..72be4dbc 100644
--- a/src/views/Sidebar/components/NotificationList.vue
+++ b/src/views/Sidebar/components/NotificationList.vue
@@ -11,7 +11,7 @@
@show-invite-request-response="$emit('show-invite-request-response', $event)" />
- {{ t('side_panel.notification_center.no_notifications') }}
+ {{ t('side_panel.notification_center.no_new_notifications') }}
@@ -73,11 +73,13 @@
const sortedNotifications = computed(() => [...props.notifications].sort((a, b) => getTs(b) - getTs(a)));
- const activeNotifications = computed(() => sortedNotifications.value.filter((n) => !n.$isExpired));
+ 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) => n.$isExpired).slice(0, MAX_EXPIRED)
+ sortedNotifications.value.filter((n) => getTs(n) <= dayjs().subtract(1, 'week').valueOf()).slice(0, MAX_EXPIRED)
);