From bef80633b1b58189a732a3959d3a59da44aa55e9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9gis=20Hanol?= Date: Fri, 21 Aug 2015 20:39:21 +0200 Subject: [PATCH] FEATURE: global admin override of most of the user preferences --- .../admin/components/site-setting.js.es6 | 56 +++++------ .../components/site-settings/bool.js.es6 | 17 ++++ .../site-settings/category-list.js.es6 | 16 ++++ .../templates/components/site-setting.hbs | 2 +- .../{ => components}/site-settings/bool.hbs | 0 .../site-settings/category-list.hbs | 3 + .../{ => components}/site-settings/enum.hbs | 2 +- .../site-settings/host-list.hbs} | 2 +- .../{ => components}/site-settings/list.hbs | 2 +- .../{ => components}/site-settings/string.hbs | 2 +- .../site-settings/url-list.hbs} | 2 +- .../components/category-group.js.es6 | 4 +- .../discourse/controllers/preferences.js.es6 | 22 ++--- .../stylesheets/common/admin/admin_base.scss | 3 + .../auto_track_duration_site_setting.rb | 27 ++++++ app/models/new_topic_duration_site_setting.rb | 24 +++++ app/models/site_setting.rb | 8 ++ app/models/topic_tracking_state.rb | 2 +- app/models/topic_user.rb | 6 +- app/models/user.rb | 82 ++++++++++++---- app/serializers/user_serializer.rb | 4 +- config/locales/client.en.yml | 24 ++--- config/locales/server.bs_BA.yml | 4 +- config/locales/server.cs.yml | 4 +- config/locales/server.da.yml | 4 +- config/locales/server.de.yml | 4 +- config/locales/server.en.yml | 24 ++++- config/locales/server.es.yml | 4 +- config/locales/server.fa_IR.yml | 4 +- config/locales/server.fi.yml | 4 +- config/locales/server.fr.yml | 4 +- config/locales/server.he.yml | 4 +- config/locales/server.it.yml | 4 +- config/locales/server.ja.yml | 4 +- config/locales/server.ko.yml | 4 +- config/locales/server.nl.yml | 4 +- config/locales/server.pl_PL.yml | 4 +- config/locales/server.pt.yml | 4 +- config/locales/server.pt_BR.yml | 4 +- config/locales/server.ro.yml | 2 +- config/locales/server.ru.yml | 4 +- config/locales/server.sq.yml | 4 +- config/locales/server.sv.yml | 2 +- config/locales/server.tr_TR.yml | 4 +- config/locales/server.uk.yml | 4 +- config/locales/server.zh_CN.yml | 4 +- config/locales/server.zh_TW.yml | 4 +- config/site_settings.yml | 37 ++++++-- lib/site_setting_extension.rb | 2 +- lib/site_setting_validations.rb | 9 ++ .../site_settings/yaml_loader_spec.rb | 2 +- spec/fixtures/site_settings/enum.yml | 2 +- spec/jobs/enqueue_digest_emails_spec.rb | 4 +- .../notify_mailing_list_subscribers_spec.rb | 95 ++++++++++--------- spec/models/topic_user_spec.rb | 12 ++- spec/models/user_spec.rb | 64 +++++++++---- 56 files changed, 438 insertions(+), 215 deletions(-) create mode 100644 app/assets/javascripts/admin/components/site-settings/bool.js.es6 create mode 100644 app/assets/javascripts/admin/components/site-settings/category-list.js.es6 rename app/assets/javascripts/admin/templates/{ => components}/site-settings/bool.hbs (100%) create mode 100644 app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs rename app/assets/javascripts/admin/templates/{ => components}/site-settings/enum.hbs (80%) rename app/assets/javascripts/admin/templates/{site-settings/url_list.hbs => components/site-settings/host-list.hbs} (60%) rename app/assets/javascripts/admin/templates/{ => components}/site-settings/list.hbs (54%) rename app/assets/javascripts/admin/templates/{ => components}/site-settings/string.hbs (62%) rename app/assets/javascripts/admin/templates/{site-settings/host_list.hbs => components/site-settings/url-list.hbs} (60%) create mode 100644 app/models/auto_track_duration_site_setting.rb create mode 100644 app/models/new_topic_duration_site_setting.rb diff --git a/app/assets/javascripts/admin/components/site-setting.js.es6 b/app/assets/javascripts/admin/components/site-setting.js.es6 index f89996c70a5..93e65743c7e 100644 --- a/app/assets/javascripts/admin/components/site-setting.js.es6 +++ b/app/assets/javascripts/admin/components/site-setting.js.es6 @@ -4,7 +4,7 @@ import SiteSetting from 'admin/models/site-setting'; import { propertyNotEqual } from 'discourse/lib/computed'; import computed from 'ember-addons/ember-computed-decorators'; -const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list']; +const CustomTypes = ['bool', 'enum', 'list', 'url_list', 'host_list', 'category_list']; export default Ember.Component.extend(BufferedContent, ScrollTop, { classNameBindings: [':row', ':setting', 'setting.overridden', 'typeClass'], @@ -12,44 +12,32 @@ export default Ember.Component.extend(BufferedContent, ScrollTop, { dirty: propertyNotEqual('buffered.value', 'setting.value'), validationMessage: null, - preview: function() { - const preview = this.get('setting.preview'); + @computed("setting.preview", "buffered.value") + preview(preview, value) { if (preview) { - return new Handlebars.SafeString("
" + - preview.replace(/\{\{value\}\}/g, this.get('buffered.value')) + - "
"); - } - }.property('buffered.value'), - - @computed('partialType') - typeClass() { - return this.get('partialType').replace("_", "-"); - }, - - @computed('buffered.value') - enabled: { - get(bufferedValue) { - if (Ember.isEmpty(bufferedValue)) { return false; } - return bufferedValue === 'true'; - }, - set(value) { - this.set('buffered.value', value ? 'true' : 'false'); - return value; + return new Handlebars.SafeString("
" + preview.replace(/\{\{value\}\}/g, value) + "
"); } }, - settingName: function() { - return this.get('setting.setting').replace(/\_/g, ' '); - }.property('setting.setting'), + @computed('componentType') + typeClass(componentType) { + return componentType.replace("_", "-"); + }, - partialType: function() { - let type = this.get('setting.type'); + @computed("setting.setting") + settingName(setting) { + return setting.replace(/\_/g, ' '); + }, + + @computed("setting.type") + componentType(type) { return CustomTypes.indexOf(type) !== -1 ? type : 'string'; - }.property('setting.type'), + }, - partialName: function() { - return 'admin/templates/site-settings/' + this.get('partialType'); - }.property('partialType'), + @computed("typeClass") + componentName(typeClass) { + return "site-settings/" + typeClass; + }, _watchEnterKey: function() { const self = this; @@ -65,8 +53,8 @@ export default Ember.Component.extend(BufferedContent, ScrollTop, { }.on("willDestroyElement"), _save() { - const setting = this.get('buffered'); - const self = this; + const self = this, + setting = this.get('buffered'); SiteSetting.update(setting.get('setting'), setting.get('value')).then(function() { self.set('validationMessage', null); self.commitBuffer(); diff --git a/app/assets/javascripts/admin/components/site-settings/bool.js.es6 b/app/assets/javascripts/admin/components/site-settings/bool.js.es6 new file mode 100644 index 00000000000..40fcfb354b6 --- /dev/null +++ b/app/assets/javascripts/admin/components/site-settings/bool.js.es6 @@ -0,0 +1,17 @@ +import computed from "ember-addons/ember-computed-decorators"; + +export default Ember.Component.extend({ + + @computed("value") + enabled: { + get(value) { + if (Ember.isEmpty(value)) { return false; } + return value === "true"; + }, + set(value) { + this.set("value", value ? "true" : "false"); + return value; + } + }, + +}); diff --git a/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 b/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 new file mode 100644 index 00000000000..487239b78fa --- /dev/null +++ b/app/assets/javascripts/admin/components/site-settings/category-list.js.es6 @@ -0,0 +1,16 @@ +import computed from "ember-addons/ember-computed-decorators"; + +export default Ember.Component.extend({ + + @computed("value") + selectedCategories: { + get(value) { + return Discourse.Category.findByIds(value.split("|")); + }, + set(value) { + this.set("value", value.mapBy("id").join("|")); + return value; + } + } + +}); diff --git a/app/assets/javascripts/admin/templates/components/site-setting.hbs b/app/assets/javascripts/admin/templates/components/site-setting.hbs index 15821600ee2..be0d4d8a08c 100644 --- a/app/assets/javascripts/admin/templates/components/site-setting.hbs +++ b/app/assets/javascripts/admin/templates/components/site-setting.hbs @@ -2,7 +2,7 @@

{{unbound settingName}}

