Browse Source

Always render the OMEMO lock icon

When OMEMO isn't possible, render it as grey.

This change makes OMEMO for MUCs easier, since there I anticipate that
OMEMO support might change dynamically based on who enters/exits the
room.

updates #1180
JC Brand 6 years ago
parent
commit
d5485d09ae

+ 2 - 0
CHANGES.md

@@ -3,6 +3,8 @@
 ## 4.0.7 (Unreleased)
 
 - Bugfix: MUC commands were being ignored
+- UI: Always show the OMEMO lock icon (grayed out if not available).
+- #1374 Can't load embedded chat when changing `view_mode` between page reloads
 
 ## 4.0.6 (2018-12-07)
 

+ 3 - 2
css/converse.css

@@ -10331,6 +10331,8 @@ body.reset {
       #conversejs .chatbox .sendXMPPMessage .chat-toolbar .fas, #conversejs .chatbox .sendXMPPMessage .chat-toolbar .fas:hover {
         color: var(--chat-head-color);
         font-size: var(--font-size-large); }
+      #conversejs .chatbox .sendXMPPMessage .chat-toolbar .disabled {
+        color: var(--text-color-lighten-15-percent) !important; }
       #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted a,
       #conversejs .chatbox .sendXMPPMessage .chat-toolbar .unencrypted {
         color: var(--text-color); }
@@ -10873,8 +10875,7 @@ body.reset {
       line-height: normal; }
       #conversejs #controlbox .controlbox-pane .controlbox-padded .change-status {
         min-width: 25px;
-        text-align: center;
-      }
+        text-align: center; }
     #conversejs #controlbox .controlbox-pane .add-converse-contact {
       margin: 0 0 0.75em 0; }
     #conversejs #controlbox .controlbox-pane .chatbox-btn {

+ 49 - 17
dist/converse.js

@@ -56472,6 +56472,20 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins
         'click .toggle-omemo': 'toggleOMEMO'
       },
 
+      initialize() {
+        this.__super__.initialize.apply(this, arguments);
+
+        this.model.on('change:omemo_active', this.renderOMEMOToolbarButton, this);
+        this.model.on('change:omemo_supported', this.onOMEMOSupportedDetermined, this);
+        this.checkOMEMOSupported();
+      },
+
+      async checkOMEMOSupported() {
+        const _converse = this.__super__._converse;
+        const supported = await _converse.contactHasOMEMOSupport(this.model.get('jid'));
+        this.model.set('omemo_supported', supported);
+      },
+
       showMessage(message) {
         // We don't show a message if it's only keying material
         if (!message.get('is_only_key')) {
@@ -56479,31 +56493,41 @@ _converse_headless_converse_core__WEBPACK_IMPORTED_MODULE_0__["default"].plugins
         }
       },
 
-      async renderOMEMOToolbarButton() {
-        const _converse = this.__super__._converse,
-              __ = _converse.__;
-        const support = await _converse.contactHasOMEMOSupport(this.model.get('jid'));
+      onOMEMOSupportedDetermined() {
+        if (!this.model.get('omemo_supported') && this.model.get('omemo_active')) {
+          this.model.set('omemo_active', false); // Will cause render
+        } else {
+          this.renderOMEMOToolbarButton();
+        }
+      },
 
-        if (support) {
-          const icon = this.el.querySelector('.toggle-omemo'),
-                html = templates_toolbar_omemo_html__WEBPACK_IMPORTED_MODULE_1___default()(_.extend(this.model.toJSON(), {
-            '__': __
-          }));
+      renderOMEMOToolbarButton() {
+        const _converse = this.__super__._converse,
+              __ = _converse.__,
+              icon = this.el.querySelector('.toggle-omemo'),
+              html = templates_toolbar_omemo_html__WEBPACK_IMPORTED_MODULE_1___default()(_.extend(this.model.toJSON(), {
+          '__': __
+        }));
 
-          if (icon) {
-            icon.outerHTML = html;
-          } else {
-            this.el.querySelector('.chat-toolbar').insertAdjacentHTML('beforeend', html);
-          }
+        if (icon) {
+          icon.outerHTML = html;
+        } else {
+          this.el.querySelector('.chat-toolbar').insertAdjacentHTML('beforeend', html);
         }
       },
 
       toggleOMEMO(ev) {
+        const _converse = this.__super__._converse,
+              __ = _converse.__;
+
+        if (!this.model.get('omemo_supported')) {
+          return _converse.api.alert.show(Strophe.LogLevel.ERROR, __('Error'), [__(`Cannot use end-to-end encryption because %1$s uses a client that doesn't support OMEMO.`, this.model.contact.getDisplayName())]);
+        }
+
         ev.preventDefault();
         this.model.save({
           'omemo_active': !this.model.get('omemo_active')
         });
-        this.renderOMEMOToolbarButton();
       }
 
     }
@@ -67162,6 +67186,10 @@ _converse_core__WEBPACK_IMPORTED_MODULE_6__["default"].plugins.add('converse-muc
 
       isMember() {
         return _.includes(['admin', 'owner', 'member'], this.get('affiliation'));
+      },
+
+      isSelf() {
+        return this.get('states').includes('110');
       }
 
     });
