From d338e54f598cb6e0effbfbe51f595ee414fcd1c9 Mon Sep 17 00:00:00 2001 From: David Taylor Date: Fri, 25 Jan 2019 15:06:06 +0000 Subject: [PATCH] FEATURE: Allow setting font size per-device using a cookie (#6947) --- .../controllers/preferences/interface.js.es6 | 14 ++++++ .../routes/preferences-interface.js.es6 | 4 +- .../templates/preferences/interface.hbs | 5 +- app/helpers/application_helper.rb | 3 +- config/locales/client.en.yml | 3 +- spec/helpers/application_helper_spec.rb | 43 ++++++++++++---- .../acceptance/preferences-test.js.es6 | 49 +++++++++++++++++++ 7 files changed, 107 insertions(+), 14 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 index b1dbc2168b..86e8f0e054 100644 --- a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 +++ b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 @@ -47,6 +47,7 @@ export default Ember.Controller.extend(PreferencesTabController, { preferencesController: Ember.inject.controller("preferences"), makeThemeDefault: true, + makeTextSizeDefault: true, @computed() availableLocales() { @@ -109,6 +110,11 @@ export default Ember.Controller.extend(PreferencesTabController, { this.set("model.user_option.theme_ids", [this.get("themeId")]); } + const makeTextSizeDefault = this.get("makeTextSizeDefault"); + if (makeTextSizeDefault) { + this.set("model.user_option.text_size", this.get("textSize")); + } + return this.get("model") .save(this.get("saveAttrNames")) .then(() => { @@ -120,6 +126,14 @@ export default Ember.Controller.extend(PreferencesTabController, { this.get("model.user_option.theme_key_seq") ); } + if ( + makeTextSizeDefault || + this.get("model.user_option.text_size") === $.cookie("text_size") + ) { + $.removeCookie("text_size"); + } else { + $.cookie("text_size", this.get("textSize")); + } this.homeChanged(); }) diff --git a/app/assets/javascripts/discourse/routes/preferences-interface.js.es6 b/app/assets/javascripts/discourse/routes/preferences-interface.js.es6 index 729e79dedd..283195b3a9 100644 --- a/app/assets/javascripts/discourse/routes/preferences-interface.js.es6 +++ b/app/assets/javascripts/discourse/routes/preferences-interface.js.es6 @@ -4,8 +4,10 @@ export default RestrictedUserRoute.extend({ showFooter: true, setupController(controller, user) { + const textSize = $.cookie("text_size") || user.get("user_option.text_size"); controller.setProperties({ - model: user + model: user, + textSize }); } }); diff --git a/app/assets/javascripts/discourse/templates/preferences/interface.hbs b/app/assets/javascripts/discourse/templates/preferences/interface.hbs index 1be49ff9b5..6b396fec1a 100644 --- a/app/assets/javascripts/discourse/templates/preferences/interface.hbs +++ b/app/assets/javascripts/discourse/templates/preferences/interface.hbs @@ -13,7 +13,10 @@
- {{combo-box valueAttribute="value" content=textSizes value=model.user_option.text_size onSelect=(action "selectTextSize")}} + {{combo-box valueAttribute="value" content=textSizes value=textSize onSelect=(action "selectTextSize")}} +
+
+ {{preference-checkbox labelKey="user.text_size_default_on_all_devices" checked=makeTextSizeDefault}}
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 6009c19824..2d891396a1 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -133,7 +133,8 @@ module ApplicationHelper end def text_size_class - size = current_user&.user_option&.text_size || SiteSetting.default_text_size + cookie_size = cookies[:text_size] if UserOption.text_sizes.keys.include?(cookies[:text_size]&.to_sym) + size = cookie_size || current_user&.user_option&.text_size || SiteSetting.default_text_size "text-size-#{size}" end diff --git a/config/locales/client.en.yml b/config/locales/client.en.yml index faea38838b..42f0aa68af 100644 --- a/config/locales/client.en.yml +++ b/config/locales/client.en.yml @@ -664,7 +664,8 @@ en: first_notification: "Your first notification! Select it to begin." disable_jump_reply: "Don't jump to my post after I reply" dynamic_favicon: "Show new / updated topic count on browser icon" - theme_default_on_all_devices: "Make this my default theme on all my devices" + theme_default_on_all_devices: "Make this the default theme on all my devices" + text_size_default_on_all_devices: "Make this the default text size on all my devices" allow_private_messages: "Allow other users to send me personal messages" external_links_in_new_tab: "Open all external links in a new tab" enable_quoting: "Enable quote reply for highlighted text" diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 594164df9f..62939db6bf 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -160,17 +160,40 @@ describe ApplicationHelper do expect(helper.html_classes.split(" ")).not_to include('rtl') end - it 'includes the user specified text size' do - user.user_option.text_size = "larger" - user.user_option.save! - helper.request.env[Auth::DefaultCurrentUserProvider::CURRENT_USER_KEY] = user - expect(helper.html_classes.split(" ")).to include('text-size-larger') - end + describe 'text size' do + context "with a user option" do + before do + user.user_option.text_size = "larger" + user.user_option.save! + helper.request.env[Auth::DefaultCurrentUserProvider::CURRENT_USER_KEY] = user + end - it 'falls back to the default text size for anon' do - expect(helper.html_classes.split(" ")).to include('text-size-normal') - SiteSetting.default_text_size = "largest" - expect(helper.html_classes.split(" ")).to include('text-size-largest') + it 'ignores invalid text sizes' do + helper.request.cookies["text_size"] = "invalid" + expect(helper.html_classes.split(" ")).to include('text-size-larger') + end + + it 'ignores missing text size' do + helper.request.cookies["text_size"] = nil + expect(helper.html_classes.split(" ")).to include('text-size-larger') + end + + it 'prioritises the cookie specified text size' do + helper.request.cookies["text_size"] = "normal" + expect(helper.html_classes.split(" ")).to include('text-size-normal') + end + + it 'includes the user specified text size' do + helper.request.env[Auth::DefaultCurrentUserProvider::CURRENT_USER_KEY] = user + expect(helper.html_classes.split(" ")).to include('text-size-larger') + end + end + + it 'falls back to the default text size for anon' do + expect(helper.html_classes.split(" ")).to include('text-size-normal') + SiteSetting.default_text_size = "largest" + expect(helper.html_classes.split(" ")).to include('text-size-largest') + end end it "includes 'anon' for anonymous users and excludes when logged in" do diff --git a/test/javascripts/acceptance/preferences-test.js.es6 b/test/javascripts/acceptance/preferences-test.js.es6 index 58360b9808..77270828b1 100644 --- a/test/javascripts/acceptance/preferences-test.js.es6 +++ b/test/javascripts/acceptance/preferences-test.js.es6 @@ -101,6 +101,55 @@ QUnit.test("update some fields", async assert => { ); }); +QUnit.test("font size change", async assert => { + $.removeCookie("text_size"); + + const savePreferences = async () => { + assert.ok(!exists(".saved-user"), "it hasn't been saved yet"); + await click(".save-user"); + assert.ok(exists(".saved-user"), "it displays the saved message"); + find(".saved-user").remove(); + }; + + await visit("/u/eviltrout/preferences/interface"); + + // Live changes without reload + await expandSelectKit(".text-size .combobox"); + await selectKitSelectRowByValue("larger", ".text-size .combobox"); + assert.ok(document.documentElement.classList.contains("text-size-larger")); + + await expandSelectKit(".text-size .combobox"); + await selectKitSelectRowByValue("largest", ".text-size .combobox"); + assert.ok(document.documentElement.classList.contains("text-size-largest")); + + assert.equal($.cookie("text_size"), null, "cookie is not set"); + + // Click save (by default this sets for all browsers, no cookie) + await savePreferences(); + + assert.equal($.cookie("text_size"), null, "cookie is not set"); + + await expandSelectKit(".text-size .combobox"); + await selectKitSelectRowByValue("larger", ".text-size .combobox"); + await click(".text-size input[type=checkbox]"); + + await savePreferences(); + + assert.equal($.cookie("text_size"), "larger", "cookie is set"); + await click(".text-size input[type=checkbox]"); + await expandSelectKit(".text-size .combobox"); + await selectKitSelectRowByValue("largest", ".text-size .combobox"); + + await savePreferences(); + assert.equal( + $.cookie("text_size"), + null, + "cookie is unset when matches user preference" + ); + + $.removeCookie("text_size"); +}); + QUnit.test("username", async assert => { await visit("/u/eviltrout/preferences/username"); assert.ok(exists("#change_username"), "it has the input element");