import '../styles/globals.css'
import type { AppProps } from 'next/app'
import { ChakraProvider, extendTheme, withDefaultColorScheme } from '@chakra-ui/react'
import { useEffect, useState, useMemo, useContext, useReducer } from 'react'
import * as d3int from 'd3-interpolate'
import { ThemeContext } from './themecontext'
import { usePersistantState } from '../util/persistant-state'
function MyApp({ Component, pageProps }: AppProps) {
const initialTheme = {
base1: '#1c1f24',
base2: '#21272d',
base3: '#23272e',
base4: '#484854',
base5: '#62686E',
base6: '#757B80',
base7: '#9ca0a4',
base8: '#DFDFDF',
bg: '#242730',
'bg-alt': '#2a2e38',
blue: '#51afef',
cyan: '#5cEfFF',
'dark-blue': '#1f5582',
'dark-cyan': '#6A8FBF',
fg: '#bbc2cf',
'fg-alt': '#5D656B',
green: '#7bc275',
grey: '#484854',
magenta: '#C57BDB',
orange: '#e69055',
red: '#ff665c',
teal: '#4db5bd',
violet: '#a991f1',
yellow: '#FCCE7B',
}
const [isInitialized, setIsInitialized] = useState(false)
const [emacsTheme, setEmacsTheme] = useState(initialTheme)
const [highlightColor, setHighlightColor] = useState('purple')
useEffect(() => {
if (isInitialized) {
localStorage.setItem('theme', JSON.stringify(emacsTheme))
}
}, [emacsTheme])
useEffect(() => {
if (isInitialized) {
localStorage.setItem('highlightColor', JSON.stringify(highlightColor))
}
}, [highlightColor])
useEffect(() => {
setEmacsTheme(
JSON.parse(localStorage.getItem('theme') ?? JSON.stringify(initialTheme)) ?? initialTheme,
)
setHighlightColor(
JSON.parse(localStorage.getItem('highlightColor') ?? JSON.stringify(highlightColor)) ??
highlightColor,
)
setIsInitialized(true)
}, [])
const themeObject = {
emacsTheme: emacsTheme,
setEmacsTheme: setEmacsTheme,
highlightColor: highlightColor,
setHighlightColor: setHighlightColor,
}
return (
)
}
function SubApp(props: any) {
const { children } = props
const { highlightColor, emacsTheme } = useContext(ThemeContext)
// yeah it's annoying, should put this someplace more sensible
const getBorderColor = () => {
if (highlightColor === 'purple') {
return emacsTheme.violet + 'aa'
}
if (highlightColor === 'pink') {
return emacsTheme.magenta + 'aa'
}
if (highlightColor === 'blue') {
return emacsTheme.blue + 'aa'
}
if (highlightColor === 'cyan') {
return emacsTheme.cyan + 'aa'
}
if (highlightColor === 'green') {
return emacsTheme.green + 'aa'
}
if (highlightColor === 'yellow') {
return emacsTheme.yellow + 'aa'
}
if (highlightColor === 'orange') {
return emacsTheme.orange + 'aa'
}
if (highlightColor === 'red') {
return emacsTheme.red + 'aa'
}
}
const missingColor = d3int.interpolate(emacsTheme.base1, emacsTheme.base2)(0.2)
const borderColor = getBorderColor()
const theme = useMemo(() => {
return {
colors: {
white: emacsTheme.bg,
black: emacsTheme.fg,
gray: {
100: emacsTheme.base1,
200: missingColor,
300: emacsTheme.base2,
400: emacsTheme.base3,
500: emacsTheme.base4,
600: emacsTheme.base5,
700: emacsTheme.base6,
800: emacsTheme.base7,
900: emacsTheme.base8,
},
blue: {
500: emacsTheme.blue,
},
teal: {
500: emacsTheme.blue,
},
yellow: {
500: emacsTheme.yellow,
},
orange: {
500: emacsTheme.orange,
},
red: {
500: emacsTheme.red,
},
green: {
500: emacsTheme.green,
},
purple: {
500: emacsTheme.violet,
},
pink: {
500: emacsTheme.magenta,
},
cyan: {
500: emacsTheme.cyan,
},
alt: {
100: emacsTheme['bg-alt'],
900: emacsTheme['fg-alt'],
},
},
shadows: {
outline: '0 0 0 3px ' + borderColor,
},
components: {
Button: {
variants: {
outline: {
border: '2px solid',
borderColor: highlightColor + '.500',
color: highlightColor + '.500',
},
ghost: {
color: highlightColor + '.500',
_hover: { bg: `inherit`, border: '1px solid', borderColor: highlightColor + '.500' },
_active: { color: `inherit`, bg: highlightColor + '.500' },
},
},
},
SliderThumb: {
bg: highlightColor + '.500',
},
SliderFilledTrack: {
bg: 'gray.400',
},
},
}
}, [highlightColor, JSON.stringify(emacsTheme)])
const extendedTheme = extendTheme(theme, withDefaultColorScheme({ colorScheme: highlightColor }))
return {children}
}
export default MyApp