matchMedia.tsx 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. import {NODE_ENV} from 'app/constants';
  2. import ConfigStore from 'app/stores/configStore';
  3. function changeFavicon(theme: 'dark' | 'light'): void {
  4. // only on prod because we have a development favicon
  5. if (NODE_ENV !== 'production') {
  6. return;
  7. }
  8. const n = document.querySelector<HTMLLinkElement>('[rel="icon"][type="image/png"]');
  9. if (!n) {
  10. return;
  11. }
  12. const path = n.href.split('/sentry/')[0];
  13. n.href = `${path}/sentry/images/${theme === 'dark' ? 'favicon-dark' : 'favicon'}.png`;
  14. }
  15. function handleColorSchemeChange(e: MediaQueryListEvent): void {
  16. const isDark = e.media === '(prefers-color-scheme: dark)' && e.matches;
  17. const type = isDark ? 'dark' : 'light';
  18. changeFavicon(type);
  19. ConfigStore.updateTheme(type);
  20. }
  21. function prefersDark(): boolean {
  22. return window.matchMedia && window.matchMedia('(prefers-color-scheme: dark)').matches;
  23. }
  24. export function setupColorScheme(): void {
  25. // Set favicon to dark on load if necessary)
  26. if (prefersDark()) {
  27. changeFavicon('dark');
  28. ConfigStore.updateTheme('dark');
  29. }
  30. // Watch for changes in preferred color scheme
  31. const lightMediaQuery = window.matchMedia('(prefers-color-scheme: light)');
  32. const darkMediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
  33. try {
  34. lightMediaQuery.addEventListener('change', handleColorSchemeChange);
  35. darkMediaQuery.addEventListener('change', handleColorSchemeChange);
  36. } catch (err) {
  37. // Safari 13 (maybe lower too) does not support `addEventListener`
  38. // `addListener` is deprecated
  39. lightMediaQuery.addListener(handleColorSchemeChange);
  40. darkMediaQuery.addListener(handleColorSchemeChange);
  41. }
  42. }