pre-ui-rearch

This commit is contained in:
2026-07-31 01:05:32 -04:00
parent 89c5ca2f7e
commit 97b2f61e5f
12 changed files with 2136 additions and 1668 deletions

View File

@@ -1,32 +1,57 @@
const createSignal = <T,>(value: T): [() => T, (next: T) => void] => {
let current = value
return [() => current, (next) => {
current = next
}]
/**
* SyncPanel — exposes Import / Export / status as SettingItems. The Import and
* Export dialogs render as depth-2 editors. No own useKeyboard.
*/
import { createSignal } from "solid-js";
import { ImportDialog } from "./ImportDialog";
import { ExportDialog } from "./ExportDialog";
import { SyncStatus } from "./SyncStatus";
import type { SettingItem } from "./types";
// Module-level state so the action items can open their dialogs as depth-2
// editors. The SettingsPage reads `syncEditor()` to decide which dialog to show.
const [syncEditor, setSyncEditor] = createSignal<"import" | "export" | null>(
null,
);
export { syncEditor };
export function closeSyncEditor() {
setSyncEditor(null);
}
import { ImportDialog } from "./ImportDialog"
import { ExportDialog } from "./ExportDialog"
import { SyncStatus } from "./SyncStatus"
import { useTheme } from "@/context/ThemeContext"
export function SyncPanel() {
const { theme } = useTheme();
const mode = createSignal<"import" | "export" | null>(null)
return (
<box style={{ flexDirection: "column", gap: 1 }}>
<box style={{ flexDirection: "row", gap: 1 }}>
<box border borderColor={theme.border} onMouseDown={() => mode[1]("import")}>
<text fg={theme.text}>Import</text>
</box>
<box border borderColor={theme.border} onMouseDown={() => mode[1]("export")}>
<text fg={theme.text}>Export</text>
</box>
</box>
<SyncStatus />
{mode[0]() === "import" ? <ImportDialog /> : null}
{mode[0]() === "export" ? <ExportDialog /> : null}
</box>
)
export function useSyncItems(): SettingItem[] {
return [
{
id: "import",
label: "Import",
kind: "editor",
display: () => "→",
help: () =>
`Import subscriptions from a sync file (JSON or OPML).\nDrill in (Enter/l) to open the import dialog.\nType: editor`,
renderEditor: () => <ImportDialog />,
},
{
id: "export",
label: "Export",
kind: "editor",
display: () => "→",
help: () =>
`Export subscriptions to a sync file.\nDrill in (Enter/l) to open the export dialog.\nType: editor`,
renderEditor: () => <ExportDialog />,
},
{
id: "status",
label: "Status",
kind: "info",
display: () => "Idle",
help: () =>
`Last sync status. (Sync is run from the import/export dialogs.)\nType: info`,
},
];
}
/** Renders the live sync status block (used by the Settings page header for the
* Sync section, when relevant). */
export function SyncStatusBlock() {
return <SyncStatus />;
}