PWA improvements
This commit is contained in:
parent
dd11708d15
commit
6ed9c74862
4 changed files with 70 additions and 31 deletions
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"short_name": "Calque",
|
"short_name": "Calque",
|
||||||
"name": "Calque",
|
"name": "Calque - manage your i18n files",
|
||||||
"description": "Simple tool for maitaining i18n files",
|
"description": "Simple tool for maitaining i18n files",
|
||||||
"icons": [
|
"icons": [
|
||||||
{
|
{
|
||||||
|
@ -13,8 +13,6 @@
|
||||||
"display_override": [
|
"display_override": [
|
||||||
"window-controls-overlay"
|
"window-controls-overlay"
|
||||||
],
|
],
|
||||||
"theme_color": "#222",
|
|
||||||
"background_color": "#222",
|
|
||||||
"screenshots": [
|
"screenshots": [
|
||||||
{
|
{
|
||||||
"src": "/images/screenshots/narrow.png",
|
"src": "/images/screenshots/narrow.png",
|
||||||
|
|
|
@ -1,47 +1,66 @@
|
||||||
import { Accessor, Component, createEffect, createSignal, For, Setter } from "solid-js";
|
import { Component, createEffect, createMemo, createResource, For, Setter } from "solid-js";
|
||||||
import css from './colorschemepicker.module.css';
|
import css from './colorschemepicker.module.css';
|
||||||
import { CgDarkMode } from "solid-icons/cg";
|
import { CgDarkMode } from "solid-icons/cg";
|
||||||
|
import { action, cache, useAction } from "@solidjs/router";
|
||||||
|
import { useSession } from "vinxi/http";
|
||||||
|
|
||||||
export enum ColorScheme {
|
export enum ColorScheme {
|
||||||
Auto = 'light dark',
|
Auto = 'light dark',
|
||||||
Light = 'light',
|
Light = 'light',
|
||||||
Dark = 'dark',
|
Dark = 'dark',
|
||||||
}
|
}
|
||||||
|
type ColorSchemeKey = keyof typeof ColorScheme;
|
||||||
|
|
||||||
const colorSchemeEntries = [
|
const colorSchemeKeys: readonly ColorSchemeKey[] = ['Auto', 'Light', 'Dark'] as const;
|
||||||
[ColorScheme.Auto, 'Auto'],
|
|
||||||
[ColorScheme.Light, 'Light'],
|
|
||||||
[ColorScheme.Dark, 'Dark'],
|
|
||||||
] as const;
|
|
||||||
|
|
||||||
interface ColorSchemePickerProps {
|
interface ColorSchemePickerProps {
|
||||||
value?: Setter<ColorScheme> | [Accessor<ColorScheme>, Setter<ColorScheme>];
|
value?: Setter<ColorScheme>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const getSession = async () => {
|
||||||
|
'use server';
|
||||||
|
|
||||||
|
return useSession<{ colorScheme: ColorSchemeKey }>({
|
||||||
|
password: process.env.SESSION_SECRET!,
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
export const getColorScheme = cache(async () => {
|
||||||
|
'use server';
|
||||||
|
|
||||||
|
const session = await getSession();
|
||||||
|
|
||||||
|
return session.data.colorScheme;
|
||||||
|
}, 'color-scheme');
|
||||||
|
|
||||||
|
const setColorScheme = action(async (colorScheme: ColorSchemeKey) => {
|
||||||
|
'use server';
|
||||||
|
|
||||||
|
const session = await getSession();
|
||||||
|
await session.update({ colorScheme });
|
||||||
|
}, 'color-scheme');
|
||||||
|
|
||||||
export const ColorSchemePicker: Component<ColorSchemePickerProps> = (props) => {
|
export const ColorSchemePicker: Component<ColorSchemePickerProps> = (props) => {
|
||||||
const [value, setValue] = createSignal<ColorScheme>(ColorScheme.Auto);
|
const [value, { mutate }] = createResource<ColorSchemeKey>(() => getColorScheme(), { initialValue: 'Auto' });
|
||||||
|
const updateStore = useAction(setColorScheme);
|
||||||
|
|
||||||
createEffect(() => {
|
createEffect(() => {
|
||||||
const currentValue = value();
|
props.value?.(ColorScheme[value()]);
|
||||||
const setter = props.value instanceof Array ? props.value[1] : props.value;
|
|
||||||
|
|
||||||
if (!setter) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
setter(currentValue);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return <label class={css.picker}>
|
return <label class={css.picker}>
|
||||||
<CgDarkMode />
|
<CgDarkMode />
|
||||||
|
|
||||||
<select name="color-scheme-picker" value={value()} onInput={(e) => {
|
<select name="color-scheme-picker" onInput={(e) => {
|
||||||
if (e.target.value !== value()) {
|
if (e.target.value !== value()) {
|
||||||
setValue(e.target.value as any);
|
const nextValue = (e.target.value ?? 'Auto') as ColorSchemeKey;
|
||||||
|
|
||||||
|
mutate(nextValue);
|
||||||
|
updateStore(nextValue);
|
||||||
}
|
}
|
||||||
}}>
|
}}>
|
||||||
<For each={colorSchemeEntries}>{
|
<For each={colorSchemeKeys}>{
|
||||||
([value, label]) => <option value={value}>{label}</option>
|
(v) => <option value={v} selected={v === value()}>{v}</option>
|
||||||
}</For>
|
}</For>
|
||||||
</select>
|
</select>
|
||||||
</label>;
|
</label>;
|
||||||
|
|
|
@ -1,17 +1,24 @@
|
||||||
import { Link, Meta, Title } from "@solidjs/meta";
|
import { Link, Title } from "@solidjs/meta";
|
||||||
import { createSignal, For, ParentProps, Show } from "solid-js";
|
import { createEffect, createMemo, createSignal, ParentProps, Show } from "solid-js";
|
||||||
import { BsTranslate } from "solid-icons/bs";
|
import { BsTranslate } from "solid-icons/bs";
|
||||||
import { FilesProvider } from "~/features/file";
|
import { FilesProvider } from "~/features/file";
|
||||||
import { CommandPalette, CommandPaletteApi, Menu, MenuProvider } from "~/features/menu";
|
import { CommandPalette, CommandPaletteApi, Menu, MenuProvider } from "~/features/menu";
|
||||||
import { isServer } from "solid-js/web";
|
import { isServer } from "solid-js/web";
|
||||||
import { A } from "@solidjs/router";
|
import { A, createAsync } from "@solidjs/router";
|
||||||
import { createCommand, Modifier } from "~/features/command";
|
import { createCommand, Modifier } from "~/features/command";
|
||||||
import { ColorScheme, ColorSchemePicker } from "~/components/colorschemepicker";
|
import { ColorScheme, ColorSchemePicker, getColorScheme } from "~/components/colorschemepicker";
|
||||||
import css from "./editor.module.css";
|
import css from "./editor.module.css";
|
||||||
|
|
||||||
export default function Editor(props: ParentProps) {
|
export default function Editor(props: ParentProps) {
|
||||||
|
const storedColorScheme = createAsync<keyof typeof ColorScheme>(() => getColorScheme(), { initialValue: 'Auto' });
|
||||||
|
|
||||||
const [commandPalette, setCommandPalette] = createSignal<CommandPaletteApi>();
|
const [commandPalette, setCommandPalette] = createSignal<CommandPaletteApi>();
|
||||||
const [colorScheme, setColorScheme] = createSignal<ColorScheme>(ColorScheme.Auto);
|
const colorScheme = createMemo(() => ColorScheme[storedColorScheme()]);
|
||||||
|
const color = createMemo(() => ({
|
||||||
|
[ColorScheme.Auto]: undefined,
|
||||||
|
[ColorScheme.Light]: '#eee',
|
||||||
|
[ColorScheme.Dark]: '#333',
|
||||||
|
}[ColorScheme[storedColorScheme()]]));
|
||||||
|
|
||||||
const supported = isServer || typeof window.showDirectoryPicker === 'function';
|
const supported = isServer || typeof window.showDirectoryPicker === 'function';
|
||||||
const commands = [
|
const commands = [
|
||||||
|
@ -22,7 +29,15 @@ export default function Editor(props: ParentProps) {
|
||||||
|
|
||||||
return <MenuProvider commands={commands}>
|
return <MenuProvider commands={commands}>
|
||||||
<Title>Calque</Title>
|
<Title>Calque</Title>
|
||||||
<Meta name="color-scheme" content={colorScheme()} />
|
|
||||||
|
<meta id="theme-scheme" name="color-scheme" content={colorScheme()} />
|
||||||
|
<meta id="theme-color" name="theme-color" content={color()} />
|
||||||
|
|
||||||
|
<Show when={color() === undefined}>
|
||||||
|
<meta id="theme-auto-light" name="theme-color" media="(prefers-color-scheme: light)" content="#eee" />
|
||||||
|
<meta id="theme-auto-dark" name="theme-color" media="(prefers-color-scheme: dark)" content="#333" />
|
||||||
|
</Show>
|
||||||
|
|
||||||
<Link rel="icon" href="/images/favicon.dark.svg" media="screen and (prefers-color-scheme: dark)" />
|
<Link rel="icon" href="/images/favicon.dark.svg" media="screen and (prefers-color-scheme: dark)" />
|
||||||
<Link rel="icon" href="/images/favicon.light.svg" media="screen and (prefers-color-scheme: light)" />
|
<Link rel="icon" href="/images/favicon.light.svg" media="screen and (prefers-color-scheme: light)" />
|
||||||
<Link rel="manifest" href="/manifest.json" />
|
<Link rel="manifest" href="/manifest.json" />
|
||||||
|
@ -34,7 +49,7 @@ export default function Editor(props: ParentProps) {
|
||||||
<Menu.Mount />
|
<Menu.Mount />
|
||||||
|
|
||||||
<section class={css.right}>
|
<section class={css.right}>
|
||||||
<ColorSchemePicker value={[colorScheme, setColorScheme]} />
|
<ColorSchemePicker />
|
||||||
</section>
|
</section>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
|
|
|
@ -11,16 +11,23 @@
|
||||||
grid-template-columns: auto minmax(0, 1fr) auto;
|
grid-template-columns: auto minmax(0, 1fr) auto;
|
||||||
grid-auto-flow: column;
|
grid-auto-flow: column;
|
||||||
justify-content: start;
|
justify-content: start;
|
||||||
|
justify-items: start;
|
||||||
position: relative;
|
position: relative;
|
||||||
z-index: 10;
|
z-index: 10;
|
||||||
|
|
||||||
gap: .5em;
|
gap: .5em;
|
||||||
padding-inline: 1em;
|
padding-inline: 1em;
|
||||||
block-size: 2em;
|
block-size: calc(env(titlebar-area-height, 2em) + .5px);
|
||||||
|
inline-size: env(titlebar-area-width, 100%);
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
|
||||||
background-color: var(--surface-3);
|
background-color: var(--surface-3);
|
||||||
color: var(--text-1);
|
color: var(--text-1);
|
||||||
|
|
||||||
|
& > * {
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
}
|
||||||
|
|
||||||
& > .logo {
|
& > .logo {
|
||||||
inline-size: 3em;
|
inline-size: 3em;
|
||||||
block-size: 3em;
|
block-size: 3em;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue