diff --git a/public/src/client/account/settings.js b/public/src/client/account/settings.js index 537baab5de..eba41faf9c 100644 --- a/public/src/client/account/settings.js +++ b/public/src/client/account/settings.js @@ -4,6 +4,12 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds'], function (header, components, sounds) { var AccountSettings = {}; + $(window).on('action:ajaxify.start', function () { + if (ajaxify.data.template.name === 'account/settings' && $('#bootswatchSkin').val() !== config.bootswatchSkin) { + changePageSkin(config.bootswatchSkin); + } + }); + AccountSettings.init = function () { header.init(); @@ -24,10 +30,7 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds' }); $('#bootswatchSkin').on('change', function () { - var css = $('#bootswatchCSS'); - var val = $(this).val() === 'default' ? config['theme:src'] : '//maxcdn.bootstrapcdn.com/bootswatch/latest/' + $(this).val() + '/bootstrap.min.css'; - - css.attr('href', val); + changePageSkin($(this).val()); }); $('[data-property="homePageRoute"]').on('change', toggleCustomRoute); @@ -44,6 +47,26 @@ define('forum/account/settings', ['forum/account/header', 'components', 'sounds' components.get('user/sessions').find('.timeago').timeago(); }; + function changePageSkin(skinName) { + var css = $('#bootswatchCSS'); + if (skinName === 'default') { + css.remove(); + } else { + var cssSource = '//maxcdn.bootstrapcdn.com/bootswatch/latest/' + skinName + '/bootstrap.min.css'; + if (css.length) { + css.attr('href', cssSource); + } else { + css = $(''); + $('head').append(css); + } + } + + var currentSkinClassName = $('body').attr('class').split(/\s+/).filter(function (className) { + return className.startsWith('skin-'); + }); + $('body').removeClass(currentSkinClassName.join(' ')).addClass('skin-' + skinName); + } + function loadSettings() { var settings = {}; diff --git a/src/controllers/api.js b/src/controllers/api.js index ab52da69cd..cfa78a6908 100644 --- a/src/controllers/api.js +++ b/src/controllers/api.js @@ -61,7 +61,7 @@ apiController.getConfig = function (req, res, next) { config.categoryTopicSort = meta.config.categoryTopicSort || 'newest_to_oldest'; config.csrf_token = req.csrfToken(); config.searchEnabled = plugins.hasListeners('filter:search.query'); - config.bootswatchSkin = 'default'; + config.bootswatchSkin = meta.config.bootswatchSkin || 'default'; var timeagoCutoff = meta.config.timeagoCutoff === undefined ? 30 : meta.config.timeagoCutoff; config.timeagoCutoff = timeagoCutoff !== '' ? Math.max(0, parseInt(timeagoCutoff, 10)) : timeagoCutoff; diff --git a/src/meta/themes.js b/src/meta/themes.js index e950847421..8853c9a086 100644 --- a/src/meta/themes.js +++ b/src/meta/themes.js @@ -104,7 +104,7 @@ module.exports = function (Meta) { themeData['theme:templates'] = config.templates ? config.templates : ''; themeData['theme:src'] = ''; - db.setObject('config', themeData, next); + Meta.configs.setMultiple(themeData, next); // Re-set the themes path (for when NodeBB is reloaded) Meta.themes.setPath(config); @@ -115,7 +115,10 @@ module.exports = function (Meta) { break; case 'bootswatch': - Meta.configs.set('theme:src', data.src, callback); + Meta.configs.setMultiple({ + 'theme:src': data.src, + bootswatchSkin: data.id.toLowerCase(), + }, callback); break; } }; diff --git a/src/middleware/header.js b/src/middleware/header.js index accbbf2fe6..44a541f4bf 100644 --- a/src/middleware/header.js +++ b/src/middleware/header.js @@ -42,7 +42,6 @@ module.exports = function (middleware) { middleware.renderHeader = function (req, res, data, callback) { var registrationType = meta.config.registrationType || 'normal'; var templateValues = { - bootswatchCSS: meta.config['theme:src'], title: meta.config.title || '', description: meta.config.description || '', 'cache-buster': meta.config['cache-buster'] || '', @@ -117,9 +116,7 @@ module.exports = function (middleware) { results.user['email:confirmed'] = parseInt(results.user['email:confirmed'], 10) === 1; results.user.isEmailConfirmSent = !!results.isEmailConfirmSent; - if (res.locals.config && parseInt(meta.config.disableCustomUserSkins, 10) !== 1 && res.locals.config.bootswatchSkin !== 'default') { - templateValues.bootswatchCSS = '//maxcdn.bootstrapcdn.com/bootswatch/latest/' + res.locals.config.bootswatchSkin + '/bootstrap.min.css'; - } + setBootswatchCSS(templateValues, res.locals.config); templateValues.browserTitle = controllers.helpers.buildTitle(data.title); templateValues.navigation = results.navigation; @@ -191,5 +188,21 @@ module.exports = function (middleware) { return title; } + + function setBootswatchCSS(obj, config) { + if (config && config.bootswatchSkin !== 'default') { + var skinToUse = ''; + + if (parseInt(meta.config.disableCustomUserSkins, 10) !== 1) { + skinToUse = config.bootswatchSkin; + } else if (meta.config.bootswatchSkin !== 'default') { + skinToUse = meta.config.bootswatchSkin; + } + + if (skinToUse) { + obj.bootswatchCSS = '//maxcdn.bootstrapcdn.com/bootswatch/latest/' + skinToUse + '/bootstrap.min.css'; + } + } + } }; diff --git a/src/user/settings.js b/src/user/settings.js index 870dd2e59c..bef20e0087 100644 --- a/src/user/settings.js +++ b/src/user/settings.js @@ -74,7 +74,7 @@ module.exports = function (User) { settings.restrictChat = parseInt(getSetting(settings, 'restrictChat', 0), 10) === 1; settings.topicSearchEnabled = parseInt(getSetting(settings, 'topicSearchEnabled', 0), 10) === 1; settings.delayImageLoading = parseInt(getSetting(settings, 'delayImageLoading', 1), 10) === 1; - settings.bootswatchSkin = settings.bootswatchSkin || 'default'; + settings.bootswatchSkin = settings.bootswatchSkin || meta.config.bootswatchSkin || 'default'; settings.scrollToMyPost = parseInt(getSetting(settings, 'scrollToMyPost', 1), 10) === 1; callback(null, settings); diff --git a/test/socket.io.js b/test/socket.io.js index 095c3b5440..497f0ed922 100644 --- a/test/socket.io.js +++ b/test/socket.io.js @@ -427,11 +427,16 @@ describe('socket.io', function () { }); it('should set theme to bootswatch', function (done) { - socketAdmin.themes.set({ uid: adminUid }, { type: 'bootswatch', src: 'darkly' }, function (err) { + socketAdmin.themes.set({ uid: adminUid }, { + type: 'bootswatch', + src: '//maxcdn.bootstrapcdn.com/bootswatch/latest/darkly/bootstrap.min.css', + id: 'darkly', + }, function (err) { assert.ifError(err); - meta.configs.get('theme:src', function (err, id) { + meta.configs.getFields(['theme:src', 'bootswatchSkin'], function (err, fields) { assert.ifError(err); - assert.equal(id, 'darkly'); + assert.equal(fields['theme:src'], '//maxcdn.bootstrapcdn.com/bootswatch/latest/darkly/bootstrap.min.css'); + assert.equal(fields.bootswatchSkin, 'darkly'); done(); }); });