FEATURE: Groundwork for user-selectable theme components
* Phase 0 for user-selectable theme components - Drops `key` column from the `themes` table - Drops `theme_key` column from the `user_options` table - Adds `theme_ids` (array of ints default []) column to the `user_options` table and migrates data from `theme_key` to the new column. - Removes the `default_theme_key` site setting and adds `default_theme_id` instead. - Replaces `theme_key` cookie with a new one called `theme_ids` - no longer need Theme.settings_for_client
This commit is contained in:
@@ -5,7 +5,7 @@ import {
|
||||
observes
|
||||
} from "ember-addons/ember-computed-decorators";
|
||||
import {
|
||||
currentThemeKey,
|
||||
currentThemeId,
|
||||
listThemes,
|
||||
previewTheme,
|
||||
setLocalTheme
|
||||
@@ -35,7 +35,7 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
||||
];
|
||||
|
||||
if (makeDefault) {
|
||||
attrs.push("theme_key");
|
||||
attrs.push("theme_ids");
|
||||
}
|
||||
|
||||
return attrs;
|
||||
@@ -50,8 +50,8 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
||||
},
|
||||
|
||||
@computed()
|
||||
themeKey() {
|
||||
return currentThemeKey();
|
||||
themeId() {
|
||||
return currentThemeId();
|
||||
},
|
||||
|
||||
userSelectableThemes: function() {
|
||||
@@ -63,10 +63,10 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
||||
return themes && themes.length > 1;
|
||||
},
|
||||
|
||||
@observes("themeKey")
|
||||
themeKeyChanged() {
|
||||
let key = this.get("themeKey");
|
||||
previewTheme(key);
|
||||
@observes("themeId")
|
||||
themeIdChanged() {
|
||||
const id = this.get("themeId");
|
||||
previewTheme(id);
|
||||
},
|
||||
|
||||
homeChanged() {
|
||||
@@ -95,7 +95,7 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
||||
this.set("saved", false);
|
||||
const makeThemeDefault = this.get("makeThemeDefault");
|
||||
if (makeThemeDefault) {
|
||||
this.set("model.user_option.theme_key", this.get("themeKey"));
|
||||
this.set("model.user_option.theme_ids", [this.get("themeId")]);
|
||||
}
|
||||
|
||||
return this.get("model")
|
||||
@@ -105,7 +105,7 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
||||
|
||||
if (!makeThemeDefault) {
|
||||
setLocalTheme(
|
||||
this.get("themeKey"),
|
||||
[this.get("themeId")],
|
||||
this.get("model.user_option.theme_key_seq")
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import DiscourseURL from "discourse/lib/url";
|
||||
import { currentThemeKey, refreshCSS } from "discourse/lib/theme-selector";
|
||||
import { currentThemeId, refreshCSS } from "discourse/lib/theme-selector";
|
||||
|
||||
// Use the message bus for live reloading of components for faster development.
|
||||
export default {
|
||||
@@ -9,18 +9,18 @@ export default {
|
||||
|
||||
if (
|
||||
window.history &&
|
||||
window.location.search.indexOf("?preview_theme_key=") === 0
|
||||
window.location.search.indexOf("?preview_theme_id=") === 0
|
||||
) {
|
||||
// force preview theme key to always be carried along
|
||||
const themeKey = window.location.search.slice(19).split("&")[0];
|
||||
if (themeKey.match(/^[a-z0-9-]+$/i)) {
|
||||
// force preview theme id to always be carried along
|
||||
const themeId = window.location.search.slice(19).split("&")[0];
|
||||
if (themeId.match(/^[a-z0-9-]+$/i)) {
|
||||
const patchState = function(f) {
|
||||
const patched = window.history[f];
|
||||
|
||||
window.history[f] = function(stateObj, name, url) {
|
||||
if (url.indexOf("preview_theme_key=") === -1) {
|
||||
if (url.indexOf("preview_theme_id=") === -1) {
|
||||
const joiner = url.indexOf("?") === -1 ? "?" : "&";
|
||||
url = `${url}${joiner}preview_theme_key=${themeKey}`;
|
||||
url = `${url}${joiner}preview_theme_id=${themeId}`;
|
||||
}
|
||||
|
||||
return patched.call(window.history, stateObj, name, url);
|
||||
@@ -35,7 +35,7 @@ export default {
|
||||
$("header.custom").each(function() {
|
||||
const header = $(this);
|
||||
return messageBus.subscribe(
|
||||
"/header-change/" + $(this).data("key"),
|
||||
"/header-change/" + $(this).data("id"),
|
||||
function(data) {
|
||||
return header.html(data);
|
||||
}
|
||||
@@ -58,12 +58,12 @@ export default {
|
||||
// Refresh if necessary
|
||||
document.location.reload(true);
|
||||
} else {
|
||||
let themeKey = currentThemeKey();
|
||||
let themeId = currentThemeId();
|
||||
|
||||
$("link").each(function() {
|
||||
if (me.hasOwnProperty("theme_key") && me.new_href) {
|
||||
if (me.hasOwnProperty("theme_id") && me.new_href) {
|
||||
let target = $(this).data("target");
|
||||
if (me.theme_key === themeKey && target === me.target) {
|
||||
if (me.theme_id === themeId && target === me.target) {
|
||||
refreshCSS(this, null, me.new_href);
|
||||
}
|
||||
} else if (this.href.match(me.name) && (me.hash || me.new_href)) {
|
||||
|
||||
@@ -1,23 +1,28 @@
|
||||
import { ajax } from "discourse/lib/ajax";
|
||||
const keySelector = "meta[name=discourse_theme_key]";
|
||||
const keySelector = "meta[name=discourse_theme_id]";
|
||||
|
||||
export function currentThemeKey() {
|
||||
let themeKey = null;
|
||||
export function currentThemeId() {
|
||||
let themeId = null;
|
||||
let elem = _.first($(keySelector));
|
||||
if (elem) {
|
||||
themeKey = elem.content;
|
||||
if (_.isEmpty(themeKey)) {
|
||||
themeKey = null;
|
||||
themeId = elem.content;
|
||||
if (_.isEmpty(themeId)) {
|
||||
themeId = null;
|
||||
} else {
|
||||
themeId = parseInt(themeId);
|
||||
}
|
||||
}
|
||||
return themeKey;
|
||||
return themeId;
|
||||
}
|
||||
|
||||
export function setLocalTheme(key, themeSeq) {
|
||||
if (key) {
|
||||
$.cookie("theme_key", `${key},${themeSeq}`, { path: "/", expires: 9999 });
|
||||
export function setLocalTheme(ids, themeSeq) {
|
||||
if (ids && ids.length > 0) {
|
||||
$.cookie("theme_ids", `${ids.join(",")}|${themeSeq}`, {
|
||||
path: "/",
|
||||
expires: 9999
|
||||
});
|
||||
} else {
|
||||
$.cookie("theme_key", null, { path: "/", expires: 1 });
|
||||
$.cookie("theme_ids", null, { path: "/", expires: 1 });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,14 +65,14 @@ export function refreshCSS(node, hash, newHref, options) {
|
||||
$orig.data("copy", reloaded);
|
||||
}
|
||||
|
||||
export function previewTheme(key) {
|
||||
if (currentThemeKey() !== key) {
|
||||
export function previewTheme(id) {
|
||||
if (currentThemeId() !== id) {
|
||||
Discourse.set("assetVersion", "forceRefresh");
|
||||
|
||||
ajax(`/themes/assets/${key ? key : "default"}`).then(results => {
|
||||
ajax(`/themes/assets/${id ? id : "default"}`).then(results => {
|
||||
let elem = _.first($(keySelector));
|
||||
if (elem) {
|
||||
elem.content = key;
|
||||
elem.content = id;
|
||||
}
|
||||
|
||||
results.themes.forEach(theme => {
|
||||
@@ -95,7 +100,7 @@ export function listThemes(site) {
|
||||
}
|
||||
|
||||
themes.forEach(t => {
|
||||
results.push({ name: t.name, id: t.theme_key });
|
||||
results.push({ name: t.name, id: t.theme_id });
|
||||
});
|
||||
|
||||
return results.length === 0 ? null : results;
|
||||
|
||||
@@ -271,7 +271,7 @@ const User = RestModel.extend({
|
||||
"notification_level_when_replying",
|
||||
"like_notification_frequency",
|
||||
"include_tl0_in_digests",
|
||||
"theme_key",
|
||||
"theme_ids",
|
||||
"allow_private_messages",
|
||||
"homepage_id"
|
||||
];
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div class="control-group theme">
|
||||
<label class="control-label">{{i18n 'user.theme'}}</label>
|
||||
<div class="controls">
|
||||
{{combo-box content=userSelectableThemes value=themeKey}}
|
||||
{{combo-box content=userSelectableThemes value=themeId}}
|
||||
</div>
|
||||
<div class="controls">
|
||||
{{preference-checkbox labelKey="user.theme_default_on_all_devices" checked=makeThemeDefault}}
|
||||
|
||||
Reference in New Issue
Block a user