better themeing
This commit is contained in:
@@ -13,6 +13,7 @@ import { format } from "date-fns";
|
||||
import type { Episode } from "@/types/episode";
|
||||
import type { Feed } from "@/types/feed";
|
||||
import { PageProps } from "@/App";
|
||||
import { useTheme } from "@/context/ThemeContext";
|
||||
|
||||
enum MyShowsPaneType {
|
||||
SHOWS = 1,
|
||||
@@ -27,6 +28,8 @@ export function MyShowsPage(props: PageProps) {
|
||||
const [showIndex, setShowIndex] = createSignal(0);
|
||||
const [episodeIndex, setEpisodeIndex] = createSignal(0);
|
||||
const [isRefreshing, setIsRefreshing] = createSignal(false);
|
||||
const { theme } = useTheme();
|
||||
const mutedColor = () => theme.muted || theme.text;
|
||||
|
||||
/** Threshold: load more when within this many items of the end */
|
||||
const LOAD_MORE_THRESHOLD = 5;
|
||||
@@ -94,23 +97,6 @@ export function MyShowsPage(props: PageProps) {
|
||||
}
|
||||
};
|
||||
|
||||
/** Get download status color */
|
||||
const downloadColor = (episodeId: string): string => {
|
||||
const status = downloadStore.getDownloadStatus(episodeId);
|
||||
switch (status) {
|
||||
case DownloadStatus.QUEUED:
|
||||
return "yellow";
|
||||
case DownloadStatus.DOWNLOADING:
|
||||
return "cyan";
|
||||
case DownloadStatus.COMPLETED:
|
||||
return "green";
|
||||
case DownloadStatus.FAILED:
|
||||
return "red";
|
||||
default:
|
||||
return "gray";
|
||||
}
|
||||
};
|
||||
|
||||
const handleRefresh = async () => {
|
||||
const show = selectedShow();
|
||||
if (!show) return;
|
||||
@@ -127,17 +113,34 @@ export function MyShowsPage(props: PageProps) {
|
||||
setEpisodeIndex(0);
|
||||
};
|
||||
|
||||
/** Get download status color */
|
||||
const downloadColor = (episodeId: string): string => {
|
||||
const status = downloadStore.getDownloadStatus(episodeId);
|
||||
switch (status) {
|
||||
case DownloadStatus.QUEUED:
|
||||
return theme.warning.toString();
|
||||
case DownloadStatus.DOWNLOADING:
|
||||
return theme.primary.toString();
|
||||
case DownloadStatus.COMPLETED:
|
||||
return theme.success.toString();
|
||||
case DownloadStatus.FAILED:
|
||||
return theme.error.toString();
|
||||
default:
|
||||
return mutedColor().toString();
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<box flexDirection="row" flexGrow={1} width="100%">
|
||||
<box flexDirection="column" height="100%">
|
||||
<Show when={isRefreshing()}>
|
||||
<text fg="yellow">Refreshing...</text>
|
||||
<text fg={theme.warning}>Refreshing...</text>
|
||||
</Show>
|
||||
<Show
|
||||
when={shows().length > 0}
|
||||
fallback={
|
||||
<box padding={1}>
|
||||
<text fg="gray">
|
||||
<text fg={theme.muted}>
|
||||
No shows yet. Subscribe from Discover or Search.
|
||||
</text>
|
||||
</box>
|
||||
@@ -154,19 +157,19 @@ export function MyShowsPage(props: PageProps) {
|
||||
gap={1}
|
||||
paddingLeft={1}
|
||||
paddingRight={1}
|
||||
backgroundColor={index() === showIndex() ? "#333" : undefined}
|
||||
backgroundColor={index() === showIndex() ? theme.primary : undefined}
|
||||
onMouseDown={() => {
|
||||
setShowIndex(index());
|
||||
setEpisodeIndex(0);
|
||||
}}
|
||||
>
|
||||
<text fg={index() === showIndex() ? "cyan" : "gray"}>
|
||||
<text fg={index() === showIndex() ? theme.primary : theme.muted}>
|
||||
{index() === showIndex() ? ">" : " "}
|
||||
</text>
|
||||
<text fg={index() === showIndex() ? "white" : undefined}>
|
||||
<text fg={index() === showIndex() ? theme.text : undefined}>
|
||||
{feed.customName || feed.podcast.title}
|
||||
</text>
|
||||
<text fg="gray">({feed.episodes.length})</text>
|
||||
<text fg={theme.muted}>({feed.episodes.length})</text>
|
||||
</box>
|
||||
)}
|
||||
</For>
|
||||
@@ -178,7 +181,7 @@ export function MyShowsPage(props: PageProps) {
|
||||
when={selectedShow()}
|
||||
fallback={
|
||||
<box padding={1}>
|
||||
<text fg="gray">Select a show</text>
|
||||
<text fg={theme.muted}>Select a show</text>
|
||||
</box>
|
||||
}
|
||||
>
|
||||
@@ -186,7 +189,7 @@ export function MyShowsPage(props: PageProps) {
|
||||
when={episodes().length > 0}
|
||||
fallback={
|
||||
<box padding={1}>
|
||||
<text fg="gray">No episodes. Press [r] to refresh.</text>
|
||||
<text fg={theme.muted}>No episodes. Press [r] to refresh.</text>
|
||||
</box>
|
||||
}
|
||||
>
|
||||
@@ -202,16 +205,16 @@ export function MyShowsPage(props: PageProps) {
|
||||
paddingLeft={1}
|
||||
paddingRight={1}
|
||||
backgroundColor={
|
||||
index() === episodeIndex() ? "#333" : undefined
|
||||
index() === episodeIndex() ? theme.primary : undefined
|
||||
}
|
||||
onMouseDown={() => setEpisodeIndex(index())}
|
||||
>
|
||||
<box flexDirection="row" gap={1}>
|
||||
<text fg={index() === episodeIndex() ? "cyan" : "gray"}>
|
||||
<text fg={index() === episodeIndex() ? theme.primary : theme.muted}>
|
||||
{index() === episodeIndex() ? ">" : " "}
|
||||
</text>
|
||||
<text
|
||||
fg={index() === episodeIndex() ? "white" : undefined}
|
||||
fg={index() === episodeIndex() ? theme.text : undefined}
|
||||
>
|
||||
{episode.episodeNumber
|
||||
? `#${episode.episodeNumber} `
|
||||
@@ -220,8 +223,8 @@ export function MyShowsPage(props: PageProps) {
|
||||
</text>
|
||||
</box>
|
||||
<box flexDirection="row" gap={2} paddingLeft={2}>
|
||||
<text fg="gray">{formatDate(episode.pubDate)}</text>
|
||||
<text fg="gray">{formatDuration(episode.duration)}</text>
|
||||
<text fg={theme.muted}>{formatDate(episode.pubDate)}</text>
|
||||
<text fg={theme.muted}>{formatDuration(episode.duration)}</text>
|
||||
<Show when={downloadLabel(episode.id)}>
|
||||
<text fg={downloadColor(episode.id)}>
|
||||
{downloadLabel(episode.id)}
|
||||
@@ -233,7 +236,7 @@ export function MyShowsPage(props: PageProps) {
|
||||
</For>
|
||||
<Show when={feedStore.isLoadingMore()}>
|
||||
<box paddingLeft={2} paddingTop={1}>
|
||||
<text fg="yellow">Loading more episodes...</text>
|
||||
<text fg={theme.warning}>Loading more episodes...</text>
|
||||
</box>
|
||||
</Show>
|
||||
<Show
|
||||
@@ -244,7 +247,7 @@ export function MyShowsPage(props: PageProps) {
|
||||
}
|
||||
>
|
||||
<box paddingLeft={2} paddingTop={1}>
|
||||
<text fg="gray">Scroll down for more episodes</text>
|
||||
<text fg={theme.muted}>Scroll down for more episodes</text>
|
||||
</box>
|
||||
</Show>
|
||||
</scrollbox>
|
||||
|
||||
@@ -3,6 +3,7 @@ import { PlaybackControls } from "./PlaybackControls";
|
||||
import { RealtimeWaveform } from "./RealtimeWaveform";
|
||||
import { useAudio } from "@/hooks/useAudio";
|
||||
import { useAppStore } from "@/stores/app";
|
||||
import { useTheme } from "@/context/ThemeContext";
|
||||
|
||||
enum PlayerPaneType {
|
||||
PLAYER = 1,
|
||||
@@ -11,6 +12,7 @@ export const PlayerPaneCount = 1;
|
||||
|
||||
export function PlayerPage(props: PageProps) {
|
||||
const audio = useAudio();
|
||||
const { theme } = useTheme();
|
||||
|
||||
const progressPercent = () => {
|
||||
const d = audio.duration();
|
||||
@@ -30,19 +32,19 @@ export function PlayerPage(props: PageProps) {
|
||||
<text>
|
||||
<strong>Now Playing</strong>
|
||||
</text>
|
||||
<text fg="gray">
|
||||
<text fg={theme.muted}>
|
||||
{formatTime(audio.position())} / {formatTime(audio.duration())} (
|
||||
{progressPercent()}%)
|
||||
</text>
|
||||
</box>
|
||||
|
||||
{audio.error() && <text fg="red">{audio.error()}</text>}
|
||||
{audio.error() && <text fg={theme.error}>{audio.error()}</text>}
|
||||
|
||||
<box border padding={1} flexDirection="column" gap={1}>
|
||||
<text fg="white">
|
||||
<text fg={theme.text}>
|
||||
<strong>{audio.currentEpisode()?.title}</strong>
|
||||
</text>
|
||||
<text fg="gray">{audio.currentEpisode()?.description}</text>
|
||||
<text fg={theme.muted}>{audio.currentEpisode()?.description}</text>
|
||||
|
||||
<RealtimeWaveform
|
||||
visualizerConfig={(() => {
|
||||
|
||||
@@ -10,6 +10,7 @@ import { SearchHistory } from "./SearchHistory";
|
||||
import type { SearchResult } from "@/types/source";
|
||||
import { PageProps } from "@/App";
|
||||
import { MyShowsPage } from "../MyShows/MyShowsPage";
|
||||
import { useTheme } from "@/context/ThemeContext";
|
||||
|
||||
enum SearchPaneType {
|
||||
INPUT = 1,
|
||||
@@ -23,6 +24,7 @@ export function SearchPage(props: PageProps) {
|
||||
const [inputValue, setInputValue] = createSignal("");
|
||||
const [resultIndex, setResultIndex] = createSignal(0);
|
||||
const [historyIndex, setHistoryIndex] = createSignal(0);
|
||||
const { theme } = useTheme();
|
||||
|
||||
// Keep parent informed about input focus state
|
||||
// TODO: have a global input focused prop in useKeyboard hook
|
||||
@@ -83,16 +85,16 @@ export function SearchPage(props: PageProps) {
|
||||
paddingRight={1}
|
||||
onMouseDown={handleSearch}
|
||||
>
|
||||
<text fg="cyan">[Enter] Search</text>
|
||||
<text fg={theme.primary}>[Enter] Search</text>
|
||||
</box>
|
||||
</box>
|
||||
|
||||
{/* Status */}
|
||||
<Show when={searchStore.isSearching()}>
|
||||
<text fg="yellow">Searching...</text>
|
||||
<text fg={theme.warning}>Searching...</text>
|
||||
</Show>
|
||||
<Show when={searchStore.error()}>
|
||||
<text fg="red">{searchStore.error()}</text>
|
||||
<text fg={theme.error}>{searchStore.error()}</text>
|
||||
</Show>
|
||||
</box>
|
||||
|
||||
@@ -102,7 +104,7 @@ export function SearchPage(props: PageProps) {
|
||||
<box flexDirection="column" flexGrow={1} border>
|
||||
<box padding={1}>
|
||||
<text
|
||||
fg={props.depth() === SearchPaneType.RESULTS ? "cyan" : "gray"}
|
||||
fg={props.depth() === SearchPaneType.RESULTS ? theme.primary : theme.muted}
|
||||
>
|
||||
Results ({searchStore.results().length})
|
||||
</text>
|
||||
@@ -111,7 +113,7 @@ export function SearchPage(props: PageProps) {
|
||||
when={searchStore.results().length > 0}
|
||||
fallback={
|
||||
<box padding={2}>
|
||||
<text fg="gray">
|
||||
<text fg={theme.muted}>
|
||||
{searchStore.query()
|
||||
? "No results found"
|
||||
: "Enter a search term to find podcasts"}
|
||||
@@ -136,7 +138,7 @@ export function SearchPage(props: PageProps) {
|
||||
<box padding={1} flexDirection="column">
|
||||
<box paddingBottom={1}>
|
||||
<text
|
||||
fg={props.depth() === SearchPaneType.HISTORY ? "cyan" : "gray"}
|
||||
fg={props.depth() === SearchPaneType.HISTORY ? theme.primary : theme.muted}
|
||||
>
|
||||
History
|
||||
</text>
|
||||
|
||||
Reference in New Issue
Block a user