diff options
-rwxr-xr-x | client/components/main/editor.js | 18 | ||||
-rw-r--r-- | i18n/en.i18n.json | 1 | ||||
-rw-r--r-- | models/activities.js | 50 | ||||
-rw-r--r-- | models/cards.js | 1 | ||||
-rw-r--r-- | models/users.js | 1 |
5 files changed, 44 insertions, 27 deletions
diff --git a/client/components/main/editor.js b/client/components/main/editor.js index b1725227..39c03aa9 100755 --- a/client/components/main/editor.js +++ b/client/components/main/editor.js @@ -94,7 +94,13 @@ Template.editor.onRendered(() => { currentBoard .activeMembers() .map(member => { - const username = Users.findOne(member.userId).username; + const user = Users.findOne(member.userId); + if (user._id === Meteor.userId()) { + return null; + } + const value = user.username; + const username = + value && value.match(/\s+/) ? `"${value}"` : value; return username.includes(term) ? username : null; }) .filter(Boolean), @@ -120,9 +126,10 @@ Template.editor.onRendered(() => { ? [ ['view', ['fullscreen']], ['table', ['table']], - ['font', ['bold', 'underline']], - //['fontsize', ['fontsize']], + ['font', ['bold']], ['color', ['color']], + ['insert', ['video']], // iframe tag will be sanitized TODO if iframe[class=note-video-clip] can be added into safe list, insert video can be enabled + //['fontsize', ['fontsize']], ] : [ ['style', ['style']], @@ -345,11 +352,12 @@ Blaze.Template.registerHelper( } return member; }); - const mentionRegex = /\B@([\w.]*)/gi; + const mentionRegex = /\B@(?:(?:"([\w.\s]*)")|([\w.]+))/gi; // including space in username let currentMention; while ((currentMention = mentionRegex.exec(content)) !== null) { - const [fullMention, username] = currentMention; + const [fullMention, quoteduser, simple] = currentMention; + const username = quoteduser || simple; const knowedUser = _.findWhere(knowedUsers, { username }); if (!knowedUser) { continue; diff --git a/i18n/en.i18n.json b/i18n/en.i18n.json index 1adee4fc..44304305 100644 --- a/i18n/en.i18n.json +++ b/i18n/en.i18n.json @@ -731,6 +731,7 @@ "almostdue": "current due time %s is approaching", "pastdue": "current due time %s is past", "duenow": "current due time %s is today", + "act-newDue": "__card__ has 1st due reminder [__board__]", "act-withDue": "__card__ due reminders [__board__]", "act-almostdue": "was reminding the current due (__timeValue__) of __card__ is approaching", "act-pastdue": "was reminding the current due (__timeValue__) of __card__ is past", diff --git a/models/activities.js b/models/activities.js index dcabfbc2..cb1dddaf 100644 --- a/models/activities.js +++ b/models/activities.js @@ -180,28 +180,34 @@ if (Meteor.isServer) { const comment = activity.comment(); params.comment = comment.text; if (board) { - const atUser = /(?:^|>|\b|\s)@(\S+?)(?:\s|$|<|\b)/g; const comment = params.comment; - if (comment.match(atUser)) { - const commenter = params.user; - while (atUser.exec(comment)) { - const username = RegExp.$1; - if (commenter === username) { - // it's person at himself, ignore it? - continue; - } - const atUser = - Users.findOne(username) || Users.findOne({ username }); - if (atUser && atUser._id) { - const uid = atUser._id; - params.atUsername = username; - params.atEmails = atUser.emails; - if (board.hasMember(uid)) { - title = 'act-atUserComment'; - watchers = _.union(watchers, [uid]); - } - } + const knownUsers = board.members.map(member => { + const u = Users.findOne(member.userId); + if (u) { + member.username = u.username; + member.emails = u.emails; } + return member; + }); + const mentionRegex = /\B@(?:(?:"([\w.\s]*)")|([\w.]+))/gi; // including space in username + let currentMention; + while ((currentMention = mentionRegex.exec(comment)) !== null) { + /*eslint no-unused-vars: ["error", { "varsIgnorePattern": "[iI]gnored" }]*/ + const [ignored, quoteduser, simple] = currentMention; + const username = quoteduser || simple; + if (username === params.user) { + // ignore commenter mention himself? + continue; + } + const atUser = _.findWhere(knownUsers, { username }); + if (!atUser) { + continue; + } + const uid = atUser.userId; + params.atUsername = username; + params.atEmails = atUser.emails; + title = 'act-atUserComment'; + watchers = _.union(watchers, [uid]); } } params.commentId = comment._id; @@ -236,8 +242,8 @@ if (Meteor.isServer) { (!activity.timeKey || activity.timeKey === 'dueAt') && activity.timeValue ) { - // due time reminder - title = 'act-withDue'; + // due time reminder, if it doesn't have old value, it's a brand new set, need some differentiation + title = activity.timeOldValue ? 'act-withDue' : 'act-newDue'; } ['timeValue', 'timeOldValue'].forEach(key => { // copy time related keys & values to params diff --git a/models/cards.js b/models/cards.js index 1414f6d7..d30baaf1 100644 --- a/models/cards.js +++ b/models/cards.js @@ -1558,6 +1558,7 @@ function cardRemover(userId, doc) { const findDueCards = days => { const seekDue = ($from, $to, activityType) => { Cards.find({ + archived: false, dueAt: { $gte: $from, $lt: $to }, }).forEach(card => { const username = Users.findOne(card.userId).username; diff --git a/models/users.js b/models/users.js index ded864e5..93fb409e 100644 --- a/models/users.js +++ b/models/users.js @@ -561,6 +561,7 @@ Users.mutations({ Meteor.methods({ setUsername(username, userId) { check(username, String); + check(userId, String); const nUsersWithUsername = Users.find({ username }).count(); if (nUsersWithUsername > 0) { throw new Meteor.Error('username-already-taken'); |