diff --git a/code/libraries/array/cpp/resources/libcpp.so b/code/libraries/array/cpp/resources/libcpp.so new file mode 100755 index 00000000..9d6d9616 Binary files /dev/null and b/code/libraries/array/cpp/resources/libcpp.so differ diff --git a/code/services-application/search-service/resources/static/search/serp.scss b/code/services-application/search-service/resources/static/search/serp.scss index b2ca3a19..fe5f231c 100644 --- a/code/services-application/search-service/resources/static/search/serp.scss +++ b/code/services-application/search-service/resources/static/search/serp.scss @@ -1,4 +1,6 @@ :root { + color-scheme: light; + --clr-bg-page: hsl(60, 42%, 95%); // $nicotine-light --clr-bg-ui: hsl(0, 0%, 100%); @@ -26,40 +28,39 @@ --font-family-heading: serif; // $heading-fonts } -@media (prefers-color-scheme: dark) { - :root { - --clr-bg-page: hsl(0, 0%, 6%); + +:root[data-theme='dark'] { - --clr-bg-ui: hsl(0, 0%, 18%); - --clr-text-ui: #ddd; + color-scheme: dark; - --clr-bg-theme: hsl(0, 0%, 2%); - --clr-text-theme: var(--clr-text-ui); + --clr-bg-page: hsl(0, 0%, 6%); - --clr-bg-highlight: hsl(0, 0%, 11%); - --clr-text-highlight: #fff; + --clr-bg-ui: hsl(0, 0%, 18%); + --clr-text-ui: #ddd; - --clr-bg-accent: hsl(200, 32%, 28%); - --clr-border-accent: hsl(200, 8%, 12%); + --clr-bg-theme: hsl(0, 0%, 2%); + --clr-text-theme: var(--clr-text-ui); - --clr-border: hsl(0, 0%, 30%); + --clr-bg-highlight: hsl(0, 0%, 11%); + --clr-text-highlight: #fff; - --clr-shadow: #000; + --clr-bg-accent: hsl(200, 32%, 28%); + --clr-border-accent: hsl(200, 8%, 12%); - --clr-link: #8a8aff; - --clr-link-visited: #ffadff; - --clr-heading-link-visited: var(--clr-link-visited); - } + --clr-border: hsl(0, 0%, 30%); + + --clr-shadow: #000; + + --clr-link: #8a8aff; + --clr-link-visited: #ffadff; + --clr-heading-link-visited: var(--clr-link-visited); } + * { box-sizing: border-box; } -html { - color-scheme: light dark; -} - a { color: var(--clr-link); } @@ -199,6 +200,8 @@ header { color: var(--clr-text-ui); box-shadow: 0 0 0.5ch var(--clr-shadow); margin-bottom: 1ch; + display: flex; + align-items: center; nav { a { @@ -228,6 +231,11 @@ header { } } +#theme { + margin-left: auto; + margin-right: .5ch; +} + #complaint { @extend .dialog; max-width: 60ch; @@ -333,10 +341,8 @@ section.cards { line-height: 1.6; } - @media (prefers-color-scheme: dark) { - & { - border: 1px solid var(--clr-border); - } + [data-theme='dark'] & { + border: 1px solid var(--clr-border); } } } diff --git a/code/services-application/search-service/resources/static/search/theme.js b/code/services-application/search-service/resources/static/search/theme.js new file mode 100644 index 00000000..73fdcd26 --- /dev/null +++ b/code/services-application/search-service/resources/static/search/theme.js @@ -0,0 +1,57 @@ +function getTheme() { + const theme = window.localStorage.getItem('theme'); + + // if a valid theme is set in localStorage, return it + if (theme === 'dark' || theme === 'light') { + return { value: theme, system: false }; + } + + // if matchMedia is supported and OS theme is dark + if (window.matchMedia('(prefers-color-scheme: dark)').matches) { + return { value: 'dark', system: true }; + } + + return { value: 'light', system: true }; +} + +function setTheme(value) { + if (value === 'dark' || value === 'light') { + window.localStorage.setItem('theme', value); + } else { + window.localStorage.removeItem('theme'); + } + + const theme = getTheme(); + + document.documentElement.setAttribute('data-theme', theme.value); +} + +function initializeTheme() { + const themeSelect = document.getElementById('theme-select'); + + const theme = getTheme(); + + document.documentElement.setAttribute('data-theme', theme.value); + + // system is selected by default in the themeSwitcher so ignore it here + if (!theme.system) { + themeSelect.value = theme.value; + } + + themeSelect.addEventListener('change', e => { + setTheme(e.target.value); + }); + + const mql = window.matchMedia('(prefers-color-scheme: dark)'); + + // if someone changes their theme at the OS level we need to update + // their theme immediately if they're using their OS theme + mql.addEventListener('change', e => { + if (themeSelect.value !== 'system') return; + + if (e.matches) setTheme('dark'); + else setTheme('light'); + }); +} + +initializeTheme(); \ No newline at end of file diff --git a/code/services-application/search-service/resources/templates/search/parts/search-header.hdb b/code/services-application/search-service/resources/templates/search/parts/search-header.hdb index c9ad0dab..805ea8a9 100644 --- a/code/services-application/search-service/resources/templates/search/parts/search-header.hdb +++ b/code/services-application/search-service/resources/templates/search/parts/search-header.hdb @@ -7,4 +7,15 @@ Donate Random +