chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
import { useState } from 'react';
import { Panel } from '#/components/atoms/panel.jsx';
import { ErrorNotice } from '#/components/molecules/error-notice.jsx';
import { Section } from '#/components/molecules/section.jsx';
import { SelectField } from '#/components/molecules/select-field.jsx';
import { post } from '#/lib/api.js';
import { queryKeys, useApiMutation } from '#/lib/query.js';
import { applyTheme } from '#/lib/theme.js';
const THEMES = [
['system', 'Match this device'],
['light', 'Light'],
['dark', 'Dark'],
];
/**
* The console's color palette. A change applies right away and is stored with
* the account, so it follows the account to other browsers. On a server that
* cannot store UI state the choice is shown but disabled.
* @param {{data: {theme: string, features: {settings: boolean}}}} props
*/
export function AppearanceCard({ data }) {
const available = data.features.settings;
const [theme, setTheme] = useState(data.theme);
const { run, busy, error } = useApiMutation([queryKeys.overview]);
const change = (next) => {
const previous = theme;
setTheme(next);
applyTheme(next);
run(async () => {
try {
await post('/settings/appearance', { theme: next });
} catch (err) {
setTheme(previous);
applyTheme(previous);
throw err;
}
});
};
return (
<Panel>
<Section
title="Appearance"
description="Light, dark, or whatever this device prefers."
>
<div className="flex flex-col gap-4">
<SelectField
label="Theme"
options={THEMES}
value={theme}
onChange={change}
disabled={busy || !available}
/>
{!available && (
<p className="text-[13px] text-muted-foreground">
This server does not store settings.
</p>
)}
<ErrorNotice error={error} />
</div>
</Section>
</Panel>
);
}