Fork of Chiri for Astro for my blog
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at a1e6ead60fb44c152fefa3a86179bcf2b84d6249 155 lines 4.3 kB view raw
1<!-- 2 This is a critical style block to prevent flashing on page load in dark mode. 3 It is injected into the <head> of the document before the main stylesheets are loaded. 4--> 5<style is:inline> 6 :root { 7 --bg: #ffffff; 8 } 9 10 html.dark { 11 --bg: #1c1c1c; 12 } 13 14 html { 15 background-color: var(--bg); 16 color-scheme: light; 17 } 18 19 html.dark { 20 color-scheme: dark; 21 } 22</style> 23 24<script is:inline> 25 // Global Theme Manager 26 ;(function () { 27 // Prevent duplicate initialization 28 if (window.ThemeManager && window.ThemeManager.initialized) { 29 return 30 } 31 32 window.ThemeManager = { 33 STORAGE_KEY: 'chiri-theme', 34 initialized: false, 35 36 getSystemTheme() { 37 return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light' 38 }, 39 40 getStoredTheme() { 41 try { 42 return localStorage.getItem(this.STORAGE_KEY) 43 } catch { 44 return null 45 } 46 }, 47 48 setStoredTheme(theme) { 49 try { 50 if (theme === 'system') { 51 localStorage.removeItem(this.STORAGE_KEY) 52 } else { 53 localStorage.setItem(this.STORAGE_KEY, theme) 54 } 55 } catch (e) { 56 console.warn('Failed to store theme preference:', e) 57 } 58 }, 59 60 getEffectiveTheme() { 61 const stored = this.getStoredTheme() 62 return stored || this.getSystemTheme() 63 }, 64 65 isUsingSystemTheme() { 66 return this.getStoredTheme() === null 67 }, 68 69 applyTheme(theme) { 70 document.documentElement.classList.remove('light', 'dark') 71 document.documentElement.classList.add(theme) 72 73 // Dispatch event for other components 74 document.dispatchEvent( 75 new CustomEvent('themechange', { 76 detail: { 77 theme, 78 isUserChoice: !this.isUsingSystemTheme(), 79 isSystemTheme: this.isUsingSystemTheme() 80 } 81 }) 82 ) 83 }, 84 85 toggle() { 86 const currentTheme = this.getEffectiveTheme() 87 // Simply toggle between light and dark 88 const newTheme = currentTheme === 'dark' ? 'light' : 'dark' 89 90 this.setStoredTheme(newTheme) 91 this.applyTheme(newTheme) 92 }, 93 94 init() { 95 if (this.initialized) return 96 97 // Set initial theme (maintain current theme when refreshing page) 98 this.applyTheme(this.getEffectiveTheme()) 99 100 // Listen for system theme changes 101 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', (e) => { 102 const newSystemTheme = e.matches ? 'dark' : 'light' 103 104 // Always follow system theme changes and update stored theme preference 105 this.setStoredTheme(newSystemTheme) 106 this.applyTheme(newSystemTheme) 107 }) 108 109 this.initialized = true 110 } 111 } 112 113 // Initialize theme manager 114 window.ThemeManager.init() 115 116 // Apply theme when needed 117 const applyTheme = () => { 118 if (window.ThemeManager) { 119 const theme = window.ThemeManager.getEffectiveTheme() 120 window.ThemeManager.applyTheme(theme) 121 } 122 } 123 124 // Apply immediately on script load 125 applyTheme() 126 127 // Listen for navigation events 128 document.addEventListener('astro:before-preparation', applyTheme) 129 130 // Apply theme after DOM changes (both swap and page load) 131 const applyThemeAfterNavigation = () => { 132 if (window.ThemeManager) { 133 const currentTheme = window.ThemeManager.getEffectiveTheme() 134 const appliedTheme = document.documentElement.classList.contains('dark') ? 'dark' : 'light' 135 136 if (currentTheme !== appliedTheme) { 137 // Use requestAnimationFrame to ensure theme is applied in the next frame, avoiding conflicts with view transition 138 requestAnimationFrame(() => { 139 window.ThemeManager.applyTheme(currentTheme) 140 }) 141 } 142 } 143 } 144 145 document.addEventListener('astro:after-swap', applyThemeAfterNavigation) 146 document.addEventListener('astro:page-load', applyThemeAfterNavigation) 147 148 // Handle system theme changes 149 window.matchMedia('(prefers-color-scheme: dark)').addEventListener('change', () => { 150 if (window.ThemeManager && window.ThemeManager.isUsingSystemTheme()) { 151 setTimeout(applyTheme, 0) 152 } 153 }) 154 })() 155</script>