@@ -94708,13 +94736,17 @@ var _ = {escape:__webpack_require__(/*! ./node_modules/lodash/escape.js */ "./no
 module.exports = function(o) {
 var __t, __p = '', __e = _.escape, __j = Array.prototype.join;
 function print() { __p += __j.call(arguments, '') }
-__p += '<!-- src/templates/toolbar_omemo.html -->\n<li class="toggle-omemo fa ';
+__p += '<!-- src/templates/toolbar_omemo.html -->\n<li class="toggle-omemo fa \n        ';
+ if (!o.omemo_supported) { ;
+__p += ' disabled ';
+ } ;
+__p += '\n        ';
  if (o.omemo_active) { ;
 __p += ' fa-lock ';
  } else { ;
 __p += ' fa-unlock ';
  } ;
-__p += '" title="' +
+__p += '"\n    title="' +
 __e(o.__('Messages are being sent in plaintext')) +
 '"></li>\n';
 return __p

+ 3 - 0
sass/_chatbox.scss

@@ -307,6 +307,9 @@
                     color: var(--chat-head-color);
                     font-size: var(--font-size-large);
                 }
+                .disabled {
+                    color: var(--text-color-lighten-15-percent) !important;
+                }
                 .unencrypted a,
                 .unencrypted {
                     color: var(--text-color);

+ 1 - 1
spec/chatbox.js

@@ -421,7 +421,7 @@
                     expect(view).toBeDefined();
                     const toolbar = view.el.querySelector('ul.chat-toolbar');
                     expect(_.isElement(toolbar)).toBe(true);
-                    expect(toolbar.querySelectorAll(':scope > li').length).toBe(1);
+                    expect(toolbar.querySelectorAll(':scope > li').length).toBe(2);
                     done();
                 }));
 

+ 12 - 0
spec/omemo.js

@@ -809,6 +809,18 @@
                 preventDefault: _.noop,
                 keyCode: 13
             });
+
+            view.model.save({'omemo_supported': false});
+            toggle = toolbar.querySelector('.toggle-omemo');
+            expect(u.hasClass('fa-lock', toggle)).toBe(false);
+            expect(u.hasClass('fa-unlock', toggle)).toBe(true);
+            expect(u.hasClass('disabled', toggle)).toBe(true);
+
+            view.model.save({'omemo_supported': true});
+            toggle = toolbar.querySelector('.toggle-omemo');
+            expect(u.hasClass('fa-lock', toggle)).toBe(false);
+            expect(u.hasClass('fa-unlock', toggle)).toBe(true);
+            expect(u.hasClass('disabled', toggle)).toBe(false);
             done();
         }));
 

+ 41 - 12
src/converse-omemo.js

