pre-ui-rearch
This commit is contained in:
@@ -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 />;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user