feat: Implement individual notification click handling, differentiate notification types for replies and subscriptions, and refine notification display text.
This commit is contained in:
@@ -1010,6 +1010,28 @@ class NotificationSystem {
|
|||||||
this.markAllReadUI();
|
this.markAllReadUI();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Handle individual notification clicks
|
||||||
|
if (this.list) {
|
||||||
|
this.list.addEventListener('click', async (e) => {
|
||||||
|
const item = e.target.closest('.notif-item');
|
||||||
|
if (!item) return;
|
||||||
|
|
||||||
|
e.preventDefault();
|
||||||
|
const id = item.dataset.id;
|
||||||
|
const href = item.getAttribute('href');
|
||||||
|
|
||||||
|
// Mark as read
|
||||||
|
if (item.classList.contains('unread')) {
|
||||||
|
try {
|
||||||
|
await fetch(`/api/notifications/${id}/read`, { method: 'POST' });
|
||||||
|
} catch (err) { console.error(err); }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigate
|
||||||
|
window.location.href = href;
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async poll() {
|
async poll() {
|
||||||
@@ -1043,12 +1065,15 @@ class NotificationSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderItem(n) {
|
renderItem(n) {
|
||||||
const typeText = n.type === 'comment_reply' ? 'replied to your comment' : 'Start';
|
let typeText = 'Start';
|
||||||
|
if (n.type === 'comment_reply') typeText = 'replied to you';
|
||||||
|
else if (n.type === 'subscription') typeText = 'commented in a thread you follow';
|
||||||
|
|
||||||
const cid = n.comment_id || n.reference_id;
|
const cid = n.comment_id || n.reference_id;
|
||||||
const link = `/${n.item_id}#c${cid}`;
|
const link = `/${n.item_id}#c${cid}`;
|
||||||
|
|
||||||
return `
|
return `
|
||||||
<a href="${link}" class="notif-item ${n.is_read ? '' : 'unread'}" onclick="window.location.href='${link}'; return false;">
|
<a href="${link}" class="notif-item ${n.is_read ? '' : 'unread'}" data-id="${n.id}">
|
||||||
<div>
|
<div>
|
||||||
<strong>${n.from_user}</strong> ${typeText}
|
<strong>${n.from_user}</strong> ${typeText}
|
||||||
</div>
|
</div>
|
||||||
@@ -1057,6 +1082,7 @@ class NotificationSystem {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
markAllReadUI() {
|
markAllReadUI() {
|
||||||
this.countBadge.style.display = 'none';
|
this.countBadge.style.display = 'none';
|
||||||
this.list.querySelectorAll('.notif-item.unread').forEach(el => el.classList.remove('unread'));
|
this.list.querySelectorAll('.notif-item.unread').forEach(el => el.classList.remove('unread'));
|
||||||
|
|||||||
@@ -110,23 +110,38 @@ export default (router, tpl) => {
|
|||||||
parentAuthor = await db`SELECT user_id FROM comments WHERE id = ${parent_id}`;
|
parentAuthor = await db`SELECT user_id FROM comments WHERE id = ${parent_id}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 3. Collect unique recipients
|
// 3. Prepare notifications
|
||||||
const recipients = new Set();
|
const notificationsToAdd = [];
|
||||||
subscribers.forEach(s => recipients.add(s.user_id));
|
|
||||||
parentAuthor.forEach(p => recipients.add(p.user_id));
|
|
||||||
|
|
||||||
// Remove self
|
// Parent author gets 'comment_reply'
|
||||||
recipients.delete(req.session.id);
|
if (parentAuthor.length > 0) {
|
||||||
|
const pid = parentAuthor[0].user_id;
|
||||||
|
if (pid !== req.session.id) {
|
||||||
|
notificationsToAdd.push({
|
||||||
|
user_id: pid,
|
||||||
|
type: 'comment_reply',
|
||||||
|
item_id: item_id,
|
||||||
|
reference_id: commentId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subscribers get 'subscription' (unless they already got comment_reply)
|
||||||
|
const parentUserId = parentAuthor.length > 0 ? parentAuthor[0].user_id : -1;
|
||||||
|
|
||||||
|
subscribers.forEach(s => {
|
||||||
|
if (s.user_id !== req.session.id && s.user_id !== parentUserId) {
|
||||||
|
notificationsToAdd.push({
|
||||||
|
user_id: s.user_id,
|
||||||
|
type: 'subscription',
|
||||||
|
item_id: item_id,
|
||||||
|
reference_id: commentId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 4. Batch insert
|
// 4. Batch insert
|
||||||
if (recipients.size > 0) {
|
if (notificationsToAdd.length > 0) {
|
||||||
const notificationsToAdd = Array.from(recipients).map(uid => ({
|
|
||||||
user_id: uid,
|
|
||||||
type: 'comment_reply',
|
|
||||||
item_id: item_id,
|
|
||||||
reference_id: commentId
|
|
||||||
}));
|
|
||||||
|
|
||||||
await db`INSERT INTO notifications ${db(notificationsToAdd)}`;
|
await db`INSERT INTO notifications ${db(notificationsToAdd)}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user