adding @mention functionality
This commit is contained in:
@@ -1208,6 +1208,7 @@ class NotificationSystem {
|
|||||||
let typeText = 'Start';
|
let typeText = 'Start';
|
||||||
if (n.type === 'comment_reply') typeText = 'replied to you';
|
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 === '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 cid = n.comment_id || n.reference_id;
|
||||||
const link = `/${n.item_id}#c${cid}`;
|
const link = `/${n.item_id}#c${cid}`;
|
||||||
|
|||||||
@@ -191,51 +191,72 @@ export default (router, tpl) => {
|
|||||||
const commentId = parseInt(newComment[0].id, 10);
|
const commentId = parseInt(newComment[0].id, 10);
|
||||||
|
|
||||||
// Notify Subscribers (excluding the author)
|
// Notify Subscribers (excluding the author)
|
||||||
// 1. Get subscribers of the item
|
// 1. Get subscribers (existing code)
|
||||||
// 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
|
|
||||||
const subscribers = await db`SELECT user_id FROM comment_subscriptions WHERE item_id = ${item_id}`;
|
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
|
// 2. Get parent author
|
||||||
let parentAuthor = [];
|
let parentAuthor = [];
|
||||||
if (parent_id) {
|
if (parent_id) {
|
||||||
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. Prepare notifications
|
// 3. Prepare notifications with priority: Mention > Reply > Subscription
|
||||||
const notificationsToAdd = [];
|
// 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) {
|
if (parentAuthor.length > 0) {
|
||||||
const pid = parentAuthor[0].user_id;
|
const pid = parentAuthor[0].user_id;
|
||||||
if (pid !== req.session.id) {
|
// Only if not already mentioned
|
||||||
notificationsToAdd.push({
|
if (pid !== req.session.id && !notificationsMap.has(pid)) {
|
||||||
user_id: pid,
|
notificationsMap.set(pid, 'comment_reply');
|
||||||
type: 'comment_reply',
|
|
||||||
item_id: item_id,
|
|
||||||
reference_id: commentId
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Subscribers get 'subscription' (unless they already got comment_reply)
|
// C. Subscribers
|
||||||
const parentUserId = parentAuthor.length > 0 ? parentAuthor[0].user_id : -1;
|
const parentUserId = parentAuthor.length > 0 ? parentAuthor[0].user_id : -1;
|
||||||
|
|
||||||
subscribers.forEach(s => {
|
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)
|
||||||
notificationsToAdd.push({
|
if (s.user_id !== req.session.id && !notificationsMap.has(s.user_id)) {
|
||||||
user_id: s.user_id,
|
notificationsMap.set(s.user_id, 'subscription');
|
||||||
type: 'subscription',
|
|
||||||
item_id: item_id,
|
|
||||||
reference_id: commentId
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Build insert array
|
||||||
|
const notificationsToAdd = [];
|
||||||
|
for (const [uid, type] of notificationsMap.entries()) {
|
||||||
|
notificationsToAdd.push({
|
||||||
|
user_id: uid,
|
||||||
|
type: type,
|
||||||
|
item_id: item_id,
|
||||||
|
reference_id: commentId
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// 4. Batch insert
|
// 4. Batch insert
|
||||||
if (notificationsToAdd.length > 0) {
|
if (notificationsToAdd.length > 0) {
|
||||||
await db`INSERT INTO notifications ${db(notificationsToAdd)}`;
|
await db`INSERT INTO notifications ${db(notificationsToAdd)}`;
|
||||||
|
|||||||
Reference in New Issue
Block a user