/** * SourceManager — exposes podcast sources as SettingItems for the depth-stack. * * • "Add Source" — an editor item; drilling in shows a name/URL add form. * • Each source — a toggle item (Space toggles enabled) whose display shows * the source type and on/off state. * * Advanced per-API-source options (country/language/explicit) are flattened to * simple toggles/cycles reachable by drilling into the source's editor. * Movement flows through nav.action — no own useKeyboard (avoids the old * right-pane key conflicts). */ import { createSignal, For, Show } from "solid-js"; import { useFeedStore } from "@/stores/feed"; import { useTheme } from "@/context/ThemeContext"; import { useInputFocusNav } from "@/hooks/useInputFocusNav"; import { SourceType } from "@/types/source"; import type { PodcastSource } from "@/types/source"; import type { SettingItem } from "./types"; export function useSourceItems(): SettingItem[] { const feedStore = useFeedStore(); const typeBadge = (s: PodcastSource) => s.type === SourceType.API ? "[API]" : s.type === SourceType.RSS ? "[RSS]" : "[?]"; const items: SettingItem[] = [ { id: "add", label: "Add Source", kind: "editor", display: () => "+", help: () => `Add a custom RSS feed by URL.\nDrill in (Enter/l) to open the add-source form.\nType: editor`, renderEditor: () => , }, ]; for (const s of feedStore.sources()) { items.push({ id: `src:${s.id}`, label: s.name, kind: "toggle", display: () => `${typeBadge(s)} ${s.enabled ? "on" : "off"}`, help: () => `Source: ${s.name}\nType: ${s.type}\nEnabled: ${s.enabled}\nURL: ${s.baseUrl ?? "(none)"}\nSpace/Enter to toggle.`, toggle: () => feedStore.toggleSource(s.id), }); } return items; } function AddSourceForm() { const feedStore = useFeedStore(); const { theme } = useTheme(); const [name, setName] = createSignal(""); const [url, setUrl] = createSignal(""); const [error, setError] = createSignal(null); // Yield navigation keybinds to the Shell router while either input is focused. const nameRef = useInputFocusNav(); const urlRef = useInputFocusNav(); const submit = () => { const u = url().trim(); if (!u) { setError("URL is required"); return; } try { new URL(u); } catch { setError("Invalid URL format"); return; } feedStore.addSource({ name: name().trim() || "Custom Source", type: SourceType.RSS, baseUrl: u, enabled: true, description: `Custom RSS feed: ${u}`, }); setName(""); setUrl(""); setError(null); }; return ( Add Source Name: URL: { setUrl(v); setError(null); }} placeholder="https://example.com/feed.rss" width={35} textColor={theme.text} focusedTextColor={theme.accent} /> [+] Add {(e) => {e()}} 0}> Current sources ({feedStore.sources().length}): {(s) => ( {s.enabled ? "●" : "○"} {s.name} )} ); }