UX: Improve color scheme choices in user prefs (#11656)

This commit is contained in:
Penar Musaraj 2021-01-07 11:15:38 -05:00 committed by GitHub
parent ef84fb6469
commit c819284660
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 118 additions and 33 deletions

View File

@ -11,11 +11,11 @@ import {
updateColorSchemeCookie, updateColorSchemeCookie,
} from "discourse/lib/color-scheme-picker"; } from "discourse/lib/color-scheme-picker";
import { listThemes, setLocalTheme } from "discourse/lib/theme-selector"; import { listThemes, setLocalTheme } from "discourse/lib/theme-selector";
import { not, reads } from "@ember/object/computed";
import I18n from "I18n"; import I18n from "I18n";
import { computed } from "@ember/object"; import { computed } from "@ember/object";
import discourseComputed from "discourse-common/utils/decorators"; import discourseComputed from "discourse-common/utils/decorators";
import { popupAjaxError } from "discourse/lib/ajax-error"; import { popupAjaxError } from "discourse/lib/ajax-error";
import { reads } from "@ember/object/computed";
import { reload } from "discourse/helpers/page-reloader"; import { reload } from "discourse/helpers/page-reloader";
const USER_HOMES = { const USER_HOMES = {
@ -33,7 +33,6 @@ const TITLE_COUNT_MODES = ["notifications", "contextual"];
export default Controller.extend({ export default Controller.extend({
currentThemeId: -1, currentThemeId: -1,
previewingColorScheme: false, previewingColorScheme: false,
selectedColorSchemeId: null,
selectedDarkColorSchemeId: null, selectedDarkColorSchemeId: null,
preferencesController: inject("preferences"), preferencesController: inject("preferences"),
makeColorSchemeDefault: true, makeColorSchemeDefault: true,
@ -41,10 +40,7 @@ export default Controller.extend({
init() { init() {
this._super(...arguments); this._super(...arguments);
this.setProperties({ this.set("selectedDarkColorSchemeId", this.session.userDarkSchemeId);
selectedColorSchemeId: this.session.userColorSchemeId,
selectedDarkColorSchemeId: this.session.userDarkSchemeId,
});
}, },
@discourseComputed("makeThemeDefault") @discourseComputed("makeThemeDefault")
@ -151,6 +147,23 @@ export default Controller.extend({
"user.color_schemes.default_description" "user.color_schemes.default_description"
), ),
@discourseComputed(
"userSelectableThemes",
"userSelectableColorSchemes",
"themeId"
)
currentSchemeCanBeSelected(userThemes, userColorSchemes, themeId) {
if (!userThemes) {
return false;
}
const currentThemeColorSchemeId = userThemes.findBy("id", themeId)
.color_scheme_id;
return userColorSchemes.findBy("id", currentThemeColorSchemeId);
},
showColorSchemeNoneItem: not("currentSchemeCanBeSelected"),
@discourseComputed("model.user_option.theme_ids", "themeId") @discourseComputed("model.user_option.theme_ids", "themeId")
showThemeSetDefault(userOptionThemes, selectedTheme) { showThemeSetDefault(userOptionThemes, selectedTheme) {
return !userOptionThemes || userOptionThemes[0] !== selectedTheme; return !userOptionThemes || userOptionThemes[0] !== selectedTheme;
@ -216,6 +229,17 @@ export default Controller.extend({
}, },
}), }),
selectedColorSchemeId: computed({
set(key, value) {
return value;
},
get() {
return this.currentSchemeCanBeSelected
? this.session.userColorSchemeId
: null;
},
}),
actions: { actions: {
save() { save() {
this.set("saved", false); this.set("saved", false);

View File

@ -34,8 +34,8 @@
onChange=(action "loadColorScheme") onChange=(action "loadColorScheme")
options=(hash options=(hash
translatedNone=selectedColorSchemeNoneLabel translatedNone=selectedColorSchemeNoneLabel
autoInsertNoneItem=showColorSchemeNoneItem
) )
}} }}
</div> </div>
</div> </div>

View File

@ -5,6 +5,7 @@ import {
} from "discourse/tests/helpers/qunit-helpers"; } from "discourse/tests/helpers/qunit-helpers";
import { click, visit } from "@ember/test-helpers"; import { click, visit } from "@ember/test-helpers";
import cookie, { removeCookie } from "discourse/lib/cookie"; import cookie, { removeCookie } from "discourse/lib/cookie";
import I18n from "I18n";
import Session from "discourse/models/session"; import Session from "discourse/models/session";
import Site from "discourse/models/site"; import Site from "discourse/models/site";
import selectKit from "discourse/tests/helpers/select-kit-helper"; import selectKit from "discourse/tests/helpers/select-kit-helper";
@ -60,7 +61,7 @@ acceptance("User Preferences - Interface", function (needs) {
test("does not show option to disable dark mode by default", async function (assert) { test("does not show option to disable dark mode by default", async function (assert) {
await visit("/u/eviltrout/preferences/interface"); await visit("/u/eviltrout/preferences/interface");
assert.equal($(".control-group.dark-mode").length, 0); assert.ok(!exists(".control-group.dark-mode"), "option not visible");
}); });
test("shows light/dark color scheme pickers", async function (assert) { test("shows light/dark color scheme pickers", async function (assert) {
@ -71,8 +72,65 @@ acceptance("User Preferences - Interface", function (needs) {
]); ]);
await visit("/u/eviltrout/preferences/interface"); await visit("/u/eviltrout/preferences/interface");
assert.ok($(".light-color-scheme").length, "has regular dropdown"); assert.ok(exists(".light-color-scheme"), "has regular dropdown");
assert.ok($(".dark-color-scheme").length, "has dark color scheme dropdown"); assert.ok(exists(".dark-color-scheme"), "has dark color scheme dropdown");
});
test("shows light color scheme default option when theme's color scheme is not user selectable", async function (assert) {
let site = Site.current();
site.set("user_themes", [
{ id: 1, name: "Cool Theme", color_scheme_id: null },
]);
site.set("user_color_schemes", [{ id: 2, name: "Cool Breeze" }]);
await visit("/u/eviltrout/preferences/interface");
assert.ok(exists(".light-color-scheme"), "has regular dropdown");
assert.equal(
selectKit(".light-color-scheme .select-kit").header().value(),
null
);
assert.equal(
selectKit(".light-color-scheme .select-kit").header().label(),
I18n.t("user.color_schemes.default_description")
);
});
test("shows no default option for light scheme when theme's color scheme is user selectable", async function (assert) {
let meta = document.createElement("meta");
meta.name = "discourse_theme_ids";
meta.content = "2";
document.getElementsByTagName("head")[0].appendChild(meta);
let site = Site.current();
site.set("user_themes", [
{ theme_id: 1, name: "Cool Theme", color_scheme_id: 2, default: true },
{
theme_id: 2,
name: "Some Other Theme",
color_scheme_id: 3,
default: false,
},
]);
site.set("user_color_schemes", [
{ id: 2, name: "Cool Breeze" },
{ id: 3, name: "Dark Night" },
]);
await visit("/u/eviltrout/preferences/interface");
assert.ok(exists(".light-color-scheme"), "has regular dropdown");
assert.equal(selectKit(".theme .select-kit").header().value(), 2);
await selectKit(".light-color-scheme .select-kit").expand();
assert.equal(
queryAll(".light-color-scheme .select-kit .select-kit-row").length,
2
);
document.querySelector("meta[name='discourse_theme_ids']").remove();
}); });
}); });
@ -93,7 +151,7 @@ acceptance(
await visit("/u/eviltrout/preferences/interface"); await visit("/u/eviltrout/preferences/interface");
assert.ok( assert.ok(
$(".control-group.dark-mode").length, exists(".control-group.dark-mode"),
"it has the option to disable dark mode" "it has the option to disable dark mode"
); );
}); });
@ -103,7 +161,7 @@ acceptance(
site.set("user_color_schemes", []); site.set("user_color_schemes", []);
await visit("/u/eviltrout/preferences/interface"); await visit("/u/eviltrout/preferences/interface");
assert.equal($(".control-group.color-scheme").length, 0); assert.ok(!exists(".control-group.color-scheme"));
}); });
test("light color scheme picker", async function (assert) { test("light color scheme picker", async function (assert) {
@ -111,10 +169,9 @@ acceptance(
site.set("user_color_schemes", [{ id: 2, name: "Cool Breeze" }]); site.set("user_color_schemes", [{ id: 2, name: "Cool Breeze" }]);
await visit("/u/eviltrout/preferences/interface"); await visit("/u/eviltrout/preferences/interface");
assert.ok($(".light-color-scheme").length, "has regular picker dropdown"); assert.ok(exists(".light-color-scheme"), "has regular picker dropdown");
assert.equal( assert.ok(
$(".dark-color-scheme").length, !exists(".dark-color-scheme"),
0,
"does not have a dark color scheme picker" "does not have a dark color scheme picker"
); );
}); });
@ -138,18 +195,15 @@ acceptance(
}; };
await visit("/u/eviltrout/preferences/interface"); await visit("/u/eviltrout/preferences/interface");
assert.ok($(".light-color-scheme").length, "has regular dropdown"); assert.ok(exists(".light-color-scheme"), "has regular dropdown");
assert.ok( assert.ok(exists(".dark-color-scheme"), "has dark color scheme dropdown");
$(".dark-color-scheme").length,
"has dark color scheme dropdown"
);
assert.equal( assert.equal(
$(".dark-color-scheme .selected-name").data("value"), queryAll(".dark-color-scheme .selected-name").data("value"),
session.userDarkSchemeId, session.userDarkSchemeId,
"sets site default as selected dark scheme" "sets site default as selected dark scheme"
); );
assert.equal( assert.ok(
$(".control-group.dark-mode").length, !exists(".control-group.dark-mode"),
0, 0,
"it does not show disable dark mode checkbox" "it does not show disable dark mode checkbox"
); );

