MediaWiki:Gadget-DarkModeSwitch.js

From Fallen London Wiki

Note: After saving, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
// 'oojs-ui-widgets'
;(function () {
  const themeStorageKey = 'flw-theme'
  const gadgetThemeDark = 'gadget-DarkMode'
  const gadgetThemeLight = 'gadget-LightMode'
  const themeAttribute = 'data-flw-theme'
  const mwApi = new mw.Api()

  const currentTheme = getCurrentTheme()
  if (currentTheme) {
    document.documentElement.setAttribute(themeAttribute, currentTheme)
  }
  const themeToggleSwitchIsChecked = currentTheme === 'dark'

  const themeToggleSwitch = new OO.ui.ToggleSwitchWidget({
    classes: ['flw-theme-toggle'],
    title: 'Toggle dark mode',
    value: themeToggleSwitchIsChecked,
  })
  themeToggleSwitch.on('change', switchTheme)

  const brightIcon = document.createElement('span')
  brightIcon.innerHTML =
    '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>bright</title><path d="M17.07 7.07V2.93h-4.14L10 0 7.07 2.93H2.93v4.14L0 10l2.93 2.93v4.14h4.14L10 20l2.93-2.93h4.14v-4.14L20 10zM10 16a6 6 0 116-6 6 6 0 01-6 6z"/><circle cx="10" cy="10" r="4.5"/></svg>'
  const brightIconWidget = new OO.ui.Widget({
    classes: ['flw-theme-icon', 'flw-theme-icon-bright'],
    content: [brightIcon],
  })

  const darkIcon = document.createElement('span')
  darkIcon.innerHTML =
    '<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20"><title>moon</title><path d="M17.39 15.14A7.33 7.33 0 0111.75 1.6c.23-.11.56-.23.79-.34a8.19 8.19 0 00-5.41.45 9 9 0 107 16.58 8.42 8.42 0 004.29-3.84 5.3 5.3 0 01-1.03.69z"/></svg>'
  const darkIconWidget = new OO.ui.Widget({
    classes: ['flw-theme-icon', 'flw-theme-icon-dark'],
    content: [darkIcon],
  })

  const themeWidget = new OO.ui.HorizontalLayout({
    classes: ['flw-theme-widget-container'],
    items: [brightIconWidget, themeToggleSwitch, darkIconWidget],
  })
  $('#p-navigation').before(themeWidget.$element)

  // ----*----
  function getCurrentTheme() {
    if (!mw.user.isAnon()) {
      return mw.user.options.get(gadgetThemeDark) ? 'dark' : 'light'
    }
    const storedPref = mw.storage.get(themeStorageKey)
    return storedPref ? storedPref : undefined
  }

  function switchTheme(value) {
    const nextTheme = value ? 'dark' : 'light'
    setTheme(nextTheme)
  }

  function setTheme(theme) {
    document.documentElement.setAttribute(themeAttribute, theme)
    mw.storage.set(themeStorageKey, theme)
    if (!mw.user.isAnon()) {
      const options = {}
      options[gadgetThemeDark] = theme === 'dark' ? 1 : 0
      options[gadgetThemeLight] = theme === 'light' ? 1 : 0
      mwApi.saveOptions(options)
    }
  }
})()