fix: set dark theme based on prefers-color-scheme (#966)

* fix: set dark theme based on prefers-color-scheme

fixes #728

* add an explicit banner fill color
This commit is contained in:
Nolan Lawson 2019-02-11 21:03:51 -08:00 committed by GitHub
parent de4016029f
commit 8179c1b53f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 34 additions and 21 deletions

View file

@ -4,7 +4,7 @@
// the build process and write it to checksum.js. // the build process and write it to checksum.js.
import { testHasLocalStorageOnce } from '../routes/_utils/testStorage' import { testHasLocalStorageOnce } from '../routes/_utils/testStorage'
import { switchToTheme } from '../routes/_utils/themeEngine' import { DEFAULT_LIGHT_THEME, DEFAULT_THEME, switchToTheme } from '../routes/_utils/themeEngine'
import { basename } from '../routes/_api/utils' import { basename } from '../routes/_api/utils'
import { onUserIsLoggedOut } from '../routes/_actions/onUserIsLoggedOut' import { onUserIsLoggedOut } from '../routes/_actions/onUserIsLoggedOut'
@ -26,12 +26,13 @@ if (currentInstance) {
document.head.appendChild(link) document.head.appendChild(link)
} }
if (currentInstance && localStorage.store_instanceThemes) { let theme = (currentInstance &&
localStorage.store_instanceThemes &&
safeParse(localStorage.store_instanceThemes)[safeParse(localStorage.store_currentInstance)]) ||
DEFAULT_THEME
if (theme !== DEFAULT_LIGHT_THEME) {
// switch theme ASAP to minimize flash of default theme // switch theme ASAP to minimize flash of default theme
let theme = safeParse(localStorage.store_instanceThemes)[safeParse(localStorage.store_currentInstance)]
if (theme && theme !== 'default') {
switchToTheme(theme) switchToTheme(theme)
}
} }
if (!hasLocalStorage || !currentInstance) { if (!hasLocalStorage || !currentInstance) {

View file

@ -1,7 +1,7 @@
import { getAccessTokenFromAuthCode, registerApplication, generateAuthLink } from '../_api/oauth' import { getAccessTokenFromAuthCode, registerApplication, generateAuthLink } from '../_api/oauth'
import { getInstanceInfo } from '../_api/instance' import { getInstanceInfo } from '../_api/instance'
import { goto } from '../../../__sapper__/client' import { goto } from '../../../__sapper__/client'
import { switchToTheme } from '../_utils/themeEngine' import { DEFAULT_THEME, switchToTheme } from '../_utils/themeEngine'
import { store } from '../_store/store' import { store } from '../_store/store'
import { updateVerifyCredentialsForInstance } from './instances' import { updateVerifyCredentialsForInstance } from './instances'
import { updateCustomEmojiForInstance } from './emoji' import { updateCustomEmojiForInstance } from './emoji'
@ -69,7 +69,7 @@ async function registerNewInstance (code) {
REDIRECT_URI REDIRECT_URI
) )
let { loggedInInstances, loggedInInstancesInOrder, instanceThemes } = store.get() let { loggedInInstances, loggedInInstancesInOrder, instanceThemes } = store.get()
instanceThemes[currentRegisteredInstanceName] = 'default' instanceThemes[currentRegisteredInstanceName] = DEFAULT_THEME
loggedInInstances[currentRegisteredInstanceName] = instanceData loggedInInstances[currentRegisteredInstanceName] = instanceData
if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) { if (!loggedInInstancesInOrder.includes(currentRegisteredInstanceName)) {
loggedInInstancesInOrder.push(currentRegisteredInstanceName) loggedInInstancesInOrder.push(currentRegisteredInstanceName)
@ -84,7 +84,7 @@ async function registerNewInstance (code) {
instanceThemes: instanceThemes instanceThemes: instanceThemes
}) })
store.save() store.save()
switchToTheme('default') switchToTheme(DEFAULT_THEME)
// fire off these requests so they're cached // fire off these requests so they're cached
/* no await */ updateVerifyCredentialsForInstance(currentRegisteredInstanceName) /* no await */ updateVerifyCredentialsForInstance(currentRegisteredInstanceName)
/* no await */ updateCustomEmojiForInstance(currentRegisteredInstanceName) /* no await */ updateCustomEmojiForInstance(currentRegisteredInstanceName)

View file

@ -1,6 +1,6 @@
import { getVerifyCredentials } from '../_api/user' import { getVerifyCredentials } from '../_api/user'
import { store } from '../_store/store' import { store } from '../_store/store'
import { switchToTheme } from '../_utils/themeEngine' import { DEFAULT_THEME, switchToTheme } from '../_utils/themeEngine'
import { toast } from '../_components/toast/toast' import { toast } from '../_components/toast/toast'
import { goto } from '../../../__sapper__/client' import { goto } from '../../../__sapper__/client'
import { cacheFirstUpdateAfter } from '../_utils/sync' import { cacheFirstUpdateAfter } from '../_utils/sync'
@ -55,7 +55,7 @@ export async function logOutOfInstance (instanceName) {
}) })
store.save() store.save()
toast.say(`Logged out of ${instanceName}`) toast.say(`Logged out of ${instanceName}`)
switchToTheme(instanceThemes[newInstance] || 'default') switchToTheme(instanceThemes[newInstance] || DEFAULT_THEME)
/* no await */ database.clearDatabaseForInstance(instanceName) /* no await */ database.clearDatabaseForInstance(instanceName)
goto('/settings/instances') goto('/settings/instances')
} }

