more indication

This commit is contained in:
2026-02-20 22:42:15 -05:00
parent 1a5efceebd
commit 1e6618211a
5 changed files with 168 additions and 135 deletions

View File

@@ -43,13 +43,17 @@ export function DiscoverPage() {
<box <box
border border
padding={1} padding={1}
borderColor={theme.border} borderColor={
nav.activeDepth() != DiscoverPagePaneType.CATEGORIES
? theme.border
: theme.accent
}
flexDirection="column" flexDirection="column"
gap={1} gap={1}
> >
<text <text
fg={ fg={
nav.activeDepth == DiscoverPagePaneType.CATEGORIES nav.activeDepth() == DiscoverPagePaneType.CATEGORIES
? theme.accent ? theme.accent
: theme.text : theme.text
} }
@@ -76,61 +80,67 @@ export function DiscoverPage() {
</For> </For>
</box> </box>
</box> </box>
<box <box
flexDirection="column" flexDirection="column"
flexGrow={1} flexGrow={1}
border border
borderColor={theme.border} borderColor={
> nav.activeDepth() == DiscoverPagePaneType.SHOWS
<box padding={1}> ? theme.accent
<SelectableText : theme.border
selected={() => false} }
primary={nav.activeDepth == DiscoverPagePaneType.SHOWS} >
> <box padding={1}>
Trending in{" "} <SelectableText
{DISCOVER_CATEGORIES.find( selected={() => false}
(c) => c.id === discoverStore.selectedCategory(), primary={nav.activeDepth() == DiscoverPagePaneType.SHOWS}
)?.name ?? "All"} >
</SelectableText> Trending in{" "}
</box> {DISCOVER_CATEGORIES.find(
<box flexDirection="column" height="100%"> (c) => c.id === discoverStore.selectedCategory(),
<Show )?.name ?? "All"}
fallback={ </SelectableText>
<box padding={2}> </box>
{discoverStore.filteredPodcasts().length !== 0 ? ( <box flexDirection="column" height="100%">
<text fg={theme.warning}>Loading trending shows...</text> <Show
) : ( fallback={
<text fg={theme.textMuted}> <box padding={2}>
No podcasts found in this category. {discoverStore.filteredPodcasts().length !== 0 ? (
</text> <text fg={theme.warning}>Loading trending shows...</text>
)} ) : (
</box> <text fg={theme.textMuted}>
} No podcasts found in this category.
when={ </text>
!discoverStore.isLoading() &&
discoverStore.filteredPodcasts().length === 0
}
>
<scrollbox>
<box flexDirection="column">
<For each={discoverStore.filteredPodcasts()}>
{(podcast, index) => (
<PodcastCard
podcast={podcast}
selected={
index() === showIndex() &&
nav.activeDepth == DiscoverPagePaneType.SHOWS
}
onSelect={() => handleShowSelect(index())}
onSubscribe={() => handleSubscribe(podcast)}
/>
)} )}
</For> </box>
</box> }
</scrollbox> when={
</Show> !discoverStore.isLoading() &&
discoverStore.filteredPodcasts().length === 0
}
>
<scrollbox
focused={nav.activeDepth() == DiscoverPagePaneType.SHOWS}
>
<box flexDirection="column">
<For each={discoverStore.filteredPodcasts()}>
{(podcast, index) => (
<PodcastCard
podcast={podcast}
selected={
index() === showIndex() &&
nav.activeDepth() == DiscoverPagePaneType.SHOWS
}
onSelect={() => handleShowSelect(index())}
onSubscribe={() => handleSubscribe(podcast)}
/>
)}
</For>
</box>
</scrollbox>
</Show>
</box>
</box> </box>
</box>
</box> </box>
); );
} }

View File