- {{partial partialName}} +{{component componentName setting=setting value=buffered.value validationMessage=validationMessage}}
{{#if dirty}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/bool.hbs b/app/assets/javascripts/admin/templates/components/site-settings/bool.hbs similarity index 100% rename from app/assets/javascripts/admin/templates/site-settings/bool.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/bool.hbs diff --git a/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs new file mode 100644 index 00000000000..621f3fa70e7 --- /dev/null +++ b/app/assets/javascripts/admin/templates/components/site-settings/category-list.hbs @@ -0,0 +1,3 @@ +{{category-group categories=selectedCategories blacklist=selectedCategories}} +
{{{unbound setting.description}}}
+{{setting-validation-message message=validationMessage}} diff --git a/app/assets/javascripts/admin/templates/site-settings/enum.hbs b/app/assets/javascripts/admin/templates/components/site-settings/enum.hbs similarity index 80% rename from app/assets/javascripts/admin/templates/site-settings/enum.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/enum.hbs index 67cbfc92ace..765a0e20d19 100644 --- a/app/assets/javascripts/admin/templates/site-settings/enum.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/enum.hbs @@ -1,4 +1,4 @@ -{{combo-box valueAttribute="value" content=setting.validValues value=buffered.value none=setting.allowsNone}} +{{combo-box valueAttribute="value" content=setting.validValues value=value none=setting.allowsNone}} {{preview}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/url_list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs similarity index 60% rename from app/assets/javascripts/admin/templates/site-settings/url_list.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs index ec8ecaf3954..5107f5b4af5 100644 --- a/app/assets/javascripts/admin/templates/site-settings/url_list.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/host-list.hbs @@ -1,3 +1,3 @@ -{{value-list values=buffered.value addKey="admin.site_settings.add_url"}} +{{value-list values=value addKey="admin.site_settings.add_host"}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/list.hbs similarity index 54% rename from app/assets/javascripts/admin/templates/site-settings/list.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/list.hbs index bc1cf2b51e7..e741bea5ed1 100644 --- a/app/assets/javascripts/admin/templates/site-settings/list.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/list.hbs @@ -1,3 +1,3 @@ -{{list-setting settingValue=buffered.value choices=setting.choices settingName=setting.setting}} +{{list-setting settingValue=value choices=setting.choices settingName=setting.setting}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/string.hbs b/app/assets/javascripts/admin/templates/components/site-settings/string.hbs similarity index 62% rename from app/assets/javascripts/admin/templates/site-settings/string.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/string.hbs index f8427094abb..71d7216f273 100644 --- a/app/assets/javascripts/admin/templates/site-settings/string.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/string.hbs @@ -1,3 +1,3 @@ -{{text-field value=buffered.value classNames="input-setting-string"}} +{{text-field value=value classNames="input-setting-string"}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/admin/templates/site-settings/host_list.hbs b/app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs similarity index 60% rename from app/assets/javascripts/admin/templates/site-settings/host_list.hbs rename to app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs index 5f0c301d0dd..41213777e36 100644 --- a/app/assets/javascripts/admin/templates/site-settings/host_list.hbs +++ b/app/assets/javascripts/admin/templates/components/site-settings/url-list.hbs @@ -1,3 +1,3 @@ -{{value-list values=buffered.value addKey="admin.site_settings.add_host"}} +{{value-list values=value addKey="admin.site_settings.add_url"}} {{setting-validation-message message=validationMessage}}
{{{unbound setting.description}}}
diff --git a/app/assets/javascripts/discourse/components/category-group.js.es6 b/app/assets/javascripts/discourse/components/category-group.js.es6 index 13906ed312d..e81fa5d1d3c 100644 --- a/app/assets/javascripts/discourse/components/category-group.js.es6 +++ b/app/assets/javascripts/discourse/components/category-group.js.es6 @@ -24,13 +24,13 @@ export default Ember.Component.extend({ const slug = link.match(regexp)[1]; return Discourse.Category.findSingleBySlug(slug); }); - self.set("categories", categories); + Em.run.next(() => self.set("categories", categories)); }, template, transformComplete(category) { return categoryBadgeHTML(category, {allowUncategorized: true}); } }); - }.on('didInsertElement') + }.on('didInsertElement'), }); diff --git a/app/assets/javascripts/discourse/controllers/preferences.js.es6 b/app/assets/javascripts/discourse/controllers/preferences.js.es6 index dd729eab29d..ee3e86e9d89 100644 --- a/app/assets/javascripts/discourse/controllers/preferences.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences.js.es6 @@ -71,19 +71,19 @@ export default Ember.Controller.extend(CanCheckEmails, { 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_n_seconds', { count: 30 }), value: 30000 }, - { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 1 }), value: 60000 }, - { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 2 }), value: 120000 }, - { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 3 }), value: 180000 }, - { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 4 }), value: 240000 }, - { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 5 }), value: 300000 }, - { name: I18n.t('user.auto_track_options.after_n_minutes', { count: 10 }), value: 600000 }], + { 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 }], considerNewTopicOptions: [{ name: I18n.t('user.new_topic_duration.not_viewed'), value: -1 }, - { name: I18n.t('user.new_topic_duration.after_n_days', { count: 1 }), value: 60 * 24 }, - { name: I18n.t('user.new_topic_duration.after_n_days', { count: 2 }), value: 60 * 48 }, - { name: I18n.t('user.new_topic_duration.after_n_weeks', { count: 1 }), value: 7 * 60 * 24 }, - { name: I18n.t('user.new_topic_duration.after_n_weeks', { count: 2 }), value: 2 * 7 * 60 * 24 }, + { 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 }], saveButtonText: function() { diff --git a/app/assets/stylesheets/common/admin/admin_base.scss b/app/assets/stylesheets/common/admin/admin_base.scss index 15875c0d2c5..d7686805af2 100644 --- a/app/assets/stylesheets/common/admin/admin_base.scss +++ b/app/assets/stylesheets/common/admin/admin_base.scss @@ -312,6 +312,9 @@ td.flaggers td { .setting-value { float: left; width: 53%; + .category-group { + width: 95%; + } @media (max-width: $mobile-breakpoint) { width: 100%; } diff --git a/app/models/auto_track_duration_site_setting.rb b/app/models/auto_track_duration_site_setting.rb new file mode 100644 index 00000000000..6b10f80a5fc --- /dev/null +++ b/app/models/auto_track_duration_site_setting.rb @@ -0,0 +1,27 @@ +require_dependency 'enum_site_setting' + +class AutoTrackDurationSiteSetting < EnumSiteSetting + + def self.valid_value?(val) + values.any? { |v| v[:value].to_s == val.to_s } + end + + def self.values + @values ||= [ + { name: 'user.auto_track_options.never', value: -1 }, + { name: 'user.auto_track_options.immediately', value: 0 }, + { name: 'user.auto_track_options.after_30_seconds', value: 1000 * 30 }, + { name: 'user.auto_track_options.after_1_minute', value: 1000 * 60 }, + { name: 'user.auto_track_options.after_2_minutes', value: 1000 * 60 * 2 }, + { name: 'user.auto_track_options.after_3_minutes', value: 1000 * 60 * 3 }, + { name: 'user.auto_track_options.after_4_minutes', value: 1000 * 60 * 4 }, + { name: 'user.auto_track_options.after_5_minutes', value: 1000 * 60 * 5 }, + { name: 'user.auto_track_options.after_10_minutes', value: 1000 * 60 * 10 }, + ] + end + + def self.translate_names? + true + end + +end diff --git a/app/models/new_topic_duration_site_setting.rb b/app/models/new_topic_duration_site_setting.rb new file mode 100644 index 00000000000..92a00ea1c66 --- /dev/null +++ b/app/models/new_topic_duration_site_setting.rb @@ -0,0 +1,24 @@ +require_dependency 'enum_site_setting' + +class NewTopicDurationSiteSetting < EnumSiteSetting + + def self.valid_value?(val) + values.any? { |v| v[:value].to_s == val.to_s } + end + + def self.values + @values ||= [ + { name: 'user.new_topic_duration.not_viewed', value: -1 }, + { name: 'user.new_topic_duration.after_1_day', value: 60 * 24 }, + { name: 'user.new_topic_duration.after_2_days', value: 60 * 24 * 2 }, + { name: 'user.new_topic_duration.after_1_week', value: 60 * 24 * 7 }, + { name: 'user.new_topic_duration.after_2_weeks', value: 60 * 24 * 7 * 2 }, + { name: 'user.new_topic_duration.last_here', value: -2 }, + ] + end + + def self.translate_names? + true + end + +end diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index ff1d17c0054..8dbcb329ce2 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -99,6 +99,14 @@ class SiteSetting < ActiveRecord::Base false end + def self.default_categories_selected + [ + SiteSetting.default_categories_watching.split("|"), + SiteSetting.default_categories_tracking.split("|"), + SiteSetting.default_categories_muted.split("|"), + ].flatten.to_set + end + end # == Schema Information diff --git a/app/models/topic_tracking_state.rb b/app/models/topic_tracking_state.rb index e5272922f9a..12370fa234b 100644 --- a/app/models/topic_tracking_state.rb +++ b/app/models/topic_tracking_state.rb @@ -110,7 +110,7 @@ class TopicTrackingState now: DateTime.now, last_visit: User::NewTopicDuration::LAST_VISIT, always: User::NewTopicDuration::ALWAYS, - default_duration: SiteSetting.new_topic_duration_minutes + default_duration: SiteSetting.default_other_new_topic_duration_minutes ).where_values[0] end diff --git a/app/models/topic_user.rb b/app/models/topic_user.rb index b900c9b0a60..01d57c58086 100644 --- a/app/models/topic_user.rb +++ b/app/models/topic_user.rb @@ -97,7 +97,7 @@ class TopicUser < ActiveRecord::Base if rows == 0 now = DateTime.now auto_track_after = User.select(:auto_track_topics_after_msecs).find_by(id: user_id).auto_track_topics_after_msecs - auto_track_after ||= SiteSetting.auto_track_topics_after + auto_track_after ||= SiteSetting.default_other_auto_track_topics_after_msecs if auto_track_after >= 0 && auto_track_after <= (attrs[:total_msecs_viewed] || 0) attrs[:notification_level] ||= notification_levels[:tracking] @@ -143,7 +143,7 @@ class TopicUser < ActiveRecord::Base now: DateTime.now, msecs: msecs, tracking: notification_levels[:tracking], - threshold: SiteSetting.auto_track_topics_after + threshold: SiteSetting.default_other_auto_track_topics_after_msecs } # In case anyone seens "highest_seen_post_number" and gets confused, like I do. @@ -198,7 +198,7 @@ class TopicUser < ActiveRecord::Base if rows.length == 0 # The user read at least one post in a topic that they haven't viewed before. args[:new_status] = notification_levels[:regular] - if (user.auto_track_topics_after_msecs || SiteSetting.auto_track_topics_after) == 0 + if (user.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs) == 0 args[:new_status] = notification_levels[:tracking] end TopicTrackingState.publish_read(topic_id, post_number, user.id, args[:new_status]) diff --git a/app/models/user.rb b/app/models/user.rb index 6b25f4f556d..650d2b9ee1e 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -75,14 +75,15 @@ class User < ActiveRecord::Base validates :ip_address, allowed_ip_address: {on: :create, message: :signup_not_allowed} after_initialize :add_trust_level - after_initialize :set_default_email_digest - after_initialize :set_default_external_links_in_new_tab + + before_create :set_default_user_preferences after_create :create_email_token after_create :create_user_stat after_create :create_user_profile after_create :ensure_in_trust_level_group after_create :automatic_group_membership + after_create :set_default_categories_preferences before_save :update_username_lower before_save :ensure_password_is_hashed @@ -578,7 +579,7 @@ class User < ActiveRecord::Base end def treat_as_new_topic_start_date - duration = new_topic_duration_minutes || SiteSetting.new_topic_duration_minutes + duration = new_topic_duration_minutes || SiteSetting.default_other_new_topic_duration_minutes [case duration when User::NewTopicDuration::ALWAYS created_at @@ -901,26 +902,42 @@ class User < ActiveRecord::Base end end - def set_default_email_digest - if has_attribute?(:email_digests) && self.email_digests.nil? - if SiteSetting.default_digest_email_frequency.blank? - self.email_digests = false - else - self.email_digests = true - self.digest_after_days ||= SiteSetting.default_digest_email_frequency.to_i if has_attribute?(:digest_after_days) - end - end + def set_default_user_preferences + set_default_email_digest_frequency + set_default_email_private_messages + set_default_email_direct + set_default_email_mailing_list_mode + set_default_email_always + + set_default_other_new_topic_duration_minutes + set_default_other_auto_track_topics_after_msecs + set_default_other_external_links_in_new_tab + set_default_other_enable_quoting + set_default_other_dynamic_favicon + set_default_other_disable_jump_reply + set_default_other_edit_history_public + + # needed, otherwise the callback chain is broken... + true end - def set_default_external_links_in_new_tab - if has_attribute?(:external_links_in_new_tab) && self.external_links_in_new_tab.nil? - self.external_links_in_new_tab = !SiteSetting.default_external_links_in_new_tab.blank? + def set_default_categories_preferences + values = [] + + %w{watching tracking muted}.each do |s| + category_ids = SiteSetting.send("default_categories_#{s}").split("|") + category_ids.each do |category_id| + values << "(#{self.id}, #{category_id}, #{CategoryUser.notification_levels[s.to_sym]})" + end + end + + if values.present? + exec_sql("INSERT INTO category_users (user_id, category_id, notification_level) VALUES #{values.join(",")}") end end # Delete unactivated accounts (without verified email) that are over a week old def self.purge_unactivated - to_destroy = User.where(active: false) .joins('INNER JOIN user_stats AS us ON us.user_id = users.id') .where("created_at < ?", SiteSetting.purge_unactivated_users_grace_period_days.days.ago) @@ -950,6 +967,39 @@ class User < ActiveRecord::Base end end + def set_default_email_digest_frequency + if has_attribute?(:email_digests) + if SiteSetting.default_email_digest_frequency.blank? + self.email_digests = false + else + self.email_digests = true + self.digest_after_days ||= SiteSetting.default_email_digest_frequency.to_i if has_attribute?(:digest_after_days) + end + end + end + + def set_default_email_mailing_list_mode + self.mailing_list_mode = SiteSetting.default_email_mailing_list_mode if has_attribute?(:mailing_list_mode) + end + + %w{private_messages direct always}.each do |s| + define_method("set_default_email_#{s}") do + self.send("email_#{s}=", SiteSetting.send("default_email_#{s}")) if has_attribute?("email_#{s}") + end + end + + %w{new_topic_duration_minutes auto_track_topics_after_msecs}.each do |s| + define_method("set_default_other_#{s}") do + self.send("#{s}=", SiteSetting.send("default_other_#{s}").to_i) if has_attribute?(s) + end + end + + %w{external_links_in_new_tab enable_quoting dynamic_favicon disable_jump_reply edit_history_public}.each do |s| + define_method("set_default_other_#{s}") do + self.send("#{s}=", SiteSetting.send("default_other_#{s}")) if has_attribute?(s) + end + end + end # == Schema Information diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index dd5132504a9..a17dd36d2ea 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -249,11 +249,11 @@ class UserSerializer < BasicUserSerializer ### def auto_track_topics_after_msecs - object.auto_track_topics_after_msecs || SiteSetting.auto_track_topics_after + object.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs end def new_topic_duration_minutes - object.new_topic_duration_minutes || SiteSetting.new_topic_duration_minutes + object.new_topic_duration_minutes || SiteSetting.default_other_new_topic_duration_minutes end def muted_category_ids diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index d85e2a46d0b..c00d476aff8 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -583,23 +583,22 @@ en: label: "Consider topics new when" not_viewed: "I haven't viewed them yet" last_here: "created since I was here last" - after_n_days: - one: "created in the last day" - other: "created in the last {{count}} days" - after_n_weeks: - one: "created in the last week" - other: "created in the last {{count}} weeks" + after_1_day: "created in the last day" + after_2_days: "created in the last 2 days" + after_1_week: "created in the last week" + after_2_weeks: "created in the last 2 weeks" auto_track_topics: "Automatically track topics I enter" auto_track_options: never: "never" immediately: "immediately" - after_n_seconds: - one: "after 1 second" - other: "after {{count}} seconds" - after_n_minutes: - one: "after 1 minute" - other: "after {{count}} minutes" + after_30_seconds: "after 30 seconds" + after_1_minute: "after 1 minute" + after_2_minutes: "after 2 minutes" + after_3_minutes: "after 3 minutes" + after_4_minutes: "after 4 minutes" + after_5_minutes: "after 5 minutes" + after_10_minutes: "after 10 minutes" invited: search: "type to search invites..." @@ -2422,6 +2421,7 @@ en: backups: "Backups" login: "Login" plugins: "Plugins" + user_preferences: "User Preferences" badges: title: Badges diff --git a/config/locales/server.bs_BA.yml b/config/locales/server.bs_BA.yml index 6757d882adf..4b690b99df4 100644 --- a/config/locales/server.bs_BA.yml +++ b/config/locales/server.bs_BA.yml @@ -698,8 +698,8 @@ bs_BA: automatically_download_gravatars: "Download Gravatars for users upon account creation or email change." digest_topics: "The maximum number of topics to display in the email digest." digest_min_excerpt_length: "Minimum post excerpt in the email digest, in characters." - default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." - default_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences." + default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." + default_other_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences." max_daily_gravatar_crawls: "Maximum number of times Discourse will check Gravatar for custom avatars in a day" public_user_custom_fields: "A whitelist of custom fields for a user that can be shown publically." allow_profile_backgrounds: "Allow users to upload profile backgrounds." diff --git a/config/locales/server.cs.yml b/config/locales/server.cs.yml index d185b599647..a80f177c7df 100644 --- a/config/locales/server.cs.yml +++ b/config/locales/server.cs.yml @@ -668,8 +668,8 @@ cs: delete_all_posts_max: "Maximální počet příspěvků, které mohou být smazány najednou tlačítkem 'Odstranit všechny příspěvky'. Pokud má uživatel více příspěvků než je zde nastaveno, nemohou být jeho příspěvky smazány najednou a uživatele nelze odstranit." username_change_period: "Počet dní od registrace za kolik si uživatel může změnit svoje uživatelské jméno (0 pokud chcete změnu uživatelského jména úplně zakázat)." email_editable: "Povolit uživatelům změnit si po registraci emailovou adresu." - default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." - default_external_links_in_new_tab: "Otevírat odkazy na externí weby v novém tabu. Uživatelé si toto můžou změnit v svém nastavení." + default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." + default_other_external_links_in_new_tab: "Otevírat odkazy na externí weby v novém tabu. Uživatelé si toto můžou změnit v svém nastavení." enable_mobile_theme: "Používat na mobilních zařízeních verzi přizpůsobenou pro mobily s možností přejít na plnou verzi. Zruště pokud chcete používat vlastní plně responzivní kaskádový styl." short_progress_text_threshold: "After the number of posts in a topic goes above this number, the progress bar will only show the current post number. If you change the progress bar's width, you may need to change this value." default_code_lang: "Default programming language syntax highlighting applied to GitHub code blocks (lang-auto, ruby, python etc.)" diff --git a/config/locales/server.da.yml b/config/locales/server.da.yml index 68addb92fab..ab8aa0037c3 100644 --- a/config/locales/server.da.yml +++ b/config/locales/server.da.yml @@ -626,8 +626,8 @@ da: delete_all_posts_max: "Det maksimale antal indlæg der kan slettes på én gang med “Slet alle indlæg”-knappen. Hvis en bruger har mere end dette antal indlæg, kan indlæggene ikke slettes på én gang og brugeren kan ikke slettes." username_change_period: "Antal dage efter oprettelsen hvor brugere kan ændre deres brugernavn (0 for ikke at tillade skift af brugernavn)." email_editable: "Lad brugerne skifte deres e-mail-adresse efter oprettelsen." - default_digest_email_frequency: "Hvor ofte brugerne som standard modtager e-mail-sammendrag. De kan ændre indstillingen på deres profil." - default_external_links_in_new_tab: "Åbn eksterne links i en nu fane; brugerne kan ændre dette på deres profil" + default_email_digest_frequency: "Hvor ofte brugerne som standard modtager e-mail-sammendrag. De kan ændre indstillingen på deres profil." + default_other_external_links_in_new_tab: "Åbn eksterne links i en nu fane; brugerne kan ændre dette på deres profil" enable_mobile_theme: "Mobile enheder bruger et mobilvenligt tema, med mulighed for at skifte til det fulde site. Deaktivér dette hvis du ønsker at anvende et brugerdefineret stylesheet som er fuldstændigt responsivt." short_progress_text_threshold: "Når antallet af indlæg overstiger dette tal viser statuslinjen kun det aktuelle indlægsnummer. Hvis du ændrer bredden af statuslinjen kan det være nødvendigt at opdatere denne værdi." default_code_lang: "Standard syntax highlighting som bruges i GitHub kodeblokke (lang-auto, ruby, python etc.)." diff --git a/config/locales/server.de.yml b/config/locales/server.de.yml index 356ef447ba2..02b0b32020e 100644 --- a/config/locales/server.de.yml +++ b/config/locales/server.de.yml @@ -912,10 +912,10 @@ de: automatically_download_gravatars: "Avatare von Gravatar herunterladen, wenn ein Nutzer sich registriert oder seine E-Mail-Adresse ändert." digest_topics: "Maximale Anzahl von Themen, die in der E-Mail-Zusammenfassung angezeigt werden." digest_min_excerpt_length: "Minimale Länge des Auszugs aus einem Beitrag in der E-Mail-Zusammenfassung, in Zeichen." - default_digest_email_frequency: "Wie oft man Zusammenfassungen per Mail standardmässig erhält. Diese Einstellung kann von jedem geändert werden." + default_email_digest_frequency: "Wie oft man Zusammenfassungen per Mail standardmässig erhält. Diese Einstellung kann von jedem geändert werden." suppress_digest_email_after_days: "Sende keine E-Mail-Zusammenfassungen an Benutzer, die die Seite seit mehr als (n) Tagen nicht mehr besucht haben." disable_digest_emails: "E-Mail-Zusammenfassungen für alle Benutzer deaktivieren." - default_external_links_in_new_tab: "Öffne externe Links in einem neuen Tab. Benutzer können dies in ihren Einstellungen ändern." + default_other_external_links_in_new_tab: "Öffne externe Links in einem neuen Tab. Benutzer können dies in ihren Einstellungen ändern." max_daily_gravatar_crawls: "Wie oft pro Tag Discourse höchstens auf Gravatar nach benuterdefinierten Avataren suchen soll." public_user_custom_fields: "Liste selbst definierter Profil-Felder, die öffentlich angezeigt werden dürfen." staff_user_custom_fields: "Liste selbst definierter Profil-Felder, die Mitarbeitern angezeigt werden dürfen." diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index dba03554a76..31391bf511f 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -95,6 +95,7 @@ en: min_username_length_range: "You cannot set the minimum above the maximum." max_username_length_exists: "You cannot set the maximum username length below the longest username." max_username_length_range: "You cannot set the maximum above the minimum." + default_categories_already_selected: "You cannot select a category used in another list." activemodel: errors: @@ -829,9 +830,6 @@ en: anon_polling_interval: "How often should anonymous clients poll in milliseconds" background_polling_interval: "How often should the clients poll in milliseconds (when the window is in the background)" - auto_track_topics_after: "Global default milliseconds before a topic is automatically tracked, users can override (0 for always, -1 for never)" - new_topic_duration_minutes: "Global default number of minutes a topic is considered new, users can override (-1 for always, -2 for last visit)" - flags_required_to_hide_post: "Number of flags that cause a post to be automatically hidden and PM sent to the user (0 for never)" cooldown_minutes_after_hiding_posts: "Number of minutes a user must wait before they can edit a post hidden via community flagging" @@ -1124,10 +1122,8 @@ en: automatically_download_gravatars: "Download Gravatars for users upon account creation or email change." digest_topics: "The maximum number of topics to display in the email digest." digest_min_excerpt_length: "Minimum post excerpt in the email digest, in characters." - default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." suppress_digest_email_after_days: "Suppress digest emails for users not seen on the site for more than (n) days." disable_digest_emails: "Disable digest emails for all users." - default_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences." detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures." max_daily_gravatar_crawls: "Maximum number of times Discourse will check Gravatar for custom avatars in a day" @@ -1195,6 +1191,24 @@ en: approve_unless_trust_level: "Posts for users below this trust level must be approved" notify_about_queued_posts_after: "If there are posts that have been waiting to be reviewed for more than this many hours, an email will be sent to the contact email. Set to 0 to disable these emails." + default_email_digest_frequency: "How often users receive digest emails by default." + default_email_private_messages: "Send an email when someone messages the user by default." + default_email_direct: "Send an email when someone quotes/replies to/mentions or invites the user by default." + default_email_mailing_list_mode: "Send an email for every new post by default." + default_email_always: "Send an email notification even when the user is active by default." + + default_other_new_topic_duration_minutes: "Global default number of minutes a topic is considered new, users can override (-1 for always, -2 for last visit)" + default_other_auto_track_topics_after_msecs: "Global default milliseconds before a topic is automatically tracked, users can override (0 for always, -1 for never)" + default_other_external_links_in_new_tab: "Open external links in a new tab by default." + default_other_enable_quoting: "Enable quote reply for highlighted text by default." + default_other_dynamic_favicon: "Show new/updated topic count on browser icon by default." + default_other_disable_jump_reply: "Don't jump to user's post after they reply by default." + default_other_edit_history_public: "Make the post revisions public by default." + + default_categories_watching: "List of categories that are watched by default." + default_categories_tracking: "List of categories that are tracked by default." + default_categories_muted: "List of categories that are muted by default." + errors: invalid_email: "Invalid email address." invalid_username: "There's no user with that username." diff --git a/config/locales/server.es.yml b/config/locales/server.es.yml index 825daf4a652..cd70349ba3e 100644 --- a/config/locales/server.es.yml +++ b/config/locales/server.es.yml @@ -962,10 +962,10 @@ es: automatically_download_gravatars: "Descargar Gravatars para usuarios cuando se creen una cuenta o cambien el email." digest_topics: "El número máximo de temas a mostrar en el resumen por email." digest_min_excerpt_length: "La extensión mínima, en caracteres, del extracto de un post en el resumen por email." - default_digest_email_frequency: "Cada cuánto tiempo los usuarios recibirán emails con el resumen del sitio por defecto. Cada usuario puede cambiar esta opción para sí en sus preferencias." + default_email_digest_frequency: "Cada cuánto tiempo los usuarios recibirán emails con el resumen del sitio por defecto. Cada usuario puede cambiar esta opción para sí en sus preferencias." suppress_digest_email_after_days: "Suprimir los emails de resumen para aquellos usuarios que no han visto el sitio desde más de (n) días." disable_digest_emails: "Inhabilitar e-mails de resumen para todos los usuarios." - default_external_links_in_new_tab: "Abrir enlaces externos en una nueva pestaña. Los usuarios pueden cambiar esto en sus preferencias." + default_other_external_links_in_new_tab: "Abrir enlaces externos en una nueva pestaña. Los usuarios pueden cambiar esto en sus preferencias." detect_custom_avatars: "Verificar o no que los usuarios han subido una imagen de perfil." max_daily_gravatar_crawls: "Máximo número de veces que Discourse comprobará Gravatar en busca de avatares personalizados en un día" public_user_custom_fields: "Una lista con campos personalizados para el usuario que pueden ser mostrados públicamente." diff --git a/config/locales/server.fa_IR.yml b/config/locales/server.fa_IR.yml index 60c71fcf50b..1920ee6b2dc 100644 --- a/config/locales/server.fa_IR.yml +++ b/config/locales/server.fa_IR.yml @@ -903,10 +903,10 @@ fa_IR: automatically_download_gravatars: "آواتار را برای کاربران دریافت کن برای ساختن حساب کاربری یا ایمیل. " digest_topics: "حداکثر تعداد جستارهایی که در دایجست ایمیل نشان داده می شود " digest_min_excerpt_length: "حداقل نوشته های گزیده در ایمیل دایجست٬‌ در کاراکتر." - default_digest_email_frequency: "هر چند وقت یکبار کاربران ایمیل های دایجست دریافت کنند بطور پیش فرض. آنها می توانند آن را در بخش تنظیمات عوض کنند. " + default_email_digest_frequency: "هر چند وقت یکبار کاربران ایمیل های دایجست دریافت کنند بطور پیش فرض. آنها می توانند آن را در بخش تنظیمات عوض کنند. " suppress_digest_email_after_days: "ایمیل های خلاصه را مهار کن برای کاربرانی که در وب سایت دیده نشده اند بیشتر از (n) روز " disable_digest_emails: "ایمیل های دایجست را برای تمام کاربران غیر فعال کن. " - default_external_links_in_new_tab: "پیوند های خارجی را در یک تب جدید باز کن. کاربران می توانند این را در قسمت تنظیماتشان تغییر دهند." + default_other_external_links_in_new_tab: "پیوند های خارجی را در یک تب جدید باز کن. کاربران می توانند این را در قسمت تنظیماتشان تغییر دهند." max_daily_gravatar_crawls: "حداکثرتعداد زمانی که دیسکورس Gravatar را چک می کند برای آواتار سفارشی در هر روز. " public_user_custom_fields: "لیست مجاز فیلد سفارشی برای کاربر که می تواند به همه نشان داده شود." staff_user_custom_fields: "لیست مجاز فیلد سفارشی برای کاربر که می تواند به مدیران نشان داده شود." diff --git a/config/locales/server.fi.yml b/config/locales/server.fi.yml index fb87dbf2bb1..91ca213c03a 100644 --- a/config/locales/server.fi.yml +++ b/config/locales/server.fi.yml @@ -971,10 +971,10 @@ fi: automatically_download_gravatars: "Lataa käyttäjille Gravatarit automaattisesti tilin luonnin ja sähköpostin vaihdon yhteydessä." digest_topics: "Sähköpostitiivistelmässä näytettävien ketjujen maksimimäärä." digest_min_excerpt_length: "Viestin katkelman vähimmäispituus sähköpostitiivistelmässä, merkeissä" - default_digest_email_frequency: "Kuinka usein käyttäjän saavat sähköpostitiivistelmän oletuksena. He voivat muuttaa asetusta omista asetuksistaan." + default_email_digest_frequency: "Kuinka usein käyttäjän saavat sähköpostitiivistelmän oletuksena. He voivat muuttaa asetusta omista asetuksistaan." suppress_digest_email_after_days: "Jätä lähettämättä tiivistelmäsähköpostit käyttäjille, joita ei ole nähty (n) päivän aikana." disable_digest_emails: "Ota tiivistelmäsähköpostit pois käytöstä kaikilta käyttäjiltä." - default_external_links_in_new_tab: "Avaa ulkoiset linkit uudessa välilehdessä. Käyttäjät voivat muuttaa tämän asetuksistaan." + default_other_external_links_in_new_tab: "Avaa ulkoiset linkit uudessa välilehdessä. Käyttäjät voivat muuttaa tämän asetuksistaan." detect_custom_avatars: "Tarkistetaanko, ovatko käyttäjät ladanneet oman profiilikuvan." max_daily_gravatar_crawls: "Korkeintaan kuinka monta kertaa Discourse tarkistaa avatarit Gravatarista päivässä" public_user_custom_fields: "Whitelist käyttäjän mukautetuista kentistä, jotka voidaan näyttää julkisesti." diff --git a/config/locales/server.fr.yml b/config/locales/server.fr.yml index 137666d2130..3d85c31a899 100644 --- a/config/locales/server.fr.yml +++ b/config/locales/server.fr.yml @@ -966,10 +966,10 @@ fr: automatically_download_gravatars: "Télécharger les gravatars pour les utilisateurs lors de la création de compte ou de la modification de courriel." digest_topics: "Nombre maximum de sujets à afficher dans le courriel de résumé." digest_min_excerpt_length: "Taille minimum du résumé des messages dans les courriels, en caractères." - default_digest_email_frequency: "A quelle fréquence les utilisateurs reçoivent-ils les courriels par défaut. Ils peuvent modifier ce paramétrage dans leur préférences." + default_email_digest_frequency: "A quelle fréquence les utilisateurs reçoivent-ils les courriels par défaut. Ils peuvent modifier ce paramétrage dans leur préférences." suppress_digest_email_after_days: "Ne pas envoyer de résumés courriel aux utilisateurs qui n'ont pas visité le site depuis (n) jours." disable_digest_emails: "Désactiver les résumés par courriels pour tous les utilisateurs." - default_external_links_in_new_tab: "Les liens externes s'ouvrent dans un nouvel onglet. Les utilisateurs peuvent modifier ceci dans leurs préférences." + default_other_external_links_in_new_tab: "Les liens externes s'ouvrent dans un nouvel onglet. Les utilisateurs peuvent modifier ceci dans leurs préférences." detect_custom_avatars: "Vérifier ou non si les utilisateurs ont envoyé une photo de profil personnalisée." max_daily_gravatar_crawls: "Nombre maximum de fois que Discourse vérifiera Gravatar pour des avatars personnalisés en une journée." public_user_custom_fields: "Une liste blanche des champs personnalisés pour un utilisateur qui peuvent être affichés publiquement." diff --git a/config/locales/server.he.yml b/config/locales/server.he.yml index 5b5fc89d7be..86aa93036df 100644 --- a/config/locales/server.he.yml +++ b/config/locales/server.he.yml @@ -950,10 +950,10 @@ he: automatically_download_gravatars: "הורדת גראווטרים למשתמשים בעת יצירת החשבון או שינוי כתובת הדוא\"ל." digest_topics: "מספר הנושאים המקסימלי להצגה במייל סיכום." digest_min_excerpt_length: "מספר התווים המינימלי למובאות מתוך הפרסום במייל הסיכום." - default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." + default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." suppress_digest_email_after_days: "השהיית מיילים מסכמים עבור משתמשים שלא נראו באתר במשך יותר מ(n) ימים." disable_digest_emails: "נטרול דוא\"ל סיכום לכל המשתמשים." - default_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences." + default_other_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences." detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures." max_daily_gravatar_crawls: "מספר הפעמים המקסימלי ש-Discourse יבדוק אווטרים ב-Gravatar ביום" public_user_custom_fields: "רשימה לבנה (whitelist) של שדות מותאמים למשתמש שיכולים להיות מוצגים באופן פומבי." diff --git a/config/locales/server.it.yml b/config/locales/server.it.yml index 0e72e1deade..bdd270d2e6a 100644 --- a/config/locales/server.it.yml +++ b/config/locales/server.it.yml @@ -896,8 +896,8 @@ it: default_avatars: "URL degli avatar che verranno utilizzati come predefiniti per tutti i nuovi utenti, fintanto che non li cambieranno esplicitamente." automatically_download_gravatars: "Scarica i Gravatars per gli utenti quando viene creato l'account o quando viene modificata l'email" digest_topics: "Numero massimo di argomenti da mostrare nel riassunto email." - default_digest_email_frequency: "Quanto spesso gli utenti ricevono email di riepilogo. Gli utenti possono modificare questa impostazione nelle loro preferenze." - default_external_links_in_new_tab: "Apri i collegamenti esterni in una nuova scheda. Gli utenti possono modificare questa impostazione nelle loro preferenze." + default_email_digest_frequency: "Quanto spesso gli utenti ricevono email di riepilogo. Gli utenti possono modificare questa impostazione nelle loro preferenze." + default_other_external_links_in_new_tab: "Apri i collegamenti esterni in una nuova scheda. Gli utenti possono modificare questa impostazione nelle loro preferenze." allow_profile_backgrounds: "Permetti agli utenti di caricare immagini di sfondo per il profilo." enable_mobile_theme: "I dispositivi mobili usano un tema apposito, con possibilità di passare alla visualizzazione completa. Disabilita questa opzione se vuoi usare un foglio di stile personalizzato che sia completamente reattivo." suppress_uncategorized_badge: "Non mostrare la targhetta per gli argomenti senza categoria nell'elenco degli argomenti." diff --git a/config/locales/server.ja.yml b/config/locales/server.ja.yml index 2c997ccda02..7e797cde41f 100644 --- a/config/locales/server.ja.yml +++ b/config/locales/server.ja.yml @@ -897,10 +897,10 @@ ja: automatically_download_gravatars: "アカウントの生成時、メールアドレスの変更時にGravatarをダウンロード" digest_topics: "ダイジェストメールに表示されるトピックの最大数" digest_min_excerpt_length: "ダイジェストメール内の投稿の抜粋の最小文字数" - default_digest_email_frequency: "ユーザがダイジェストメールを受け取る頻度のデフォルト値。ユーザは設定画面でこの値をカスタマイズできます。" + default_email_digest_frequency: "ユーザがダイジェストメールを受け取る頻度のデフォルト値。ユーザは設定画面でこの値をカスタマイズできます。" suppress_digest_email_after_days: "(n)日以上ユーザが参照していなければダイジェストメールを抑制します" disable_digest_emails: "全てのユーザのダイジェストメールを無効にする" - default_external_links_in_new_tab: "外部リンクは新しいタブで開きます。ユーザーはこの設定を変更する事が出来ます" + default_other_external_links_in_new_tab: "外部リンクは新しいタブで開きます。ユーザーはこの設定を変更する事が出来ます" detect_custom_avatars: "ユーザがプロフィール画像をアップロードしたか確認する" max_daily_gravatar_crawls: "Discourseがプロフィール画像の確認をgravastarに行う回数の上限" public_user_custom_fields: "パブリックに公開されるカスタムフィールドのホワイトリスト" diff --git a/config/locales/server.ko.yml b/config/locales/server.ko.yml index 0b2b79d3330..d1e54c3b2be 100644 --- a/config/locales/server.ko.yml +++ b/config/locales/server.ko.yml @@ -886,10 +886,10 @@ ko: automatically_download_gravatars: "사용자가 계정을 만들거나 이메일을 변경하자마자 Gravatar를 다운로드합니다." digest_topics: "요약 이메일에서 보여질 최대 토픽 개수" digest_min_excerpt_length: "요약 이메일에서 최소 포스트 발췌 수" - default_digest_email_frequency: "사용자가 요약 이메일을 받는 횟수 기본값. 사용자는 그들의 환경설정에서 변경할 수 있음" + default_email_digest_frequency: "사용자가 요약 이메일을 받는 횟수 기본값. 사용자는 그들의 환경설정에서 변경할 수 있음" suppress_digest_email_after_days: "(n)일동안 사이트에서 보지 못한 사용자에게는 이메일 요약을 보내지 않습니다." disable_digest_emails: "모든 유저들 이메일 다이제스트 못하게 하기" - default_external_links_in_new_tab: "다른 싸이트의 링크는 새 탭으로 연다. 사용자는 자신의 설정에 따라 바꿀 수 있음" + default_other_external_links_in_new_tab: "다른 싸이트의 링크는 새 탭으로 연다. 사용자는 자신의 설정에 따라 바꿀 수 있음" max_daily_gravatar_crawls: "하루에 Discourse가 커스텀 아파타를 위해 Gravatar를 체크하는 최대 횟수" public_user_custom_fields: "유저가 쓸 수 있는 공개 커스텀 필드 목록" staff_user_custom_fields: "스태프가 쓸 수 있는 공개 커스텀 필드 목록" diff --git a/config/locales/server.nl.yml b/config/locales/server.nl.yml index 9ccb24406a6..54fd386f944 100644 --- a/config/locales/server.nl.yml +++ b/config/locales/server.nl.yml @@ -840,8 +840,8 @@ nl: email_editable: "Gebruikers mogen hun e-mailadres na registratie nog wijzigen." digest_topics: "Het maximum aantal topics dat in de e-maildigest opgenomen wordt." digest_min_excerpt_length: "Hoeveel karakters er per bericht getoond worden in de mail digest" - default_digest_email_frequency: "Hoe vaak ontvangen gebruikers standaard de digestmails. Ze kunnen dit in hun eigen instellingen nog aanpassen." - default_external_links_in_new_tab: "Open externe links in a nieuwe tab. Gebruikers kunnen dit wijzigen in hun instellingen." + default_email_digest_frequency: "Hoe vaak ontvangen gebruikers standaard de digestmails. Ze kunnen dit in hun eigen instellingen nog aanpassen." + default_other_external_links_in_new_tab: "Open externe links in a nieuwe tab. Gebruikers kunnen dit wijzigen in hun instellingen." allow_profile_backgrounds: "Gebruikers mogen een profielachtergrond instellen." enable_mobile_theme: "Mobiele apparaten gebruiken een mobiel-vriendelijke theme met de mogelijkheid te schakelen naar de volledige site. Schakel deze optie uit als je een eigen stylesheet wil gebruiken die volledig responsive is." suppress_uncategorized_badge: "Laat de badge niet zien voor topics zonder categorie in de topiclijsten." diff --git a/config/locales/server.pl_PL.yml b/config/locales/server.pl_PL.yml index 1677c38ad64..d76b6f50857 100644 --- a/config/locales/server.pl_PL.yml +++ b/config/locales/server.pl_PL.yml @@ -796,10 +796,10 @@ pl_PL: email_editable: "Allow users to change their e-mail address after registration." digest_topics: "Maksymalna liczba tematów w podsumowaniu e-mail." digest_min_excerpt_length: "Minimalny wycinek wpisu (liczba znaków) w podsumowaniu e-mail." - default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." + default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." suppress_digest_email_after_days: "Nie wysyłaj podsumowań e-mail użytkownikom, którzy nie odwiedzili serwisu dłużej niż (n) dni." disable_digest_emails: "Wyłącz wysyłanie podsumowania e-mail wszystkim uzytkownikom. " - default_external_links_in_new_tab: "Otwieraj zewnętrzne odnośniki w nowej karcie. Użytkownicy mogą zmienić to ustawienie w swoich preferencjach." + default_other_external_links_in_new_tab: "Otwieraj zewnętrzne odnośniki w nowej karcie. Użytkownicy mogą zmienić to ustawienie w swoich preferencjach." allow_profile_backgrounds: "Zezwól użytkownikom na przesyłanie obrazu tła dla profilu." enable_mobile_theme: "Urządzenia mobilne używają dedykowanego mobilnego szablonu. Wyłącz to, jeśli chcesz użyć własnego, pojedynczego i responsywnego szablonu stylów. " suppress_uncategorized_badge: "Nie pokazuj etykiety z nazwą kategorii Inne na listach tematów." diff --git a/config/locales/server.pt.yml b/config/locales/server.pt.yml index d702d482516..a56c7fe213c 100644 --- a/config/locales/server.pt.yml +++ b/config/locales/server.pt.yml @@ -975,10 +975,10 @@ pt: automatically_download_gravatars: "Descarregar Gravatars para os utilizadores após criação de conta ou mudança de email." digest_topics: "Número máximo de tópicos a serem apresentados no resumo do email." digest_min_excerpt_length: "Tamanho mínimo do excerto da mensagem no resumo do email, em caracteres." - default_digest_email_frequency: "Por defeito, quantas vezes os utilizadores recebem emails de resumo. Os utilizadores podem alterar esta configuração nas suas preferências." + default_email_digest_frequency: "Por defeito, quantas vezes os utilizadores recebem emails de resumo. Os utilizadores podem alterar esta configuração nas suas preferências." suppress_digest_email_after_days: "Suprimir emails de resumos para utilizadores não vistos no sítio por mais de (n) dias." disable_digest_emails: "Desativar os emails de resumo para todos os utilizadores." - default_external_links_in_new_tab: "Abrir hiperligações externas num novo separador. Os utilizadores podem alterar isto nas suas preferências." + default_other_external_links_in_new_tab: "Abrir hiperligações externas num novo separador. Os utilizadores podem alterar isto nas suas preferências." detect_custom_avatars: "Se deve ou não verificar que os utilizadores carregaram fotografias de perfil personalizadas." max_daily_gravatar_crawls: "Número máximo de vezes que o Discourse irá verificar o Gravatar para avatars personalizados, por dia" public_user_custom_fields: "Lista de campos personalizados para um utilizador e que podem ser exibidos publicamente." diff --git a/config/locales/server.pt_BR.yml b/config/locales/server.pt_BR.yml index 6ea46219628..c1d7dbd4231 100644 --- a/config/locales/server.pt_BR.yml +++ b/config/locales/server.pt_BR.yml @@ -938,10 +938,10 @@ pt_BR: automatically_download_gravatars: "Fazer download de Gravatars dos usuários ao criar conta ou mudança de email." digest_topics: "O número máximo de tópicos a serem mostrados no resumo via email." digest_min_excerpt_length: "O excerto mínimo de post no resumo via email, em caracteres." - default_digest_email_frequency: "Quantas vezes os usuários recebem emails de resumo por padrão. Eles podem alterar essa configuração em suas preferências." + default_email_digest_frequency: "Quantas vezes os usuários recebem emails de resumo por padrão. Eles podem alterar essa configuração em suas preferências." suppress_digest_email_after_days: "Suprimir emails de resumo para usuários não vistos no site há mais do que (n) dias." disable_digest_emails: "Desabilitar emails de resumo para todos os usuários." - default_external_links_in_new_tab: "Abrir links externos em uma nova guia. Os usuários podem mudar isso em suas preferências." + default_other_external_links_in_new_tab: "Abrir links externos em uma nova guia. Os usuários podem mudar isso em suas preferências." max_daily_gravatar_crawls: "Número máximo de vezes que o Discourse irá checar o Gravatar por avatares personalizados em um dia" public_user_custom_fields: "Um conjunto de campos personalizados para um usuário que podem ser apresentados publicamente." staff_user_custom_fields: "Um conjunto de campos personalizados para um usuário que pode ser mostrado para membros da equipe." diff --git a/config/locales/server.ro.yml b/config/locales/server.ro.yml index fc589c87cfb..d3bef4d66a3 100644 --- a/config/locales/server.ro.yml +++ b/config/locales/server.ro.yml @@ -770,7 +770,7 @@ ro: automatically_download_gravatars: "Descarcă Gravatare pentru utilizatori la crearea contului sau schimbarea email-ului." digest_topics: "Numărul maxim de discuții arătate în email-ul rezumat." digest_min_excerpt_length: "Numărul minimum de extrase din postări din email-ul rezumat, în caractere." - default_digest_email_frequency: "Cat de des utliziatorii primesc emailuri rezumat din oficiu. Utilizatorii pot schimba această opțiune în preferințe." + default_email_digest_frequency: "Cat de des utliziatorii primesc emailuri rezumat din oficiu. Utilizatorii pot schimba această opțiune în preferințe." max_daily_gravatar_crawls: "Numărul maxim de verificări făcute de Discourse pentru existența unui gravatar preferențial într-o zi" allow_profile_backgrounds: "Permite utilizatorilor să încarce fundaluri de profil." sequential_replies_threshold: "Numărul de postări la rând într-o discuție până să-i fie amintit utilizatorului că sunt prea multe răspunsuri secvențiale. " diff --git a/config/locales/server.ru.yml b/config/locales/server.ru.yml index faade29e258..49f466e6535 100644 --- a/config/locales/server.ru.yml +++ b/config/locales/server.ru.yml @@ -986,10 +986,10 @@ ru: automatically_download_gravatars: "Скачивать аватарку Gravatar пользователя во время создания учетной записи или изменения e-mail." digest_topics: "Максимальное количество тем в письме - сводке новостей." digest_min_excerpt_length: "Минимальная длина (в символах) вытяжки из сообщения в письме - сводке новостей." - default_digest_email_frequency: "Как часто пользователи получают дайджест по умолчанию. Возможно изменение этой настройки каждым пользователем." + default_email_digest_frequency: "Как часто пользователи получают дайджест по умолчанию. Возможно изменение этой настройки каждым пользователем." suppress_digest_email_after_days: "Не рассылать новости для пользователей, которые не заходили на сайт в течении (n) дней." disable_digest_emails: "Отключить рассылку новостей для всех пользователей." - default_external_links_in_new_tab: "Открывать внешние ссылки в новом окне. Пользователи могут изменить данное поведение в настройках." + default_other_external_links_in_new_tab: "Открывать внешние ссылки в новом окне. Пользователи могут изменить данное поведение в настройках." max_daily_gravatar_crawls: "Максимальное количество загрузок аватаорок с Gravatar за один день" public_user_custom_fields: "Список разрешенных дополнительных полей пользователей, которые могут быть отображены публично." staff_user_custom_fields: "Список разрешенных дополнительных полей пользователей, которые могут быть отображены для модераторов." diff --git a/config/locales/server.sq.yml b/config/locales/server.sq.yml index 3cf162ef810..b2639ae2fd9 100644 --- a/config/locales/server.sq.yml +++ b/config/locales/server.sq.yml @@ -971,10 +971,10 @@ sq: automatically_download_gravatars: "Download Gravatars for users upon account creation or email change." digest_topics: "The maximum number of topics to display in the email digest." digest_min_excerpt_length: "Minimum post excerpt in the email digest, in characters." - default_digest_email_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." + default_email_digest_frequency: "How often users receive digest emails by default. They can change this setting in their preferences." suppress_digest_email_after_days: "Suppress digest emails for users not seen on the site for more than (n) days." disable_digest_emails: "Disable digest emails for all users." - default_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences." + default_other_external_links_in_new_tab: "Open external links in a new tab. Users can change this in their preferences." detect_custom_avatars: "Whether or not to check that users have uploaded custom profile pictures." max_daily_gravatar_crawls: "Maximum number of times Discourse will check Gravatar for custom avatars in a day" public_user_custom_fields: "A whitelist of custom fields for a user that can be shown publicly." diff --git a/config/locales/server.sv.yml b/config/locales/server.sv.yml index 6e939fcfd32..2c7bcaaf393 100644 --- a/config/locales/server.sv.yml +++ b/config/locales/server.sv.yml @@ -719,7 +719,7 @@ sv: disable_emails: "Förhindra Discourse från att skicka någon form av e-post" pop3_polling_ssl: "Använd SSL vid anslutning till POP3-servern. (Rekommenderat)" email_editable: "Tillåt användare att ändra deras e-postadress efter registrering." - default_digest_email_frequency: "Hur ofta användare får emailutskick som standard. De kan ändra detta val under sina inställningar." + default_email_digest_frequency: "Hur ofta användare får emailutskick som standard. De kan ändra detta val under sina inställningar." enable_user_directory: "Tillhandahåll en bläddringsbar användarkatalog" allow_anonymous_posting: "Tillåt användare att växla till anonymt läge" anonymous_posting_min_trust_level: "Lägsta förtroendenivå som krävs för att aktivera anonyma inlägg" diff --git a/config/locales/server.tr_TR.yml b/config/locales/server.tr_TR.yml index 053737520bb..d938e4cf611 100644 --- a/config/locales/server.tr_TR.yml +++ b/config/locales/server.tr_TR.yml @@ -889,10 +889,10 @@ tr_TR: automatically_download_gravatars: "Hesap oluşturma veya e-posta değişikliği esnasında kullanıcılar için Gravatarları indir" digest_topics: "Özet e-postalarda yer alacak en fazla konu sayısı. " digest_min_excerpt_length: "Özet e-postalarında, gönderi alıntılarında olması gereken en az karakter sayısı." - default_digest_email_frequency: "Varsayılan olarak, özet e-postalar hangi sıklıkta gönderilsin? Üyeler, ayarlar sayfasından bu değeri değiştirebilir." + default_email_digest_frequency: "Varsayılan olarak, özet e-postalar hangi sıklıkta gönderilsin? Üyeler, ayarlar sayfasından bu değeri değiştirebilir." suppress_digest_email_after_days: "Siteye (n) günden fazla süredir uğramayan kullanıcılar için özet e-posta gönderimini durdur" disable_digest_emails: "Tüm kullanıcılar için özet e-postalarını devre dışı bırak." - default_external_links_in_new_tab: "Dış bağlantıları yeni sekmede aç. Üyeler, ayarlar sayfasından bu ayarı değiştirebilir." + default_other_external_links_in_new_tab: "Dış bağlantıları yeni sekmede aç. Üyeler, ayarlar sayfasından bu ayarı değiştirebilir." max_daily_gravatar_crawls: "Discourse'un gün içinde özel avatarlar için Gravatar'ı en fazla kaç kere kontrol edeceği." public_user_custom_fields: "Kullanıcıların için, herkes tarafından görüntülenebilir özel alanların beyaz listesi." staff_user_custom_fields: "Kullanıcıların için, sadece görevlilere görüntülenebilir özel alanların beyaz listesi." diff --git a/config/locales/server.uk.yml b/config/locales/server.uk.yml index 9ad9d639e02..07262f51331 100644 --- a/config/locales/server.uk.yml +++ b/config/locales/server.uk.yml @@ -371,8 +371,8 @@ uk: delete_all_posts_max: "Максимальне число дописів, які можна видалити за один раз кнопкою \"Видалити всі дописи\". Якщо користувач має більше дописів, ніж це число, їх не можна буде видалити за один раз, і користувача також." username_change_period: "Кількість днів після реєстрації, протягом яких новим обліковим записам можна змінювати своє ім'я користувача (0 щоб заборонити зміну імені користувача)." email_editable: "Дозволити користувачам змінювати свою електронну скриньку після реєстрації." - default_digest_email_frequency: "Як часто користувачі отримують листи зі стислим викладом новин за замовчуванням. Вони можуть змінити це у своїх налаштуваннях." - default_external_links_in_new_tab: "Відкривати нові посилання у новій вкладці. Користувачі можуть змінити це у своїх налаштуваннях." + default_email_digest_frequency: "Як часто користувачі отримують листи зі стислим викладом новин за замовчуванням. Вони можуть змінити це у своїх налаштуваннях." + default_other_external_links_in_new_tab: "Відкривати нові посилання у новій вкладці. Користувачі можуть змінити це у своїх налаштуваннях." allow_profile_backgrounds: "Дозволити користувачам завантажувати фони профілю." enable_mobile_theme: "Мобільні пристрої використовуватимуть тему, дружню для них, з можливістю перемикатися на повний сайт. Відключіть це, якщо хочете використовувати власну, повністю чутливу, таблицю стилів." display_name_on_posts: "Показувати повні імена користувачів на їх дописах у додаток до їх @username." diff --git a/config/locales/server.zh_CN.yml b/config/locales/server.zh_CN.yml index 13821a1111c..5c834650d09 100644 --- a/config/locales/server.zh_CN.yml +++ b/config/locales/server.zh_CN.yml @@ -937,10 +937,10 @@ zh_CN: automatically_download_gravatars: "为注册或更改邮箱的用户下载 Gravatar 头像。" digest_topics: "邮件摘要中显示的最大主题数目。" digest_min_excerpt_length: "在邮件摘要中每个帖子最少显示的字符数量。" - default_digest_email_frequency: "用户收到摘要邮件的默认间隔。用户可以在参数设置中更改这个设置。" + default_email_digest_frequency: "用户收到摘要邮件的默认间隔。用户可以在参数设置中更改这个设置。" suppress_digest_email_after_days: "不发送摘要邮件给超过 (n) 天未出现的用户。" disable_digest_emails: "为所有用户禁用摘要邮件。" - default_external_links_in_new_tab: "在新标签页中打开外部链接。用户可以在参数设置中更改这个设置。" + default_other_external_links_in_new_tab: "在新标签页中打开外部链接。用户可以在参数设置中更改这个设置。" detect_custom_avatars: "检测用户是否上传了自定义个人头像。" max_daily_gravatar_crawls: "一天内 Discourse 将自动检查 gravatar 自定义头像的次数" public_user_custom_fields: "可公开显示的用户自定义属性白名单" diff --git a/config/locales/server.zh_TW.yml b/config/locales/server.zh_TW.yml index 4c8efad4cff..dd0d0c98509 100644 --- a/config/locales/server.zh_TW.yml +++ b/config/locales/server.zh_TW.yml @@ -769,10 +769,10 @@ zh_TW: automatically_download_gravatars: "當用戶註冊或更改EMail時下載 Gravatars 圖片" digest_topics: "EMail 摘要中顯示的最大話題數量" digest_min_excerpt_length: "EMail 摘要中每篇文章最少顯示的字元數量" - default_digest_email_frequency: "用戶收到摘要郵件的默認間隔。用戶可以在設定中更改。" + default_email_digest_frequency: "用戶收到摘要郵件的默認間隔。用戶可以在設定中更改。" suppress_digest_email_after_days: "不發送摘要郵件給超過 (n) 天閒置的用戶。" disable_digest_emails: "禁用發送摘要郵件給所有用戶。" - default_external_links_in_new_tab: "以新分頁開啟所有外部連結,用戶可於個人偏好設定更改設定。" + default_other_external_links_in_new_tab: "以新分頁開啟所有外部連結,用戶可於個人偏好設定更改設定。" max_daily_gravatar_crawls: "一天內 Discourse 將自動檢查 Gravatar 自訂個人圖示的次數" public_user_custom_fields: "用戶可設定公開顯示的自定欄位白名單。" staff_user_custom_fields: "用戶可設定只給管理員顯示的自定欄位白名單。" diff --git a/config/site_settings.yml b/config/site_settings.yml index 3dd9f030544..7720cf89030 100644 --- a/config/site_settings.yml +++ b/config/site_settings.yml @@ -70,7 +70,6 @@ basic: min: 0 limit_suggested_to_category: default: false - default_external_links_in_new_tab: false track_external_right_clicks: client: true default: false @@ -282,7 +281,6 @@ users: default: '' hidden: true username_change_period: 3 - auto_track_topics_after: 240000 email_editable: true logout_redirect: client: true @@ -474,9 +472,6 @@ email: email_posts_context: 5 digest_min_excerpt_length: 100 digest_topics: 20 - default_digest_email_frequency: - default: 7 - enum: 'DigestEmailSiteSetting' suppress_digest_email_after_days: 365 disable_digest_emails: default: false @@ -841,7 +836,6 @@ uncategorized: max_similar_results: 5 minimum_topics_similar: 50 - new_topic_duration_minutes: 2880 previous_visit_timeout_hours: 1 staff_like_weight: 3 topic_view_duration_hours: 8 @@ -959,3 +953,34 @@ uncategorized: privacy_topic_id: default: -1 hidden: true + +user_preferences: + default_email_digest_frequency: + enum: 'DigestEmailSiteSetting' + default: 7 + default_email_private_messages: true + default_email_direct: true + default_email_mailing_list_mode: false + default_email_always: false + + default_other_new_topic_duration_minutes: + enum: 'NewTopicDurationSiteSetting' + default: 2880 + default_other_auto_track_topics_after_msecs: + enum: 'AutoTrackDurationSiteSetting' + default: 240000 + default_other_external_links_in_new_tab: false + default_other_enable_quoting: true + default_other_dynamic_favicon: false + default_other_disable_jump_reply: false + default_other_edit_history_public: false + + default_categories_watching: + type: category_list + default: '' + default_categories_tracking: + type: category_list + default: '' + default_categories_muted: + type: category_list + default: '' diff --git a/lib/site_setting_extension.rb b/lib/site_setting_extension.rb index f4c7c1df20a..19ad366f06e 100644 --- a/lib/site_setting_extension.rb +++ b/lib/site_setting_extension.rb @@ -21,7 +21,7 @@ module SiteSettingExtension end def types - @types ||= Enum.new(:string, :time, :fixnum, :float, :bool, :null, :enum, :list, :url_list, :host_list) + @types ||= Enum.new(:string, :time, :fixnum, :float, :bool, :null, :enum, :list, :url_list, :host_list, :category_list) end def mutex diff --git a/lib/site_setting_validations.rb b/lib/site_setting_validations.rb index 6ed44df8037..5a9fbb2fb9d 100644 --- a/lib/site_setting_validations.rb +++ b/lib/site_setting_validations.rb @@ -14,4 +14,13 @@ module SiteSettingValidations validate_error :min_username_length_range if new_val < SiteSetting.min_username_length validate_error :max_username_length_exists if User.where('length(username) > ?', new_val).exists? end + + def validate_default_categories(new_val) + validate_error :default_categories_already_selected if (new_val.split("|").to_set & SiteSetting.default_categories_selected).size > 0 + end + + alias_method :validate_default_categories_watching, :validate_default_categories + alias_method :validate_default_categories_tracking, :validate_default_categories + alias_method :validate_default_categories_muted, :validate_default_categories + end diff --git a/spec/components/site_settings/yaml_loader_spec.rb b/spec/components/site_settings/yaml_loader_spec.rb index a6800a1134a..6fc59b623a3 100644 --- a/spec/components/site_settings/yaml_loader_spec.rb +++ b/spec/components/site_settings/yaml_loader_spec.rb @@ -64,7 +64,7 @@ describe SiteSettings::YamlLoader do end it "can load enum settings" do - receiver.expects(:setting).with('email', 'default_digest_email_frequency', 7, {enum: 'DigestEmailSiteSetting'}) + receiver.expects(:setting).with('email', 'default_email_digest_frequency', 7, {enum: 'DigestEmailSiteSetting'}) receiver.load_yaml(enum) end diff --git a/spec/fixtures/site_settings/enum.yml b/spec/fixtures/site_settings/enum.yml index 999b30b5ee6..638caeee206 100644 --- a/spec/fixtures/site_settings/enum.yml +++ b/spec/fixtures/site_settings/enum.yml @@ -1,4 +1,4 @@ email: - default_digest_email_frequency: + default_email_digest_frequency: default: 7 enum: 'DigestEmailSiteSetting' diff --git a/spec/jobs/enqueue_digest_emails_spec.rb b/spec/jobs/enqueue_digest_emails_spec.rb index 2c32d343187..459e087051b 100644 --- a/spec/jobs/enqueue_digest_emails_spec.rb +++ b/spec/jobs/enqueue_digest_emails_spec.rb @@ -3,11 +3,11 @@ require_dependency 'jobs/base' describe Jobs::EnqueueDigestEmails do - describe '#target_users' do context 'disabled digests' do - let!(:user_no_digests) { Fabricate(:active_user, email_digests: false, last_emailed_at: 8.days.ago, last_seen_at: 10.days.ago) } + before { SiteSetting.stubs(:default_email_digest_frequency).returns("") } + let!(:user_no_digests) { Fabricate(:active_user, last_emailed_at: 8.days.ago, last_seen_at: 10.days.ago) } it "doesn't return users with email disabled" do expect(Jobs::EnqueueDigestEmails.new.target_user_ids.include?(user_no_digests.id)).to eq(false) diff --git a/spec/jobs/notify_mailing_list_subscribers_spec.rb b/spec/jobs/notify_mailing_list_subscribers_spec.rb index bd70b7d3d92..84e94dc58fc 100644 --- a/spec/jobs/notify_mailing_list_subscribers_spec.rb +++ b/spec/jobs/notify_mailing_list_subscribers_spec.rb @@ -3,62 +3,69 @@ require "spec_helper" describe Jobs::NotifyMailingListSubscribers do context "with mailing list on" do - let(:user) { Fabricate(:user, mailing_list_mode: true) } + before { SiteSetting.stubs(:default_email_mailing_list_mode).returns(true) } - context "with a valid post" do + context "with mailing list on" do + let(:user) { Fabricate(:user) } + + context "with a valid post" do + let!(:post) { Fabricate(:post, user: user) } + + it "sends the email to the user" do + UserNotifications.expects(:mailing_list_notify).with(user, post).once + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + end + end + + context "with a deleted post" do + let!(:post) { Fabricate(:post, user: user, deleted_at: Time.now) } + + it "doesn't send the email to the user" do + UserNotifications.expects(:mailing_list_notify).with(user, post).never + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + end + end + + context "with a user_deleted post" do + let!(:post) { Fabricate(:post, user: user, user_deleted: true) } + + it "doesn't send the email to the user" do + UserNotifications.expects(:mailing_list_notify).with(user, post).never + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + end + end + + context "with a deleted topic" do + let!(:post) { Fabricate(:post, user: user) } + + before do + post.topic.update_column(:deleted_at, Time.now) + end + + it "doesn't send the email to the user" do + UserNotifications.expects(:mailing_list_notify).with(user, post).never + Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) + end + end + + end + + context "to an anonymous user with mailing list on" do + let(:user) { Fabricate(:anonymous) } let!(:post) { Fabricate(:post, user: user) } - it "sends the email to the user" do - UserNotifications.expects(:mailing_list_notify).with(user, post).once - Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) - end - end - - context "with a deleted post" do - let!(:post) { Fabricate(:post, user: user, deleted_at: Time.now) } - it "doesn't send the email to the user" do UserNotifications.expects(:mailing_list_notify).with(user, post).never Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) end end - context "with a user_deleted post" do - let!(:post) { Fabricate(:post, user: user, user_deleted: true) } - - it "doesn't send the email to the user" do - UserNotifications.expects(:mailing_list_notify).with(user, post).never - Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) - end - end - - context "with a deleted topic" do - let!(:post) { Fabricate(:post, user: user) } - - before do - post.topic.update_column(:deleted_at, Time.now) - end - - it "doesn't send the email to the user" do - UserNotifications.expects(:mailing_list_notify).with(user, post).never - Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) - end - end - - end - - context "to an anonymous user with mailing list on" do - let(:user) { Fabricate(:anonymous, mailing_list_mode: true) } - let!(:post) { Fabricate(:post, user: user) } - - it "doesn't send the email to the user" do - UserNotifications.expects(:mailing_list_notify).with(user, post).never - Jobs::NotifyMailingListSubscribers.new.execute(post_id: post.id) - end end context "with mailing list off" do - let(:user) { Fabricate(:user, mailing_list_mode: false) } + before { SiteSetting.stubs(:default_email_mailing_list_mode).returns(false) } + + let(:user) { Fabricate(:user) } let!(:post) { Fabricate(:post, user: user) } it "doesn't send the email to the user" do diff --git a/spec/models/topic_user_spec.rb b/spec/models/topic_user_spec.rb index ce8ec92a9ef..4498d6e3608 100644 --- a/spec/models/topic_user_spec.rb +++ b/spec/models/topic_user_spec.rb @@ -181,13 +181,13 @@ describe TopicUser do it 'should automatically track topics after they are read for long enough' do expect(topic_new_user.notification_level).to eq(TopicUser.notification_levels[:regular]) - TopicUser.update_last_read(new_user, topic.id, 2, 1001) + TopicUser.update_last_read(new_user, topic.id, 2, SiteSetting.default_other_auto_track_topics_after_msecs + 1) expect(TopicUser.get(topic, new_user).notification_level).to eq(TopicUser.notification_levels[:tracking]) end it 'should not automatically track topics after they are read for long enough if changed manually' do TopicUser.change(new_user, topic, notification_level: TopicUser.notification_levels[:regular]) - TopicUser.update_last_read(new_user, topic, 2, 1001) + TopicUser.update_last_read(new_user, topic, 2, SiteSetting.default_other_auto_track_topics_after_msecs + 1) expect(topic_new_user.notification_level).to eq(TopicUser.notification_levels[:regular]) end end @@ -256,9 +256,13 @@ describe TopicUser do it "will receive email notification for every topic" do user1 = Fabricate(:user) - user2 = Fabricate(:user, mailing_list_mode: true) + + SiteSetting.stubs(:default_email_mailing_list_mode).returns(true) + + user2 = Fabricate(:user) post = create_post - user3 = Fabricate(:user, mailing_list_mode: true) + + user3 = Fabricate(:user) create_post(topic_id: post.topic_id) # mails posts from earlier topics diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 7f3aeb68128..e2bd09f772d 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -156,24 +156,6 @@ describe User do expect(subject.email_direct).to eq(true) end - context 'digest emails' do - it 'defaults to digests every week' do - expect(subject.email_digests).to eq(true) - expect(subject.digest_after_days).to eq(7) - end - - it 'uses default_digest_email_frequency' do - SiteSetting.stubs(:default_digest_email_frequency).returns(1) - expect(subject.email_digests).to eq(true) - expect(subject.digest_after_days).to eq(1) - end - - it 'disables digests by default if site setting says so' do - SiteSetting.stubs(:default_digest_email_frequency).returns('') - expect(subject.email_digests).to eq(false) - end - end - context 'after_save' do before { subject.save } @@ -1223,4 +1205,50 @@ describe User do end end + context "when user preferences are overriden" do + + before do + SiteSetting.stubs(:default_email_digest_frequency).returns(1) # daily + SiteSetting.stubs(:default_email_private_messages).returns(false) + SiteSetting.stubs(:default_email_direct).returns(false) + SiteSetting.stubs(:default_email_mailing_list_mode).returns(true) + SiteSetting.stubs(:default_email_always).returns(true) + + SiteSetting.stubs(:default_other_new_topic_duration_minutes).returns(-1) # not viewed + SiteSetting.stubs(:default_other_auto_track_topics_after_msecs).returns(0) # immediately + SiteSetting.stubs(:default_other_external_links_in_new_tab).returns(true) + SiteSetting.stubs(:default_other_enable_quoting).returns(false) + SiteSetting.stubs(:default_other_dynamic_favicon).returns(true) + SiteSetting.stubs(:default_other_disable_jump_reply).returns(true) + SiteSetting.stubs(:default_other_edit_history_public).returns(true) + + SiteSetting.stubs(:default_categories_watching).returns("1") + SiteSetting.stubs(:default_categories_tracking).returns("2") + SiteSetting.stubs(:default_categories_muted).returns("3") + end + + it "has overriden preferences" do + user = Fabricate(:user) + + expect(user.digest_after_days).to eq(1) + expect(user.email_private_messages).to eq(false) + expect(user.email_direct).to eq(false) + expect(user.mailing_list_mode).to eq(true) + expect(user.email_always).to eq(true) + + expect(user.new_topic_duration_minutes).to eq(-1) + expect(user.auto_track_topics_after_msecs).to eq(0) + expect(user.external_links_in_new_tab).to eq(true) + expect(user.enable_quoting).to eq(false) + expect(user.dynamic_favicon).to eq(true) + expect(user.disable_jump_reply).to eq(true) + expect(user.edit_history_public).to eq(true) + + expect(CategoryUser.lookup(user, :watching).pluck(:category_id)).to eq([1]) + expect(CategoryUser.lookup(user, :tracking).pluck(:category_id)).to eq([2]) + expect(CategoryUser.lookup(user, :muted).pluck(:category_id)).to eq([3]) + end + + end + end