FEATURE: Allow the base font size to be changed on a per-user basis (#6859)
This commit is contained in:
parent
59e3eecfa6
commit
1ebd3dbbd0
|
@ -20,6 +20,8 @@ const USER_HOMES = {
|
|||
5: "top"
|
||||
};
|
||||
|
||||
const TEXT_SIZES = ["normal", "larger", "largest"];
|
||||
|
||||
export default Ember.Controller.extend(PreferencesTabController, {
|
||||
@computed("makeThemeDefault")
|
||||
saveAttrNames(makeDefault) {
|
||||
|
@ -32,7 +34,8 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
|||
"automatically_unpin_topics",
|
||||
"allow_private_messages",
|
||||
"homepage_id",
|
||||
"hide_profile_and_presence"
|
||||
"hide_profile_and_presence",
|
||||
"text_size"
|
||||
];
|
||||
|
||||
if (makeDefault) {
|
||||
|
@ -55,6 +58,13 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
|||
return currentThemeId();
|
||||
},
|
||||
|
||||
@computed
|
||||
textSizes() {
|
||||
return TEXT_SIZES.map(value => {
|
||||
return { name: I18n.t(`user.text_size.${value}`), value };
|
||||
});
|
||||
},
|
||||
|
||||
userSelectableThemes: function() {
|
||||
return listThemes(this.site);
|
||||
}.property(),
|
||||
|
@ -114,6 +124,22 @@ export default Ember.Controller.extend(PreferencesTabController, {
|
|||
this.homeChanged();
|
||||
})
|
||||
.catch(popupAjaxError);
|
||||
},
|
||||
|
||||
selectTextSize(newSize) {
|
||||
const classList = document.documentElement.classList;
|
||||
|
||||
TEXT_SIZES.forEach(name => {
|
||||
const className = `text-size-${name}`;
|
||||
if (newSize === name) {
|
||||
classList.add(className);
|
||||
} else {
|
||||
classList.remove(className);
|
||||
}
|
||||
});
|
||||
|
||||
// Force refresh when leaving this screen
|
||||
Discourse.set("assetVersion", "forceRefresh");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -285,7 +285,8 @@ const User = RestModel.extend({
|
|||
"theme_ids",
|
||||
"allow_private_messages",
|
||||
"homepage_id",
|
||||
"hide_profile_and_presence"
|
||||
"hide_profile_and_presence",
|
||||
"text_size"
|
||||
];
|
||||
|
||||
if (fields) {
|
||||
|
|
|
@ -10,6 +10,13 @@
|
|||
</div>
|
||||
{{/if}}
|
||||
|
||||
<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")}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if siteSettings.allow_user_locale}}
|
||||
<div class="control-group pref-locale">
|
||||
<label class="control-label">{{i18n 'user.locale.title'}}</label>
|
||||
|
|
|
@ -13,6 +13,14 @@ html {
|
|||
background-color: $secondary;
|
||||
overflow-y: scroll;
|
||||
direction: ltr;
|
||||
|
||||
&.text-size-larger {
|
||||
font-size: $base-font-size-larger;
|
||||
}
|
||||
|
||||
&.text-size-largest {
|
||||
font-size: $base-font-size-largest;
|
||||
}
|
||||
}
|
||||
|
||||
// Links
|
||||
|
|
|
@ -33,6 +33,8 @@ $bronze: #cd7f32 !default;
|
|||
// --------------------------------------------------
|
||||
|
||||
$base-font-size: 14px !default;
|
||||
$base-font-size-larger: 16px !default;
|
||||
$base-font-size-largest: 18px !default;
|
||||
$base-font-family: Helvetica, Arial, sans-serif !default;
|
||||
|
||||
// Font-size defintions, multiplier ^ (step / interval)
|
||||
|
|
|
@ -109,7 +109,12 @@ module ApplicationHelper
|
|||
end
|
||||
|
||||
def html_classes
|
||||
"#{mobile_view? ? 'mobile-view' : 'desktop-view'} #{mobile_device? ? 'mobile-device' : 'not-mobile-device'} #{rtl_class} #{current_user ? '' : 'anon'}"
|
||||
list = []
|
||||
list << (mobile_view? ? 'mobile-view' : 'desktop-view')
|
||||
list << (mobile_device? ? 'mobile-device' : 'not-mobile-device')
|
||||
list << 'rtl' if rtl?
|
||||
list << text_size_class
|
||||
list.join(' ')
|
||||
end
|
||||
|
||||
def body_classes
|
||||
|
@ -126,8 +131,9 @@ module ApplicationHelper
|
|||
result.join(' ')
|
||||
end
|
||||
|
||||
def rtl_class
|
||||
rtl? ? 'rtl' : ''
|
||||
def text_size_class
|
||||
size = current_user&.user_option&.text_size || SiteSetting.default_text_size
|
||||
"text-size-#{size}"
|
||||
end
|
||||
|
||||
def escape_unicode(javascript)
|
||||
|
|
|
@ -28,6 +28,12 @@ class UserOption < ActiveRecord::Base
|
|||
@like_notification_frequency_type ||= Enum.new(always: 0, first_time_and_daily: 1, first_time: 2, never: 3)
|
||||
end
|
||||
|
||||
def self.text_sizes
|
||||
@text_sizes ||= Enum.new(normal: 0, larger: 1, largest: 2)
|
||||
end
|
||||
|
||||
validates :text_size_key, inclusion: { in: UserOption.text_sizes.values }
|
||||
|
||||
def set_defaults
|
||||
self.email_always = SiteSetting.default_email_always
|
||||
self.mailing_list_mode = SiteSetting.default_email_mailing_list_mode
|
||||
|
@ -58,6 +64,8 @@ class UserOption < ActiveRecord::Base
|
|||
|
||||
self.include_tl0_in_digests = SiteSetting.default_include_tl0_in_digests
|
||||
|
||||
self.text_size = SiteSetting.default_text_size
|
||||
|
||||
true
|
||||
end
|
||||
|
||||
|
@ -146,6 +154,14 @@ class UserOption < ActiveRecord::Base
|
|||
end
|
||||
end
|
||||
|
||||
def text_size
|
||||
UserOption.text_sizes[text_size_key]
|
||||
end
|
||||
|
||||
def text_size=(value)
|
||||
self.text_size_key = UserOption.text_sizes[value.to_sym]
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_tracked_topics
|
||||
|
@ -185,6 +201,7 @@ end
|
|||
# homepage_id :integer
|
||||
# theme_ids :integer default([]), not null, is an Array
|
||||
# hide_profile_and_presence :boolean default(FALSE), not null
|
||||
# text_size_key :integer default(0), not null
|
||||
#
|
||||
# Indexes
|
||||
#
|
||||
|
|
|
@ -23,7 +23,8 @@ class UserOptionSerializer < ApplicationSerializer
|
|||
:theme_key_seq,
|
||||
:allow_private_messages,
|
||||
:homepage_id,
|
||||
:hide_profile_and_presence
|
||||
:hide_profile_and_presence,
|
||||
:text_size
|
||||
|
||||
def auto_track_topics_after_msecs
|
||||
object.auto_track_topics_after_msecs || SiteSetting.default_other_auto_track_topics_after_msecs
|
||||
|
|
|
@ -37,7 +37,8 @@ class UserUpdater
|
|||
:theme_ids,
|
||||
:allow_private_messages,
|
||||
:homepage_id,
|
||||
:hide_profile_and_presence
|
||||
:hide_profile_and_presence,
|
||||
:text_size
|
||||
]
|
||||
|
||||
def initialize(actor, user)
|
||||
|
|
|
@ -909,6 +909,13 @@ en:
|
|||
website: "Web Site"
|
||||
email_settings: "Email"
|
||||
hide_profile_and_presence: "Hide my public profile and presence features"
|
||||
|
||||
text_size:
|
||||
title: "Text Size"
|
||||
normal: "Normal"
|
||||
larger: "Larger"
|
||||
largest: "Largest"
|
||||
|
||||
like_notification_frequency:
|
||||
title: "Notify when liked"
|
||||
always: "Always"
|
||||
|
|
|
@ -1877,6 +1877,8 @@ en:
|
|||
default_categories_muted: "List of categories that are muted by default."
|
||||
default_categories_watching_first_post: "List of categories in which first post in each new topic will be watched by default."
|
||||
|
||||
default_text_size: "Text size which is selected by default"
|
||||
|
||||
retain_web_hook_events_period_days: "Number of days to retain web hook event records."
|
||||
retry_web_hook_events: "Automatically retry failed web hook events for 4 times. Time gaps between the retries are 1, 5, 25 and 125 minutes."
|
||||
|
||||
|
|
|
@ -1811,6 +1811,14 @@ user_preferences:
|
|||
default_categories_watching_first_post:
|
||||
type: category_list
|
||||
default: ''
|
||||
|
||||
default_text_size:
|
||||
type: enum
|
||||
default: normal
|
||||
choices:
|
||||
- normal
|
||||
- larger
|
||||
- largest
|
||||
|
||||
api:
|
||||
retain_web_hook_events_period_days:
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddTextSizeKeyToUserOptions < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_column :user_options, :text_size_key, :integer, null: false, default: 0
|
||||
end
|
||||
end
|
|
@ -147,15 +147,29 @@ describe ApplicationHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#rtl_class' do
|
||||
it "returns 'rtl' when the I18n.locale is rtl" do
|
||||
describe '#html_classes' do
|
||||
it "includes 'rtl' when the I18n.locale is rtl" do
|
||||
I18n.stubs(:locale).returns(:he)
|
||||
expect(helper.rtl_class).to eq('rtl')
|
||||
expect(helper.html_classes.split(" ")).to include('rtl')
|
||||
end
|
||||
|
||||
it 'returns an empty string when the I18n.locale is not rtl' do
|
||||
I18n.stubs(:locale).returns(:zh_TW)
|
||||
expect(helper.rtl_class).to eq('')
|
||||
expect(helper.html_classes.split(" ")).not_to include('rtl')
|
||||
end
|
||||
|
||||
it 'includes the user specified text size' do
|
||||
user = Fabricate(:user)
|
||||
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
|
||||
|
||||
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
|
||||
|
||||
|
|
Loading…
Reference in New Issue