too lazy to think of a message, so enjoy this pointless text. Good luck future me...
All checks were successful
Test action / Print hello world (push) Successful in 8m32s

This commit is contained in:
Chris Kruining 2025-10-08 10:49:59 +00:00
parent e7b0307690
commit 28fdba8b00
15 changed files with 3868 additions and 2785 deletions

View file

@ -1,88 +1,88 @@
import {
ContextProviderProps,
createContextProvider,
} from "@solid-primitives/context";
import { action, createAsyncStore, query, useAction } from "@solidjs/router";
import { createStore } from "solid-js/store";
import { useSession } from "vinxi/http";
export enum ColorScheme {
Auto = "light dark",
Light = "light",
Dark = "dark",
}
export interface State {
colorScheme: ColorScheme;
hue: number;
}
const getSession = async () => {
"use server";
return useSession<State>({
password: process.env.SESSION_SECRET!,
});
};
export const getState = query(async () => {
"use server";
const session = await getSession();
if (Object.getOwnPropertyNames(session.data).length === 0) {
await session.update({
colorScheme: ColorScheme.Auto,
hue: 0,
});
}
return session.data;
}, "color-scheme");
const setState = action(async (state: State) => {
"use server";
const session = await getSession();
await session.update((prev) => ({ ...prev, ...state }));
}, "color-scheme");
interface ThemeContextType {
readonly theme: State;
setColorScheme(colorScheme: ColorScheme): void;
setHue(colorScheme: number): void;
}
const [ThemeContextProvider, useTheme] = createContextProvider<
ThemeContextType,
ContextProviderProps
>(
(props) => {
const updateState = useAction(setState);
const state = createAsyncStore(() => getState());
return {
get theme() {
return state.latest ?? { colorScheme: null };
},
setColorScheme(colorScheme) {
// updateState({ colorScheme, hue: state.latest!.hue });
},
setHue(hue) {
// updateState({ hue, colorScheme: state.latest!.colorScheme });
},
};
},
{
theme: {
colorScheme: ColorScheme.Auto,
hue: 180,
},
setColorScheme(colorScheme) {},
setHue(hue) {},
},
);
export { ThemeContextProvider, useTheme };
import {
ContextProviderProps,
createContextProvider,
} from "@solid-primitives/context";
import { action, createAsyncStore, query, useAction } from "@solidjs/router";
import { createStore } from "solid-js/store";
import { useSession } from "vinxi/http";
export enum ColorScheme {
Auto = "light dark",
Light = "light",
Dark = "dark",
}
export interface State {
colorScheme: ColorScheme;
hue: number;
}
const getSession = async () => {
"use server";
return useSession<State>({
password: process.env.SESSION_SECRET!,
});
};
export const getState = query(async () => {
"use server";
const session = await getSession();
if (Object.getOwnPropertyNames(session.data).length === 0) {
await session.update({
colorScheme: ColorScheme.Auto,
hue: 0,
});
}
return session.data;
}, "color-scheme");
const setState = action(async (state: State) => {
"use server";
const session = await getSession();
await session.update((prev) => ({ ...prev, ...state }));
}, "color-scheme");
interface ThemeContextType {
readonly theme: State;
setColorScheme(colorScheme: ColorScheme): void;
setHue(colorScheme: number): void;
}
const [ThemeContextProvider, useTheme] = createContextProvider<
ThemeContextType,
ContextProviderProps
>(
(props) => {
const updateState = useAction(setState);
const state = createAsyncStore(() => getState());
return {
get theme() {
return state.latest ?? { colorScheme: null };
},
setColorScheme(colorScheme) {
// updateState({ colorScheme, hue: state.latest!.hue });
},
setHue(hue) {
// updateState({ hue, colorScheme: state.latest!.colorScheme });
},
};
},
{
theme: {
colorScheme: ColorScheme.Auto,
hue: 180,
},
setColorScheme(colorScheme) {},
setHue(hue) {},
},
);
export { ThemeContextProvider, useTheme };

