diff --git a/src/components/Selectable.tsx b/src/components/Selectable.tsx
index 3a590e9..690ca89 100644
--- a/src/components/Selectable.tsx
+++ b/src/components/Selectable.tsx
@@ -6,7 +6,11 @@ export function SelectableBox({
selected,
children,
...props
-}: { selected: () => boolean; children: JSXElement } & BoxOptions) {
+}: {
+ selected: () => boolean;
+
+ children: JSXElement;
+} & BoxOptions) {
const { theme } = useTheme();
return (
@@ -21,18 +25,54 @@ export function SelectableBox({
);
}
+enum ColorSet {
+ PRIMARY,
+ SECONDARY,
+ TERTIARY,
+ DEFAULT,
+}
+function getTextColor(set: ColorSet, selected: () => boolean) {
+ const { theme } = useTheme();
+ switch (set) {
+ case ColorSet.PRIMARY:
+ return selected() ? theme.textSelectedPrimary : theme.textPrimary;
+ case ColorSet.SECONDARY:
+ return selected() ? theme.textSelectedSecondary : theme.textSecondary;
+ case ColorSet.TERTIARY:
+ return selected() ? theme.textSelectedTertiary : theme.textTertiary;
+ default:
+ return theme.textPrimary;
+ }
+}
+
export function SelectableText({
selected,
children,
+ primary,
+ secondary,
+ tertiary,
...props
}: {
selected: () => boolean;
+ primary?: boolean;
+ secondary?: boolean;
+ tertiary?: boolean;
children: JSXElement;
} & TextOptions) {
- const { theme } = useTheme();
-
return (
-
+
{children}
);
diff --git a/src/context/ThemeContext.tsx b/src/context/ThemeContext.tsx
index 866ca48..28805a9 100644
--- a/src/context/ThemeContext.tsx
+++ b/src/context/ThemeContext.tsx
@@ -22,7 +22,7 @@ import {
type TerminalColors,
} from "@opentui/core";
-type ThemeResolved = {
+export type ThemeResolved = {
primary: RGBA;
secondary: RGBA;
accent: RGBA;
@@ -32,7 +32,13 @@ type ThemeResolved = {
info: RGBA;
text: RGBA;
textMuted: RGBA;
- selectedListItemText: RGBA;
+ textPrimary: RGBA;
+ textSecondary: RGBA;
+ textTertiary: RGBA;
+ textSelectedPrimary: RGBA;
+ textSelectedSecondary: RGBA;
+ textSelectedTertiary: RGBA;
+
background: RGBA;
backgroundPanel: RGBA;
backgroundElement: RGBA;
@@ -77,6 +83,7 @@ type ThemeResolved = {
syntaxPunctuation: RGBA;
muted?: RGBA;
surface?: RGBA;
+ selectedListItemText?: RGBA;
layerBackgrounds?: {
layer0: RGBA;
layer1: RGBA;
diff --git a/src/pages/Discover/PodcastCard.tsx b/src/pages/Discover/PodcastCard.tsx
index 3061018..6150806 100644
--- a/src/pages/Discover/PodcastCard.tsx
+++ b/src/pages/Discover/PodcastCard.tsx
@@ -29,7 +29,7 @@ export function PodcastCard(props: PodcastCardProps) {
onMouseDown={props.onSelect}
>
- props.selected}>
+ props.selected} primary>
{props.podcast.title}
@@ -42,7 +42,7 @@ export function PodcastCard(props: PodcastCardProps) {
props.selected}
- fg={theme.textMuted}
+ tertiary
>
by {props.podcast.author}
@@ -52,7 +52,7 @@ export function PodcastCard(props: PodcastCardProps) {
props.selected}
- fg={theme.text}
+ tertiary
>
{props.podcast.description!.length > 80
? props.podcast.description!.slice(0, 80) + "..."
diff --git a/src/pages/Feed/FeedItem.tsx b/src/pages/Feed/FeedItem.tsx
index d4bced8..c9880ac 100644
--- a/src/pages/Feed/FeedItem.tsx
+++ b/src/pages/Feed/FeedItem.tsx
@@ -54,26 +54,26 @@ export function FeedItem(props: FeedItemProps) {
>
props.isSelected}
- fg={theme.primary}
+ primary
>
{props.isSelected ? ">" : " "}
props.isSelected}
- fg={visibilityColor()}
+ tertiary
>
{visibilityIcon()}
props.isSelected}
- fg={theme.text}
+ primary
>
{props.feed.customName || props.feed.podcast.title}
{props.showEpisodeCount && (
props.isSelected}
- fg={theme.textMuted}
+ tertiary
>
({episodeCount()})
@@ -95,25 +95,25 @@ export function FeedItem(props: FeedItemProps) {
props.isSelected}
- fg={theme.primary}
+ primary
>
{props.isSelected ? ">" : " "}
props.isSelected}
- fg={visibilityColor()}
+ tertiary
>
{visibilityIcon()}
props.isSelected}
- fg={theme.warning}
+ secondary
>
{pinnedIndicator()}
props.isSelected}
- fg={theme.text}
+ primary
>
{props.feed.customName || props.feed.podcast.title}
@@ -123,7 +123,7 @@ export function FeedItem(props: FeedItemProps) {
{props.showEpisodeCount && (
props.isSelected}
- fg={theme.textMuted}
+ tertiary
>
{episodeCount()} episodes ({unplayedCount()} new)
@@ -131,7 +131,7 @@ export function FeedItem(props: FeedItemProps) {
{props.showLastUpdated && (
props.isSelected}
- fg={theme.textMuted}
+ tertiary
>
Updated: {formatDate(props.feed.lastUpdated)}
@@ -143,7 +143,7 @@ export function FeedItem(props: FeedItemProps) {
selected={() => props.isSelected}
paddingLeft={4}
paddingTop={0}
- fg={theme.textMuted}
+ tertiary
>
{props.feed.podcast.description.slice(0, 60)}
{props.feed.podcast.description.length > 60 ? "..." : ""}
diff --git a/src/pages/Feed/FeedPage.tsx b/src/pages/Feed/FeedPage.tsx
index 1b1aee4..0d7173e 100644
--- a/src/pages/Feed/FeedPage.tsx
+++ b/src/pages/Feed/FeedPage.tsx
@@ -80,9 +80,9 @@ export function FeedPage(props: PageProps) {
b.localeCompare(a))}>
{([date, episode], groupIndex) => (
<>
-
- {date}
-
+
+ false} primary>{date}
+
groupIndex() === selectedIndex()}
flexDirection="column"
@@ -93,23 +93,25 @@ export function FeedPage(props: PageProps) {
paddingBottom={0}
onMouseDown={() => setSelectedIndex(groupIndex())}
>
- groupIndex() === selectedIndex()}>
+ groupIndex() === selectedIndex()} primary>
{groupIndex() === selectedIndex() ? ">" : " "}
groupIndex() === selectedIndex()}
- fg={theme.text}
+ primary
>
{episode.episode.title}
- {episode.feed.podcast.title}
-
+ groupIndex() === selectedIndex()} primary>
+ {episode.feed.podcast.title}
+
+ groupIndex() === selectedIndex()} tertiary>
{formatDate(episode.episode.pubDate)}
-
-
+
+ groupIndex() === selectedIndex()} tertiary>
{formatDuration(episode.episode.duration)}
-
+
>
diff --git a/src/pages/Search/ResultCard.tsx b/src/pages/Search/ResultCard.tsx
index 15dec65..c04f168 100644
--- a/src/pages/Search/ResultCard.tsx
+++ b/src/pages/Search/ResultCard.tsx
@@ -27,19 +27,19 @@ export function ResultCard(props: ResultCardProps) {
justifyContent="space-between"
alignItems="center"
>
-
- props.selected}
- fg={theme.primary}
- >
- {podcast().title}
-
-
-
+
+ props.selected}
+ primary
+ >
+ {podcast().title}
+
+
+
[Subscribed]
diff --git a/src/types/desktop-theme.ts b/src/types/desktop-theme.ts
index 71f992d..c18053f 100644
--- a/src/types/desktop-theme.ts
+++ b/src/types/desktop-theme.ts
@@ -16,10 +16,18 @@ export const BASE_THEME_COLORS: ThemeColors = {
secondary: "#a9b1d6",
accent: "#f6c177",
text: "#e6edf3",
+ textPrimary: "#e6edf3",
+ textSecondary: "#a9b1d6",
+ textTertiary: "#7d8590",
+ textSelectedPrimary: "#1b1f27",
+ textSelectedSecondary: "#e6edf3",
+ textSelectedTertiary: "#a9b1d6",
muted: "#7d8590",
warning: "#f0b429",
error: "#f47067",
success: "#3fb950",
+ _hasSelectedListItemText: true,
+ thinkingOpacity: 0.5,
}
// Base layer backgrounds
@@ -61,16 +69,22 @@ export const THEMES_DESKTOP: DesktopTheme = {
secondary: "#cba6f7",
accent: "#f9e2af",
text: "#cdd6f4",
+ textPrimary: "#cdd6f4",
+ textSecondary: "#cba6f7",
+ textTertiary: "#7f849c",
+ textSelectedPrimary: "#1e1e2e",
+ textSelectedSecondary: "#cdd6f4",
+ textSelectedTertiary: "#cba6f7",
muted: "#7f849c",
warning: "#fab387",
error: "#f38ba8",
success: "#a6e3a1",
- layerBackgrounds: {
- layer0: "transparent",
- layer1: "#181825",
- layer2: "#11111b",
- layer3: "#0a0a0f",
- },
+ layerBackgrounds: {
+ layer0: "transparent",
+ layer1: "#181825",
+ layer2: "#11111b",
+ layer3: "#0a0a0f",
+ },
},
},
{
@@ -82,6 +96,12 @@ export const THEMES_DESKTOP: DesktopTheme = {
secondary: "#83a598",
accent: "#fe8019",
text: "#ebdbb2",
+ textPrimary: "#ebdbb2",
+ textSecondary: "#83a598",
+ textTertiary: "#928374",
+ textSelectedPrimary: "#282828",
+ textSelectedSecondary: "#ebdbb2",
+ textSelectedTertiary: "#83a598",
muted: "#928374",
warning: "#fabd2f",
error: "#fb4934",
@@ -103,6 +123,12 @@ export const THEMES_DESKTOP: DesktopTheme = {
secondary: "#bb9af7",
accent: "#e0af68",
text: "#c0caf5",
+ textPrimary: "#c0caf5",
+ textSecondary: "#bb9af7",
+ textTertiary: "#565f89",
+ textSelectedPrimary: "#1a1b26",
+ textSelectedSecondary: "#c0caf5",
+ textSelectedTertiary: "#bb9af7",
muted: "#565f89",
warning: "#e0af68",
error: "#f7768e",
@@ -124,6 +150,12 @@ export const THEMES_DESKTOP: DesktopTheme = {
secondary: "#81a1c1",
accent: "#ebcb8b",
text: "#eceff4",
+ textPrimary: "#eceff4",
+ textSecondary: "#81a1c1",
+ textTertiary: "#4c566a",
+ textSelectedPrimary: "#2e3440",
+ textSelectedSecondary: "#eceff4",
+ textSelectedTertiary: "#81a1c1",
muted: "#4c566a",
warning: "#ebcb8b",
error: "#bf616a",
diff --git a/src/types/settings.ts b/src/types/settings.ts
index 996250d..2abf560 100644
--- a/src/types/settings.ts
+++ b/src/types/settings.ts
@@ -23,11 +23,20 @@ export type ThemeColors = {
secondary: ColorValue;
accent: ColorValue;
text: ColorValue;
+ textPrimary?: ColorValue;
+ textSecondary?: ColorValue;
+ textTertiary?: ColorValue;
+ textSelectedPrimary?: ColorValue;
+ textSelectedSecondary?: ColorValue;
+ textSelectedTertiary?: ColorValue;
muted: ColorValue;
warning: ColorValue;
error: ColorValue;
success: ColorValue;
layerBackgrounds?: LayerBackgrounds;
+ _hasSelectedListItemText?: boolean;
+ thinkingOpacity?: number;
+ selectedListItemText?: ColorValue;
};
export type ThemeVariant = {
diff --git a/src/types/theme-schema.ts b/src/types/theme-schema.ts
index 65fb6ae..a5004fa 100644
--- a/src/types/theme-schema.ts
+++ b/src/types/theme-schema.ts
@@ -23,4 +23,10 @@ export type ThemeJson = {
export type ThemeColors = Record & {
_hasSelectedListItemText: boolean
thinkingOpacity: number
+ textPrimary?: ColorValue
+ textSecondary?: ColorValue
+ textTertiary?: ColorValue
+ textSelectedPrimary?: ColorValue
+ textSelectedSecondary?: ColorValue
+ textSelectedTertiary?: ColorValue
}