@@ -129,8 +129,14 @@ export function MyShowsPage() {
} }
> >
<scrollbox <scrollbox
border
height="100%" height="100%"
focused={nav.activeDepth == MyShowsPaneType.SHOWS} borderColor={
nav.activeDepth() == MyShowsPaneType.SHOWS
? theme.accent
: theme.border
}
focused={nav.activeDepth() == MyShowsPaneType.SHOWS}
> >
<For each={shows()}> <For each={shows()}>
{(feed, index) => ( {(feed, index) => (
@@ -171,26 +177,32 @@ export function MyShowsPage() {
</Show> </Show>
</box> </box>
<box flexDirection="column" height="100%"> <box flexDirection="column" height="100%">
<Show
when={selectedShow()}
fallback={
<box padding={1}>
<text fg={theme.muted}>Select a show</text>
</box>
}
>
<Show <Show
when={episodes().length > 0} when={selectedShow()}
fallback={ fallback={
<box padding={1}> <box padding={1}>
<text fg={theme.muted}>No episodes. Press [r] to refresh.</text> <text fg={theme.muted}>Select a show</text>
</box> </box>
} }
> >
<scrollbox <Show
height="100%" when={episodes().length > 0}
focused={nav.activeDepth == MyShowsPaneType.EPISODES} fallback={
<box padding={1}>
<text fg={theme.muted}>No episodes. Press [r] to refresh.</text>
</box>
}
> >
<scrollbox
border
height="100%"
borderColor={
nav.activeDepth() == MyShowsPaneType.EPISODES
? theme.accent
: theme.border
}
focused={nav.activeDepth() == MyShowsPaneType.EPISODES}
>
<For each={episodes()}> <For each={episodes()}>
{(episode, index) => ( {(episode, index) => (
<box <box

View File

@@ -3,6 +3,7 @@ import { RealtimeWaveform } from "./RealtimeWaveform";
import { useAudio } from "@/hooks/useAudio"; import { useAudio } from "@/hooks/useAudio";
import { useAppStore } from "@/stores/app"; import { useAppStore } from "@/stores/app";
import { useTheme } from "@/context/ThemeContext"; import { useTheme } from "@/context/ThemeContext";
import { useNavigation } from "@/context/NavigationContext";
enum PlayerPaneType { enum PlayerPaneType {
PLAYER = 1, PLAYER = 1,
@@ -12,6 +13,7 @@ export const PlayerPaneCount = 1;
export function PlayerPage() { export function PlayerPage() {
const audio = useAudio(); const audio = useAudio();
const { theme } = useTheme(); const { theme } = useTheme();
const nav = useNavigation();
const progressPercent = () => { const progressPercent = () => {
const d = audio.duration(); const d = audio.duration();
@@ -41,7 +43,7 @@ export function PlayerPage() {
<box <box
border border
borderColor={theme.border} borderColor={nav.activeDepth() == PlayerPaneType.PLAYER ? theme.accent : theme.border}
padding={1} padding={1}
flexDirection="column" flexDirection="column"
gap={1} gap={1}

View File

@@ -69,7 +69,7 @@ export function SearchPage() {
setInputValue(value); setInputValue(value);
}} }}
placeholder="Enter podcast name, topic, or author..." placeholder="Enter podcast name, topic, or author..."
focused={nav.activeDepth === SearchPaneType.INPUT} focused={nav.activeDepth() === SearchPaneType.INPUT}
width={50} width={50}
/> />
<box <box
@@ -92,76 +92,80 @@ export function SearchPage() {
</Show> </Show>
</box> </box>
{/* Main Content - Results or History */} {/* Main Content - Results or History */}
<box flexDirection="row" height="100%" gap={2}> <box flexDirection="row" height="100%" gap={2}>
{/* Results Panel */} {/* Results Panel */}
<box <box
flexDirection="column" flexDirection="column"
flexGrow={1} flexGrow={1}
border border
borderColor={theme.border} borderColor={
> nav.activeDepth() === SearchPaneType.RESULTS
<box padding={1}> ? theme.accent
<text : theme.border
fg={
nav.activeDepth === SearchPaneType.RESULTS
? theme.primary
: theme.muted
}
>
Results ({searchStore.results().length})
</text>
</box>
<Show
when={searchStore.results().length > 0}
fallback={
<box padding={2}>
<text fg={theme.muted}>
{searchStore.query()
? "No results found"
: "Enter a search term to find podcasts"}
</text>
</box>
} }
> >
<SearchResults <box padding={1}>
results={searchStore.results()}
selectedIndex={resultIndex()}
focused={nav.activeDepth === SearchPaneType.RESULTS}
onSelect={handleResultSelect}
onChange={setResultIndex}
isSearching={searchStore.isSearching()}
error={searchStore.error()}
/>
</Show>
</box>
{/* History Sidebar */}
<box width={30} border borderColor={theme.border}>
<box padding={1} flexDirection="column">
<box paddingBottom={1}>
<text <text
fg={ fg={
nav.activeDepth === SearchPaneType.HISTORY nav.activeDepth() === SearchPaneType.RESULTS
? theme.primary ? theme.primary
: theme.muted : theme.muted
} }
> >
History Results ({searchStore.results().length})
</text> </text>
</box> </box>
<SearchHistory <Show
history={searchStore.history()} when={searchStore.results().length > 0}
selectedIndex={historyIndex()} fallback={
focused={nav.activeDepth === SearchPaneType.HISTORY} <box padding={2}>
onSelect={handleHistorySelect} <text fg={theme.muted}>
onRemove={searchStore.removeFromHistory} {searchStore.query()
onClear={searchStore.clearHistory} ? "No results found"
onChange={setHistoryIndex} : "Enter a search term to find podcasts"}
/> </text>
</box>
}
>
<SearchResults
results={searchStore.results()}
selectedIndex={resultIndex()}
focused={nav.activeDepth() === SearchPaneType.RESULTS}
onSelect={handleResultSelect}
onChange={setResultIndex}
isSearching={searchStore.isSearching()}
error={searchStore.error()}
/>
</Show>
</box>
{/* History Sidebar */}
<box width={30} border borderColor={theme.border}>
<box padding={1} flexDirection="column">
<box paddingBottom={1}>
<text
fg={
nav.activeDepth() === SearchPaneType.HISTORY
? theme.primary
: theme.muted
}
>
History
</text>
</box>
<SearchHistory
history={searchStore.history()}
selectedIndex={historyIndex()}
focused={nav.activeDepth() === SearchPaneType.HISTORY}
onSelect={handleHistorySelect}
onRemove={searchStore.removeFromHistory}
onClear={searchStore.clearHistory}
onChange={setHistoryIndex}
/>
</box>
</box> </box>
</box> </box>
</box>
</box> </box>
); );
} }

View File

@@ -28,6 +28,11 @@ export function SettingsPage() {
const { theme } = useTheme(); const { theme } = useTheme();
const nav = useNavigation(); const nav = useNavigation();
// Helper function to check if a depth is active
const isActive = (depth: SettingsPaneType): boolean => {
return nav.activeDepth() === depth;
};
return ( return (
<box flexDirection="column" gap={1} height="100%" width="100%"> <box flexDirection="column" gap={1} height="100%" width="100%">
<box flexDirection="row" gap={1}> <box flexDirection="row" gap={1}>
@@ -56,23 +61,23 @@ export function SettingsPage() {
<box <box
border border
borderColor={theme.border} borderColor={isActive(SettingsPaneType.SYNC) || isActive(SettingsPaneType.SOURCES) || isActive(SettingsPaneType.PREFERENCES) || isActive(SettingsPaneType.VISUALIZER) || isActive(SettingsPaneType.ACCOUNT) ? theme.accent : theme.border}
flexGrow={1} flexGrow={1}
padding={1} padding={1}
flexDirection="column" flexDirection="column"
gap={1} gap={1}
> >
{nav.activeDepth === SettingsPaneType.SYNC && <SyncPanel />} {isActive(SettingsPaneType.SYNC) && <SyncPanel />}
{nav.activeDepth === SettingsPaneType.SOURCES && ( {isActive(SettingsPaneType.SOURCES) && (
<SourceManager focused /> <SourceManager focused />
)} )}
{nav.activeDepth === SettingsPaneType.PREFERENCES && ( {isActive(SettingsPaneType.PREFERENCES) && (
<PreferencesPanel /> <PreferencesPanel />
)} )}
{nav.activeDepth === SettingsPaneType.VISUALIZER && ( {isActive(SettingsPaneType.VISUALIZER) && (
<VisualizerSettings /> <VisualizerSettings />
)} )}
{nav.activeDepth === SettingsPaneType.ACCOUNT && ( {isActive(SettingsPaneType.ACCOUNT) && (
<box flexDirection="column" gap={1}> <box flexDirection="column" gap={1}>
<text fg={theme.textMuted}>Account</text> <text fg={theme.textMuted}>Account</text>
</box> </box>