View file

@ -1,4 +1,4 @@
export { ThemeContextProvider, useTheme } from './context';
export { ThemeContextProvider, useTheme } from './context';
export { ColorSchemePicker } from './picker';

View file

@ -1,9 +1,9 @@
.picker {
grid-template-columns: auto 1fr;
}
.hue {
display: flex;
flex-flow: row;
align-items: center;
.picker {
grid-template-columns: auto 1fr;
}
.hue {
display: flex;
flex-flow: row;
align-items: center;
}

View file

@ -1,69 +1,69 @@
import {
WiMoonAltFirstQuarter,
WiMoonAltFull,
WiMoonAltNew,
} from "solid-icons/wi";
import {
Component,
createEffect,
For,
Match,
on,
Setter,
Switch,
} from "solid-js";
import { ColorScheme, useTheme } from "./context";
import css from "./picker.module.css";
import { Select } from "~/components/select";
const colorSchemes: Record<ColorScheme, keyof typeof ColorScheme> =
Object.fromEntries(
Object.entries(ColorScheme).map(([k, v]) => [v, k])
) as any;
export const ColorSchemePicker: Component = (props) => {
const themeContext = useTheme();
const setScheme: Setter<ColorScheme> = (next) => {
if (typeof next === "function") {
next = next();
}
themeContext.setColorScheme(next);
};
return (
<>
<label aria-label="Color scheme picker">
<Select
id="color-scheme-picker"
class={css.picker}
value={themeContext.theme.colorScheme}
setValue={setScheme}
values={colorSchemes}
>
{(k, v) => (
<>
<Switch>
<Match when={k === ColorScheme.Auto}>
<WiMoonAltFirstQuarter />
</Match>
<Match when={k === ColorScheme.Light}>
<WiMoonAltNew />
</Match>
<Match when={k === ColorScheme.Dark}>
<WiMoonAltFull />
</Match>
</Switch>
{v}
</>
)}
</Select>
</label>
{/* <label class={css.hue} aria-label="Hue slider">
<input type="range" min="0" max="360" value={theme.hue} onInput={e => setHue(e.target.valueAsNumber)} />
</label> */}
</>
);
};
import {
WiMoonAltFirstQuarter,
WiMoonAltFull,
WiMoonAltNew,
} from "solid-icons/wi";
import {
Component,
createEffect,
For,
Match,
on,
Setter,
Switch,
} from "solid-js";
import { ColorScheme, useTheme } from "./context";
import css from "./picker.module.css";
import { Select } from "~/components/select";
const colorSchemes: Record<ColorScheme, keyof typeof ColorScheme> =
Object.fromEntries(
Object.entries(ColorScheme).map(([k, v]) => [v, k])
) as any;
export const ColorSchemePicker: Component = (props) => {
const themeContext = useTheme();
const setScheme: Setter<ColorScheme> = (next) => {
if (typeof next === "function") {
next = next();
}
themeContext.setColorScheme(next);
};
return (
<>
<label aria-label="Color scheme picker">
<Select
id="color-scheme-picker"
class={css.picker}
value={themeContext.theme.colorScheme}
setValue={setScheme}
values={colorSchemes}
>
{(k, v) => (
<>
<Switch>
<Match when={k === ColorScheme.Auto}>
<WiMoonAltFirstQuarter />
</Match>
<Match when={k === ColorScheme.Light}>
<WiMoonAltNew />
</Match>
<Match when={k === ColorScheme.Dark}>
<WiMoonAltFull />
</Match>
</Switch>
{v}
</>
)}
</Select>
</label>
{/* <label class={css.hue} aria-label="Hue slider">
<input type="range" min="0" max="360" value={theme.hue} onInput={e => setHue(e.target.valueAsNumber)} />
</label> */}
</>
);
};