diff --git a/app/assets/javascripts/discourse/controllers/flag_action_type_controller.js b/app/assets/javascripts/discourse/controllers/flag_action_type_controller.js new file mode 100644 index 00000000000..c099bd022d7 --- /dev/null +++ b/app/assets/javascripts/discourse/controllers/flag_action_type_controller.js @@ -0,0 +1,48 @@ +/** + Supports logic for flags in the modal + + @class FlagActionTypeController + @extends Discourse.ObjectController + @namespace Discourse + @module Discourse +**/ +Discourse.FlagActionTypeController = Discourse.ObjectController.extend({ + needs: ['flag'], + + message: Em.computed.alias('controllers.flag.message'), + + customPlaceholder: function(){ + return Em.String.i18n("flagging.custom_placeholder_" + this.get('name_key')); + }.property('name_key'), + + formattedName: function(){ + return this.get('name').replace("{{username}}", this.get('controllers.flag.username')); + }.property('name'), + + selected: function() { + return this.get('model') === this.get('controllers.flag.selected'); + }.property('controllers.flag.selected'), + + showMessageInput: Em.computed.and('is_custom_flag', 'selected'), + showDescription: Em.computed.not('showMessageInput'), + + customMessageLengthClasses: function() { + return (this.get('message.length') < Discourse.PostActionType.MIN_MESSAGE_LENGTH) ? "too-short" : "ok" + }.property('message.length'), + + customMessageLength: function() { + var len = this.get('message.length') || 0; + var minLen = Discourse.PostActionType.MIN_MESSAGE_LENGTH; + if (len === 0) { + return Em.String.i18n("flagging.custom_message.at_least", { n: minLen }); + } else if (len < minLen) { + return Em.String.i18n("flagging.custom_message.more", { n: minLen - len }); + } else { + return Em.String.i18n("flagging.custom_message.left", { + n: Discourse.PostActionType.MAX_MESSAGE_LENGTH - len + }); + } + }.property('message.length') + +}); + diff --git a/app/assets/javascripts/discourse/controllers/flag_controller.js b/app/assets/javascripts/discourse/controllers/flag_controller.js index fe014fb3dbc..0d1d6c85fbd 100644 --- a/app/assets/javascripts/discourse/controllers/flag_controller.js +++ b/app/assets/javascripts/discourse/controllers/flag_controller.js @@ -9,70 +9,58 @@ **/ Discourse.FlagController = Discourse.ObjectController.extend(Discourse.ModalFunctionality, { - // trick to bind user / post to flag - boundFlags: function() { - var _this = this; - var original = this.get('flagsAvailable'); - if(original){ - return $.map(original, function(v){ - var b = Discourse.BoundPostActionType.create(v); - b.set('post', _this.get('model')); - return b; - }); - } - }.property('flagsAvailable.@each'), - changePostActionType: function(action) { - if (this.get('postActionTypeId') === action.id) return false; - - this.get('boundFlags').setEach('selected', false); - action.set('selected', true); - - this.set('postActionTypeId', action.id); - this.set('isCustomFlag', action.is_custom_flag); this.set('selected', action); - return false; }, - showSubmit: function() { - if (this.get('postActionTypeId')) { - if (this.get('isCustomFlag')) { - var m = this.get('selected.message'); - return m && m.length >= 10 && m.length <= 500; - } else { - return true; - } + submitEnabled: function() { + var selected = this.get('selected'); + if (!selected) return false; + + if (selected.get('is_custom_flag')) { + var len = this.get('message.length') || 0; + return len >= Discourse.PostActionType.MIN_MESSAGE_LENGTH && + len <= Discourse.PostActionType.MAX_MESSAGE_LENGTH; } - return false; - }.property('isCustomFlag', 'selected.customMessageLength', 'postActionTypeId'), + return true; + }.property('selected.is_custom_flag', 'message.length'), + + submitDisabled: Em.computed.not('submitEnabled'), + + // Staff accounts can "take action" + canTakeAction: function() { + // We can only take actions on non-custom flags + if (this.get('selected.is_custom_flag')) return false; + return Discourse.User.current('staff'); + }.property('selected.is_custom_flag'), submitText: function(){ - var action = this.get('selected'); if (this.get('selected.is_custom_flag')) { return Em.String.i18n("flagging.notify_action"); } else { return Em.String.i18n("flagging.action"); } - }.property('selected'), + }.property('selected.is_custom_flag'), - createFlag: function() { - var _this = this; + takeAction: function() { + this.createFlag({takeAction: true}) + this.set('hidden', true); + }, - var action = this.get('selected'); - var postAction = this.get('actionByName.' + (action.get('name_key'))); + createFlag: function(opts) { + var flagController = this; + var postAction = this.get('actionByName.' + this.get('selected.name_key')); + var params = this.get('selected.is_custom_flag') ? {message: this.get('message')} : {} - var actionType = Discourse.Site.instance().postActionTypeById(this.get('postActionTypeId')); - if (postAction) { - postAction.act({ - message: action.get('message') - }).then(function() { - return $('#discourse-modal').modal('hide'); - }, function(errors) { - return _this.displayErrors(errors); - }); - } - return false; + if (opts) params = $.extend(params, opts); + + postAction.act(params).then(function() { + flagController.closeModal(); + }, function(errors) { + flagController.displayErrors(errors); + }); } + }); diff --git a/app/assets/javascripts/discourse/controllers/modal_controller.js b/app/assets/javascripts/discourse/controllers/modal_controller.js index 0659c14533c..9ad491122c0 100644 --- a/app/assets/javascripts/discourse/controllers/modal_controller.js +++ b/app/assets/javascripts/discourse/controllers/modal_controller.js @@ -8,6 +8,16 @@ **/ Discourse.ModalController = Discourse.Controller.extend({ + /** + Close the modal. + + @method closeModal + **/ + closeModal: function() { + // Currently uses jQuery to hide it. + $('#discourse-modal').modal('hide'); + } + }); diff --git a/app/assets/javascripts/discourse/mixins/modal_functionality.js b/app/assets/javascripts/discourse/mixins/modal_functionality.js index acb22820496..7ddac0f78bd 100644 --- a/app/assets/javascripts/discourse/mixins/modal_functionality.js +++ b/app/assets/javascripts/discourse/mixins/modal_functionality.js @@ -21,6 +21,16 @@ Discourse.ModalFunctionality = Em.Mixin.create({ message: message, messageClass: messageClass })); + }, + + /** + Close the modal. + + @method closeModal + **/ + closeModal: function() { + // Currently uses jQuery to hide it. + this.get('controllers.modal').closeModal(); } }); diff --git a/app/assets/javascripts/discourse/models/action_summary.js b/app/assets/javascripts/discourse/models/action_summary.js index e21152ceaa8..7b6cc03597a 100644 --- a/app/assets/javascripts/discourse/models/action_summary.js +++ b/app/assets/javascripts/discourse/models/action_summary.js @@ -37,6 +37,8 @@ Discourse.ActionSummary = Discourse.Model.extend({ // Perform this action act: function(opts) { + if (!opts) opts = {}; + var action = this.get('actionType.name_key'); // Mark it as acted @@ -63,7 +65,8 @@ Discourse.ActionSummary = Discourse.Model.extend({ data: { id: this.get('post.id'), post_action_type_id: this.get('id'), - message: (opts ? opts.message : void 0) || "" + message: opts.message, + take_action: opts.takeAction } }).then(null, function (error) { actionSummary.removeAction(); diff --git a/app/assets/javascripts/discourse/models/post_action_type.js b/app/assets/javascripts/discourse/models/post_action_type.js index 25bd5937147..4ff10880aae 100644 --- a/app/assets/javascripts/discourse/models/post_action_type.js +++ b/app/assets/javascripts/discourse/models/post_action_type.js @@ -6,31 +6,9 @@ @namespace Discourse @module Discourse **/ -Discourse.PostActionType = Discourse.Model.extend({ -}); +Discourse.PostActionType = Discourse.Model.extend({}); -Discourse.BoundPostActionType = Discourse.PostActionType.extend({ - customPlaceholder: function(){ - return Em.String.i18n("flagging.custom_placeholder_" + this.get('name_key')); - }.property('name_key'), - - formattedName: function(){ - return this.get('name').replace("{{username}}", this.get('post.username')); - }.property('name'), - - messageChanged: function() { - var len, message, minLen, _ref; - minLen = 10; - len = ((_ref = this.get('message')) ? _ref.length : void 0) || 0; - this.set("customMessageLengthClasses", "too-short custom-message-length"); - if (len === 0) { - message = Em.String.i18n("flagging.custom_message.at_least", { n: minLen }); - } else if (len < minLen) { - message = Em.String.i18n("flagging.custom_message.more", { n: minLen - len }); - } else { - message = Em.String.i18n("flagging.custom_message.left", { n: 500 - len }); - this.set("customMessageLengthClasses", "ok custom-message-length"); - } - this.set("customMessageLength", message); - }.observes("message") -}); +Discourse.PostActionType.reopenClass({ + MIN_MESSAGE_LENGTH: 10, + MAX_MESSAGE_LENGTH: 500 +}) diff --git a/app/assets/javascripts/discourse/routes/topic_route.js b/app/assets/javascripts/discourse/routes/topic_route.js index 5129bdabb22..61f92900781 100644 --- a/app/assets/javascripts/discourse/routes/topic_route.js +++ b/app/assets/javascripts/discourse/routes/topic_route.js @@ -13,9 +13,7 @@ Discourse.TopicRoute = Discourse.Route.extend({ showFlags: function(post) { Discourse.Route.showModal(this, 'flag', post); - this.controllerFor('flag').setProperties({ - postActionTypeId: null - }); + this.controllerFor('flag').setProperties({ selected: null }); }, showAutoClose: function() { diff --git a/app/assets/javascripts/discourse/templates/modal/archetype_options.js.handlebars b/app/assets/javascripts/discourse/templates/modal/archetype_options.js.handlebars index 1c638975c99..80fed824d2c 100644 --- a/app/assets/javascripts/discourse/templates/modal/archetype_options.js.handlebars +++ b/app/assets/javascripts/discourse/templates/modal/archetype_options.js.handlebars @@ -1,8 +1,8 @@ -