View File

@ -58,7 +58,7 @@ class Theme < ActiveRecord::Base
theme_fields.select(&:basic_html_field?).each(&:invalidate_baked!) theme_fields.select(&:basic_html_field?).each(&:invalidate_baked!)
end end
Theme.expire_site_cache! if saved_change_to_user_selectable? || saved_change_to_name? Theme.expire_site_cache! if saved_change_to_color_scheme_id? || saved_change_to_user_selectable? || saved_change_to_name?
notify_with_scheme = saved_change_to_color_scheme_id? notify_with_scheme = saved_change_to_color_scheme_id?
reload reload

View File

@ -947,7 +947,7 @@ en:
color_scheme_default_on_all_devices: "Set default color scheme(s) on all my devices" color_scheme_default_on_all_devices: "Set default color scheme(s) on all my devices"
color_scheme: "Color Scheme" color_scheme: "Color Scheme"
color_schemes: color_schemes:
default_description: "Default" default_description: "Theme default"
disable_dark_scheme: "Same as regular" disable_dark_scheme: "Same as regular"
dark_instructions: "You can preview the dark mode color scheme by toggling your device's dark mode." dark_instructions: "You can preview the dark mode color scheme by toggling your device's dark mode."
undo: "Reset" undo: "Reset"

View File

@ -21,6 +21,8 @@ describe Site do
default_theme = Fabricate(:theme) default_theme = Fabricate(:theme)
SiteSetting.default_theme_id = default_theme.id SiteSetting.default_theme_id = default_theme.id
user_theme = Fabricate(:theme, user_selectable: true) user_theme = Fabricate(:theme, user_selectable: true)
second_user_theme = Fabricate(:theme, user_selectable: true)
color_scheme = Fabricate(:color_scheme)
anon_guardian = Guardian.new anon_guardian = Guardian.new
user_guardian = Guardian.new(Fabricate(:user)) user_guardian = Guardian.new(Fabricate(:user))
@ -39,6 +41,11 @@ describe Site do
expect_correct_themes(anon_guardian) expect_correct_themes(anon_guardian)
expect_correct_themes(user_guardian) expect_correct_themes(user_guardian)
second_user_theme.color_scheme_id = color_scheme.id
second_user_theme.save!
expect_correct_themes(anon_guardian)
expect_correct_themes(user_guardian)
end end
it "returns correct notification level for categories" do it "returns correct notification level for categories" do