@@ -454,6 +454,19 @@ converse.plugins.add('converse-omemo', {
                 'click .toggle-omemo': 'toggleOMEMO'
             },
 
+            initialize () {
+                this.__super__.initialize.apply(this, arguments);
+                this.model.on('change:omemo_active', this.renderOMEMOToolbarButton, this);
+                this.model.on('change:omemo_supported', this.onOMEMOSupportedDetermined, this);
+                this.checkOMEMOSupported();
+            },
+
+            async checkOMEMOSupported () {
+                const { _converse } = this.__super__;
+                const supported = await _converse.contactHasOMEMOSupport(this.model.get('jid'));
+                this.model.set('omemo_supported', supported);
+            },
+
             showMessage (message) {
                 // We don't show a message if it's only keying material
                 if (!message.get('is_only_key')) {
@@ -461,24 +474,40 @@ converse.plugins.add('converse-omemo', {
                 }
             },
 
-            async renderOMEMOToolbarButton () {
-                const { _converse } = this.__super__, { __ } = _converse;
-                const support = await _converse.contactHasOMEMOSupport(this.model.get('jid'));
-                if (support) {
-                    const icon = this.el.querySelector('.toggle-omemo'),
-                          html = tpl_toolbar_omemo(_.extend(this.model.toJSON(), {'__': __}));
-                    if (icon) {
-                        icon.outerHTML = html;
-                    } else {
-                        this.el.querySelector('.chat-toolbar').insertAdjacentHTML('beforeend', html);
-                    }
+            onOMEMOSupportedDetermined () {
+                if (!this.model.get('omemo_supported') && this.model.get('omemo_active')) {
+                    this.model.set('omemo_active', false); // Will cause render
+                } else {
+                    this.renderOMEMOToolbarButton();
+                }
+            },
+
+            renderOMEMOToolbarButton () {
+                const { _converse } = this.__super__,
+                      { __ } = _converse,
+                      icon = this.el.querySelector('.toggle-omemo'),
+                      html = tpl_toolbar_omemo(_.extend(this.model.toJSON(), {'__': __}));
+
+                if (icon) {
+                    icon.outerHTML = html;
+                } else {
+                    this.el.querySelector('.chat-toolbar').insertAdjacentHTML('beforeend', html);
                 }
             },
 
             toggleOMEMO (ev) {
+                const { _converse } = this.__super__, { __ } = _converse;
+                if (!this.model.get('omemo_supported')) {
+                    return _converse.api.alert.show(
+                        Strophe.LogLevel.ERROR,
+                        __('Error'),
+                        [__(`Cannot use end-to-end encryption because %1$s uses a client that doesn't support OMEMO.`,
+                            this.model.contact.getDisplayName()
+                           )] 
+                    )
+                }
                 ev.preventDefault();
                 this.model.save({'omemo_active': !this.model.get('omemo_active')});
-                this.renderOMEMOToolbarButton();
             }
         }
     },

+ 2 - 2
src/headless/converse-chatboxes.js

@@ -631,11 +631,11 @@ converse.plugins.add('converse-chatboxes', {
             },
 
             registerMessageHandler () {
-                _converse.connection.addHandler((stanza) => {
+                _converse.connection.addHandler(stanza => {
                     this.onMessage(stanza);
                     return true;
                 }, null, 'message', 'chat');
-                _converse.connection.addHandler((stanza) => {
+                _converse.connection.addHandler(stanza => {
                     this.onErrorMessage(stanza);
                     return true;
                 }, null, 'message', 'error');

+ 4 - 0
src/headless/converse-muc.js

@@ -1131,6 +1131,10 @@ converse.plugins.add('converse-muc', {
 
             isMember () {
                 return _.includes(['admin', 'owner', 'member'], this.get('affiliation'));
+            },
+
+            isSelf () {
+                return this.get('states').includes('110');
             }
         });
 

+ 4 - 1
src/templates/toolbar_omemo.html

@@ -1 +1,4 @@
-<li class="toggle-omemo fa {[ if (o.omemo_active) { ]} fa-lock {[ } else { ]} fa-unlock {[ } ]}" title="{{{o.__('Messages are being sent in plaintext')}}}"></li>
+<li class="toggle-omemo fa 
+        {[ if (!o.omemo_supported) { ]} disabled {[ } ]}
+        {[ if (o.omemo_active) { ]} fa-lock {[ } else { ]} fa-unlock {[ } ]}"
+    title="{{{o.__('Messages are being sent in plaintext')}}}"></li>