Skip to content

Make server-side aware of dark mode setting #574

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions app/helpers/application_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,8 @@ def github_url(ruby_doc)
# Inspiration: https://github.com/rack/rack/pull/1202
%(#{GITHUB_REPO}/#{version}/#{file}#{"#L#{line}" if line})
end

def dark_mode?
cookies[:'rubyapi-darkMode'] == "1"
end
end
36 changes: 27 additions & 9 deletions app/javascript/controllers/theme-switch_controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,29 +5,47 @@ export default class extends Controller {

connect() {
const osDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
const supportsLocalStorage = 'localStorage' in window

// Dark theme was previously stored using localStorage.
// Migrate to a cookie if the old localStorage key is present.
const supportsLocalStorage = 'localStorage' in window
if (supportsLocalStorage) {
const darkMode = localStorage.getItem('rubyapi-darkMode')

if (darkMode !== null && darkMode === '1') {
this.setDarkMode(this.switchTarget)
} else if (osDarkMode && darkMode === null) {
this.setDarkMode(this.switchTarget)
const localStorageDarkMode = localStorage.getItem('rubyapi-darkMode')
if (localStorageDarkMode !== null) {
this.savePreference(localStorageDarkMode)
localStorage.removeItem('rubyapi-darkMode')
}
}

const cookies = document.cookie.split('; ')
const darkModeCookie = cookies.find(cookie => cookie.startsWith('rubyapi-darkMode='))
const darkMode = darkModeCookie !== undefined
? darkModeCookie.split("=")[1]
: null

if (darkMode !== null && darkMode === '1') {
this.setDarkMode(this.switchTarget)
} else if (osDarkMode && darkMode === null) {
this.setDarkMode(this.switchTarget)
} else {
this.setLightMode(this.switchTarget)
}
}

setLightMode(target) {
target.classList.replace("fa-moon", "fa-sun")
document.documentElement.classList.remove("mode-dark")
localStorage.setItem('rubyapi-darkMode', '0')
this.savePreference(0)
}

setDarkMode(target) {
target.classList.replace("fa-sun", "fa-moon")
document.documentElement.classList.add("mode-dark")
localStorage.setItem('rubyapi-darkMode', '1')
this.savePreference(1)
}

savePreference(value) {
document.cookie = `rubyapi-darkMode=${value}; expires=Fri, 31 Dec 9999 23:59:59 GMT; path=/`
}

toggle() {
Expand Down
2 changes: 1 addition & 1 deletion app/views/layouts/_theme_selector.html.slim
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
-#frozen_string_literal: true
div class="relative ml-4 md:block hidden" data-controller="theme-switch"
button id="darkmode-toggle" class="relative z-20 text-xl hover:text-red-100 dark-hover:text-gray-400 hover:fill-current" data-action="theme-switch#toggle" aria-label="Toggle theme" title="Toggle theme"
i class="fas fa-sun" data-target="theme-switch.switch"
i class="fas #{dark_mode? ? 'fa-moon' : 'fa-sun'}" data-target="theme-switch.switch"
2 changes: 1 addition & 1 deletion app/views/layouts/application.html.slim
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
-# frozen_string_literal: true
doctype html
html lang="en"
html lang="en" class=("mode-dark" if dark_mode?)
head
= display_meta_tags site: "Ruby API (#{dev? ? "dev" : "v" + ruby_version})", reverse: true
meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"
Expand Down