more indication
This commit is contained in:
@@ -43,13 +43,17 @@ export function DiscoverPage() {
|
||||
<box
|
||||
border
|
||||
padding={1}
|
||||
borderColor={theme.border}
|
||||
borderColor={
|
||||
nav.activeDepth() != DiscoverPagePaneType.CATEGORIES
|
||||
? theme.border
|
||||
: theme.accent
|
||||
}
|
||||
flexDirection="column"
|
||||
gap={1}
|
||||
>
|
||||
<text
|
||||
fg={
|
||||
nav.activeDepth == DiscoverPagePaneType.CATEGORIES
|
||||
nav.activeDepth() == DiscoverPagePaneType.CATEGORIES
|
||||
? theme.accent
|
||||
: theme.text
|
||||
}
|
||||
@@ -76,61 +80,67 @@ export function DiscoverPage() {
|
||||
</For>
|
||||
</box>
|
||||
</box>
|
||||
<box
|
||||
flexDirection="column"
|
||||
flexGrow={1}
|
||||
border
|
||||
borderColor={theme.border}
|
||||
>
|
||||
<box padding={1}>
|
||||
<SelectableText
|
||||
selected={() => false}
|
||||
primary={nav.activeDepth == DiscoverPagePaneType.SHOWS}
|
||||
>
|
||||
Trending in{" "}
|
||||
{DISCOVER_CATEGORIES.find(
|
||||
(c) => c.id === discoverStore.selectedCategory(),
|
||||
)?.name ?? "All"}
|
||||
</SelectableText>
|
||||
</box>
|
||||
<box flexDirection="column" height="100%">
|
||||
<Show
|
||||
fallback={
|
||||
<box padding={2}>
|
||||
{discoverStore.filteredPodcasts().length !== 0 ? (
|
||||
<text fg={theme.warning}>Loading trending shows...</text>
|
||||
) : (
|
||||
<text fg={theme.textMuted}>
|
||||
No podcasts found in this category.
|
||||
</text>
|
||||
)}
|
||||
</box>
|
||||
}
|
||||
when={
|
||||
!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)}
|
||||
/>
|
||||
<box
|
||||
flexDirection="column"
|
||||
flexGrow={1}
|
||||
border
|
||||
borderColor={
|
||||
nav.activeDepth() == DiscoverPagePaneType.SHOWS
|
||||
? theme.accent
|
||||
: theme.border
|
||||
}
|
||||
>
|
||||
<box padding={1}>
|
||||
<SelectableText
|
||||
selected={() => false}
|
||||
primary={nav.activeDepth() == DiscoverPagePaneType.SHOWS}
|
||||
>
|
||||
Trending in{" "}
|
||||
{DISCOVER_CATEGORIES.find(
|
||||
(c) => c.id === discoverStore.selectedCategory(),
|
||||
)?.name ?? "All"}
|
||||
</SelectableText>
|
||||
</box>
|
||||
<box flexDirection="column" height="100%">
|
||||
<Show
|
||||
fallback={
|
||||
<box padding={2}>
|
||||
{discoverStore.filteredPodcasts().length !== 0 ? (
|
||||
<text fg={theme.warning}>Loading trending shows...</text>
|
||||
) : (
|
||||
<text fg={theme.textMuted}>
|
||||
No podcasts found in this category.
|
||||
</text>
|
||||
)}
|
||||
</For>
|
||||
</box>
|
||||
</scrollbox>
|
||||
</Show>
|
||||
</box>
|
||||
}
|
||||
when={
|
||||
!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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -129,8 +129,14 @@ export function MyShowsPage() {
|
||||
}
|
||||
>
|
||||
<scrollbox
|
||||
border
|
||||
height="100%"
|
||||
focused={nav.activeDepth == MyShowsPaneType.SHOWS}
|
||||
borderColor={
|
||||
nav.activeDepth() == MyShowsPaneType.SHOWS
|
||||
? theme.accent
|
||||
: theme.border
|
||||
}
|
||||
focused={nav.activeDepth() == MyShowsPaneType.SHOWS}
|
||||
>
|
||||
<For each={shows()}>
|
||||
{(feed, index) => (
|
||||
@@ -171,26 +177,32 @@ export function MyShowsPage() {
|
||||
</Show>
|
||||
</box>
|
||||
<box flexDirection="column" height="100%">
|
||||
<Show
|
||||
when={selectedShow()}
|
||||
fallback={
|
||||
<box padding={1}>
|
||||
<text fg={theme.muted}>Select a show</text>
|
||||
</box>
|
||||
}
|
||||
>
|
||||
<Show
|
||||
when={episodes().length > 0}
|
||||
when={selectedShow()}
|
||||
fallback={
|
||||
<box padding={1}>
|
||||
<text fg={theme.muted}>No episodes. Press [r] to refresh.</text>
|
||||
<text fg={theme.muted}>Select a show</text>
|
||||
</box>
|
||||
}
|
||||
>
|
||||
<scrollbox
|
||||
height="100%"
|
||||
focused={nav.activeDepth == MyShowsPaneType.EPISODES}
|
||||
<Show
|
||||
when={episodes().length > 0}
|
||||
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()}>
|
||||
{(episode, index) => (
|
||||
<box
|
||||
|
||||
@@ -3,6 +3,7 @@ import { RealtimeWaveform } from "./RealtimeWaveform";
|
||||
import { useAudio } from "@/hooks/useAudio";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import { useTheme } from "@/context/ThemeContext";
|
||||
import { useNavigation } from "@/context/NavigationContext";
|
||||
|
||||
enum PlayerPaneType {
|
||||
PLAYER = 1,
|
||||
@@ -12,6 +13,7 @@ export const PlayerPaneCount = 1;
|
||||
export function PlayerPage() {
|
||||
const audio = useAudio();
|
||||
const { theme } = useTheme();
|
||||
const nav = useNavigation();
|
||||
|
||||
const progressPercent = () => {
|
||||
const d = audio.duration();
|
||||
@@ -41,7 +43,7 @@ export function PlayerPage() {
|
||||
|
||||
<box
|
||||
border
|
||||
borderColor={theme.border}
|
||||
borderColor={nav.activeDepth() == PlayerPaneType.PLAYER ? theme.accent : theme.border}
|
||||
padding={1}
|
||||
flexDirection="column"
|
||||
gap={1}
|
||||
|
||||
@@ -69,7 +69,7 @@ export function SearchPage() {
|
||||
setInputValue(value);
|
||||
}}
|
||||
placeholder="Enter podcast name, topic, or author..."
|
||||
focused={nav.activeDepth === SearchPaneType.INPUT}
|
||||
focused={nav.activeDepth() === SearchPaneType.INPUT}
|
||||
width={50}
|
||||
/>
|
||||
<box
|
||||
@@ -92,76 +92,80 @@ export function SearchPage() {
|
||||
</Show>
|
||||
</box>
|
||||
|
||||
{/* Main Content - Results or History */}
|
||||
<box flexDirection="row" height="100%" gap={2}>
|
||||
{/* Results Panel */}
|
||||
<box
|
||||
flexDirection="column"
|
||||
flexGrow={1}
|
||||
border
|
||||
borderColor={theme.border}
|
||||
>
|
||||
<box padding={1}>
|
||||
<text
|
||||
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>
|
||||
{/* Main Content - Results or History */}
|
||||
<box flexDirection="row" height="100%" gap={2}>
|
||||
{/* Results Panel */}
|
||||
<box
|
||||
flexDirection="column"
|
||||
flexGrow={1}
|
||||
border
|
||||
borderColor={
|
||||
nav.activeDepth() === SearchPaneType.RESULTS
|
||||
? theme.accent
|
||||
: theme.border
|
||||
}
|
||||
>
|
||||
<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}>
|
||||
<box padding={1}>
|
||||
<text
|
||||
fg={
|
||||
nav.activeDepth === SearchPaneType.HISTORY
|
||||
nav.activeDepth() === SearchPaneType.RESULTS
|
||||
? theme.primary
|
||||
: theme.muted
|
||||
}
|
||||
>
|
||||
History
|
||||
Results ({searchStore.results().length})
|
||||
</text>
|
||||
</box>
|
||||
<SearchHistory
|
||||
history={searchStore.history()}
|
||||
selectedIndex={historyIndex()}
|
||||
focused={nav.activeDepth === SearchPaneType.HISTORY}
|
||||
onSelect={handleHistorySelect}
|
||||
onRemove={searchStore.removeFromHistory}
|
||||
onClear={searchStore.clearHistory}
|
||||
onChange={setHistoryIndex}
|
||||
/>
|
||||
<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
|
||||
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>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,11 @@ export function SettingsPage() {
|
||||
const { theme } = useTheme();
|
||||
const nav = useNavigation();
|
||||
|
||||
// Helper function to check if a depth is active
|
||||
const isActive = (depth: SettingsPaneType): boolean => {
|
||||
return nav.activeDepth() === depth;
|
||||
};
|
||||
|
||||
return (
|
||||
<box flexDirection="column" gap={1} height="100%" width="100%">
|
||||
<box flexDirection="row" gap={1}>
|
||||
@@ -56,23 +61,23 @@ export function SettingsPage() {
|
||||
|
||||
<box
|
||||
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}
|
||||
padding={1}
|
||||
flexDirection="column"
|
||||
gap={1}
|
||||
>
|
||||
{nav.activeDepth === SettingsPaneType.SYNC && <SyncPanel />}
|
||||
{nav.activeDepth === SettingsPaneType.SOURCES && (
|
||||
{isActive(SettingsPaneType.SYNC) && <SyncPanel />}
|
||||
{isActive(SettingsPaneType.SOURCES) && (
|
||||
<SourceManager focused />
|
||||
)}
|
||||
{nav.activeDepth === SettingsPaneType.PREFERENCES && (
|
||||
{isActive(SettingsPaneType.PREFERENCES) && (
|
||||
<PreferencesPanel />
|
||||
)}
|
||||
{nav.activeDepth === SettingsPaneType.VISUALIZER && (
|
||||
{isActive(SettingsPaneType.VISUALIZER) && (
|
||||
<VisualizerSettings />
|
||||
)}
|
||||
{nav.activeDepth === SettingsPaneType.ACCOUNT && (
|
||||
{isActive(SettingsPaneType.ACCOUNT) && (
|
||||
<box flexDirection="column" gap={1}>
|
||||
<text fg={theme.textMuted}>Account</text>
|
||||
</box>
|
||||
|
||||
Reference in New Issue
Block a user