FEATURE: Allow setting font size per-device using a cookie (#6947)

FEATURE: Allow setting font size per-device using a cookie (#6947)

diff --git a/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6 b/app/assets/javascripts/discourse/controllers/preferences/interface.js.es6
index b1dbc21..86e8f0e 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 729e79d..283195b 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 1be49ff..6b396fe 100644
--- a/app/assets/javascripts/discourse/templates/preferences/interface.hbs
+++ b/app/assets/javascripts/discourse/templates/preferences/interface.hbs
@@ -13,7 +13,10 @@
 <div class="control-group text-size">
   <label class="control-label">{{i18n 'user.text_size.title'}}</label>
   <div class="controls">
-    {{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")}}
+  </div>
+  <div class="controls">
+    {{preference-checkbox labelKey="user.text_size_default_on_all_devices" checked=makeTextSizeDefault}}
   </div>
 </div>
 
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 6009c19..2d89139 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 faea388..42f0aa6 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 594164d..62939db 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 '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 '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 '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 58360b9..7727082 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");

[... diff too long, it was truncated ...]

GitHub sha: d338e54f