adding @mention functionality

This commit is contained in:
2026-01-27 14:48:02 +01:00
parent e33115c2d9
commit a52c50198e
2 changed files with 47 additions and 25 deletions

View File

@@ -1208,6 +1208,7 @@ class NotificationSystem {
let typeText = 'Start';
if (n.type === 'comment_reply') typeText = 'replied to you';
else if (n.type === 'subscription') typeText = 'commented in a thread you follow';
else if (n.type === 'mention') typeText = 'highlighted you';
const cid = n.comment_id || n.reference_id;
const link = `/${n.item_id}#c${cid}`;

View File

@@ -191,50 +191,71 @@ export default (router, tpl) => {
const commentId = parseInt(newComment[0].id, 10);
// Notify Subscribers (excluding the author)
// 1. Get subscribers of the item
// 2. If it's a reply, notify parent author? (Optional, complex logic. Let's stick to item subscription for now + Parent author)
// Logic: Notify users who subscribed to this item OR are the parent author.
// Exclude current user.
// 1. Get subscribers
// 1. Get subscribers (existing code)
const subscribers = await db`SELECT user_id FROM comment_subscriptions WHERE item_id = ${item_id}`;
// Mentions Logic: Parse content for @username
// Allow alphanumeric, underscore, dash.
const mentionRegex = /@([a-zA-Z0-9_\-]+)/g;
const matches = [...content.matchAll(mentionRegex)];
const mentionedNames = [...new Set(matches.map(m => m[1]))];
const lowerNames = mentionedNames.map(n => n.toLowerCase());
console.log("DEBUG: Mentions found:", mentionedNames);
let mentionedUsers = [];
if (lowerNames.length > 0) {
// Fetch IDs via login column (lowercase)
mentionedUsers = await db`SELECT id, user FROM "user" WHERE login IN ${db(lowerNames)}`;
console.log("DEBUG: Users resolved:", mentionedUsers);
}
// 2. Get parent author
let parentAuthor = [];
if (parent_id) {
parentAuthor = await db`SELECT user_id FROM comments WHERE id = ${parent_id}`;
}
// 3. Prepare notifications
const notificationsToAdd = [];
// 3. Prepare notifications with priority: Mention > Reply > Subscription
// Use a Map to ensure one notification per user
const notificationsMap = new Map(); // UserId -> { type, ... }
// Parent author gets 'comment_reply'
// A. Mentions
mentionedUsers.forEach(u => {
if (u.id !== req.session.id) {
notificationsMap.set(u.id, 'mention');
}
});
// B. Reply (Parent Author)
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
});
// Only if not already mentioned
if (pid !== req.session.id && !notificationsMap.has(pid)) {
notificationsMap.set(pid, 'comment_reply');
}
}
// Subscribers get 'subscription' (unless they already got comment_reply)
// C. Subscribers
const parentUserId = parentAuthor.length > 0 ? parentAuthor[0].user_id : -1;
subscribers.forEach(s => {
if (s.user_id !== req.session.id && s.user_id !== parentUserId) {
// If not self, and not already notified (as mention or reply)
if (s.user_id !== req.session.id && !notificationsMap.has(s.user_id)) {
notificationsMap.set(s.user_id, 'subscription');
}
});
// Build insert array
const notificationsToAdd = [];
for (const [uid, type] of notificationsMap.entries()) {
notificationsToAdd.push({
user_id: s.user_id,
type: 'subscription',
user_id: uid,
type: type,
item_id: item_id,
reference_id: commentId
});
}
});
// 4. Batch insert
if (notificationsToAdd.length > 0) {