This commit is contained in:
Michael Freno
2026-02-04 11:24:19 -05:00
parent 4cee352641
commit 9b1a3585e6

View File

@@ -1,45 +1,47 @@
import { createSignal } from "solid-js" import { createSignal } from "solid-js";
import { Layout } from "./components/Layout" import { Layout } from "./components/Layout";
import { Navigation } from "./components/Navigation" import { Navigation } from "./components/Navigation";
import { TabNavigation } from "./components/TabNavigation" import { TabNavigation } from "./components/TabNavigation";
import { SyncPanel } from "./components/SyncPanel" import { SyncPanel } from "./components/SyncPanel";
import { FeedList } from "./components/FeedList" import { FeedList } from "./components/FeedList";
import { LoginScreen } from "./components/LoginScreen" import { LoginScreen } from "./components/LoginScreen";
import { CodeValidation } from "./components/CodeValidation" import { CodeValidation } from "./components/CodeValidation";
import { OAuthPlaceholder } from "./components/OAuthPlaceholder" import { OAuthPlaceholder } from "./components/OAuthPlaceholder";
import { SyncProfile } from "./components/SyncProfile" import { SyncProfile } from "./components/SyncProfile";
import { SearchPage } from "./components/SearchPage" import { SearchPage } from "./components/SearchPage";
import { DiscoverPage } from "./components/DiscoverPage" import { DiscoverPage } from "./components/DiscoverPage";
import { useAuthStore } from "./stores/auth" import { useAuthStore } from "./stores/auth";
import { useFeedStore } from "./stores/feed" import { useFeedStore } from "./stores/feed";
import { FeedVisibility } from "./types/feed" import { FeedVisibility } from "./types/feed";
import { useAppKeyboard } from "./hooks/useAppKeyboard" import { useAppKeyboard } from "./hooks/useAppKeyboard";
import type { TabId } from "./components/Tab" import type { TabId } from "./components/Tab";
import type { AuthScreen } from "./types/auth" import type { AuthScreen } from "./types/auth";
export function App() { export function App() {
const [activeTab, setActiveTab] = createSignal<TabId>("discover") const [activeTab, setActiveTab] = createSignal<TabId>("settings");
const [authScreen, setAuthScreen] = createSignal<AuthScreen>("login") const [authScreen, setAuthScreen] = createSignal<AuthScreen>("login");
const [showAuthPanel, setShowAuthPanel] = createSignal(false) const [showAuthPanel, setShowAuthPanel] = createSignal(false);
const [inputFocused, setInputFocused] = createSignal(false) const [inputFocused, setInputFocused] = createSignal(false);
const auth = useAuthStore() const auth = useAuthStore();
const feedStore = useFeedStore() const feedStore = useFeedStore();
// Centralized keyboard handler for all tab navigation and shortcuts // Centralized keyboard handler for all tab navigation and shortcuts
useAppKeyboard({ useAppKeyboard({
get activeTab() { return activeTab() }, get activeTab() {
return activeTab();
},
onTabChange: setActiveTab, onTabChange: setActiveTab,
inputFocused: inputFocused(), inputFocused: inputFocused(),
onAction: (action) => { onAction: (action) => {
if (action === "escape") { if (action === "escape") {
setShowAuthPanel(false) setShowAuthPanel(false);
setInputFocused(false) setInputFocused(false);
} }
}, },
}) });
const renderContent = () => { const renderContent = () => {
const tab = activeTab() const tab = activeTab();
switch (tab) { switch (tab) {
case "feeds": case "feeds":
@@ -52,7 +54,7 @@ export function App() {
// Would open feed detail view // Would open feed detail view
}} }}
/> />
) );
case "settings": case "settings":
// Show auth panel or sync panel based on state // Show auth panel or sync panel based on state
@@ -62,12 +64,12 @@ export function App() {
<SyncProfile <SyncProfile
focused={true} focused={true}
onLogout={() => { onLogout={() => {
auth.logout() auth.logout();
setShowAuthPanel(false) setShowAuthPanel(false);
}} }}
onManageSync={() => setShowAuthPanel(false)} onManageSync={() => setShowAuthPanel(false)}
/> />
) );
} }
switch (authScreen()) { switch (authScreen()) {
@@ -77,7 +79,7 @@ export function App() {
focused={true} focused={true}
onBack={() => setAuthScreen("login")} onBack={() => setAuthScreen("login")}
/> />
) );
case "oauth": case "oauth":
return ( return (
<OAuthPlaceholder <OAuthPlaceholder
@@ -85,7 +87,7 @@ export function App() {
onBack={() => setAuthScreen("login")} onBack={() => setAuthScreen("login")}
onNavigateToCode={() => setAuthScreen("code")} onNavigateToCode={() => setAuthScreen("code")}
/> />
) );
case "login": case "login":
default: default:
return ( return (
@@ -94,7 +96,7 @@ export function App() {
onNavigateToCode={() => setAuthScreen("code")} onNavigateToCode={() => setAuthScreen("code")}
onNavigateToOAuth={() => setAuthScreen("oauth")} onNavigateToOAuth={() => setAuthScreen("oauth")}
/> />
) );
} }
} }
@@ -122,12 +124,10 @@ export function App() {
</box> </box>
</box> </box>
</box> </box>
) );
case "discover": case "discover":
return ( return <DiscoverPage focused={!inputFocused()} />;
<DiscoverPage focused={!inputFocused()} />
)
case "search": case "search":
return ( return (
@@ -135,23 +135,23 @@ export function App() {
focused={!inputFocused()} focused={!inputFocused()}
onInputFocusChange={setInputFocused} onInputFocusChange={setInputFocused}
onSubscribe={(result) => { onSubscribe={(result) => {
const feeds = feedStore.feeds() const feeds = feedStore.feeds();
const alreadySubscribed = feeds.some( const alreadySubscribed = feeds.some(
(feed) => (feed) =>
feed.podcast.id === result.podcast.id || feed.podcast.id === result.podcast.id ||
feed.podcast.feedUrl === result.podcast.feedUrl feed.podcast.feedUrl === result.podcast.feedUrl,
) );
if (!alreadySubscribed) { if (!alreadySubscribed) {
feedStore.addFeed( feedStore.addFeed(
{ ...result.podcast, isSubscribed: true }, { ...result.podcast, isSubscribed: true },
result.sourceId, result.sourceId,
FeedVisibility.PUBLIC FeedVisibility.PUBLIC,
) );
} }
}} }}
/> />
) );
case "player": case "player":
default: default:
@@ -163,20 +163,18 @@ export function App() {
Player - coming in later phases Player - coming in later phases
</text> </text>
</box> </box>
) );
} }
} };
return ( return (
<Layout <Layout
header={ header={
<TabNavigation activeTab={activeTab()} onTabSelect={setActiveTab} /> <TabNavigation activeTab={activeTab()} onTabSelect={setActiveTab} />
} }
footer={ footer={<Navigation activeTab={activeTab()} onTabSelect={setActiveTab} />}
<Navigation activeTab={activeTab()} onTabSelect={setActiveTab} />
}
> >
<box style={{ padding: 1 }}>{renderContent()}</box> <box style={{ padding: 1 }}>{renderContent()}</box>
</Layout> </Layout>
) );
} }