View file

@ -27,11 +27,11 @@
.not-logged-in-home-svg { .not-logged-in-home-svg {
width: 70px; width: 70px;
height: 70px; height: 70px;
fill: royalblue; fill: var(--banner-fill);
display: inline-block; display: inline-block;
} }
.not-logged-in-home h1 { .not-logged-in-home h1 {
color: royalblue; color: var(--banner-fill);
display: inline-block; display: inline-block;
font-size: 3em; font-size: 3em;
margin: auto 15px; margin: auto 15px;

View file

@ -75,19 +75,20 @@
import { changeTheme } from '../../../_actions/instances' import { changeTheme } from '../../../_actions/instances'
import { store } from '../../../_store/store' import { store } from '../../../_store/store'
import { themes } from '../../../_static/themes' import { themes } from '../../../_static/themes'
import { DEFAULT_THEME } from '../../../_utils/themeEngine'
export default { export default {
async oncreate () { async oncreate () {
let { instanceName } = this.get() let { instanceName } = this.get()
let { instanceThemes } = this.store.get() let { instanceThemes } = this.store.get()
this.set({ this.set({
selectedTheme: instanceThemes[instanceName] || 'default' selectedTheme: instanceThemes[instanceName] || DEFAULT_THEME
}) })
}, },
store: () => store, store: () => store,
data: () => ({ data: () => ({
themes, themes,
selectedTheme: 'default' selectedTheme: DEFAULT_THEME
}), }),
computed: { computed: {
themeGroups: ({ themes }) => ([ themeGroups: ({ themes }) => ([

View file

@ -1,3 +1,5 @@
import { DEFAULT_THEME } from '../../_utils/themeEngine'
function computeForInstance (store, computedKey, key, defaultValue) { function computeForInstance (store, computedKey, key, defaultValue) {
store.compute(computedKey, store.compute(computedKey,
[key, 'currentInstance'], [key, 'currentInstance'],
@ -5,7 +7,7 @@ function computeForInstance (store, computedKey, key, defaultValue) {
} }
export function instanceComputations (store) { export function instanceComputations (store) {
computeForInstance(store, 'currentTheme', 'instanceThemes', 'default') computeForInstance(store, 'currentTheme', 'instanceThemes', DEFAULT_THEME)
computeForInstance(store, 'currentVerifyCredentials', 'verifyCredentials', null) computeForInstance(store, 'currentVerifyCredentials', 'verifyCredentials', null)
computeForInstance(store, 'currentInstanceInfo', 'instanceInfos', null) computeForInstance(store, 'currentInstanceInfo', 'instanceInfos', null)
computeForInstance(store, 'pinnedPage', 'pinnedPages', '/local') computeForInstance(store, 'pinnedPage', 'pinnedPages', '/local')

View file

@ -1,5 +1,10 @@
let meta = process.browser && document.getElementById('theThemeColor') let meta = process.browser && document.getElementById('theThemeColor')
let offlineStyle = process.browser && document.getElementById('theOfflineStyle') let offlineStyle = process.browser && document.getElementById('theOfflineStyle')
let prefersDarkTheme = process.browser && window.matchMedia('(prefers-color-scheme: dark)').matches
export const DEFAULT_LIGHT_THEME = 'default'
export const DEFAULT_DARK_THEME = 'ozark'
export const DEFAULT_THEME = prefersDarkTheme ? DEFAULT_DARK_THEME : DEFAULT_LIGHT_THEME
function getExistingThemeLink () { function getExistingThemeLink () {
return document.head.querySelector('link[rel=stylesheet][href^="/theme-"]') return document.head.querySelector('link[rel=stylesheet][href^="/theme-"]')
@ -30,10 +35,10 @@ function loadCSS (href) {
document.head.insertBefore(link, offlineStyle) document.head.insertBefore(link, offlineStyle)
} }
export function switchToTheme (themeName = 'default') { export function switchToTheme (themeName = DEFAULT_THEME) {
let themeColor = window.__themeColors[themeName] let themeColor = window.__themeColors[themeName]
meta.content = themeColor || window.__themeColors['default'] meta.content = themeColor || window.__themeColors[DEFAULT_THEME]
if (themeName !== 'default') { if (themeName !== DEFAULT_LIGHT_THEME) {
loadCSS(`/theme-${themeName}.css`) loadCSS(`/theme-${themeName}.css`)
} else { } else {
resetExistingTheme() resetExistingTheme()

View file

@ -97,4 +97,6 @@
--compose-button-halo: #{rgba(255, 255, 255, 0.1)}; --compose-button-halo: #{rgba(255, 255, 255, 0.1)};
--file-drop-mask: #{rgba(255, 255, 255, 0.8)}; --file-drop-mask: #{rgba(255, 255, 255, 0.8)};
--banner-fill: #{$main-theme-color};
} }

View file

@ -37,4 +37,6 @@
--settings-list-item-text-hover: #{$main-text-color}; --settings-list-item-text-hover: #{$main-text-color};
--settings-list-item-bg-active: #{lighten($main-bg-color, 7%)}; --settings-list-item-bg-active: #{lighten($main-bg-color, 7%)};
--settings-list-item-bg-hover: #{lighten($main-bg-color, 3%)}; --settings-list-item-bg-hover: #{lighten($main-bg-color, 3%)};
--banner-fill: #{lighten($main-theme-color, 10%)};
} }