Merge pull request #1086 from simon04/prefers-color-scheme

Add support for prefers-color-scheme media query
pull/1158/head
Jed Fox 5 years ago committed by GitHub
commit 364be3bf11
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -7,7 +7,8 @@ class app.Settings
'arrowScroll' 'arrowScroll'
'analyticsConsent' 'analyticsConsent'
'docs' 'docs'
'dark' 'dark' # legacy
'theme'
'layout' 'layout'
'size' 'size'
'tips' 'tips'
@ -31,10 +32,16 @@ class app.Settings
manualUpdate: false manualUpdate: false
schema: 1 schema: 1
analyticsConsent: false analyticsConsent: false
theme: 'auto'
constructor: -> constructor: ->
@store = new CookiesStore @store = new CookiesStore
@cache = {} @cache = {}
@autoSupported = window.matchMedia('(prefers-color-scheme)').media != 'not all'
if @autoSupported
@darkModeQuery = window.matchMedia('(prefers-color-scheme: dark)')
@darkModeQuery.addListener => @setTheme(@get('theme'))
get: (key) -> get: (key) ->
return @cache[key] if @cache.hasOwnProperty(key) return @cache[key] if @cache.hasOwnProperty(key)
@ -43,7 +50,7 @@ class app.Settings
set: (key, value) -> set: (key, value) ->
@store.set(key, value) @store.set(key, value)
delete @cache[key] delete @cache[key]
@toggleDark(value) if key == 'dark' @setTheme(value) if key == 'theme'
return return
del: (key) -> del: (key) ->
@ -114,15 +121,24 @@ class app.Settings
return return
initLayout: -> initLayout: ->
@toggleDark(@get('dark') is 1) if @get('dark') is 1
@set('theme', 'dark')
@del 'dark'
@setTheme(@get('theme'))
@toggleLayout(layout, @hasLayout(layout)) for layout in @LAYOUTS @toggleLayout(layout, @hasLayout(layout)) for layout in @LAYOUTS
@initSidebarWidth() @initSidebarWidth()
return return
toggleDark: (enable) -> setTheme: (theme) ->
if theme is 'auto'
theme = if @darkModeQuery.matches then 'dark' else 'default'
classList = document.documentElement.classList classList = document.documentElement.classList
classList.toggle('_theme-default', !enable) classList.remove('_theme-default', '_theme-dark')
classList.toggle('_theme-dark', enable) classList.add('_theme-' + theme)
@updateColorMeta()
return
updateColorMeta: ->
color = getComputedStyle(document.documentElement).getPropertyValue('--headerBackground').trim() color = getComputedStyle(document.documentElement).getPropertyValue('--headerBackground').trim()
$('meta[name=theme-color]').setAttribute('content', color) $('meta[name=theme-color]').setAttribute('content', color)
return return

@ -1,13 +1,29 @@
themeOption = ({ label, value }, settings) -> """
<label class="_settings-label _theme-label">
<input type="radio" name="theme" value="#{value}"#{if settings.theme == value then ' checked' else ''}>
#{label}
</label>
"""
app.templates.settingsPage = (settings) -> """ app.templates.settingsPage = (settings) -> """
<h1 class="_lined-heading">Preferences</h1> <h1 class="_lined-heading">Preferences</h1>
<div class="_settings-fieldset">
<h2 class="_settings-legend">Theme:</h2>
<div class="_settings-inputs">
#{if settings.autoSupported
themeOption label: "Automatic <small>Matches system setting</small>", value: "auto", settings
else
""}
#{themeOption label: "Light", value: "default", settings}
#{themeOption label: "Dark", value: "dark", settings}
</div>
</div>
<div class="_settings-fieldset"> <div class="_settings-fieldset">
<h2 class="_settings-legend">General:</h2> <h2 class="_settings-legend">General:</h2>
<div class="_settings-inputs"> <div class="_settings-inputs">
<label class="_settings-label">
<input type="checkbox" form="settings" name="dark" value="1"#{if settings.dark then ' checked' else ''}>Enable dark theme
</label>
<label class="_settings-label _setting-max-width"> <label class="_settings-label _setting-max-width">
<input type="checkbox" form="settings" name="layout" value="_max-width"#{if settings['_max-width'] then ' checked' else ''}>Enable fixed-width layout <input type="checkbox" form="settings" name="layout" value="_max-width"#{if settings['_max-width'] then ' checked' else ''}>Enable fixed-width layout
</label> </label>

@ -11,19 +11,20 @@ class app.views.SettingsPage extends app.View
currentSettings: -> currentSettings: ->
settings = {} settings = {}
settings.dark = app.settings.get('dark') settings.theme = app.settings.get('theme')
settings.smoothScroll = !app.settings.get('fastScroll') settings.smoothScroll = !app.settings.get('fastScroll')
settings.arrowScroll = app.settings.get('arrowScroll') settings.arrowScroll = app.settings.get('arrowScroll')
settings.autoInstall = app.settings.get('autoInstall') settings.autoInstall = app.settings.get('autoInstall')
settings.analyticsConsent = app.settings.get('analyticsConsent') settings.analyticsConsent = app.settings.get('analyticsConsent')
settings.autoSupported = app.settings.autoSupported
settings[layout] = app.settings.hasLayout(layout) for layout in app.settings.LAYOUTS settings[layout] = app.settings.hasLayout(layout) for layout in app.settings.LAYOUTS
settings settings
getTitle: -> getTitle: ->
'Preferences' 'Preferences'
toggleDark: (enable) -> setTheme: (value) ->
app.settings.set('dark', !!enable) app.settings.set('theme', value)
return return
toggleLayout: (layout, enable) -> toggleLayout: (layout, enable) ->
@ -74,8 +75,8 @@ class app.views.SettingsPage extends app.View
onChange: (event) => onChange: (event) =>
input = event.target input = event.target
switch input.name switch input.name
when 'dark' when 'theme'
@toggleDark input.checked @setTheme input.value
when 'layout' when 'layout'
@toggleLayout input.value, input.checked @toggleLayout input.value, input.checked
when 'smoothScroll' when 'smoothScroll'

@ -48,15 +48,21 @@
} }
._settings-label { ._settings-label {
margin: 0 0 .375rem; &:not(._theme-label) {
margin: 0 0 .375rem;
}
> small { > small {
display: block; display: block;
color: var(--textColorLight); color: var(--textColorLight);
margin-left: 1.75rem; margin-left: 1.75rem;
} }
&._theme-label > small {
display: inline-block;
margin-left: 0.75rem;
}
input[type=checkbox] { input[type=checkbox], input[type=radio] {
vertical-align: top; vertical-align: top;
margin: .25rem .375rem; margin: .25rem .375rem;
} }

@ -10,6 +10,13 @@ html {
@import 'global/print'; @import 'global/print';
} }
html._theme-default {
color-scheme: light only;
}
html._theme-dark {
color-scheme: dark only;
}
body { body {
height: 100%; height: 100%;
margin: 0; margin: 0;

Loading…
Cancel
Save