summaryrefslogtreecommitdiff
path: root/_includes/extensions/theme-toggle.html
blob: 623c4257ba1d9679c7ad056fea0df1e375c353c5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<div class="theme-toggle">
  <input type="checkbox" id="theme-switch">
  <label for="theme-switch">
    <div class="toggle"></div>
    <div class="names">
      <p class="light">Light</p>
      <p class="dark">Dark</p>
    </div>
  </label>
</div>

{%- assign name = 'night_mode' -%}
{%- include functions.html func='get_value' default='auto' -%}
{%- assign night_mode = return -%}

<script>
  (function() {
    var sw = document.getElementById('theme-switch');
    var html = document.getElementsByTagName('html')[0];
    var themeData = loadThemeData();

    function saveThemeData(data) {
      localStorage.setItem('theme', JSON.stringify(data));
    }

    function loadThemeData() {
      var data = localStorage.getItem('theme');
      try {
        data = JSON.parse(data ? data : '');
      } catch(e) {
        data = { nightShift: false, autoToggleAt: 0 };
        saveThemeData(data);
      }
      return data;
    }

    function handleThemeToggle(nightShift) {
      themeData.nightShift = nightShift;
      saveThemeData(themeData);
      html.dataset.theme = nightShift ? 'dark' : 'light';
      setTimeout(function() {
        sw.checked = nightShift ? true : false;
      }, 50);
    }

    function autoThemeToggle() {
      // Next time point of theme toggle
      var now = new Date();
      var toggleAt = new Date();
      var hours = now.getHours();
      var nightShift = hours >= 19 || hours <=7;

      if (nightShift) {
        if (hours > 7) {
          toggleAt.setDate(toggleAt.getDate() + 1);
        }
        toggleAt.setHours(7);
      } else {
        toggleAt.setHours(19);
      }

      toggleAt.setMinutes(0);
      toggleAt.setSeconds(0);
      toggleAt.setMilliseconds(0)

      var delay = toggleAt.getTime() - now.getTime();

      // auto toggle theme mode
      setTimeout(function() {
        handleThemeToggle(!nightShift);
      }, delay);

      return {
        nightShift: nightShift,
        toggleAt: toggleAt.getTime()
      };
    }

    // Listen the theme toggle event
    sw.addEventListener('change', function(event) {
      handleThemeToggle(event.target.checked);
    });

    var nightModeOption = '{{ night_mode }}' || 'auto';
    nightModeOption = nightModeOption.toLowerCase();

    if (nightModeOption == 'auto') {
      var data = autoThemeToggle();

      // Toggle theme by local setting
      if (data.toggleAt > themeData.autoToggleAt) {
        themeData.autoToggleAt = data.toggleAt;
        handleThemeToggle(data.nightShift);
      } else {
        handleThemeToggle(themeData.nightShift);
      }
    } else if (nightModeOption == 'manual') {
      handleThemeToggle(themeData.nightShift);
    } else {
      handleThemeToggle(nightModeOption == 'on');
    }
  })();
</script>