diff --git a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
index 002eaba949f..18dccd86858 100644
--- a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
+++ b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
@@ -1,8 +1,11 @@
import PreferencesTabController from "discourse/mixins/preferences-tab-controller";
+import { setDefaultHomepage } from "discourse/lib/utilities";
import { default as computed, observes } from "ember-addons/ember-computed-decorators";
import { currentThemeKey, listThemes, previewTheme, setLocalTheme } from 'discourse/lib/theme-selector';
import { popupAjaxError } from 'discourse/lib/ajax-error';
+const USER_HOMES = { 1: "latest", 2: "categories", 3: "unread", 4: "new", 5: "top" };
+
export default Ember.Controller.extend(PreferencesTabController, {
@computed("makeThemeDefault")
@@ -14,6 +17,8 @@ export default Ember.Controller.extend(PreferencesTabController, {
'enable_quoting',
'disable_jump_reply',
'automatically_unpin_topics',
+ 'allow_private_messages',
+ 'homepage_id',
];
if (makeDefault) {
@@ -51,6 +56,19 @@ export default Ember.Controller.extend(PreferencesTabController, {
previewTheme(key);
},
+ homeChanged() {
+ const siteHome = Discourse.SiteSettings.top_menu.split("|")[0].split(",")[0];
+ const userHome = USER_HOMES[this.get('model.user_option.homepage_id')];
+ setDefaultHomepage(userHome || siteHome);
+ },
+
+ @computed()
+ userSelectableHome() {
+ return _.map(USER_HOMES, (name, num) => {
+ return {name: I18n.t('filters.' + name + '.title'), value: num};
+ });
+ },
+
actions: {
save() {
this.set('saved', false);
@@ -66,6 +84,8 @@ export default Ember.Controller.extend(PreferencesTabController, {
setLocalTheme(this.get('themeKey'), this.get('model.user_option.theme_key_seq'));
}
+ this.homeChanged();
+
}).catch(popupAjaxError);
}
}
diff --git a/app/assets/javascripts/discourse/lib/utilities.js.es6 b/app/assets/javascripts/discourse/lib/utilities.js.es6
index fe3616abb54..cba27615715 100644
--- a/app/assets/javascripts/discourse/lib/utilities.js.es6
+++ b/app/assets/javascripts/discourse/lib/utilities.js.es6
@@ -1,5 +1,7 @@
import { escape } from 'pretty-text/sanitizer';
+const homepageSelector = 'meta[name=discourse_current_homepage]';
+
export function translateSize(size) {
switch (size) {
case 'tiny': return 20;
@@ -349,8 +351,22 @@ export function displayErrorForUpload(data) {
}
export function defaultHomepage() {
- // the homepage is the first item of the 'top_menu' site setting
- return Discourse.SiteSettings.top_menu.split("|")[0].split(",")[0];
+ let homepage = null;
+ let elem = _.first($(homepageSelector));
+ if (elem) {
+ homepage = elem.content;
+ }
+ if (!homepage) {
+ homepage = Discourse.SiteSettings.top_menu.split("|")[0].split(",")[0];
+ }
+ return homepage;
+}
+
+export function setDefaultHomepage(homepage) {
+ let elem = _.first($(homepageSelector));
+ if (elem) {
+ elem.content = homepage;
+ }
}
export function determinePostReplaceSelection({ selection, needle, replacement }) {
diff --git a/app/assets/javascripts/discourse/models/user.js.es6 b/app/assets/javascripts/discourse/models/user.js.es6
index 17e7f9bfc11..82171ada01b 100644
--- a/app/assets/javascripts/discourse/models/user.js.es6
+++ b/app/assets/javascripts/discourse/models/user.js.es6
@@ -249,6 +249,7 @@ const User = RestModel.extend({
'include_tl0_in_digests',
'theme_key',
'allow_private_messages',
+ 'homepage_id',
];
if (fields) {
diff --git a/app/assets/javascripts/discourse/templates/preferences/interface.hbs b/app/assets/javascripts/discourse/templates/preferences/interface.hbs
index 8e8d5852e90..f6db98b840c 100644
--- a/app/assets/javascripts/discourse/templates/preferences/interface.hbs
+++ b/app/assets/javascripts/discourse/templates/preferences/interface.hbs
@@ -23,6 +23,13 @@
{{/if}}
+
+
+
+ {{combo-box content=userSelectableHome valueAttribute="value" value=model.user_option.homepage_id}}
+
+
+
diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb
index 71d3e9e683c..05fbfdb733d 100644
--- a/app/controllers/application_controller.rb
+++ b/app/controllers/application_controller.rb
@@ -308,7 +308,7 @@ class ApplicationController < ActionController::Base
end
def current_homepage
- current_user ? SiteSetting.homepage : SiteSetting.anonymous_homepage
+ current_user&.user_option&.homepage || SiteSetting.anonymous_homepage
end
def serialize_data(obj, serializer, opts = nil)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index de63356aa17..40bb8244436 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -347,6 +347,10 @@ module ApplicationHelper
end
end
+ def current_homepage
+ current_user&.user_option&.homepage || SiteSetting.anonymous_homepage
+ end
+
def build_plugin_html(name)
return "" unless allow_plugins?
DiscoursePluginRegistry.build_html(name, controller) || ""
diff --git a/app/models/user_option.rb b/app/models/user_option.rb
index 17eed6baa7f..a780a4015f2 100644
--- a/app/models/user_option.rb
+++ b/app/models/user_option.rb
@@ -128,6 +128,17 @@ class UserOption < ActiveRecord::Base
times.max
end
+ def homepage
+ case homepage_id
+ when 1 then "latest"
+ when 2 then "categories"
+ when 3 then "unread"
+ when 4 then "new"
+ when 5 then "top"
+ else SiteSetting.homepage
+ end
+ end
+
private
def update_tracked_topics
@@ -165,6 +176,7 @@ end
# theme_key :string
# theme_key_seq :integer default(0), not null
# allow_private_messages :boolean default(TRUE), not null
+# homepage_id :integer default(null)
#
# Indexes
#
diff --git a/app/serializers/user_option_serializer.rb b/app/serializers/user_option_serializer.rb
index 844f6c06b5c..6bccbe81766 100644
--- a/app/serializers/user_option_serializer.rb
+++ b/app/serializers/user_option_serializer.rb
@@ -22,6 +22,7 @@ class UserOptionSerializer < ApplicationSerializer
:theme_key,
:theme_key_seq,
:allow_private_messages,
+ :homepage_id,
def auto_track_topics_after_msecs
object.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs
diff --git a/app/services/user_updater.rb b/app/services/user_updater.rb
index 591a50a966f..305f96fddc1 100644
--- a/app/services/user_updater.rb
+++ b/app/services/user_updater.rb
@@ -36,6 +36,7 @@ class UserUpdater
:include_tl0_in_digests,
:theme_key,
:allow_private_messages,
+ :homepage_id,
]
def initialize(actor, user)
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index a6e1e707582..83c7bccf1cd 100644
--- a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -5,6 +5,7 @@
<%= content_for?(:title) ? yield(:title) : SiteSetting.title %>
+
<%= render partial: "layouts/head" %>
<%= discourse_csrf_tags %>
diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml
index 2b28082280a..a3ec45596d3 100644
--- a/config/locales/client.en.yml
+++ b/config/locales/client.en.yml
@@ -658,6 +658,7 @@ en:
undo_revoke_access: "Undo Revoke Access"
api_approved: "Approved:"
theme: "Theme"
+ home: "Default Home Page"
staff_counters:
flags_given: "helpful flags"
diff --git a/db/migrate/20171026014317_add_user_option_home.rb b/db/migrate/20171026014317_add_user_option_home.rb
new file mode 100644
index 00000000000..8724ec40e7f
--- /dev/null
+++ b/db/migrate/20171026014317_add_user_option_home.rb
@@ -0,0 +1,5 @@
+class AddUserOptionHome < ActiveRecord::Migration[5.1]
+ def change
+ add_column :user_options, :homepage_id, :integer, null: true, default: nil
+ end
+end
diff --git a/lib/homepage_constraint.rb b/lib/homepage_constraint.rb
index a5cfb347582..586581425c3 100644
--- a/lib/homepage_constraint.rb
+++ b/lib/homepage_constraint.rb
@@ -7,7 +7,7 @@ class HomePageConstraint
return @filter == 'finish_installation' if SiteSetting.has_login_hint?
provider = Discourse.current_user_provider.new(request.env)
- homepage = provider.current_user ? SiteSetting.homepage : SiteSetting.anonymous_homepage
+ homepage = provider&.current_user&.user_option&.homepage || SiteSetting.anonymous_homepage
homepage == @filter
rescue Discourse::InvalidAccess
false
diff --git a/test/javascripts/lib/utilities-test.js.es6 b/test/javascripts/lib/utilities-test.js.es6
index e903b977923..8ef76a79fac 100644
--- a/test/javascripts/lib/utilities-test.js.es6
+++ b/test/javascripts/lib/utilities-test.js.es6
@@ -10,6 +10,7 @@ import {
getRawSize,
avatarImg,
defaultHomepage,
+ setDefaultHomepage,
validateUploadedFiles,
getUploadMarkdown,
caretRowCol,
@@ -204,6 +205,22 @@ QUnit.test("allowsAttachments", assert => {
QUnit.test("defaultHomepage", assert => {
Discourse.SiteSettings.top_menu = "latest|top|hot";
assert.equal(defaultHomepage(), "latest", "default homepage is the first item in the top_menu site setting");
+ var meta = document.createElement("meta");
+ meta.name = "discourse_current_homepage";
+ meta.content = "hot";
+ document.body.appendChild(meta);
+ assert.equal(defaultHomepage(), "hot", "default homepage is pulled from ");
+ document.body.removeChild(meta);
+});
+
+QUnit.test("setDefaultHomepage", assert => {
+ var meta = document.createElement("meta");
+ meta.name = "discourse_current_homepage";
+ meta.content = "hot";
+ document.body.appendChild(meta);
+ setDefaultHomepage("top");
+ assert.equal(meta.content, "top", "default homepage set by setDefaultHomepage");
+ document.body.removeChild(meta);
});
QUnit.test("caretRowCol", assert => {