Bug 1552227 - OTR: improve UX of 'Add Finderprint' dialog. r=mkmelin,kaie
--- a/chat/content/otr-add-fingerprint.js
+++ b/chat/content/otr-add-fingerprint.js
@@ -1,47 +1,78 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-const {
- XPCOMUtils,
- l10nHelper,
-} = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
-const {OTR} = ChromeUtils.import("resource:///modules/OTR.jsm");
-
-var args = window.arguments[0].wrappedJSObject;
+var {l10nHelper} = ChromeUtils.import("resource:///modules/imXPCOMUtils.jsm");
+var {OTR} = ChromeUtils.import("resource:///modules/OTR.jsm");
var otrAddFinger = {
async onload() {
- let title = await document.l10n.formatValue(
- "otr-add-finger-name-title", {name: args.screenname});
- document.title = title;
- document.addEventListener("dialogaccept", () => {
- return this.add();
+ let args = window.arguments[0].wrappedJSObject;
+
+ this.fingerWarning = document.getElementById("fingerWarning");
+ this.fingerError = document.getElementById("fingerError");
+ this.keyCount = document.getElementById("keyCount");
+
+ let description = await document.l10n.formatValue(
+ "otr-add-finger-description", { name: args.screenname });
+ document.getElementById("otrDescription").textContent = description;
+
+ let warningTooltip =
+ await document.l10n.formatValue("otr-add-finger-tooltip-error");
+ this.fingerWarning.setAttribute("tooltiptext", warningTooltip);
+
+ document.addEventListener("dialogaccept", (event) => {
+ let hex = document.getElementById("fingerprint").value;
+ let context = OTR.getContextFromRecipient(
+ args.account,
+ args.protocol,
+ args.screenname
+ );
+ let finger = OTR.addFingerprint(context, hex);
+ if (finger.isNull()) {
+ event.preventDefault();
+ return;
+ }
+ try {
+ // Ignore the return, this is just a test.
+ OTR.getUIConvFromContext(context);
+ } catch (error) {
+ // We expect that a conversation may not have been started.
+ context = null;
+ }
+ OTR.setTrust(finger, true, context);
});
- },
- oninput(e) {
- e.value = e.value.replace(/[^0-9a-fA-F]/gi, "");
- document.documentElement.getButton("accept").disabled = (e.value.length != 40);
+ window.sizeToContent();
},
- add(e) {
- let hex = document.getElementById("finger").value;
- let context = OTR.getContextFromRecipient(
- args.account,
- args.protocol,
- args.screenname
- );
- let finger = OTR.addFingerprint(context, hex);
- if (finger.isNull())
- return;
- try {
- // Ignore the return, this is just a test.
- OTR.getUIConvFromContext(context);
- } catch (error) {
- // We expect that a conversation may not have been started.
- context = null;
+ addBlankSpace(value) {
+ return value.replace(/\s/g, "").trim().replace(/(.{8})/g, "$1 ").trim();
+ },
+
+ oninput(input) {
+ let hex = input.value.replace(/\s/g, "");
+
+ if ((/[^0-9A-F]/gi).test(hex)) {
+ this.keyCount.hidden = true;
+ this.fingerWarning.hidden = false;
+ this.fingerError.hidden = false;
+ } else {
+ this.keyCount.hidden = false;
+ this.fingerWarning.hidden = true;
+ this.fingerError.hidden = true;
}
- OTR.setTrust(finger, true, context);
+
+ document.documentElement.getButton("accept").disabled =
+ input.value && !input.validity.valid;
+
+ this.keyCount.value = `${hex.length}/40`;
+ input.value = this.addBlankSpace(input.value);
+
+ window.sizeToContent();
+ },
+
+ onblur(input) {
+ input.value = this.addBlankSpace(input.value);
},
};
--- a/chat/content/otr-add-fingerprint.xul
+++ b/chat/content/otr-add-fingerprint.xul
@@ -1,32 +1,64 @@
<?xml version="1.0" ?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<?xml-stylesheet href="chrome://global/skin/" type="text/css" ?>
+<?xml-stylesheet href="chrome://chat/skin/otrFingerprintDialog.css" type="text/css"?>
<!DOCTYPE dialog>
<dialog id="otrAddFingerDialog"
data-l10n-id="otr-add-finger"
- data-l10n-attrs="buttonlabelcancel"
windowtype="OTR:AddFinger"
onload="otrAddFinger.onload()"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
xmlns:html="http://www.w3.org/1999/xhtml"
buttons="accept,cancel"
buttondisabledaccept="true">
+ <keyset id="mailKeys">
+ <key keycode="VK_ESCAPE" oncommand="window.close();"/>
+ </keyset>
+
<linkset>
<html:link rel="localization" href="messenger/otr/add-finger.ftl"/>
</linkset>
<script src="chrome://chat/content/otr-add-fingerprint.js"/>
- <vbox flex="1">
- <label data-l10n-id="otr-add-finger-tooltip" control="name" flex="1"/>
- <hbox id="fingerBox" align="baseline" flex="1">
- <label data-l10n-id="otr-add-finger-fingerprint" control="name"/>
- <textbox id="finger" oninput="otrAddFinger.oninput(this)" flex="1"/>
+ <script src="chrome://global/content/globalOverlay.js"/>
+ <script src="chrome://global/content/editMenuOverlay.js"/>
+ <vbox class="dialog-container" flex="1">
+ <hbox align="center" pack="center" class="header-container">
+ <vbox>
+ <image class="header-icon icon-login"/>
+ </vbox>
+ <vbox flex="1">
+ <description id="otrDescription"/>
+ </vbox>
</hbox>
+ <hbox class="form-control" align="center">
+ <label data-l10n-id="otr-add-finger-fingerprint"
+ class="label-box"
+ control="fingerprint"/>
+ <hbox class="input-control" align="center" flex="1">
+ <html:input id="fingerprint" type="text"
+ data-l10n-id="otr-add-finger-input"
+ class="input-field"
+ oninput="otrAddFinger.oninput(this);"
+ onblur="otrAddFinger.onblur(this);"
+ pattern="[ 0-9a-fA-F]*"
+ minlength="44"
+ maxlength="44"/>
+ </hbox>
+ <image id="fingerWarning" class="form-icon icon-warning" hidden="true"/>
+ </hbox>
+ <vbox class="input-helper-container" flex="1" align="end">
+ <label id="fingerError"
+ data-l10n-id="otr-add-finger-tooltip-error"
+ class="msg-error"
+ hidden="true"/>
+ <label id="keyCount" class="input-helper" value="0/40"/>
+ </vbox>
</vbox>
</dialog>
--- a/chat/content/otr/add-finger.ftl
+++ b/chat/content/otr/add-finger.ftl
@@ -1,16 +1,17 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
otr-add-finger =
- .title = Add Fingerprint
- .buttonlabelcancel = Skip
+ .title = Add OTR Key Fingerprint
# Variables:
# $name (String) - name of a chat contact person
-otr-add-finger-name-title = Enter the fingerprint of the OTR key used by { $name }
+# Do not translate 'OTR' (name of an encryption protocol)
+otr-add-finger-description = Enter the OTR key fingerprint for { $name }.
-otr-add-finger-fingerprint = Fingerprint
+otr-add-finger-fingerprint = Fingerprint:
+otr-add-finger-tooltip-error = Invalid character entered. Only letters ABCDEF and numbers are allowed
-# Do not translate 'OTR' (name of an encryption protocol)
-otr-add-finger-tooltip = If you know the 40 character long HEX fingerprint of your contact's OTR private key, enter it now.
+otr-add-finger-input =
+ .placeholder = The 40 character long OTR key fingerprint
--- a/chat/content/otr/otrUI.ftl
+++ b/chat/content/otr/otrUI.ftl
@@ -15,17 +15,17 @@ auth-success = Verifying your contact's
auth-successThem = Your contact has successfully verified your identity. You may want to verify their identity as well by asking your own question.
auth-fail = Failed to verify your contact's identity.
auth-waiting = Waiting for contact to complete verification …
finger-verify = Verify
finger-verify-accessKey = V
# Do not translate 'OTR' (name of an encryption protocol)
-buddycontextmenu-label = Add Contact's OTR Fingerprint
+buddycontextmenu-label = Add OTR Fingerprint
# Variables:
# $name (String) - the screen name of a chat contact person
alert-start = Attempting to start an encrypted conversation with { $name }.
# Variables:
# $name (String) - the screen name of a chat contact person
alert-refresh = Attempting to refresh the encrypted conversation with { $name }.
--- a/chat/themes/jar.mn
+++ b/chat/themes/jar.mn
@@ -16,16 +16,17 @@ chat.jar:
skin/classic/chat/unknown-16.png
skin/classic/chat/chat-16.png
skin/classic/chat/chat-left-16.png
skin/classic/chat/conv.css
skin/classic/chat/browserRequest.css
skin/classic/chat/imtooltip.css
skin/classic/chat/status.css
skin/classic/chat/otr.css
+ skin/classic/chat/otrFingerprintDialog.css
skin/classic/chat/prpl-generic/icon32.png (icons/prpl-generic-32.png)
skin/classic/chat/prpl-generic/icon48.png (icons/prpl-generic-48.png)
skin/classic/chat/prpl-generic/icon.png (icons/prpl-generic.png)
skin/classic/chat/prpl-unknown/icon32.png (icons/prpl-unknown-32.png)
skin/classic/chat/prpl-unknown/icon48.png (icons/prpl-unknown-48.png)
skin/classic/chat/prpl-unknown/icon.png (icons/prpl-unknown.png)
skin/classic/chat/otr-connection-encrypted.svg (icons/otr-connection-encrypted.svg)
skin/classic/chat/otr-connection-finished.svg (icons/otr-connection-finished.svg)
new file mode 100644
--- /dev/null
+++ b/chat/themes/otrFingerprintDialog.css
@@ -0,0 +1,96 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+:root {
+ --text-color: #36385A;
+ --primary-color: #0a84ff;
+ --warning-color: #FF9400;
+ --error-color: #5A0002;
+}
+
+.dialog-container {
+ width: 36em;
+}
+
+.dialog-button-box {
+ margin-top: 5px;
+}
+
+.header-container {
+ margin: 0px 10px 5px;
+}
+
+.label-title {
+ font-weight: bold;
+ margin-bottom: 5px;
+ color: var(--text-color);
+}
+
+.msg-error {
+ color: var(--error-color);
+}
+
+/* Form and input fields */
+
+.form-control {
+ position: relative;
+ margin: 0px 0px 10px;
+}
+
+.input-control {
+ display: flex;
+ align-items: stretch;
+}
+
+.input-field {
+ padding: 5px 30px 5px 6px;
+ flex-grow: 1;
+ margin: 2px 4px;
+}
+
+.input-field:invalid {
+ box-shadow: 0 0 2px 1px var(--warning-color);
+}
+
+.input-helper-container {
+ margin-top: -6px;
+}
+
+.input-helper {
+ font-family: monospace;
+ font-size: 1em;
+ opacity: 0.7;
+}
+
+/* Icons */
+
+.header-icon {
+ -moz-context-properties: fill, stroke-opacity;
+ fill: currentColor;
+ color: var(--primary-color);
+ width: 3.5em;
+ margin: 10px;
+}
+
+.form-icon {
+ cursor: pointer;
+ -moz-context-properties: fill, stroke-opacity;
+ fill: currentColor;
+ margin-left: -26px;
+ margin-right: 10px;
+ color: var(--text-color);
+}
+
+.icon-info {
+ list-style-image: url("chrome://messenger/skin/icons/info.svg");
+}
+
+.icon-warning {
+ list-style-image: url("chrome://global/skin/icons/warning.svg");
+ color: var(--warning-color);
+}
+
+.icon-login {
+ list-style-image: url("chrome://messenger/skin/icons/login.svg");
+}
--- a/mail/themes/shared/jar.inc.mn
+++ b/mail/themes/shared/jar.inc.mn
@@ -51,16 +51,17 @@
skin/classic/messenger/icons/forward.svg (../shared/mail/icons/forward.svg)
skin/classic/messenger/icons/getmsg.svg (../shared/mail/icons/getmsg.svg)
skin/classic/messenger/icons/goback.svg (../shared/mail/icons/goback.svg)
skin/classic/messenger/icons/goforward.svg (../shared/mail/icons/goforward.svg)
skin/classic/messenger/icons/info.svg (../shared/mail/icons/info.svg)
skin/classic/messenger/icons/join.svg (../shared/mail/icons/join.svg)
skin/classic/messenger/icons/junk.svg (../shared/mail/icons/junk.svg)
skin/classic/messenger/icons/junk-col.svg (../shared/mail/icons/junk-col.svg)
+ skin/classic/messenger/icons/login.svg (../shared/mail/icons/login.svg)
skin/classic/messenger/icons/mark.svg (../shared/mail/icons/mark.svg)
skin/classic/messenger/icons/message.svg (../shared/mail/icons/message.svg)
skin/classic/messenger/icons/move-bottom.svg (../shared/mail/icons/move-bottom.svg)
skin/classic/messenger/icons/move-down.svg (../shared/mail/icons/move-down.svg)
skin/classic/messenger/icons/move-together.svg (../shared/mail/icons/move-together.svg)
skin/classic/messenger/icons/move-top.svg (../shared/mail/icons/move-top.svg)
skin/classic/messenger/icons/move-up.svg (../shared/mail/icons/move-up.svg)
skin/classic/messenger/icons/navigation.svg (../shared/mail/icons/navigation.svg)
new file mode 100644
--- /dev/null
+++ b/mail/themes/shared/mail/icons/login.svg
@@ -0,0 +1,4 @@
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16"><path fill="context-fill" d="M10.992 1a4.009 4.009 0 0 0-4.009 4.008c0 .1.022.187.028.282-.059.05-.119.087-.178.143L5.667 6.6a.366.366 0 0 0 0 .467A1.878 1.878 0 0 0 6 7.5.353.353 0 0 1 6 8l-5 5v1.767a.229.229 0 0 0 .233.233H3.77a.229.229 0 0 0 .23-.233v-.778h.75a.227.227 0 0 0 .233-.228v-.768H5.2s.28 0 .28-.235V12.5h.779s.233-.1.233-.244v-1.271h.855l1.12-1.118H8.7l.467.467c.233.233.233.233.365.233a.437.437 0 0 0 .275-.127l.993-1.273c.034-.053.054-.107.084-.161.036 0 .07.011.107.011a4.008 4.008 0 1 0 0-8.017zM12.5 4.489a1 1 0 1 1 1-1 1 1 0 0 1-1 1z"></path></svg>