FEATURE: Improve error handling.

FEATURE: Improve error handling.

diff --git a/assets/javascripts/discourse/components/encrypted-checkbox.js.es6 b/assets/javascripts/discourse/components/encrypted-checkbox.js.es6
deleted file mode 100644
index 7774d1a..0000000
--- a/assets/javascripts/discourse/components/encrypted-checkbox.js.es6
+++ /dev/null
@@ -1,22 +0,0 @@
-import computed from "ember-addons/ember-computed-decorators";
-
-export default Ember.Component.extend({
-  tagName: "",
-
-  @computed("checked", "disabled")
-  title(checked, disabled) {
-    if (disabled) {
-      return "encrypt.checkbox.disabled";
-    } else if (checked) {
-      return "encrypt.checkbox.checked";
-    } else {
-      return "encrypt.checkbox.unchecked";
-    }
-  },
-
-  clicked() {
-    if (!this.get("disabled")) {
-      this.set("checked", !this.get("checked"));
-    }
-  }
-});
diff --git a/assets/javascripts/discourse/connectors/composer-action-after/encrypt.hbs b/assets/javascripts/discourse/connectors/composer-action-after/encrypt.hbs
index 2d18d5b..8f1982c 100644
--- a/assets/javascripts/discourse/connectors/composer-action-after/encrypt.hbs
+++ b/assets/javascripts/discourse/connectors/composer-action-after/encrypt.hbs
@@ -1,7 +1,10 @@
-{{#if model.creatingPrivateMessage}}
-  {{#if isEncryptActive}}
-    {{encrypted-checkbox checked=model.isEncrypted disabled=model.isEncryptedDisabled}}
-    {{#if model.encryptError}}
+{{#if isEncryptActive}}
+  {{#if (or model.creatingPrivateMessage model.topic.isPrivateMessage)}}
+    <a {{action clicked}} title={{i18n title}}>
+      {{d-icon (if model.isEncrypted "lock" "unlock") class=(if model.isEncryptedDisabled "disabled")}}
+    </a>
+
+    {{#if model.showEncryptError}}
       <span class="error">{{model.encryptError}}</span>
     {{/if}}
   {{/if}}
diff --git a/assets/javascripts/discourse/connectors/composer-action-after/encrypt.js.es6 b/assets/javascripts/discourse/connectors/composer-action-after/encrypt.js.es6
index fdc78d1..47cd5df 100644
--- a/assets/javascripts/discourse/connectors/composer-action-after/encrypt.js.es6
+++ b/assets/javascripts/discourse/connectors/composer-action-after/encrypt.js.es6
@@ -1,3 +1,4 @@
+import computed from "ember-addons/ember-computed-decorators";
 import {
   ENCRYPT_ACTIVE,
   getEncryptionStatus
@@ -8,20 +9,42 @@ export default {
     const currentUser = Discourse.User.current();
     component.setProperties({
       model: args.model,
+
       /** @var Whether the encryption is active on this device. */
       isEncryptActive: getEncryptionStatus(currentUser) === ENCRYPT_ACTIVE,
-      /** Listens for encryptino status updates. */
+
+      /** Listens for encryption status updates. */
       listener() {
         const newStatus = getEncryptionStatus(currentUser);
         component.set("isEncryptActive", newStatus === ENCRYPT_ACTIVE);
       },
+
       didInsertElement() {
         this._super(...arguments);
         this.appEvents.on("encrypt:status-changed", this.get("listener"));
       },
+
       willDestroyElement() {
         this._super(...arguments);
         this.appEvents.off("encrypt:status-changed", this.get("listener"));
+      },
+
+      @computed("model.isEncrypted", "model.isEncryptedDisabled")
+      title(checked, disabled) {
+        if (disabled) {
+          return "encrypt.checkbox.disabled";
+        } else if (checked) {
+          return "encrypt.checkbox.checked";
+        } else {
+          return "encrypt.checkbox.unchecked";
+        }
+      },
+
+      clicked() {
+        this.set("model.showEncryptError", true);
+        if (!this.get("model.isEncryptedDisabled")) {
+          this.set("model.isEncrypted", !this.get("model.isEncrypted"));
+        }
       }
     });
   }
diff --git a/assets/javascripts/discourse/initializers/hook-composer-controller.js.es6 b/assets/javascripts/discourse/initializers/hook-composer-controller.js.es6
deleted file mode 100644
index cb9dedc..0000000
--- a/assets/javascripts/discourse/initializers/hook-composer-controller.js.es6
+++ /dev/null
@@ -1,35 +0,0 @@
-import Composer from "discourse/controllers/composer";
-import {
-  canEnableEncrypt,
-  ENCRYPT_ACTIVE,
-  getEncryptionStatus
-} from "discourse/plugins/discourse-encrypt/lib/discourse";
-
-export default {
-  name: "hook-composer-controller",
-
-  initialize(container) {
-    const currentUser = container.lookup("current-user:main");
-    if (!canEnableEncrypt(currentUser)) {
-      return;
-    }
-
-    Composer.reopen({
-      open(opts) {
-        // TODO: https://github.com/emberjs/ember.js/issues/15291
-        let { _super } = this;
-
-        if (
-          opts.topic &&
-          opts.topic.get("topic_key") &&
-          getEncryptionStatus(Discourse.User.current()) !== ENCRYPT_ACTIVE
-        ) {
-          bootbox.alert(I18n.t("encrypt.status_inactive"));
-          return;
-        }
-
-        return _super.call(this, ...arguments);
-      }
-    });
-  }
-};
diff --git a/assets/javascripts/discourse/initializers/hook-composer.js.es6 b/assets/javascripts/discourse/initializers/hook-composer.js.es6
index 6225652..115d8a4 100644
--- a/assets/javascripts/discourse/initializers/hook-composer.js.es6
+++ b/assets/javascripts/discourse/initializers/hook-composer.js.es6
@@ -207,9 +207,21 @@ export default {
       @on("init")
       initEncrypt() {
         this.setProperties({
+          isEncryptedDisabled: false,
+          isEncrypted: false,
           encryptError: "",
+          showEncryptError: false
+        });
+      },
+
+      @observes("topic")
+      topicUpdated() {
+        const value = hasTopicKey(this.get("topic.id"));
+        this.setProperties({
           isEncryptedDisabled: false,
-          isEncrypted: false
+          isEncrypted: value,
+          encryptError: value ? "" : I18n.t("encrypt.cannot_encrypt"),
+          showEncryptError: true
         });
       },
 
@@ -218,9 +230,9 @@ export default {
         const usernames = this.get("recipients");
         if (usernames.length === 0) {
           this.setProperties({
-            encryptError: "",
             isEncryptedDisabled: false,
-            isEncrypted: true
+            isEncrypted: true,
+            encryptError: ""
           });
           return;
         }
@@ -232,18 +244,12 @@ export default {
           for (let i = 0; i < usernames.length; ++i) {
             const username = usernames[i];
             if (!userKeys[username]) {
-              // Show the error message only if user is interested in encrypting
-              // the message (i.e. filled the encrypt checkbox).
-              if (this.get("isEncrypted")) {
-                this.set(
-                  "encryptError",
-                  I18n.t("encrypt.composer.user_has_no_key", { username })
-                );
-              }
-
               this.setProperties({
                 isEncryptedDisabled: true,
-                isEncrypted: false
+                isEncrypted: false,
+                encryptError: I18n.t("encrypt.composer.user_has_no_key", {
+                  username
+                })
               });
               return;
             }
@@ -254,9 +260,9 @@ export default {
           // his uncheck.
           if (this.get("isEncryptedDisabled")) {
             this.setProperties({
-              encryptError: "",
               isEncryptedDisabled: false,
-              isEncrypted: true
+              isEncrypted: true,
+              encryptError: ""
             });
           }
         });
diff --git a/assets/javascripts/discourse/initializers/hook-decrypt-post.js.es6 b/assets/javascripts/discourse/initializers/hook-decrypt-post.js.es6
index 2599cb1..5b50e6b 100644
--- a/assets/javascripts/discourse/initializers/hook-decrypt-post.js.es6
+++ b/assets/javascripts/discourse/initializers/hook-decrypt-post.js.es6
@@ -87,7 +87,8 @@ export default {
               iconHTML("times") +
               " " +
               I18n.t("encrypt.decryption_failed") +
-              "</div>";
+              "</div>" +
+              attrs.cooked;

[... diff too long, it was truncated ...]

GitHub sha: 98f02b03