diff --git a/_locales/en/messages.json b/_locales/en/messages.json index d6e7e7e5b..14915f324 100644 --- a/_locales/en/messages.json +++ b/_locales/en/messages.json @@ -781,6 +781,9 @@ "cancel": { "message": "Cancel" }, + "clear": { + "message": "Clear" + }, "failedToSend": { "message": "Failed to send to some recipients. Check your network connection." diff --git a/background.html b/background.html index e7463fcb5..40dc5bb73 100644 --- a/background.html +++ b/background.html @@ -150,6 +150,20 @@ 0:00 + + diff --git a/js/background.js b/js/background.js index 71e5935ee..03f49ba4a 100644 --- a/js/background.js +++ b/js/background.js @@ -568,6 +568,12 @@ } }); + Whisper.events.on('showNicknameDialog', options => { + if (appView) { + appView.showNicknameDialog(options); + } + }); + Whisper.events.on('calculatingPoW', ({ pubKey, timestamp }) => { try { const conversation = ConversationController.get(pubKey); diff --git a/js/views/app_view.js b/js/views/app_view.js index 1db6314e3..acd6a8329 100644 --- a/js/views/app_view.js +++ b/js/views/app_view.js @@ -178,5 +178,15 @@ }); } }, + showNicknameDialog({ pubKey, title, nickname, onOk, onCancel }) { + const _title = title || `Change nickname for ${pubKey}`; + const dialog = new Whisper.NicknameDialogView({ + title: _title, + name: nickname, + resolve: onOk, + reject: onCancel, + }); + this.el.append(dialog.el); + }, }); })(); diff --git a/js/views/nickname_dialog_view.js b/js/views/nickname_dialog_view.js new file mode 100644 index 000000000..8d4d092eb --- /dev/null +++ b/js/views/nickname_dialog_view.js @@ -0,0 +1,101 @@ +/* global Whisper, i18n, _ */ + +// eslint-disable-next-line func-names +(function() { + 'use strict'; + + window.Whisper = window.Whisper || {}; + + Whisper.NicknameDialogView = Whisper.View.extend({ + className: 'nickname-dialog modal', + templateName: 'nickname-dialog', + initialize(options) { + this.message = options.message; + this.name = options.name; + + this.resolve = options.resolve; + this.okText = options.okText || i18n('ok'); + + this.reject = options.reject; + this.cancelText = options.cancelText || i18n('cancel'); + + this.clear = options.clear; + this.clearText = options.clearText || i18n('clear'); + + this.title = options.title; + + this.render(); + + this.$input = this.$('input'); + this.validateNickname(); + }, + events: { + keyup: 'onKeyup', + 'click .ok': 'ok', + 'click .cancel': 'cancel', + 'click .clear': 'clear', + change: 'validateNickname', + }, + isValidNickname(name) { + return (name || '').length < 20; + }, + validateNickname() { + const nickname = this.$input.val(); + + if (_.isEmpty(nickname)) { + this.$('.clear').hide(); + } else { + this.$('.clear').show(); + } + + if (this.isValidNickname(nickname)) { + this.$('.content').removeClass('invalid'); + this.$('.content').addClass('valid'); + this.$('.ok').show(); + } else { + this.$('.content').removeClass('valid'); + this.$('.ok').hide(); + } + }, + render_attributes() { + return { + name: this.name, + message: this.message, + showCancel: !this.hideCancel, + cancel: this.cancelText, + ok: this.okText, + clear: this.clearText, + title: this.title, + }; + }, + ok() { + const nickname = this.$input.val(); + if (!this.isValidNickname(nickname)) return; + + this.remove(); + if (this.resolve) { + this.resolve(nickname); + } + }, + cancel() { + this.remove(); + if (this.reject) { + this.reject(); + } + }, + clear() { + this.$input.val('').trigger('change'); + }, + onKeyup(event) { + if (event.key === 'Escape' || event.key === 'Esc') { + this.cancel(); + return; + } + + this.validateNickname(); + }, + focusCancel() { + this.$('.cancel').focus(); + }, + }); +})(); diff --git a/stylesheets/_conversation.scss b/stylesheets/_conversation.scss index 3d8376aa9..ca468bd9b 100644 --- a/stylesheets/_conversation.scss +++ b/stylesheets/_conversation.scss @@ -351,6 +351,57 @@ } } + +.nickname-dialog { + display: flex; + align-items: center; + justify-content: center; + + .content { + max-width: 75%; + padding: 1em; + background: white; + border-radius: $border-radius; + overflow: auto; + box-shadow: 0px 0px 15px 0px rgba(0, 0, 0, 0.3); + + .buttons { + margin-top: 10px; + + button { + float: right; + margin-left: 10px; + background-color: $grey_l; + border-radius: $border-radius; + padding: 5px 8px; + border: 1px solid $grey_l2; + + &:hover { + background-color: $grey_l2; + border-color: $grey_l3; + } + } + } + + input { + width: 100%; + padding: 8px; + margin-bottom: 4px; + } + + h4 { + white-space: -moz-pre-wrap; /* Mozilla */ + white-space: -hp-pre-wrap; /* HP printers */ + white-space: -o-pre-wrap; /* Opera 7 */ + white-space: -pre-wrap; /* Opera 4-6 */ + white-space: pre-wrap; /* CSS 2.1 */ + white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */ + word-wrap: break-word; /* IE */ + word-break: break-all; + } + } +} + .permissions-popup, .debug-log-window { .modal { diff --git a/test/index.html b/test/index.html index e03ce96cf..05d46c1c6 100644 --- a/test/index.html +++ b/test/index.html @@ -127,6 +127,17 @@ 0:00 + +