From ae040dd405b6f3696c99ae655a8658f292aa1444 Mon Sep 17 00:00:00 2001 From: Max Goodman Date: Mon, 10 Sep 2012 14:26:23 -0700 Subject: [PATCH] registration: As-you-type username availability check. --- r2/r2/controllers/api.py | 9 +++++++ r2/r2/public/static/css/reddit.css | 39 +++++++++++++++++++++++++++++- r2/r2/public/static/js/login.js | 36 +++++++++++++++++++++++++++ r2/r2/templates/login.html | 5 +++- 4 files changed, 87 insertions(+), 2 deletions(-) diff --git a/r2/r2/controllers/api.py b/r2/r2/controllers/api.py index 363ac8138..5ef162731 100755 --- a/r2/r2/controllers/api.py +++ b/r2/r2/controllers/api.py @@ -147,6 +147,15 @@ class ApiController(RedditController, OAuth2ResourceController): else: return {} + @json_validate(user=VUname("user")) + @api_doc(api_section.users, extensions=["json"]) + def GET_username_available(self, responder, user): + """ + Check whether a username is available for registration. + """ + if not (responder.has_errors("user", errors.BAD_USERNAME)): + return bool(user) + @validatedForm(VCaptcha(), name=VRequired('name', errors.NO_NAME), email=ValidEmails('email', num = 1), diff --git a/r2/r2/public/static/css/reddit.css b/r2/r2/public/static/css/reddit.css index d6cb55860..3b21027c8 100755 --- a/r2/r2/public/static/css/reddit.css +++ b/r2/r2/public/static/css/reddit.css @@ -2149,6 +2149,29 @@ li.searchfacet { #passform h1 {margin-bottom: 0px} #passform p {margin-bottom: 5px; font-size: small} +.register-form .name-entry * { + vertical-align: middle; +} + +.notice-taken, .notice-available { + display: none; + margin-left: 6px; + line-height: 16px; +} + +.register-form.name-taken .notice-taken, .register-form.name-available .notice-available { + display: inline-block; +} + +.register-form .name-entry .throbber { + display: none; + margin-left: 5px; +} + +.register-form.name-checking .name-entry .throbber { + display: inline-block; +} + /* cover */ .cover { position: fixed; @@ -4826,7 +4849,9 @@ dd { margin-left: 20px; } .icon-menu .reddit-modqueue:before, .giftgold a:before, .gold-form h1.goldgift:before, -.users-online:before { +.users-online:before, +.notice-taken:before, +.notice-available:before { height: 16px; width: 16px; display: block; @@ -4905,6 +4930,18 @@ dd { margin-left: 20px; } background-image: url(../online.png); /* SPRITE */ } +.notice-taken:before, .notice-available:before { + margin-right: 3px; +} + +.notice-taken:before { + background-image: url(../icon-circle-exclamation.png); /* SPRITE */ +} + +.notice-available:before { + background-image: url(../icon-circle-check.png); /* SPRITE */ +} + .linkinfo { padding: 5px; border: 1px solid #5f99cf; diff --git a/r2/r2/public/static/js/login.js b/r2/r2/public/static/js/login.js index 53def2754..f25886808 100644 --- a/r2/r2/public/static/js/login.js +++ b/r2/r2/public/static/js/login.js @@ -207,8 +207,44 @@ r.ui.LoginForm.prototype = $.extend(new r.ui.Form(), { r.ui.RegisterForm = function() { r.ui.Form.apply(this, arguments) + this.checkUsernameDebounced = _.debounce($.proxy(this, 'checkUsername'), 500) + this.$user = this.$el.find('[name="user"]') + this.$user.on('keyup', $.proxy(this, 'usernameChanged')) } r.ui.RegisterForm.prototype = $.extend(new r.ui.Form(), { + usernameChanged: function() { + var name = this.$user.val() + if (name == this._priorName) { + return + } else { + this._priorName = name + } + + this.$el.find('.error.field-user').hide() + this.$el.removeClass('name-available name-taken') + this.checkUsernameDebounced(name) + this.$el.toggleClass('name-checking', !!name) + }, + + checkUsername: function(name) { + if (name) { + $.ajax({ + url: '/api/username_available.json', + data: {user: name}, + success: $.proxy(this, 'displayUsernameStatus'), + complete: $.proxy(function() { this.$el.removeClass('name-checking') }, this) + }) + } + }, + + displayUsernameStatus: function(result) { + if (result.json && result.json.errors) { + this.showErrors(result.json.errors) + } else { + this.$el.addClass(result ? 'name-available' : 'name-taken') + } + }, + _submit: function() { r.login.post(this, 'register', $.proxy(this, 'handleResult')) }, diff --git a/r2/r2/templates/login.html b/r2/r2/templates/login.html index 083f45c95..a9bb0da7e 100644 --- a/r2/r2/templates/login.html +++ b/r2/r2/templates/login.html @@ -62,11 +62,14 @@ %endif