diff --git a/app/assets/javascripts/discourse/controllers/preferences_badge_title_controller.js b/app/assets/javascripts/discourse/controllers/preferences_badge_title_controller.js
new file mode 100644
index 00000000000..85352626d87
--- /dev/null
+++ b/app/assets/javascripts/discourse/controllers/preferences_badge_title_controller.js
@@ -0,0 +1,64 @@
+/**
+ Controller for selecting a badge to use as your title.
+
+ @class PreferencesBadgeTitleController
+ @extends Ember.ArrayController
+ @namespace Discourse
+ @module Discourse
+**/
+Discourse.PreferencesBadgeTitleController = Ember.ArrayController.extend({
+ saving: false,
+ saved: false,
+
+ savingStatus: function() {
+ if (this.get('saving')) {
+ return I18n.t('saving');
+ } else {
+ return I18n.t('save');
+ }
+ }.property('saving'),
+
+ selectableUserBadges: Em.computed.filter('model', function(userBadge) {
+ var badgeType = userBadge.get('badge.badge_type.name');
+ return (badgeType === "Gold" || badgeType === "Silver");
+ }),
+
+ selectedUserBadge: function() {
+ var selectedUserBadgeId = parseInt(this.get('selectedUserBadgeId'));
+ var selectedUserBadge = null;
+ this.get('selectableUserBadges').forEach(function(userBadge) {
+ if (userBadge.get('id') === selectedUserBadgeId) {
+ selectedUserBadge = userBadge;
+ }
+ });
+ return selectedUserBadge;
+ }.property('selectedUserBadgeId'),
+
+ titleNotChanged: function() {
+ return this.get('user.title') === this.get('selectedUserBadge.badge.name');
+ }.property('selectedUserBadge', 'user.title'),
+
+ disableSave: Em.computed.or('saving', 'titleNotChanged'),
+
+ actions: {
+ save: function() {
+ var self = this;
+
+ self.set('saved', false);
+ self.set('saving', true);
+
+ Discourse.ajax("/users/" + self.get('user.username_lower') + "/preferences/badge_title", {
+ type: "PUT",
+ data: {
+ user_badge_id: self.get('selectedUserBadgeId')
+ }
+ }).then(function() {
+ self.set('saved', true);
+ self.set('saving', false);
+ self.set('user.title', self.get('selectedUserBadge.badge.name'));
+ }, function() {
+ bootbox.alert(I18n.t('generic_error'));
+ });
+ }
+ }
+});
diff --git a/app/assets/javascripts/discourse/controllers/preferences_controller.js b/app/assets/javascripts/discourse/controllers/preferences_controller.js
index c5f6c143054..1467b87ba97 100644
--- a/app/assets/javascripts/discourse/controllers/preferences_controller.js
+++ b/app/assets/javascripts/discourse/controllers/preferences_controller.js
@@ -38,6 +38,17 @@ Discourse.PreferencesController = Discourse.ObjectController.extend({
return Discourse.SiteSettings.enable_names;
}.property(),
+ canSelectTitle: function() {
+ if (!Discourse.SiteSettings.enable_badges || this.get('model.badge_count') === 0) {
+ return false;
+ }
+
+ // If the first featured badge isn't gold or silver we know the user won't have
+ // _any_ gold or silver badges.
+ var badgeType = this.get('model.featured_user_badges')[0].get('badge.badge_type.name');
+ return (badgeType === "Gold" || badgeType === "Silver");
+ }.property('model.badge_count', 'model.featured_user_badges.@each.badge.badge_type.name'),
+
availableLocales: function() {
return Discourse.SiteSettings.available_locales.split('|').map( function(s) {
return {name: s, value: s};
diff --git a/app/assets/javascripts/discourse/routes/application_routes.js b/app/assets/javascripts/discourse/routes/application_routes.js
index 9e46bfb9b75..e14386703af 100644
--- a/app/assets/javascripts/discourse/routes/application_routes.js
+++ b/app/assets/javascripts/discourse/routes/application_routes.js
@@ -81,6 +81,7 @@ Discourse.Route.buildRoutes(function() {
this.route('username');
this.route('email');
this.route('about', { path: '/about-me' });
+ this.route('badgeTitle', { path: '/badge_title' });
});
this.route('invited');
diff --git a/app/assets/javascripts/discourse/routes/preferences_routes.js b/app/assets/javascripts/discourse/routes/preferences_routes.js
index fbf0d63b2a7..ef59b99d418 100644
--- a/app/assets/javascripts/discourse/routes/preferences_routes.js
+++ b/app/assets/javascripts/discourse/routes/preferences_routes.js
@@ -44,7 +44,7 @@ Discourse.PreferencesRoute = Discourse.RestrictedUserRoute.extend({
user.set('avatar_template', avatarSelector.get('avatarTemplate'));
avatarSelector.send('closeModal');
},
-
+
showProfileBackgroundFileSelector: function() {
$("#profile-background-input").click();
},
@@ -161,3 +161,43 @@ Discourse.PreferencesUsernameRoute = Discourse.RestrictedUserRoute.extend({
controller.setProperties({ model: user, newUsername: user.get('username') });
}
});
+
+/**
+ The route for updating a user's title to one of their badges
+
+ @class PreferencesBadgeTitleRoute
+ @extends Discourse.RestrictedUserRoute
+ @namespace Discourse
+ @module Discourse
+**/
+Discourse.PreferencesBadgeTitleRoute = Discourse.RestrictedUserRoute.extend({
+ model: function() {
+ return Discourse.UserBadge.findByUsername(this.modelFor('user').get('username'));
+ },
+
+ renderTemplate: function() {
+ return this.render('user/badge-title', { into: 'user', outlet: 'userOutlet' });
+ },
+
+ // A bit odd, but if we leave to /preferences we need to re-render that outlet
+ deactivate: function() {
+ this._super();
+ this.render('preferences', { into: 'user', outlet: 'userOutlet', controller: 'preferences' });
+ },
+
+ setupController: function(controller, model) {
+ controller.set('model', model);
+ controller.set('user', this.modelFor('user'));
+
+ model.forEach(function(userBadge) {
+ if (userBadge.get('badge.name') === controller.get('user.title')) {
+ controller.set('selectedUserBadgeId', userBadge.get('id'));
+ }
+ });
+ if (!controller.get('selectedUserBadgeId')) {
+ controller.set('selectedUserBadgeId', controller.get('selectableUserBadges')[0].get('id'));
+ }
+ }
+});
+
+
diff --git a/app/assets/javascripts/discourse/templates/user/badge-title.js.handlebars b/app/assets/javascripts/discourse/templates/user/badge-title.js.handlebars
new file mode 100644
index 00000000000..6bf807b8de1
--- /dev/null
+++ b/app/assets/javascripts/discourse/templates/user/badge-title.js.handlebars
@@ -0,0 +1,25 @@
+