more theme color integration

This commit is contained in:
2026-02-10 15:10:07 -05:00
parent a405474f11
commit f707594d0c
18 changed files with 247 additions and 217 deletions

View File

@@ -1,6 +1,7 @@
import { Show } from "solid-js";
import type { SearchResult } from "@/types/source";
import { SourceBadge } from "./SourceBadge";
import { useTheme } from "@/context/ThemeContext";
type ResultCardProps = {
result: SearchResult;
@@ -10,6 +11,7 @@ type ResultCardProps = {
};
export function ResultCard(props: ResultCardProps) {
const { theme } = useTheme();
const podcast = () => props.result.podcast;
return (
@@ -17,8 +19,8 @@ export function ResultCard(props: ResultCardProps) {
flexDirection="column"
padding={1}
border={props.selected}
borderColor={props.selected ? "cyan" : undefined}
backgroundColor={props.selected ? "#222" : undefined}
borderColor={props.selected ? theme.primary : undefined}
backgroundColor={props.selected ? theme.backgroundElement : undefined}
onMouseDown={props.onSelect}
>
<box
@@ -27,9 +29,9 @@ export function ResultCard(props: ResultCardProps) {
alignItems="center"
>
<box flexDirection="row" gap={2} alignItems="center">
<text fg={props.selected ? "cyan" : "white"}>
<strong>{podcast().title}</strong>
</text>
<text fg={props.selected ? theme.primary : theme.text}>
<strong>{podcast().title}</strong>
</text>
<SourceBadge
sourceId={props.result.sourceId}
sourceName={props.result.sourceName}
@@ -37,17 +39,17 @@ export function ResultCard(props: ResultCardProps) {
/>
</box>
<Show when={podcast().isSubscribed}>
<text fg="green">[Subscribed]</text>
<text fg={theme.success}>[Subscribed]</text>
</Show>
</box>
<Show when={podcast().author}>
<text fg="gray">by {podcast().author}</text>
<text fg={theme.textMuted}>by {podcast().author}</text>
</Show>
<Show when={podcast().description}>
{(description) => (
<text fg={props.selected ? "white" : "gray"}>
<text fg={props.selected ? theme.text : theme.textMuted}>
{description().length > 120
? description().slice(0, 120) + "..."
: description()}
@@ -58,7 +60,7 @@ export function ResultCard(props: ResultCardProps) {
<Show when={(podcast().categories ?? []).length > 0}>
<box flexDirection="row" gap={1}>
{(podcast().categories ?? []).slice(0, 3).map((category) => (
<text fg="yellow">[{category}]</text>
<text fg={theme.warning}>[{category}]</text>
))}
</box>
</Show>
@@ -75,7 +77,7 @@ export function ResultCard(props: ResultCardProps) {
props.onSubscribe?.();
}}
>
<text fg="cyan">[+] Add to Feeds</text>
<text fg={theme.primary}>[+] Add to Feeds</text>
</box>
</Show>
</box>

View File

@@ -2,6 +2,7 @@ import { Show } from "solid-js";
import { format } from "date-fns";
import type { SearchResult } from "@/types/source";
import { SourceBadge } from "./SourceBadge";
import { useTheme } from "@/context/ThemeContext";
type ResultDetailProps = {
result?: SearchResult;
@@ -9,15 +10,16 @@ type ResultDetailProps = {
};
export function ResultDetail(props: ResultDetailProps) {
const { theme } = useTheme();
return (
<box flexDirection="column" border padding={1} gap={1} height="100%">
<box flexDirection="column" border padding={1} gap={1} height="100%" borderColor={theme.border}>
<Show
when={props.result}
fallback={<text fg="gray">Select a result to see details.</text>}
fallback={ <text fg={theme.textMuted}>Select a result to see details.</text>}
>
{(result) => (
<>
<text fg="white">
<text fg={theme.text}>
<strong>{result().podcast.title}</strong>
</text>
@@ -28,24 +30,24 @@ export function ResultDetail(props: ResultDetailProps) {
/>
<Show when={result().podcast.author}>
<text fg="gray">by {result().podcast.author}</text>
<text fg={theme.textMuted}>by {result().podcast.author}</text>
</Show>
<Show when={result().podcast.description}>
<text fg="gray">{result().podcast.description}</text>
<text fg={theme.textMuted}>{result().podcast.description}</text>
</Show>
<Show when={(result().podcast.categories ?? []).length > 0}>
<box flexDirection="row" gap={1}>
{(result().podcast.categories ?? []).map((category) => (
<text fg="yellow">[{category}]</text>
<text fg={theme.warning}>[{category}]</text>
))}
</box>
</Show>
<text fg="gray">Feed: {result().podcast.feedUrl}</text>
<text fg={theme.textMuted}>Feed: {result().podcast.feedUrl}</text>
<text fg="gray">
<text fg={theme.textMuted}>
Updated: {format(result().podcast.lastUpdated, "MMM d, yyyy")}
</text>
@@ -58,12 +60,12 @@ export function ResultDetail(props: ResultDetailProps) {
width={18}
onMouseDown={() => props.onSubscribe?.(result())}
>
<text fg="cyan">[+] Add to Feeds</text>
<text fg={theme.primary}>[+] Add to Feeds</text>
</box>
</Show>
<Show when={result().podcast.isSubscribed}>
<text fg="green">Already subscribed</text>
<text fg={theme.success}>Already subscribed</text>
</Show>
</>
)}

View File

@@ -3,6 +3,7 @@
*/
import { For, Show } from "solid-js"
import { useTheme } from "@/context/ThemeContext"
type SearchHistoryProps = {
history: string[]
@@ -15,6 +16,7 @@ type SearchHistoryProps = {
}
export function SearchHistory(props: SearchHistoryProps) {
const { theme } = useTheme();
const handleSearchClick = (index: number, query: string) => {
props.onChange?.(index)
props.onSelect?.(query)
@@ -27,19 +29,19 @@ export function SearchHistory(props: SearchHistoryProps) {
return (
<box flexDirection="column" gap={1}>
<box flexDirection="row" justifyContent="space-between">
<text fg="gray">Recent Searches</text>
<Show when={props.history.length > 0}>
<box onMouseDown={() => props.onClear?.()} padding={0}>
<text fg="red">[Clear All]</text>
</box>
</Show>
<text fg={theme.textMuted}>Recent Searches</text>
<Show when={props.history.length > 0}>
<box onMouseDown={() => props.onClear?.()} padding={0}>
<text fg={theme.error}>[Clear All]</text>
</box>
</Show>
</box>
<Show
when={props.history.length > 0}
fallback={
<box padding={1}>
<text fg="gray">No recent searches</text>
<text fg={theme.textMuted}>No recent searches</text>
</box>
}
>
@@ -56,15 +58,15 @@ export function SearchHistory(props: SearchHistoryProps) {
padding={0}
paddingLeft={1}
paddingRight={1}
backgroundColor={isSelected() ? "#333" : undefined}
backgroundColor={isSelected() ? theme.backgroundElement : undefined}
onMouseDown={() => handleSearchClick(index(), query)}
>
<box flexDirection="row" gap={1}>
<text fg="gray">{">"}</text>
<text fg={isSelected() ? "cyan" : "white"}>{query}</text>
<text fg={theme.textMuted}>{">"}</text>
<text fg={isSelected() ? theme.primary : theme.text}>{query}</text>
</box>
<box onMouseDown={() => handleRemoveClick(query)} padding={0}>
<text fg="red">[x]</text>
<text fg={theme.error}>[x]</text>
</box>
</box>
)

View File

@@ -1,4 +1,5 @@
import { SourceType } from "@/types/source";
import { useTheme } from "@/context/ThemeContext";
type SourceBadgeProps = {
sourceId: string;
@@ -14,21 +15,29 @@ const typeLabel = (sourceType?: SourceType) => {
};
const typeColor = (sourceType?: SourceType) => {
if (sourceType === SourceType.API) return "cyan";
if (sourceType === SourceType.RSS) return "green";
if (sourceType === SourceType.CUSTOM) return "yellow";
return "gray";
if (sourceType === SourceType.API) return theme.primary;
if (sourceType === SourceType.RSS) return theme.success;
if (sourceType === SourceType.CUSTOM) return theme.warning;
return theme.textMuted;
};
export function SourceBadge(props: SourceBadgeProps) {
const { theme } = useTheme();
const label = () => props.sourceName || props.sourceId;
const typeColor = (sourceType?: SourceType) => {
if (sourceType === SourceType.API) return theme.primary;
if (sourceType === SourceType.RSS) return theme.success;
if (sourceType === SourceType.CUSTOM) return theme.warning;
return theme.textMuted;
};
return (
<box flexDirection="row" gap={1} padding={0}>
<text fg={typeColor(props.sourceType)}>
[{typeLabel(props.sourceType)}]
</text>
<text fg="gray">{label()}</text>
<text fg={theme.textMuted}>{label()}</text>
</box>
);
}