@@ -1,230 +1,3 @@
|
||||
import { setting } from 'discourse/lib/computed';
|
||||
import CanCheckEmails from 'discourse/mixins/can-check-emails';
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
|
||||
import { cook } from 'discourse/lib/text';
|
||||
import { NotificationLevels } from 'discourse/lib/notification-levels';
|
||||
import { listThemes, selectDefaultTheme, previewTheme } from 'discourse/lib/theme-selector';
|
||||
|
||||
export default Ember.Controller.extend(CanCheckEmails, {
|
||||
|
||||
userSelectableThemes: function(){
|
||||
return listThemes(this.site);
|
||||
}.property(),
|
||||
|
||||
@observes("selectedTheme")
|
||||
themeKeyChanged() {
|
||||
let key = this.get("selectedTheme");
|
||||
previewTheme(key);
|
||||
},
|
||||
|
||||
@computed("model.watchedCategories", "model.trackedCategories", "model.mutedCategories")
|
||||
selectedCategories(watched, tracked, muted) {
|
||||
return [].concat(watched, tracked, muted);
|
||||
},
|
||||
|
||||
// By default we haven't saved anything
|
||||
saved: false,
|
||||
|
||||
newNameInput: null,
|
||||
|
||||
@computed("model.user_fields.@each.value")
|
||||
userFields() {
|
||||
let siteUserFields = this.site.get('user_fields');
|
||||
if (!Ember.isEmpty(siteUserFields)) {
|
||||
const userFields = this.get('model.user_fields');
|
||||
|
||||
// Staff can edit fields that are not `editable`
|
||||
if (!this.get('currentUser.staff')) {
|
||||
siteUserFields = siteUserFields.filterBy('editable', true);
|
||||
}
|
||||
return siteUserFields.sortBy('position').map(function(field) {
|
||||
const value = userFields ? userFields[field.get('id').toString()] : null;
|
||||
return Ember.Object.create({ value, field });
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
cannotDeleteAccount: Em.computed.not('currentUser.can_delete_account'),
|
||||
deleteDisabled: Em.computed.or('model.isSaving', 'deleting', 'cannotDeleteAccount'),
|
||||
|
||||
canEditName: setting('enable_names'),
|
||||
|
||||
@computed()
|
||||
nameInstructions() {
|
||||
return I18n.t(this.siteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions');
|
||||
},
|
||||
|
||||
@computed("model.has_title_badges")
|
||||
canSelectTitle(hasTitleBadges) {
|
||||
return this.siteSettings.enable_badges && hasTitleBadges;
|
||||
},
|
||||
|
||||
@computed("model.can_change_bio")
|
||||
canChangeBio(canChangeBio)
|
||||
{
|
||||
return canChangeBio;
|
||||
},
|
||||
|
||||
@computed()
|
||||
canChangePassword() {
|
||||
return !this.siteSettings.enable_sso && this.siteSettings.enable_local_logins;
|
||||
},
|
||||
|
||||
@computed()
|
||||
availableLocales() {
|
||||
return this.siteSettings.available_locales.split('|').map(s => ({ name: s, value: s }));
|
||||
},
|
||||
|
||||
@computed()
|
||||
frequencyEstimate() {
|
||||
var estimate = this.get('model.mailing_list_posts_per_day');
|
||||
if (!estimate || estimate < 2) {
|
||||
return I18n.t('user.mailing_list_mode.few_per_day');
|
||||
} else {
|
||||
return I18n.t('user.mailing_list_mode.many_per_day', { dailyEmailEstimate: estimate });
|
||||
}
|
||||
},
|
||||
|
||||
@computed()
|
||||
mailingListModeOptions() {
|
||||
return [
|
||||
{name: I18n.t('user.mailing_list_mode.daily'), value: 0},
|
||||
{name: this.get('frequencyEstimate'), value: 1},
|
||||
{name: I18n.t('user.mailing_list_mode.individual_no_echo'), value: 2}
|
||||
];
|
||||
},
|
||||
|
||||
previousRepliesOptions: [
|
||||
{name: I18n.t('user.email_previous_replies.always'), value: 0},
|
||||
{name: I18n.t('user.email_previous_replies.unless_emailed'), value: 1},
|
||||
{name: I18n.t('user.email_previous_replies.never'), value: 2}
|
||||
],
|
||||
|
||||
digestFrequencies: [{ name: I18n.t('user.email_digests.every_30_minutes'), value: 30 },
|
||||
{ name: I18n.t('user.email_digests.every_hour'), value: 60 },
|
||||
{ name: I18n.t('user.email_digests.daily'), value: 1440 },
|
||||
{ name: I18n.t('user.email_digests.every_three_days'), value: 4320 },
|
||||
{ name: I18n.t('user.email_digests.weekly'), value: 10080 },
|
||||
{ name: I18n.t('user.email_digests.every_two_weeks'), value: 20160 }],
|
||||
|
||||
likeNotificationFrequencies: [{ name: I18n.t('user.like_notification_frequency.always'), value: 0 },
|
||||
{ name: I18n.t('user.like_notification_frequency.first_time_and_daily'), value: 1 },
|
||||
{ name: I18n.t('user.like_notification_frequency.first_time'), value: 2 },
|
||||
{ name: I18n.t('user.like_notification_frequency.never'), value: 3 }],
|
||||
|
||||
autoTrackDurations: [{ name: I18n.t('user.auto_track_options.never'), value: -1 },
|
||||
{ name: I18n.t('user.auto_track_options.immediately'), value: 0 },
|
||||
{ name: I18n.t('user.auto_track_options.after_30_seconds'), value: 30000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_1_minute'), value: 60000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_2_minutes'), value: 120000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_3_minutes'), value: 180000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_4_minutes'), value: 240000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_5_minutes'), value: 300000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_10_minutes'), value: 600000 }],
|
||||
|
||||
notificationLevelsForReplying: [{ name: I18n.t('topic.notifications.watching.title'), value: NotificationLevels.WATCHING },
|
||||
{ name: I18n.t('topic.notifications.tracking.title'), value: NotificationLevels.TRACKING },
|
||||
{ name: I18n.t('topic.notifications.regular.title'), value: NotificationLevels.REGULAR }],
|
||||
|
||||
|
||||
considerNewTopicOptions: [{ name: I18n.t('user.new_topic_duration.not_viewed'), value: -1 },
|
||||
{ name: I18n.t('user.new_topic_duration.after_1_day'), value: 60 * 24 },
|
||||
{ name: I18n.t('user.new_topic_duration.after_2_days'), value: 60 * 48 },
|
||||
{ name: I18n.t('user.new_topic_duration.after_1_week'), value: 7 * 60 * 24 },
|
||||
{ name: I18n.t('user.new_topic_duration.after_2_weeks'), value: 2 * 7 * 60 * 24 },
|
||||
{ name: I18n.t('user.new_topic_duration.last_here'), value: -2 }],
|
||||
|
||||
@computed("model.isSaving")
|
||||
saveButtonText(isSaving) {
|
||||
return isSaving ? I18n.t('saving') : I18n.t('save');
|
||||
},
|
||||
|
||||
reset() {
|
||||
this.setProperties({
|
||||
passwordProgress: null
|
||||
});
|
||||
},
|
||||
|
||||
passwordProgress: null,
|
||||
|
||||
actions: {
|
||||
|
||||
save() {
|
||||
this.set('saved', false);
|
||||
|
||||
const model = this.get('model');
|
||||
|
||||
const userFields = this.get('userFields');
|
||||
|
||||
// Update the user fields
|
||||
if (!Ember.isEmpty(userFields)) {
|
||||
const modelFields = model.get('user_fields');
|
||||
if (!Ember.isEmpty(modelFields)) {
|
||||
userFields.forEach(function(uf) {
|
||||
modelFields[uf.get('field.id').toString()] = uf.get('value');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Cook the bio for preview
|
||||
model.set('name', this.get('newNameInput'));
|
||||
return model.save().then(() => {
|
||||
if (Discourse.User.currentProp('id') === model.get('id')) {
|
||||
Discourse.User.currentProp('name', model.get('name'));
|
||||
}
|
||||
model.set('bio_cooked', cook(model.get('bio_raw')));
|
||||
selectDefaultTheme(this.get('selectedTheme'));
|
||||
this.set('saved', true);
|
||||
}).catch(popupAjaxError);
|
||||
},
|
||||
|
||||
changePassword() {
|
||||
if (!this.get('passwordProgress')) {
|
||||
this.set('passwordProgress', I18n.t("user.change_password.in_progress"));
|
||||
return this.get('model').changePassword().then(() => {
|
||||
// password changed
|
||||
this.setProperties({
|
||||
changePasswordProgress: false,
|
||||
passwordProgress: I18n.t("user.change_password.success")
|
||||
});
|
||||
}).catch(() => {
|
||||
// password failed to change
|
||||
this.setProperties({
|
||||
changePasswordProgress: false,
|
||||
passwordProgress: I18n.t("user.change_password.error")
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
delete() {
|
||||
this.set('deleting', true);
|
||||
const self = this,
|
||||
message = I18n.t('user.delete_account_confirm'),
|
||||
model = this.get('model'),
|
||||
buttons = [
|
||||
{ label: I18n.t("cancel"),
|
||||
class: "cancel-inline",
|
||||
link: true,
|
||||
callback: () => { this.set('deleting', false); }
|
||||
},
|
||||
{ label: '<i class="fa fa-exclamation-triangle"></i> ' + I18n.t("user.delete_account"),
|
||||
class: "btn btn-danger",
|
||||
callback() {
|
||||
model.delete().then(function() {
|
||||
bootbox.alert(I18n.t('user.deleted_yourself'), function() {
|
||||
window.location.pathname = Discourse.getURL('/');
|
||||
});
|
||||
}, function() {
|
||||
bootbox.alert(I18n.t('user.delete_yourself_not_allowed'));
|
||||
self.set('deleting', false);
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
bootbox.dialog(message, buttons, {"classes": "delete-account"});
|
||||
}
|
||||
}
|
||||
|
||||
export default Ember.Controller.extend({
|
||||
application: Ember.inject.controller()
|
||||
});
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
import CanCheckEmails from 'discourse/mixins/can-check-emails';
|
||||
import { default as computed } from "ember-addons/ember-computed-decorators";
|
||||
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
|
||||
|
||||
export default Ember.Controller.extend(CanCheckEmails, PreferencesTabController, {
|
||||
|
||||
passwordProgress: null,
|
||||
|
||||
cannotDeleteAccount: Em.computed.not('currentUser.can_delete_account'),
|
||||
deleteDisabled: Em.computed.or('model.isSaving', 'deleting', 'cannotDeleteAccount'),
|
||||
|
||||
reset() {
|
||||
this.setProperties({
|
||||
passwordProgress: null
|
||||
});
|
||||
},
|
||||
|
||||
@computed()
|
||||
canChangePassword() {
|
||||
return !this.siteSettings.enable_sso && this.siteSettings.enable_local_logins;
|
||||
},
|
||||
|
||||
actions: {
|
||||
changePassword() {
|
||||
if (!this.get('passwordProgress')) {
|
||||
this.set('passwordProgress', I18n.t("user.change_password.in_progress"));
|
||||
return this.get('model').changePassword().then(() => {
|
||||
// password changed
|
||||
this.setProperties({
|
||||
changePasswordProgress: false,
|
||||
passwordProgress: I18n.t("user.change_password.success")
|
||||
});
|
||||
}).catch(() => {
|
||||
// password failed to change
|
||||
this.setProperties({
|
||||
changePasswordProgress: false,
|
||||
passwordProgress: I18n.t("user.change_password.error")
|
||||
});
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
delete() {
|
||||
this.set('deleting', true);
|
||||
const self = this,
|
||||
message = I18n.t('user.delete_account_confirm'),
|
||||
model = this.get('model'),
|
||||
buttons = [
|
||||
{ label: I18n.t("cancel"),
|
||||
class: "cancel-inline",
|
||||
link: true,
|
||||
callback: () => { this.set('deleting', false); }
|
||||
},
|
||||
{ label: '<i class="fa fa-exclamation-triangle"></i> ' + I18n.t("user.delete_account"),
|
||||
class: "btn btn-danger",
|
||||
callback() {
|
||||
model.delete().then(function() {
|
||||
bootbox.alert(I18n.t('user.deleted_yourself'), function() {
|
||||
window.location.pathname = Discourse.getURL('/');
|
||||
});
|
||||
}, function() {
|
||||
bootbox.alert(I18n.t('user.delete_yourself_not_allowed'));
|
||||
self.set('deleting', false);
|
||||
});
|
||||
}
|
||||
}
|
||||
];
|
||||
bootbox.dialog(message, buttons, {"classes": "delete-account"});
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,20 @@
|
||||
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Controller.extend(PreferencesTabController, {
|
||||
saveAttrNames: [
|
||||
'muted_category_ids',
|
||||
'watched_category_ids',
|
||||
'tracked_category_ids',
|
||||
'watched_first_post_category_ids'
|
||||
],
|
||||
|
||||
actions: {
|
||||
save() {
|
||||
this.set('saved', false);
|
||||
return this.get('model').save(this.get('saveAttrNames')).then(() => {
|
||||
this.set('saved', true);
|
||||
}).catch(popupAjaxError);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,62 @@
|
||||
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
|
||||
import { default as computed } from "ember-addons/ember-computed-decorators";
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Controller.extend(PreferencesTabController, {
|
||||
|
||||
saveAttrNames: [
|
||||
'email_always',
|
||||
'mailing_list_mode',
|
||||
'mailing_list_mode_frequency',
|
||||
'email_digests',
|
||||
'email_direct',
|
||||
'email_in_reply_to',
|
||||
'email_private_messages',
|
||||
'email_previous_replies',
|
||||
'digest_after_minutes',
|
||||
'include_tl0_in_digests'
|
||||
],
|
||||
|
||||
@computed()
|
||||
frequencyEstimate() {
|
||||
var estimate = this.get('model.mailing_list_posts_per_day');
|
||||
if (!estimate || estimate < 2) {
|
||||
return I18n.t('user.mailing_list_mode.few_per_day');
|
||||
} else {
|
||||
return I18n.t('user.mailing_list_mode.many_per_day', { dailyEmailEstimate: estimate });
|
||||
}
|
||||
},
|
||||
|
||||
@computed()
|
||||
mailingListModeOptions() {
|
||||
return [
|
||||
{name: I18n.t('user.mailing_list_mode.daily'), value: 0},
|
||||
{name: this.get('frequencyEstimate'), value: 1},
|
||||
{name: I18n.t('user.mailing_list_mode.individual_no_echo'), value: 2}
|
||||
];
|
||||
},
|
||||
|
||||
previousRepliesOptions: [
|
||||
{name: I18n.t('user.email_previous_replies.always'), value: 0},
|
||||
{name: I18n.t('user.email_previous_replies.unless_emailed'), value: 1},
|
||||
{name: I18n.t('user.email_previous_replies.never'), value: 2}
|
||||
],
|
||||
|
||||
digestFrequencies: [
|
||||
{ name: I18n.t('user.email_digests.every_30_minutes'), value: 30 },
|
||||
{ name: I18n.t('user.email_digests.every_hour'), value: 60 },
|
||||
{ name: I18n.t('user.email_digests.daily'), value: 1440 },
|
||||
{ name: I18n.t('user.email_digests.every_three_days'), value: 4320 },
|
||||
{ name: I18n.t('user.email_digests.weekly'), value: 10080 },
|
||||
{ name: I18n.t('user.email_digests.every_two_weeks'), value: 20160 }
|
||||
],
|
||||
|
||||
actions: {
|
||||
save() {
|
||||
this.set('saved', false);
|
||||
return this.get('model').save(this.get('saveAttrNames')).then(() => {
|
||||
this.set('saved', true);
|
||||
}).catch(popupAjaxError);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,45 @@
|
||||
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
|
||||
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
|
||||
import { listThemes, previewTheme } from 'discourse/lib/theme-selector';
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
import { selectDefaultTheme } from 'discourse/lib/theme-selector';
|
||||
|
||||
export default Ember.Controller.extend(PreferencesTabController, {
|
||||
|
||||
saveAttrNames: [
|
||||
'locale',
|
||||
'external_links_in_new_tab',
|
||||
'dynamic_favicon',
|
||||
'enable_quoting',
|
||||
'disable_jump_reply',
|
||||
'automatically_unpin_topics'
|
||||
],
|
||||
|
||||
preferencesController: Ember.inject.controller('preferences'),
|
||||
|
||||
@computed()
|
||||
availableLocales() {
|
||||
return this.siteSettings.available_locales.split('|').map(s => ({ name: s, value: s }));
|
||||
},
|
||||
|
||||
userSelectableThemes: function(){
|
||||
return listThemes(this.site);
|
||||
}.property(),
|
||||
|
||||
@observes("selectedTheme")
|
||||
themeKeyChanged() {
|
||||
let key = this.get("selectedTheme");
|
||||
this.get('preferencesController').set('selectedTheme', key);
|
||||
previewTheme(key);
|
||||
},
|
||||
|
||||
actions: {
|
||||
save() {
|
||||
this.set('saved', false);
|
||||
return this.get('model').save(this.get('saveAttrNames')).then(() => {
|
||||
this.set('saved', true);
|
||||
selectDefaultTheme(this.get('selectedTheme'));
|
||||
}).catch(popupAjaxError);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,56 @@
|
||||
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
|
||||
import { default as computed } from "ember-addons/ember-computed-decorators";
|
||||
import { NotificationLevels } from 'discourse/lib/notification-levels';
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Controller.extend(PreferencesTabController, {
|
||||
|
||||
saveAttrNames:[
|
||||
'muted_usernames',
|
||||
'new_topic_duration_minutes',
|
||||
'auto_track_topics_after_msecs',
|
||||
'notification_level_when_replying',
|
||||
'like_notification_frequency'
|
||||
],
|
||||
|
||||
@computed("model.watchedCategories", "model.trackedCategories", "model.mutedCategories")
|
||||
selectedCategories(watched, tracked, muted) {
|
||||
return [].concat(watched, tracked, muted);
|
||||
},
|
||||
|
||||
likeNotificationFrequencies: [{ name: I18n.t('user.like_notification_frequency.always'), value: 0 },
|
||||
{ name: I18n.t('user.like_notification_frequency.first_time_and_daily'), value: 1 },
|
||||
{ name: I18n.t('user.like_notification_frequency.first_time'), value: 2 },
|
||||
{ name: I18n.t('user.like_notification_frequency.never'), value: 3 }],
|
||||
|
||||
autoTrackDurations: [{ name: I18n.t('user.auto_track_options.never'), value: -1 },
|
||||
{ name: I18n.t('user.auto_track_options.immediately'), value: 0 },
|
||||
{ name: I18n.t('user.auto_track_options.after_30_seconds'), value: 30000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_1_minute'), value: 60000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_2_minutes'), value: 120000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_3_minutes'), value: 180000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_4_minutes'), value: 240000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_5_minutes'), value: 300000 },
|
||||
{ name: I18n.t('user.auto_track_options.after_10_minutes'), value: 600000 }],
|
||||
|
||||
notificationLevelsForReplying: [{ name: I18n.t('topic.notifications.watching.title'), value: NotificationLevels.WATCHING },
|
||||
{ name: I18n.t('topic.notifications.tracking.title'), value: NotificationLevels.TRACKING },
|
||||
{ name: I18n.t('topic.notifications.regular.title'), value: NotificationLevels.REGULAR }],
|
||||
|
||||
considerNewTopicOptions: [{ name: I18n.t('user.new_topic_duration.not_viewed'), value: -1 },
|
||||
{ name: I18n.t('user.new_topic_duration.after_1_day'), value: 60 * 24 },
|
||||
{ name: I18n.t('user.new_topic_duration.after_2_days'), value: 60 * 48 },
|
||||
{ name: I18n.t('user.new_topic_duration.after_1_week'), value: 7 * 60 * 24 },
|
||||
{ name: I18n.t('user.new_topic_duration.after_2_weeks'), value: 2 * 7 * 60 * 24 },
|
||||
{ name: I18n.t('user.new_topic_duration.last_here'), value: -2 }],
|
||||
|
||||
actions: {
|
||||
save() {
|
||||
this.set('saved', false);
|
||||
return this.get('model').save(this.get('saveAttrNames')).then(() => {
|
||||
this.set('saved', true);
|
||||
}).catch(popupAjaxError);
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
@@ -0,0 +1,84 @@
|
||||
import { default as computed } from "ember-addons/ember-computed-decorators";
|
||||
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
|
||||
import { setting } from 'discourse/lib/computed';
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
import { cook } from 'discourse/lib/text';
|
||||
|
||||
export default Ember.Controller.extend(PreferencesTabController, {
|
||||
|
||||
saveAttrNames: [
|
||||
'name',
|
||||
'bio_raw',
|
||||
'website',
|
||||
'location',
|
||||
'custom_fields',
|
||||
'user_fields',
|
||||
'profile_background',
|
||||
'card_background',
|
||||
'date_of_birth'
|
||||
],
|
||||
|
||||
canEditName: setting('enable_names'),
|
||||
|
||||
newNameInput: null,
|
||||
|
||||
@computed()
|
||||
nameInstructions() {
|
||||
return I18n.t(this.siteSettings.full_name_required ? 'user.name.instructions_required' : 'user.name.instructions');
|
||||
},
|
||||
|
||||
@computed("model.has_title_badges")
|
||||
canSelectTitle(hasTitleBadges) {
|
||||
return this.siteSettings.enable_badges && hasTitleBadges;
|
||||
},
|
||||
|
||||
@computed("model.user_fields.@each.value")
|
||||
userFields() {
|
||||
let siteUserFields = this.site.get('user_fields');
|
||||
if (!Ember.isEmpty(siteUserFields)) {
|
||||
const userFields = this.get('model.user_fields');
|
||||
|
||||
// Staff can edit fields that are not `editable`
|
||||
if (!this.get('currentUser.staff')) {
|
||||
siteUserFields = siteUserFields.filterBy('editable', true);
|
||||
}
|
||||
return siteUserFields.sortBy('position').map(function(field) {
|
||||
const value = userFields ? userFields[field.get('id').toString()] : null;
|
||||
return Ember.Object.create({ value, field });
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
@computed("model.can_change_bio")
|
||||
canChangeBio(canChangeBio)
|
||||
{
|
||||
return canChangeBio;
|
||||
},
|
||||
|
||||
actions: {
|
||||
|
||||
save() {
|
||||
this.set('saved', false);
|
||||
|
||||
const model = this.get('model'),
|
||||
userFields = this.get('userFields');
|
||||
|
||||
model.set('name', this.get('newNameInput'));
|
||||
|
||||
// Update the user fields
|
||||
if (!Ember.isEmpty(userFields)) {
|
||||
const modelFields = model.get('user_fields');
|
||||
if (!Ember.isEmpty(modelFields)) {
|
||||
userFields.forEach(function(uf) {
|
||||
modelFields[uf.get('field.id').toString()] = uf.get('value');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return model.save(this.get('saveAttrNames')).then(() => {
|
||||
model.set('bio_cooked', cook(model.get('bio_raw')));
|
||||
this.set('saved', true);
|
||||
}).catch(popupAjaxError);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
|
||||
export default Ember.Controller.extend(PreferencesTabController, {
|
||||
|
||||
saveAttrNames: [
|
||||
'muted_tags',
|
||||
'tracked_tags',
|
||||
'watched_tags',
|
||||
'watching_first_post_tags'
|
||||
],
|
||||
|
||||
actions: {
|
||||
save() {
|
||||
this.set('saved', false);
|
||||
return this.get('model').save(this.get('saveAttrNames')).then(() => {
|
||||
this.set('saved', true);
|
||||
}).catch(popupAjaxError);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import { default as computed } from "ember-addons/ember-computed-decorators";
|
||||
|
||||
export default Ember.Mixin.create({
|
||||
saved: false,
|
||||
|
||||
@computed("model.isSaving")
|
||||
saveButtonText(isSaving) {
|
||||
return isSaving ? I18n.t('saving') : I18n.t('save');
|
||||
}
|
||||
});
|
||||
@@ -201,8 +201,9 @@ const User = RestModel.extend({
|
||||
return Discourse.User.create(this.getProperties(Object.keys(this)));
|
||||
},
|
||||
|
||||
save() {
|
||||
const data = this.getProperties(
|
||||
save(fields) {
|
||||
|
||||
let userFields = [
|
||||
'bio_raw',
|
||||
'website',
|
||||
'location',
|
||||
@@ -217,43 +218,55 @@ const User = RestModel.extend({
|
||||
'tracked_tags',
|
||||
'watched_tags',
|
||||
'watching_first_post_tags',
|
||||
'date_of_birth');
|
||||
'date_of_birth'
|
||||
];
|
||||
|
||||
['email_always',
|
||||
'mailing_list_mode',
|
||||
'mailing_list_mode_frequency',
|
||||
'external_links_in_new_tab',
|
||||
'email_digests',
|
||||
'email_direct',
|
||||
'email_in_reply_to',
|
||||
'email_private_messages',
|
||||
'email_previous_replies',
|
||||
'dynamic_favicon',
|
||||
'enable_quoting',
|
||||
'disable_jump_reply',
|
||||
'automatically_unpin_topics',
|
||||
'digest_after_minutes',
|
||||
'new_topic_duration_minutes',
|
||||
'auto_track_topics_after_msecs',
|
||||
'notification_level_when_replying',
|
||||
'like_notification_frequency',
|
||||
'include_tl0_in_digests'
|
||||
].forEach(s => {
|
||||
const data = this.getProperties(fields ? _.intersection(userFields, fields) : userFields);
|
||||
|
||||
let userOptionFields = [
|
||||
'email_always',
|
||||
'mailing_list_mode',
|
||||
'mailing_list_mode_frequency',
|
||||
'external_links_in_new_tab',
|
||||
'email_digests',
|
||||
'email_direct',
|
||||
'email_in_reply_to',
|
||||
'email_private_messages',
|
||||
'email_previous_replies',
|
||||
'dynamic_favicon',
|
||||
'enable_quoting',
|
||||
'disable_jump_reply',
|
||||
'automatically_unpin_topics',
|
||||
'digest_after_minutes',
|
||||
'new_topic_duration_minutes',
|
||||
'auto_track_topics_after_msecs',
|
||||
'notification_level_when_replying',
|
||||
'like_notification_frequency',
|
||||
'include_tl0_in_digests'
|
||||
];
|
||||
|
||||
if (fields) {
|
||||
userOptionFields = _.intersection(userOptionFields, fields);
|
||||
}
|
||||
|
||||
userOptionFields.forEach(s => {
|
||||
data[s] = this.get(`user_option.${s}`);
|
||||
});
|
||||
|
||||
var updatedState = {};
|
||||
|
||||
['muted','watched','tracked','watched_first_post'].forEach(s => {
|
||||
let prop = s === "watched_first_post" ? "watchedFirstPostCategories" : s + "Categories";
|
||||
let cats = this.get(prop);
|
||||
if (cats) {
|
||||
let cat_ids = cats.map(c => c.get('id'));
|
||||
updatedState[s + '_category_ids'] = cat_ids;
|
||||
if (fields === undefined || fields.includes(s + '_category_ids')) {
|
||||
let prop = s === "watched_first_post" ? "watchedFirstPostCategories" : s + "Categories";
|
||||
let cats = this.get(prop);
|
||||
if (cats) {
|
||||
let cat_ids = cats.map(c => c.get('id'));
|
||||
updatedState[s + '_category_ids'] = cat_ids;
|
||||
|
||||
// HACK: denote lack of categories
|
||||
if (cats.length === 0) { cat_ids = [-1]; }
|
||||
data[s + '_category_ids'] = cat_ids;
|
||||
// HACK: denote lack of categories
|
||||
if (cats.length === 0) { cat_ids = [-1]; }
|
||||
data[s + '_category_ids'] = cat_ids;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -97,6 +97,15 @@ export default function() {
|
||||
});
|
||||
|
||||
this.route('preferences', { resetNamespace: true }, function() {
|
||||
this.route('account');
|
||||
this.route('profile');
|
||||
this.route('emails');
|
||||
this.route('notifications');
|
||||
this.route('categories');
|
||||
this.route('tags');
|
||||
this.route('interface');
|
||||
this.route('apps');
|
||||
|
||||
this.route('username');
|
||||
this.route('email');
|
||||
this.route('about', { path: '/about-me' });
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||
|
||||
export default RestrictedUserRoute.extend({
|
||||
setupController(controller, user) {
|
||||
controller.reset();
|
||||
controller.setProperties({ model: user });
|
||||
}
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||
|
||||
export default RestrictedUserRoute.extend({
|
||||
renderTemplate: function() {
|
||||
this.render('preferences', { into: 'user', controller: 'preferences' });
|
||||
redirect() {
|
||||
this.transitionTo('preferences.account');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||
import { currentThemeKey } from 'discourse/lib/theme-selector';
|
||||
|
||||
export default RestrictedUserRoute.extend({
|
||||
setupController(controller, user) {
|
||||
controller.setProperties({
|
||||
model: user,
|
||||
selectedTheme: $.cookie('theme_key') || currentThemeKey()
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,10 @@
|
||||
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||
|
||||
export default RestrictedUserRoute.extend({
|
||||
setupController(controller, user) {
|
||||
controller.setProperties({
|
||||
model: user,
|
||||
newNameInput: user.get('name')
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -1,7 +1,6 @@
|
||||
import RestrictedUserRoute from "discourse/routes/restricted-user";
|
||||
import showModal from 'discourse/lib/show-modal';
|
||||
import { popupAjaxError } from 'discourse/lib/ajax-error';
|
||||
import { currentThemeKey } from 'discourse/lib/theme-selector';
|
||||
|
||||
export default RestrictedUserRoute.extend({
|
||||
model() {
|
||||
@@ -9,11 +8,8 @@ export default RestrictedUserRoute.extend({
|
||||
},
|
||||
|
||||
setupController(controller, user) {
|
||||
controller.reset();
|
||||
controller.setProperties({
|
||||
model: user,
|
||||
newNameInput: user.get('name'),
|
||||
selectedTheme: $.cookie('theme_key') || currentThemeKey()
|
||||
model: user
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<label>{{{field.name}}}</label>
|
||||
<label class="control-label">{{{field.name}}}</label>
|
||||
<div class='controls'>
|
||||
{{input value=value maxlength=site.user_field_max_length}}
|
||||
{{#if field.required}}<span class='required'>*</span>{{/if}}
|
||||
<p>{{{field.description}}}</p>
|
||||
<div class="instructions">{{{field.description}}}</div>
|
||||
</div>
|
||||
|
||||
@@ -1,383 +1,25 @@
|
||||
{{#d-section pageClass="user-preferences" class="user-content user-preferences"}}
|
||||
{{#d-section pageClass="user-preferences" class="user-navigation"}}
|
||||
{{#mobile-nav class='preferences-nav' desktopClass='preferences-list action-list nav-stacked' currentPath=application.currentPath}}
|
||||
<li class='no-glyph nav-account'>{{#link-to 'preferences.account'}}{{i18n 'user.preferences_nav.account'}}{{/link-to}}</li>
|
||||
<li class='no-glyph nav-profile'>{{#link-to 'preferences.profile'}}{{i18n 'user.preferences_nav.profile'}}{{/link-to}}</li>
|
||||
<li class='no-glyph nav-emails'>{{#link-to 'preferences.emails'}}{{i18n 'user.preferences_nav.emails'}}{{/link-to}}</li>
|
||||
<li class='no-glyph nav-notifications'>{{#link-to 'preferences.notifications'}}{{i18n 'user.preferences_nav.notifications'}}{{/link-to}}</li>
|
||||
<li class='no-glyph indent nav-categories'>{{#link-to 'preferences.categories'}}{{i18n 'user.preferences_nav.categories'}}{{/link-to}}</li>
|
||||
{{#if siteSettings.tagging_enabled}}
|
||||
<li class='no-glyph indent nav-tags'>{{#link-to 'preferences.tags'}}{{i18n 'user.preferences_nav.tags'}}{{/link-to}}</li>
|
||||
{{/if}}
|
||||
<li class='no-glyph nav-interface'>{{#link-to 'preferences.interface'}}{{i18n 'user.preferences_nav.interface'}}{{/link-to}}</li>
|
||||
{{#if model.userApiKeys}}
|
||||
<li class='no-glyph nav-apps'>{{#link-to 'preferences.apps'}}{{i18n 'user.preferences_nav.apps'}}{{/link-to}}</li>
|
||||
{{/if}}
|
||||
{{plugin-outlet name="user-preferences-nav"}}
|
||||
{{/mobile-nav}}
|
||||
{{/d-section}}
|
||||
|
||||
<section class='user-right user-preferences'>
|
||||
{{plugin-outlet name="above-user-preferences"}}
|
||||
|
||||
<form class="form-horizontal">
|
||||
|
||||
<div class="control-group save-button" id='save-button-top'>
|
||||
<div class="controls">
|
||||
{{partial 'user/preferences/save-button'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pref-username">
|
||||
<label class="control-label">{{i18n 'user.username.title'}}</label>
|
||||
<div class="controls">
|
||||
<span class='static'>{{model.username}}</span>
|
||||
{{#if model.can_edit_username}}
|
||||
{{#link-to "preferences.username" class="btn btn-small pad-left no-text"}}<i class="fa fa-pencil"></i>{{/link-to}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{{i18n 'user.username.short_instructions' username=model.username}}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if canEditName}}
|
||||
<div class="control-group pref-name">
|
||||
<label class="control-label">{{i18n 'user.name.title'}}</label>
|
||||
<div class="controls">
|
||||
{{#if model.can_edit_name}}
|
||||
{{text-field value=newNameInput classNames="input-xxlarge"}}
|
||||
{{else}}
|
||||
<span class='static'>{{model.name}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{nameInstructions}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if canSelectTitle}}
|
||||
<div class="control-group pref-title">
|
||||
<label class="control-label">{{i18n 'user.title.title'}}</label>
|
||||
<div class="controls">
|
||||
<span class="static">{{model.title}}</span>
|
||||
{{#link-to "preferences.badgeTitle" class="btn btn-small pad-left no-text"}}{{fa-icon "pencil"}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if canCheckEmails}}
|
||||
<div class="control-group pref-email">
|
||||
<label class="control-label">{{i18n 'user.email.title'}}</label>
|
||||
{{#if model.email}}
|
||||
<div class="controls">
|
||||
<span class='static'>{{model.email}}</span>
|
||||
{{#if model.can_edit_email}}
|
||||
{{#link-to "preferences.email" class="btn btn-small pad-left no-text"}}{{fa-icon "pencil"}}{{/link-to}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{i18n 'user.email.instructions'}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="controls">
|
||||
{{d-button action="checkEmail" actionParam=model title="admin.users.check_email.title" icon="envelope-o" label="admin.users.check_email.text"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if canChangePassword}}
|
||||
<div class="control-group pref-password">
|
||||
<label class="control-label">{{i18n 'user.password.title'}}</label>
|
||||
<div class="controls">
|
||||
<a href {{action "changePassword"}} class='btn'>
|
||||
{{fa-icon "envelope"}}
|
||||
{{#if model.no_password}}
|
||||
{{i18n 'user.change_password.set_password'}}
|
||||
{{else}}
|
||||
{{i18n 'user.change_password.action'}}
|
||||
{{/if}}
|
||||
</a>
|
||||
{{passwordProgress}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group pref-avatar">
|
||||
<label class="control-label">{{i18n 'user.avatar.title'}}</label>
|
||||
<div class="controls">
|
||||
{{! we want the "huge" version even though we're downsizing it to "large" in CSS }}
|
||||
{{bound-avatar model "huge"}}
|
||||
{{#unless siteSettings.sso_overrides_avatar}}
|
||||
{{d-button action="showAvatarSelector" class="pad-left" icon="pencil"}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if siteSettings.allow_profile_backgrounds}}
|
||||
<div class="control-group pref-profile-bg">
|
||||
<label class="control-label">{{i18n 'user.change_profile_background.title'}}</label>
|
||||
<div class="controls">
|
||||
{{image-uploader imageUrl=model.profile_background type="profile_background"}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{i18n 'user.change_profile_background.instructions'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pref-profile-bg">
|
||||
<label class="control-label">{{i18n 'user.change_card_background.title'}}</label>
|
||||
<div class="controls">
|
||||
{{image-uploader imageUrl=model.card_background type="card_background"}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{i18n 'user.change_card_background.instructions'}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if siteSettings.allow_user_locale}}
|
||||
<div class="control-group pref-locale">
|
||||
<label class="control-label">{{i18n 'user.locale.title'}}</label>
|
||||
<div class="controls">
|
||||
{{combo-box valueAttribute="value" content=availableLocales value=model.locale none="user.locale.default"}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{i18n 'user.locale.instructions'}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if canChangeBio}}
|
||||
<div class="control-group pref-bio">
|
||||
<label class="control-label">{{i18n 'user.bio'}}</label>
|
||||
<div class="controls bio-composer">
|
||||
{{d-editor value=model.bio_raw}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#each userFields as |uf|}}
|
||||
{{user-field field=uf.field value=uf.value}}
|
||||
{{/each}}
|
||||
<div class='clearfix'></div>
|
||||
|
||||
<div class="control-group pref-location">
|
||||
<label class="control-label">{{i18n 'user.location'}}</label>
|
||||
<div class="controls">
|
||||
{{input type="text" value=model.location class="input-xxlarge" id='edit-location'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pref-website">
|
||||
<label class="control-label">{{i18n 'user.website'}}</label>
|
||||
<div class="controls">
|
||||
{{input type="text" value=model.website class="input-xxlarge"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pref-card-badge">
|
||||
<label class="control-label">{{i18n 'user.card_badge.title'}}</label>
|
||||
<div class="controls">
|
||||
{{#if model.card_image_badge}}
|
||||
{{icon-or-image model.card_image_badge}}
|
||||
{{/if}}
|
||||
{{#link-to "preferences.card-badge" class="btn btn-small pad-left no-text"}}{{fa-icon "pencil"}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pref-email-settings">
|
||||
<label class="control-label">{{i18n 'user.email_settings'}}</label>
|
||||
<div class='controls controls-dropdown'>
|
||||
<label>{{i18n 'user.email_previous_replies.title'}}</label>
|
||||
{{combo-box valueAttribute="value" content=previousRepliesOptions value=model.user_option.email_previous_replies}}
|
||||
</div>
|
||||
{{preference-checkbox labelKey="user.email_in_reply_to" checked=model.user_option.email_in_reply_to}}
|
||||
{{preference-checkbox labelKey="user.email_private_messages" checked=model.user_option.email_private_messages}}
|
||||
{{preference-checkbox labelKey="user.email_direct" checked=model.user_option.email_direct}}
|
||||
{{preference-checkbox labelKey="user.email_always" checked=model.user_option.email_always}}
|
||||
{{#unless model.user_option.email_always}}
|
||||
<div class='instructions'>
|
||||
{{#if siteSettings.email_time_window_mins}}
|
||||
{{i18n 'user.email.frequency' count=siteSettings.email_time_window_mins}}
|
||||
{{else}}
|
||||
{{i18n 'user.email.frequency_immediately'}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
|
||||
{{#unless siteSettings.disable_digest_emails}}
|
||||
<div class='control-group pref-activity-summary'>
|
||||
<label class="control-label">{{i18n 'user.email_activity_summary'}}</label>
|
||||
{{preference-checkbox labelKey="user.email_digests.title" disabled=model.user_option.mailing_list_mode checked=model.user_option.email_digests}}
|
||||
{{#if model.user_option.email_digests}}
|
||||
<div class='controls controls-dropdown'>
|
||||
{{combo-box valueAttribute="value" content=digestFrequencies value=model.user_option.digest_after_minutes}}
|
||||
</div>
|
||||
{{preference-checkbox labelKey="user.include_tl0_in_digests" disabled=model.user_option.mailing_list_mode checked=model.user_option.include_tl0_in_digests}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
{{#unless siteSettings.disable_mailing_list_mode}}
|
||||
<div class='control-group pref-mailing-list-mode'>
|
||||
<label class="control-label">{{i18n 'user.mailing_list_mode.label'}}</label>
|
||||
{{preference-checkbox labelKey="user.mailing_list_mode.enabled" checked=model.user_option.mailing_list_mode}}
|
||||
<div class='instructions'>{{{i18n 'user.mailing_list_mode.instructions'}}}</div>
|
||||
{{#if model.user_option.mailing_list_mode}}
|
||||
<div class='controls controls-dropdown'>
|
||||
{{combo-box valueAttribute="value" content=mailingListModeOptions value=model.user_option.mailing_list_mode_frequency}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
<div class="control-group notifications">
|
||||
<label class="control-label">{{i18n 'user.desktop_notifications.label'}}</label>
|
||||
{{desktop-notification-config}}
|
||||
<div class="instructions">{{i18n 'user.desktop_notifications.each_browser_note'}}</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group other">
|
||||
<label class="control-label">{{i18n 'user.other_settings'}}</label>
|
||||
|
||||
<div class="controls controls-dropdown">
|
||||
<label>{{i18n 'user.new_topic_duration.label'}}</label>
|
||||
{{combo-box valueAttribute="value" content=considerNewTopicOptions value=model.user_option.new_topic_duration_minutes}}
|
||||
</div>
|
||||
|
||||
<div class="controls controls-dropdown">
|
||||
<label>{{i18n 'user.auto_track_topics'}}</label>
|
||||
{{combo-box valueAttribute="value" content=autoTrackDurations value=model.user_option.auto_track_topics_after_msecs}}
|
||||
</div>
|
||||
|
||||
<div class="controls controls-dropdown">
|
||||
<label>{{i18n 'user.notification_level_when_replying'}}</label>
|
||||
{{combo-box valueAttribute="value" content=notificationLevelsForReplying value=model.user_option.notification_level_when_replying}}
|
||||
</div>
|
||||
|
||||
<div class="controls controls-dropdown">
|
||||
<label>{{i18n 'user.like_notification_frequency.title'}}</label>
|
||||
{{combo-box valueAttribute="value" content=likeNotificationFrequencies value=model.user_option.like_notification_frequency}}
|
||||
</div>
|
||||
|
||||
{{preference-checkbox labelKey="user.external_links_in_new_tab" checked=model.user_option.external_links_in_new_tab}}
|
||||
{{preference-checkbox labelKey="user.enable_quoting" checked=model.user_option.enable_quoting}}
|
||||
{{preference-checkbox labelKey="user.dynamic_favicon" checked=model.user_option.dynamic_favicon}}
|
||||
{{preference-checkbox labelKey="user.disable_jump_reply" checked=model.user_option.disable_jump_reply}}
|
||||
{{plugin-outlet name="user-custom-preferences" args=(hash model=model)}}
|
||||
</div>
|
||||
|
||||
<div class="control-group category">
|
||||
<label class="control-label">{{i18n 'user.categories_settings'}}</label>
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-exclamation-circle watching"></span> {{i18n 'user.watched_categories'}}</label>
|
||||
{{category-selector categories=model.watchedCategories blacklist=selectedCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_categories_instructions'}}</div>
|
||||
<div class="controls category-controls">
|
||||
<a href="{{unbound model.watchingTopicsPath}}">{{i18n 'user.watched_topics_link'}}</a>
|
||||
</div>
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-circle tracking"></span> {{i18n 'user.tracked_categories'}}</label>
|
||||
{{category-selector categories=model.trackedCategories blacklist=selectedCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.tracked_categories_instructions'}}</div>
|
||||
<div class="controls category-controls">
|
||||
<a href="{{unbound model.trackingTopicsPath}}">{{i18n 'user.tracked_topics_link'}}</a>
|
||||
</div>
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-dot-circle-o watching-first-post"></span> {{i18n 'user.watched_first_post_categories'}}</label>
|
||||
{{category-selector categories=model.watchedFirstPostCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_first_post_categories_instructions'}}</div>
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-times-circle muted"></span> {{i18n 'user.muted_categories'}}</label>
|
||||
{{category-selector categories=model.mutedCategories blacklist=selectedCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.muted_categories_instructions'}}</div>
|
||||
<div class="controls category-controls">
|
||||
<a href="{{unbound model.mutedTopicsPath}}">{{i18n 'user.muted_topics_link'}}</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if siteSettings.tagging_enabled}}
|
||||
<div class="control-group tags">
|
||||
<label class="control-label">{{i18n 'user.tag_settings'}}</label>
|
||||
<div class="controls tag-controls">
|
||||
<label><span class="icon fa fa-exclamation-circle watching"></span> {{i18n 'user.watched_tags'}}</label>
|
||||
{{tag-chooser tags=model.watched_tags blacklist=selectedTags allowCreate=false placeholder="" everyTag="true" unlimitedTagCount="true"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_tags_instructions'}}</div>
|
||||
<div class="controls tag-controls">
|
||||
<label><span class="icon fa fa-circle tracking"></span> {{i18n 'user.tracked_tags'}}</label>
|
||||
{{tag-chooser tags=model.tracked_tags blacklist=selectedTags allowCreate=false placeholder="" everyTag="true" unlimitedTagCount="true"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.tracked_tags_instructions'}}</div>
|
||||
<div class="controls tag-controls">
|
||||
<label><span class="icon fa fa-dot-circle-o watching-first-post"></span> {{i18n 'user.watched_first_post_tags'}}</label>
|
||||
{{tag-chooser tags=model.watching_first_post_tags blacklist=selectedTags allowCreate=false placeholder="" everyTag="true" unlimitedTagCount="true"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_first_post_tags_instructions'}}</div>
|
||||
<div class="controls tag-controls">
|
||||
<label><span class="icon fa fa-times-circle muted"></span> {{i18n 'user.muted_tags'}}</label>
|
||||
{{tag-chooser tags=model.muted_tags blacklist=selectedTags allowCreate=false placeholder="" everyTag="true" unlimitedTagCount="true"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.muted_tags_instructions'}}</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group muting">
|
||||
<label class="control-label">{{i18n 'user.users'}}</label>
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-times-circle muted"></span> {{i18n 'user.muted_users'}}</label>
|
||||
{{user-selector excludeCurrentUser=true usernames=model.muted_usernames class="user-selector"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.muted_users_instructions'}}</div>
|
||||
</div>
|
||||
|
||||
{{#if siteSettings.automatically_unpin_topics}}
|
||||
<div class="control-group topics">
|
||||
<label class="control-label">{{i18n 'categories.topics'}}</label>
|
||||
{{preference-checkbox labelKey="user.automatically_unpin_topics" checked=model.user_option.automatically_unpin_topics}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if model.userApiKeys}}
|
||||
<div class="control-group apps">
|
||||
<label class="control-label">{{i18n 'user.apps'}}</label>
|
||||
<div class="controls">
|
||||
{{#each model.userApiKeys as |key|}}
|
||||
<div>
|
||||
<span>{{key.application_name}}</span>
|
||||
{{#if key.revoked}}
|
||||
{{d-button action="undoRevokeApiKey" actionParam=key class="btn" label="user.undo_revoke_access"}}
|
||||
{{else}}
|
||||
{{d-button action="revokeApiKey" actionParam=key class="btn" label="user.revoke_access"}}
|
||||
{{/if}}
|
||||
<p>
|
||||
<ul>
|
||||
{{#each key.scopes as |scope|}}
|
||||
<li>{{scope}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</p>
|
||||
<p><span>{{i18n "user.api_approved"}}</span> {{bound-date key.created_at}}</p>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if userSelectableThemes}}
|
||||
<div class="control-group theme">
|
||||
<label class="control-label">{{i18n 'user.theme'}}</label>
|
||||
<div class="controls">
|
||||
{{combo-box content=userSelectableThemes value=selectedTheme}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{plugin-outlet name="user-custom-controls" args=(hash model=model)}}
|
||||
|
||||
<div class="control-group save-button">
|
||||
<div class="controls">
|
||||
{{partial 'user/preferences/save-button'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if model.canDeleteAccount}}
|
||||
<div class="control-group delete-account">
|
||||
<hr/>
|
||||
<div class="controls">
|
||||
{{d-button action="delete" disabled=deleteDisabled class="btn-danger" icon="trash-o" label="user.delete_account"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
<form class="form-vertical">
|
||||
{{outlet}}
|
||||
</form>
|
||||
{{/d-section}}
|
||||
</section>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<div class="control-group pref-username">
|
||||
<label class="control-label">{{i18n 'user.username.title'}}</label>
|
||||
<div class="controls">
|
||||
<span class='static'>{{model.username}}</span>
|
||||
{{#if model.can_edit_username}}
|
||||
{{#link-to "preferences.username" class="btn btn-small pad-left no-text"}}<i class="fa fa-pencil"></i>{{/link-to}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{{i18n 'user.username.short_instructions' username=model.username}}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if canCheckEmails}}
|
||||
<div class="control-group pref-email">
|
||||
<label class="control-label">{{i18n 'user.email.title'}}</label>
|
||||
{{#if model.email}}
|
||||
<div class="controls">
|
||||
<span class='static'>{{model.email}}</span>
|
||||
{{#if model.can_edit_email}}
|
||||
{{#link-to "preferences.email" class="btn btn-small pad-left no-text"}}{{fa-icon "pencil"}}{{/link-to}}
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{i18n 'user.email.instructions'}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="controls">
|
||||
{{d-button action="checkEmail" actionParam=model title="admin.users.check_email.title" icon="envelope-o" label="admin.users.check_email.text"}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if canChangePassword}}
|
||||
<div class="control-group pref-password">
|
||||
<label class="control-label">{{i18n 'user.password.title'}}</label>
|
||||
<div class="controls">
|
||||
<a href {{action "changePassword"}} class='btn'>
|
||||
{{fa-icon "envelope"}}
|
||||
{{#if model.no_password}}
|
||||
{{i18n 'user.change_password.set_password'}}
|
||||
{{else}}
|
||||
{{i18n 'user.change_password.action'}}
|
||||
{{/if}}
|
||||
</a>
|
||||
{{passwordProgress}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{plugin-outlet name="user-preferences-account"}}
|
||||
|
||||
<br/>
|
||||
|
||||
{{#if model.canDeleteAccount}}
|
||||
<div class="control-group delete-account">
|
||||
<br/>
|
||||
<div class="controls">
|
||||
{{d-button action="delete" disabled=deleteDisabled class="btn-danger" icon="trash-o" label="user.delete_account"}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
@@ -0,0 +1,27 @@
|
||||
{{#if model.userApiKeys}}
|
||||
<div class="control-group apps">
|
||||
<label class="control-label">{{i18n 'user.apps'}}</label>
|
||||
<div class="controls">
|
||||
{{#each model.userApiKeys as |key|}}
|
||||
<div>
|
||||
<span>{{key.application_name}}</span>
|
||||
{{#if key.revoked}}
|
||||
{{d-button action="undoRevokeApiKey" actionParam=key class="btn" label="user.undo_revoke_access"}}
|
||||
{{else}}
|
||||
{{d-button action="revokeApiKey" actionParam=key class="btn" label="user.revoke_access"}}
|
||||
{{/if}}
|
||||
<p>
|
||||
<ul>
|
||||
{{#each key.scopes as |scope|}}
|
||||
<li>{{scope}}</li>
|
||||
{{/each}}
|
||||
</ul>
|
||||
</p>
|
||||
<p><span>{{i18n "user.api_approved"}}</span> {{bound-date key.created_at}}</p>
|
||||
</div>
|
||||
{{/each}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{plugin-outlet name="user-preferences-apps"}}
|
||||
@@ -0,0 +1,50 @@
|
||||
<div class="control-group category-notifications">
|
||||
|
||||
<label class="control-label">{{i18n 'user.categories_settings'}}</label>
|
||||
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-exclamation-circle watching"></span> {{i18n 'user.watched_categories'}}</label>
|
||||
{{category-selector categories=model.watchedCategories blacklist=selectedCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_categories_instructions'}}</div>
|
||||
<div class="controls">
|
||||
<a href="{{unbound model.watchingTopicsPath}}">{{i18n 'user.watched_topics_link'}}</a>
|
||||
</div>
|
||||
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-circle tracking"></span> {{i18n 'user.tracked_categories'}}</label>
|
||||
{{category-selector categories=model.trackedCategories blacklist=selectedCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.tracked_categories_instructions'}}</div>
|
||||
<div class="controls">
|
||||
<a href="{{unbound model.trackingTopicsPath}}">{{i18n 'user.tracked_topics_link'}}</a>
|
||||
</div>
|
||||
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-dot-circle-o watching-first-post"></span> {{i18n 'user.watched_first_post_categories'}}</label>
|
||||
{{category-selector categories=model.watchedFirstPostCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_first_post_categories_instructions'}}</div>
|
||||
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-times-circle muted"></span> {{i18n 'user.muted_categories'}}</label>
|
||||
{{category-selector categories=model.mutedCategories blacklist=selectedCategories}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.muted_categories_instructions'}}</div>
|
||||
<div class="controls">
|
||||
<a href="{{unbound model.mutedTopicsPath}}">{{i18n 'user.muted_topics_link'}}</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{plugin-outlet name="user-preferences-categories"}}
|
||||
|
||||
<br/>
|
||||
|
||||
{{plugin-outlet name="user-custom-controls" args=(hash model=model)}}
|
||||
|
||||
<div class="control-group save-button">
|
||||
<div class="controls">
|
||||
{{partial 'user/preferences/save-button'}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,58 @@
|
||||
<div class="control-group pref-email-settings">
|
||||
<label class="control-label">{{i18n 'user.email_settings'}}</label>
|
||||
<div class='controls controls-dropdown'>
|
||||
<label>{{i18n 'user.email_previous_replies.title'}}</label>
|
||||
{{combo-box valueAttribute="value" content=previousRepliesOptions value=model.user_option.email_previous_replies}}
|
||||
</div>
|
||||
{{preference-checkbox labelKey="user.email_in_reply_to" checked=model.user_option.email_in_reply_to}}
|
||||
{{preference-checkbox labelKey="user.email_private_messages" checked=model.user_option.email_private_messages}}
|
||||
{{preference-checkbox labelKey="user.email_direct" checked=model.user_option.email_direct}}
|
||||
{{preference-checkbox labelKey="user.email_always" checked=model.user_option.email_always}}
|
||||
{{#unless model.user_option.email_always}}
|
||||
<div class='instructions'>
|
||||
{{#if siteSettings.email_time_window_mins}}
|
||||
{{i18n 'user.email.frequency' count=siteSettings.email_time_window_mins}}
|
||||
{{else}}
|
||||
{{i18n 'user.email.frequency_immediately'}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
</div>
|
||||
|
||||
{{#unless siteSettings.disable_digest_emails}}
|
||||
<div class='control-group pref-activity-summary'>
|
||||
<label class="control-label">{{i18n 'user.email_activity_summary'}}</label>
|
||||
{{preference-checkbox labelKey="user.email_digests.title" disabled=model.user_option.mailing_list_mode checked=model.user_option.email_digests}}
|
||||
{{#if model.user_option.email_digests}}
|
||||
<div class='controls controls-dropdown'>
|
||||
{{combo-box valueAttribute="value" content=digestFrequencies value=model.user_option.digest_after_minutes}}
|
||||
</div>
|
||||
{{preference-checkbox labelKey="user.include_tl0_in_digests" disabled=model.user_option.mailing_list_mode checked=model.user_option.include_tl0_in_digests}}
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
{{#unless siteSettings.disable_mailing_list_mode}}
|
||||
<div class='control-group pref-mailing-list-mode'>
|
||||
<label class="control-label">{{i18n 'user.mailing_list_mode.label'}}</label>
|
||||
{{preference-checkbox labelKey="user.mailing_list_mode.enabled" checked=model.user_option.mailing_list_mode}}
|
||||
<div class='instructions'>{{{i18n 'user.mailing_list_mode.instructions'}}}</div>
|
||||
{{#if model.user_option.mailing_list_mode}}
|
||||
<div class='controls controls-dropdown'>
|
||||
{{combo-box valueAttribute="value" content=mailingListModeOptions value=model.user_option.mailing_list_mode_frequency}}
|
||||
</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
{{/unless}}
|
||||
|
||||
{{plugin-outlet name="user-preferences-emails"}}
|
||||
|
||||
<br/>
|
||||
|
||||
{{plugin-outlet name="user-custom-controls" args=(hash model=model)}}
|
||||
|
||||
<div class="control-group save-button">
|
||||
<div class="controls">
|
||||
{{partial 'user/preferences/save-button'}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,49 @@
|
||||
{{#if userSelectableThemes}}
|
||||
<div class="control-group theme">
|
||||
<label class="control-label">{{i18n 'user.theme'}}</label>
|
||||
<div class="controls">
|
||||
{{combo-box content=userSelectableThemes value=selectedTheme}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if siteSettings.allow_user_locale}}
|
||||
<div class="control-group pref-locale">
|
||||
<label class="control-label">{{i18n 'user.locale.title'}}</label>
|
||||
<div class="controls">
|
||||
{{combo-box valueAttribute="value" content=availableLocales value=model.locale none="user.locale.default"}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{i18n 'user.locale.instructions'}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
|
||||
<div class="control-group other">
|
||||
<label class="control-label">{{i18n 'user.other_settings'}}</label>
|
||||
|
||||
{{preference-checkbox labelKey="user.external_links_in_new_tab" checked=model.user_option.external_links_in_new_tab}}
|
||||
{{preference-checkbox labelKey="user.enable_quoting" checked=model.user_option.enable_quoting}}
|
||||
{{preference-checkbox labelKey="user.dynamic_favicon" checked=model.user_option.dynamic_favicon}}
|
||||
{{preference-checkbox labelKey="user.disable_jump_reply" checked=model.user_option.disable_jump_reply}}
|
||||
</div>
|
||||
|
||||
{{#if siteSettings.automatically_unpin_topics}}
|
||||
<div class="control-group topics">
|
||||
<label class="control-label">{{i18n 'categories.topics'}}</label>
|
||||
{{preference-checkbox labelKey="user.automatically_unpin_topics" checked=model.user_option.automatically_unpin_topics}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{plugin-outlet name="user-preferences-interface"}}
|
||||
|
||||
<br/>
|
||||
|
||||
{{plugin-outlet name="user-custom-controls" args=(hash model=model)}}
|
||||
|
||||
<div class="control-group save-button">
|
||||
<div class="controls">
|
||||
{{partial 'user/preferences/save-button'}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,48 @@
|
||||
<div class="control-group notifications">
|
||||
<div class="controls controls-dropdown">
|
||||
<label>{{i18n 'user.new_topic_duration.label'}}</label>
|
||||
{{combo-box valueAttribute="value" content=considerNewTopicOptions value=model.user_option.new_topic_duration_minutes}}
|
||||
</div>
|
||||
|
||||
<div class="controls controls-dropdown">
|
||||
<label>{{i18n 'user.auto_track_topics'}}</label>
|
||||
{{combo-box valueAttribute="value" content=autoTrackDurations value=model.user_option.auto_track_topics_after_msecs}}
|
||||
</div>
|
||||
|
||||
<div class="controls controls-dropdown">
|
||||
<label>{{i18n 'user.notification_level_when_replying'}}</label>
|
||||
{{combo-box valueAttribute="value" content=notificationLevelsForReplying value=model.user_option.notification_level_when_replying}}
|
||||
</div>
|
||||
|
||||
<div class="controls controls-dropdown">
|
||||
<label>{{i18n 'user.like_notification_frequency.title'}}</label>
|
||||
{{combo-box valueAttribute="value" content=likeNotificationFrequencies value=model.user_option.like_notification_frequency}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group desktop-notifications">
|
||||
<label class="control-label">{{i18n 'user.desktop_notifications.label'}}</label>
|
||||
{{desktop-notification-config}}
|
||||
<div class="instructions">{{i18n 'user.desktop_notifications.each_browser_note'}}</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group muting">
|
||||
<label class="control-label">{{i18n 'user.users'}}</label>
|
||||
<div class="controls category-controls">
|
||||
<label><span class="icon fa fa-times-circle muted"></span> {{i18n 'user.muted_users'}}</label>
|
||||
{{user-selector excludeCurrentUser=true usernames=model.muted_usernames class="user-selector"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.muted_users_instructions'}}</div>
|
||||
</div>
|
||||
|
||||
{{plugin-outlet name="user-preferences-notifications"}}
|
||||
|
||||
<br/>
|
||||
|
||||
{{plugin-outlet name="user-custom-controls" args=(hash model=model)}}
|
||||
|
||||
<div class="control-group save-button">
|
||||
<div class="controls">
|
||||
{{partial 'user/preferences/save-button'}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,112 @@
|
||||
{{#if canEditName}}
|
||||
<div class="control-group pref-name">
|
||||
<label class="control-label">{{i18n 'user.name.title'}}</label>
|
||||
<div class="controls">
|
||||
{{#if model.can_edit_name}}
|
||||
{{text-field value=newNameInput classNames="input-xxlarge"}}
|
||||
{{else}}
|
||||
<span class='static'>{{model.name}}</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{nameInstructions}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if canSelectTitle}}
|
||||
<div class="control-group pref-title">
|
||||
<label class="control-label">{{i18n 'user.title.title'}}</label>
|
||||
<div class="controls">
|
||||
<span class="static">{{model.title}}</span>
|
||||
{{#link-to "preferences.badgeTitle" class="btn btn-small pad-left no-text"}}{{fa-icon "pencil"}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group pref-avatar">
|
||||
<label class="control-label">{{i18n 'user.avatar.title'}}</label>
|
||||
<div class="controls">
|
||||
{{! we want the "huge" version even though we're downsizing it to "large" in CSS }}
|
||||
{{bound-avatar model "huge"}}
|
||||
{{#unless siteSettings.sso_overrides_avatar}}
|
||||
{{d-button action="showAvatarSelector" class="pad-left" icon="pencil"}}
|
||||
{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if siteSettings.allow_profile_backgrounds}}
|
||||
<div class="control-group pref-profile-bg">
|
||||
<label class="control-label">{{i18n 'user.change_profile_background.title'}}</label>
|
||||
<div class="controls">
|
||||
{{image-uploader imageUrl=model.profile_background type="profile_background"}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{i18n 'user.change_profile_background.instructions'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pref-profile-bg">
|
||||
<label class="control-label">{{i18n 'user.change_card_background.title'}}</label>
|
||||
<div class="controls">
|
||||
{{image-uploader imageUrl=model.card_background type="card_background"}}
|
||||
</div>
|
||||
<div class='instructions'>
|
||||
{{i18n 'user.change_card_background.instructions'}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if canChangeBio}}
|
||||
<div class="control-group pref-bio">
|
||||
<label class="control-label">{{i18n 'user.bio'}}</label>
|
||||
<div class="controls bio-composer">
|
||||
{{d-editor value=model.bio_raw}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
<div class="control-group pref-location">
|
||||
<label class="control-label">{{i18n 'user.location'}}</label>
|
||||
<div class="controls">
|
||||
{{input type="text" value=model.location class="input-xxlarge" id='edit-location'}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="control-group pref-website">
|
||||
<label class="control-label">{{i18n 'user.website'}}</label>
|
||||
<div class="controls">
|
||||
{{input type="text" value=model.website class="input-xxlarge"}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#each userFields as |uf|}}
|
||||
<div class="control-group">
|
||||
{{user-field field=uf.field value=uf.value}}
|
||||
</div>
|
||||
{{/each}}
|
||||
<div class='clearfix'></div>
|
||||
|
||||
<div class="control-group pref-card-badge">
|
||||
<label class="control-label">{{i18n 'user.card_badge.title'}}</label>
|
||||
<div class="controls">
|
||||
{{#if model.card_image_badge}}
|
||||
{{icon-or-image model.card_image_badge}}
|
||||
{{/if}}
|
||||
{{#link-to "preferences.card-badge" class="btn btn-small pad-left no-text"}}{{fa-icon "pencil"}}{{/link-to}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{plugin-outlet name="user-preferences-profile"}}
|
||||
|
||||
{{plugin-outlet name="user-custom-preferences" args=(hash model=model)}}
|
||||
|
||||
<br/>
|
||||
|
||||
{{plugin-outlet name="user-custom-controls" args=(hash model=model)}}
|
||||
|
||||
<div class="control-group save-button">
|
||||
<div class="controls">
|
||||
{{partial 'user/preferences/save-button'}}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,43 @@
|
||||
{{#if siteSettings.tagging_enabled}}
|
||||
<div class="control-group tag-notifications">
|
||||
|
||||
<label class="control-label">{{i18n 'user.tag_settings'}}</label>
|
||||
|
||||
<div class="controls tag-controls">
|
||||
<label><span class="icon fa fa-exclamation-circle watching"></span> {{i18n 'user.watched_tags'}}</label>
|
||||
{{tag-chooser tags=model.watched_tags blacklist=selectedTags allowCreate=false placeholder="" everyTag="true" unlimitedTagCount="true"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_tags_instructions'}}</div>
|
||||
|
||||
<div class="controls tag-controls">
|
||||
<label><span class="icon fa fa-circle tracking"></span> {{i18n 'user.tracked_tags'}}</label>
|
||||
{{tag-chooser tags=model.tracked_tags blacklist=selectedTags allowCreate=false placeholder="" everyTag="true" unlimitedTagCount="true"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.tracked_tags_instructions'}}</div>
|
||||
|
||||
<div class="controls tag-controls">
|
||||
<label><span class="icon fa fa-dot-circle-o watching-first-post"></span> {{i18n 'user.watched_first_post_tags'}}</label>
|
||||
{{tag-chooser tags=model.watching_first_post_tags blacklist=selectedTags allowCreate=false placeholder="" everyTag="true" unlimitedTagCount="true"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.watched_first_post_tags_instructions'}}</div>
|
||||
|
||||
<div class="controls tag-controls">
|
||||
<label><span class="icon fa fa-times-circle muted"></span> {{i18n 'user.muted_tags'}}</label>
|
||||
{{tag-chooser tags=model.muted_tags blacklist=selectedTags allowCreate=false placeholder="" everyTag="true" unlimitedTagCount="true"}}
|
||||
</div>
|
||||
<div class="instructions">{{i18n 'user.muted_tags_instructions'}}</div>
|
||||
|
||||
</div>
|
||||
|
||||
{{plugin-outlet name="user-preferences-tags"}}
|
||||
|
||||
<br/>
|
||||
|
||||
{{plugin-outlet name="user-custom-controls" args=(hash model=model)}}
|
||||
|
||||
<div class="control-group save-button">
|
||||
<div class="controls">
|
||||
{{partial 'user/preferences/save-button'}}
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
Reference in New Issue
Block a user