module Dashi.ColourScheme where

import Dashi.Prelude
import Dashi.Style.Colour qualified as Colour (Scheme)
import Dashi.Style.Colour qualified as Colour.Scheme

browserPreference :: IO Colour.Scheme
browserPreference :: IO Scheme
browserPreference =
    IO Bool
[js|
        return window.matchMedia("(prefers-color-scheme: dark)").matches
    |]
        IO Bool -> (Bool -> Scheme) -> IO Scheme
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> Getting Scheme Bool Scheme -> Bool -> Scheme
forall s (m :: * -> *) a. MonadReader s m => Getting a s a -> m a
view (AnIso Scheme Scheme Bool Bool -> Iso Bool Bool Scheme Scheme
forall s t a b. AnIso s t a b -> Iso b a t s
from AnIso Scheme Scheme Bool Bool
Iso' Scheme Bool
Colour.Scheme.isDark)

get :: IO Colour.Scheme
get :: IO Scheme
get =
    IO MisoString
[js|
        return document.querySelector('meta[name=color-scheme]')?.content || "";
    |]
        IO MisoString -> (MisoString -> IO Scheme) -> IO Scheme
forall a b. IO a -> (a -> IO b) -> IO b
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (String -> IO Scheme)
-> (Scheme -> IO Scheme) -> Either String Scheme -> IO Scheme
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (IO Scheme -> String -> IO Scheme
forall a b. a -> b -> a
const IO Scheme
browserPreference) Scheme -> IO Scheme
forall a. a -> IO a
forall (f :: * -> *) a. Applicative f => a -> f a
pure
        (Either String Scheme -> IO Scheme)
-> (MisoString -> Either String Scheme) -> MisoString -> IO Scheme
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. MisoString -> Either String Scheme
forall t. FromMisoString t => MisoString -> Either String t
fromMisoStringEither

set :: Colour.Scheme -> IO ()
set :: Scheme -> IO ()
set Scheme
c =
    IO ()
[js|
        function create() {
            const meta = document.createElement('meta');
            meta.setAttribute('name', 'color-scheme');
            document.getElementsByTagName('head')[0].appendChild(meta);
            return meta;
        }
        const header = document.querySelector('meta[name=color-scheme]') || create();
        header.setAttribute('content', ${c});
    |]