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:
OsamaSayegh
2018-07-12 07:18:21 +03:00
committed by Sam
parent f13a7226db
commit decf1f27cf
45 changed files with 289 additions and 241 deletions
@@ -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}}