diff --git a/app/assets/javascripts/discourse/components/composer-editor.js.es6 b/app/assets/javascripts/discourse/components/composer-editor.js.es6 index 9cc3120bb16..51a7a8fe143 100644 --- a/app/assets/javascripts/discourse/components/composer-editor.js.es6 +++ b/app/assets/javascripts/discourse/components/composer-editor.js.es6 @@ -114,6 +114,25 @@ export default Ember.Component.extend({ _renderUnseen: function($preview, unseen) { fetchUnseenMentions($preview, unseen, this.siteSettings).then(() => { linkSeenMentions($preview, this.siteSettings); + this._warnMentionedGroups($preview); + }); + }, + + _warnMentionedGroups($preview) { + Ember.run.scheduleOnce('afterRender', () => { + this._warnedMentions = this._warnedMentions || []; + var found = []; + $preview.find('.mention-group.notify').each((idx,e) => { + const $e = $(e); + var name = $e.data('name'); + found.push(name); + if (this._warnedMentions.indexOf(name) === -1){ + this._warnedMentions.push(name); + this.sendAction('groupsMentioned', [{name: name, user_count: $e.data('mentionable-user-count')}]); + } + }); + + this._warnedMentions = found; }); }, @@ -370,6 +389,8 @@ export default Ember.Component.extend({ Ember.run.debounce(this, this._renderUnseen, $preview, unseen, 500); } + this._warnMentionedGroups($preview); + const post = this.get('composer.post'); let refresh = false; diff --git a/app/assets/javascripts/discourse/controllers/composer-messages.js.es6 b/app/assets/javascripts/discourse/controllers/composer-messages.js.es6 index 345837474f2..7a712ba7487 100644 --- a/app/assets/javascripts/discourse/controllers/composer-messages.js.es6 +++ b/app/assets/javascripts/discourse/controllers/composer-messages.js.es6 @@ -48,6 +48,23 @@ export default Ember.ArrayController.extend({ this.get('queuedForTyping').forEach(msg => this.send("popup", msg)); }, + groupsMentioned(groups) { + // reset existing messages, this should always win it is critical + this.reset(); + groups.forEach(group => { + const msg = I18n.t('composer.group_mentioned', { + group: "@" + group.name, + count: group.user_count, + group_link: Discourse.getURL(`/group/${group.name}/members`) + }); + this.send("popup", + Em.Object.create({ + templateName: 'composer/group-mentioned', + body: msg}) + ); + }); + }, + // Figure out if there are any messages that should be displayed above the composer. queryFor(composer) { if (this.get('checkedMessages')) { return; } diff --git a/app/assets/javascripts/discourse/controllers/composer.js.es6 b/app/assets/javascripts/discourse/controllers/composer.js.es6 index d4b15a0af70..822c833010c 100644 --- a/app/assets/javascripts/discourse/controllers/composer.js.es6 +++ b/app/assets/javascripts/discourse/controllers/composer.js.es6 @@ -171,6 +171,12 @@ export default Ember.Controller.extend({ } }, + groupsMentioned(groups) { + if (!this.get('model.creatingPrivateMessage') && !this.get('model.topic.isPrivateMessage')) { + this.get('controllers.composer-messages').groupsMentioned(groups); + } + } + }, categories: function() { diff --git a/app/assets/javascripts/discourse/lib/link-mentions.js.es6 b/app/assets/javascripts/discourse/lib/link-mentions.js.es6 index 0dfa36adba2..476ae64fc45 100644 --- a/app/assets/javascripts/discourse/lib/link-mentions.js.es6 +++ b/app/assets/javascripts/discourse/lib/link-mentions.js.es6 @@ -1,8 +1,13 @@ function replaceSpan($e, username, opts) { if (opts && opts.group) { + var extra = "", extraClass = ""; + if (opts.mentionable) { + extra = " data-name='" + username + "' data-mentionable-user-count='" + opts.mentionable.user_count + "' "; + extraClass = " notify"; + } $e.replaceWith("@" + username + ""); + "' class='mention-group" + extraClass + "'" + extra + ">@" + username + ""); } else { $e.replaceWith(" +{{{body}}} diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 8c28d3f1883..213442d11d2 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -206,13 +206,21 @@ class UsersController < ApplicationController usernames.each(&:downcase!) groups = Group.where(name: usernames).pluck(:name) + mentionable_groups = + if current_user + Group.mentionable(current_user) + .where(name: usernames) + .pluck(:name, :user_count) + .map{ |name,user_count| {name: name, user_count: user_count} } + end + usernames -= groups result = User.where(staged: false) .where(username_lower: usernames) .pluck(:username_lower) - render json: {valid: result, valid_groups: groups} + render json: {valid: result, valid_groups: groups, mentionable_groups: mentionable_groups} end def render_available_true diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index e8b5454a956..e66c1f214e4 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -850,6 +850,8 @@ en: similar_topics: "Your topic is similar to..." drafts_offline: "drafts offline" + group_mentioned: "By using {{group}}, you are about to notify {{count}} people." + error: title_missing: "Title is required" title_too_short: "Title must be at least {{min}} characters"