<commit_before><script>
  // Extensions
  import SettingsGroup from './Group'

  // Utilities
  import { sync } from 'vuex-pathify'

  // Globals
  import { IN_BROWSER } from '@/util/globals'

  export default {
    name: 'DefaultSettingsTheme',

    extends: SettingsGroup,

    data: () => ({ path: 'theme' }),

    computed: {
      ...sync('user', [
        'theme@dark',
        'theme@mixed',
        'theme@system',
      ]),
      items () {
        return [
          {
            text: 'light',
            icon: '$mdiWhiteBalanceSunny',
            cb: () => this.setTheme(),
          },
          {
            text: 'dark',
            icon: '$mdiWeatherNight',
            cb: () => this.setTheme(true),
          },
          {
            text: 'system',
            icon: '$mdiDesktopTowerMonitor',
            cb: () => this.setSystemTheme(),
          },
          {
            text: 'mixed',
            icon: '$mdiThemeLightDark',
            cb: () => this.setTheme(false, true),
          },
        ]
      },
      internalValue: {
        get () {
          if (this.mixed) return 'mixed'
          if (this.system) return 'system'

          return this.dark ? 'dark' : 'light'
        },
        set (val) {
          const set = this.items.find(item => item.text === val)

          set.cb()
        },
      },
    },

    watch: {
      '$vuetify.theme.dark' (val) {
        if (this.dark === val) return

        this.dark = val
      },
      dark (val) {
        if (this.$vuetify.theme.dark === val) return

        this.$vuetify.theme.dark = val
      },
    },

    created () {
      const matchMedia = this.getMatchMedia()
      if (!matchMedia) return

      if (this.internalValue === 'system') {
        this.dark = matchMedia.matches
      }

      matchMedia.onchange = ({ matches }) => {
        if (this.system) {
          this.dark = matches
        }
      }
    },

    methods: {
      getMatchMedia () {
        return (IN_BROWSER && window.matchMedia) ? window.matchMedia('(prefers-color-scheme: dark)') : false<commit_msg>docs: prevent memory leak in theme selector<commit_after><script>
  // Extensions
  import SettingsGroup from './Group'

  // Utilities
  import { sync } from 'vuex-pathify'

  // Globals
  import { IN_BROWSER } from '@/util/globals'

  export default {
    name: 'DefaultSettingsTheme',

    extends: SettingsGroup,

    data: () => ({ path: 'theme' }),

    computed: {
      ...sync('user', [
        'theme@dark',
        'theme@mixed',
        'theme@system',
      ]),
      items () {
        return [
          {
            text: 'light',
            icon: '$mdiWhiteBalanceSunny',
            cb: () => this.setTheme(),
          },
          {
            text: 'dark',
            icon: '$mdiWeatherNight',
            cb: () => this.setTheme(true),
          },
          {
            text: 'system',
            icon: '$mdiDesktopTowerMonitor',
            cb: () => this.setSystemTheme(),
          },
          {
            text: 'mixed',
            icon: '$mdiThemeLightDark',
            cb: () => this.setTheme(false, true),
          },
        ]
      },
      internalValue: {
        get () {
          if (this.mixed) return 'mixed'
          if (this.system) return 'system'

          return this.dark ? 'dark' : 'light'
        },
        set (val) {
          const set = this.items.find(item => item.text === val)

          set.cb()
        },
      },
    },

    watch: {
      '$vuetify.theme.dark' (val) {
        if (this.dark === val) return

        this.dark = val
      },
      dark (val) {
        if (this.$vuetify.theme.dark === val) return

        this.$vuetify.theme.dark = val
      },
    },

    created () {
      const matchMedia = this.mql = this.getMatchMedia()
      if (!matchMedia) return

      if (this.internalValue === 'system') {
        this.dark = matchMedia.matches
      }

      matchMedia.onchange = ({ matches }) => {
        if (this.system) {
          this.dark = matches
        }
      }
    },

    beforeDestroy () {
      if (!this.mql) return

      this.mql.onchange = null
      this.mql = null
    },

    methods: {
      getMatchMedia () {
        return (IN_BROWSER && window.matchMedia) ? window.matchMedia('(prefers-color-scheme: dark)') : false
{'fraction_non_alphanumeric': 0.15051020408163265, 'fraction_numerical': 0.0, 'mean_word_length': 1.4858789625360231, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 19, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5007144', 'n_tokens_mistral': 1335, 'n_tokens_neox': 1292, 'n_words': 258}