From 362c515f33f8a8e10526635331c5860e961fc160 Mon Sep 17 00:00:00 2001
From: Arpit Jalan <arpit@techapj.com>
Date: Tue, 24 Nov 2015 18:16:42 +0530
Subject: [PATCH] FEATURE: compose a new pre-filled message via URL

---
 .../discourse/mixins/open-composer.js.es6     | 14 ++++++++++-
 .../discourse/routes/app-route-map.js.es6     |  1 +
 .../discourse/routes/application.js.es6       |  6 ++++-
 .../discourse/routes/new-message.js.es6       | 25 +++++++++++++++++++
 app/controllers/static_controller.rb          |  2 +-
 config/locales/client.en.yml                  |  1 +
 config/routes.rb                              |  1 +
 7 files changed, 47 insertions(+), 3 deletions(-)
 create mode 100644 app/assets/javascripts/discourse/routes/new-message.js.es6

diff --git a/app/assets/javascripts/discourse/mixins/open-composer.js.es6 b/app/assets/javascripts/discourse/mixins/open-composer.js.es6
index 3341fa3dd..d2e79622b 100644
--- a/app/assets/javascripts/discourse/mixins/open-composer.js.es6
+++ b/app/assets/javascripts/discourse/mixins/open-composer.js.es6
@@ -12,7 +12,7 @@ export default Ember.Mixin.create({
     });
   },
 
-  openComposerWithParams(controller, topicTitle, topicBody, topicCategoryId, topicCategory) {
+  openComposerWithTopicParams(controller, topicTitle, topicBody, topicCategoryId, topicCategory) {
     const Composer = require('discourse/models/composer').default;
     this.controllerFor('composer').open({
       action: Composer.CREATE_TOPIC,
@@ -23,6 +23,18 @@ export default Ember.Mixin.create({
       draftKey: controller.get('model.draft_key'),
       draftSequence: controller.get('model.draft_sequence')
     });
+  },
+
+  openComposerWithMessageParams(usernames, topicTitle, topicBody) {
+    const Composer = require('discourse/models/composer').default;
+    this.controllerFor('composer').open({
+      action: Composer.PRIVATE_MESSAGE,
+      usernames,
+      topicTitle,
+      topicBody,
+      archetypeId: 'private_message',
+      draftKey: 'new_private_message'
+    });
   }
 
 });
diff --git a/app/assets/javascripts/discourse/routes/app-route-map.js.es6 b/app/assets/javascripts/discourse/routes/app-route-map.js.es6
index 34f0a98b4..64078554f 100644
--- a/app/assets/javascripts/discourse/routes/app-route-map.js.es6
+++ b/app/assets/javascripts/discourse/routes/app-route-map.js.es6
@@ -93,6 +93,7 @@ export default function() {
   this.route('guidelines', {path: '/guidelines'});
 
   this.route('new-topic', {path: '/new-topic'});
+  this.route('new-message', {path: '/new-message'});
 
   this.resource('badges', function() {
     this.route('show', {path: '/:id/:slug'});
diff --git a/app/assets/javascripts/discourse/routes/application.js.es6 b/app/assets/javascripts/discourse/routes/application.js.es6
index 7175aa864..8c1637b7a 100644
--- a/app/assets/javascripts/discourse/routes/application.js.es6
+++ b/app/assets/javascripts/discourse/routes/application.js.es6
@@ -145,7 +145,11 @@ const ApplicationRoute = Discourse.Route.extend(OpenComposer, {
     },
 
     createNewTopicViaParams(title, body, category_id, category) {
-      this.openComposerWithParams(this.controllerFor('discovery/topics'), title, body, category_id, category);
+      this.openComposerWithTopicParams(this.controllerFor('discovery/topics'), title, body, category_id, category);
+    },
+
+    createNewMessageViaParams(username, title, body) {
+      this.openComposerWithMessageParams(username, title, body);
     }
   },
 
diff --git a/app/assets/javascripts/discourse/routes/new-message.js.es6 b/app/assets/javascripts/discourse/routes/new-message.js.es6
new file mode 100644
index 000000000..845d10e88
--- /dev/null
+++ b/app/assets/javascripts/discourse/routes/new-message.js.es6
@@ -0,0 +1,25 @@
+export default Discourse.Route.extend({
+  beforeModel: function(transition) {
+    const self = this;
+    if (Discourse.User.current()) {
+      // User is logged in
+      self.replaceWith('discovery.latest').then(function(e) {
+        Discourse.User.findByUsername(transition.queryParams.username).then((user) => {
+          if (user.can_send_private_message_to_user) {
+            Ember.run.next(function() {
+              e.send('createNewMessageViaParams', user.username, transition.queryParams.title, transition.queryParams.body);
+            });
+          } else {
+            bootbox.alert(I18n.t("composer.cant_send_pm", {username: user.username}));
+          }
+        }).catch((error) => {
+          bootbox.alert(I18n.t("generic_error"));
+        });
+      });
+    } else {
+      // User is not logged in
+      self.session.set("shouldRedirectToUrl", window.location.href);
+      self.replaceWith('login');
+    }
+  }
+});
diff --git a/app/controllers/static_controller.rb b/app/controllers/static_controller.rb
index 3387e8c36..031e278e9 100644
--- a/app/controllers/static_controller.rb
+++ b/app/controllers/static_controller.rb
@@ -75,7 +75,7 @@ class StaticController < ApplicationController
            uri.path !~ /\./
 
           destination = uri.path
-          destination = "#{uri.path}?#{uri.query}" if uri.path =~ /new-topic/
+          destination = "#{uri.path}?#{uri.query}" if uri.path =~ /new-topic/ || uri.path =~ /new-message/
         end
       rescue URI::InvalidURIError
         # Do nothing if the URI is invalid
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index eacc34f2f..413fead1a 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -907,6 +907,7 @@ en:
       toggler: "hide or show the composer panel"
       modal_ok: "OK"
       modal_cancel: "Cancel"
+      cant_send_pm: "Sorry, you can't send a message to %{username}."
 
       admin_options_title: "Optional staff settings for this topic"
       auto_close:
diff --git a/config/routes.rb b/config/routes.rb
index df8e88d41..2fc80e4eb 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -463,6 +463,7 @@ Discourse::Application.routes.draw do
   get 'embed/info' => 'embed#info'
 
   get "new-topic" => "list#latest"
+  get "new-message" => "list#latest"
 
   # Topic routes
   get "t/id_for/:slug" => "topics#id_for_slug"