feat(settings): configurable selection marker, default off
Adds a Selection Marker toggle under Settings → Preferences that controls the ❯ cursor glyph on the focused row of every list. Default off; rows keep a leading space for alignment either way. Every list pane (tab strip, feed, my shows, discover, search, settings, whitelist editor) reads the glyph through the shared useSelectionMarker hook. Also aligns the lead column across panes: page list rows drop their extra box paddingLeft so labels start at the same column as the tab strip (2 cells without nerd icons, 4 with), keeping episode sub-rows aligned to the title.
This commit is contained in:
@@ -19,6 +19,7 @@ import { For } from "solid-js";
|
|||||||
import { useTheme } from "@/context/ThemeContext";
|
import { useTheme } from "@/context/ThemeContext";
|
||||||
import { useNavigation } from "@/context/NavigationContext";
|
import { useNavigation } from "@/context/NavigationContext";
|
||||||
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
||||||
|
import { useSelectionMarker } from "@/hooks/useSelectionMarker";
|
||||||
import { TABS } from "@/utils/navigation";
|
import { TABS } from "@/utils/navigation";
|
||||||
import { NF_ICONS, supportsNerdFonts } from "@/utils/nerd-fonts";
|
import { NF_ICONS, supportsNerdFonts } from "@/utils/nerd-fonts";
|
||||||
|
|
||||||
@@ -51,6 +52,7 @@ export function TabListPane(props: { muted?: boolean }) {
|
|||||||
const nerd = supportsNerdFonts();
|
const nerd = supportsNerdFonts();
|
||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const nav = useNavigation();
|
const nav = useNavigation();
|
||||||
|
const marker = useSelectionMarker();
|
||||||
|
|
||||||
const cursor = () => nav.tabCursor();
|
const cursor = () => nav.tabCursor();
|
||||||
const activeTab = () => nav.activeTab();
|
const activeTab = () => nav.activeTab();
|
||||||
@@ -104,7 +106,7 @@ export function TabListPane(props: { muted?: boolean }) {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{/* ── selection marker (j/k cursor) ─────────────────────────── */}
|
{/* ── selection marker (j/k cursor) ─────────────────────────── */}
|
||||||
<text fg={focusFg(tab)}>{isCursor() ? "❯" : " "}</text>
|
<text fg={focusFg(tab)}>{isCursor() ? marker() : " "}</text>
|
||||||
{nerd && (
|
{nerd && (
|
||||||
<text fg={focusFg(tab)} paddingRight={1}>
|
<text fg={focusFg(tab)} paddingRight={1}>
|
||||||
{TAB_ICON[tab]}
|
{TAB_ICON[tab]}
|
||||||
|
|||||||
16
src/hooks/useSelectionMarker.ts
Normal file
16
src/hooks/useSelectionMarker.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
/**
|
||||||
|
* useSelectionMarker — reactive accessor for the row-selection marker glyph.
|
||||||
|
*
|
||||||
|
* When the `showSelectionMarker` setting is on, the focused row of every list
|
||||||
|
* renders `❯`; when off (the default), it renders a space so column alignment
|
||||||
|
* is preserved. Every list pane in the app reads the marker through this hook
|
||||||
|
* so the setting applies consistently everywhere.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { useAppStore } from "@/stores/app";
|
||||||
|
|
||||||
|
export function useSelectionMarker(): () => string {
|
||||||
|
const app = useAppStore();
|
||||||
|
return () =>
|
||||||
|
app.state().settings.showSelectionMarker ? "❯" : " ";
|
||||||
|
}
|
||||||
@@ -33,6 +33,7 @@ import { PaneRow } from "@/components/PaneRow";
|
|||||||
import { TabListPane } from "@/components/TabPanel";
|
import { TabListPane } from "@/components/TabPanel";
|
||||||
import { LoadingIndicator } from "@/components/LoadingIndicator";
|
import { LoadingIndicator } from "@/components/LoadingIndicator";
|
||||||
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
||||||
|
import { useSelectionMarker } from "@/hooks/useSelectionMarker";
|
||||||
|
|
||||||
export const DiscoverPaneCount = 1;
|
export const DiscoverPaneCount = 1;
|
||||||
|
|
||||||
@@ -43,6 +44,7 @@ function DiscoverPage() {
|
|||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const muted = () => theme.muted || theme.text;
|
const muted = () => theme.muted || theme.text;
|
||||||
const nav = useNavigation();
|
const nav = useNavigation();
|
||||||
|
const marker = useSelectionMarker();
|
||||||
|
|
||||||
const depth = nav.currentDepth;
|
const depth = nav.currentDepth;
|
||||||
const focus = (d: number = depth()) => nav.depthFocus(d);
|
const focus = (d: number = depth()) => nav.depthFocus(d);
|
||||||
@@ -182,12 +184,11 @@ function DiscoverPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
gap={1}
|
gap={1}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(index(), lf(), false)}
|
backgroundColor={focusBg(index(), lf(), false)}
|
||||||
>
|
>
|
||||||
<text fg={focusFg(index(), nav.depthFocus(0), false)}>
|
<text fg={focusFg(index(), nav.depthFocus(0), false)}>
|
||||||
{index() === nav.depthFocus(0) ? "❯" : " "}
|
{index() === nav.depthFocus(0) ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
{nerd && (
|
{nerd && (
|
||||||
<text fg={focusFg(index(), nav.depthFocus(0), false)}>
|
<text fg={focusFg(index(), nav.depthFocus(0), false)}>
|
||||||
@@ -219,7 +220,6 @@ function DiscoverPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
gap={1}
|
gap={1}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(index(), lf(), isActive())}
|
backgroundColor={focusBg(index(), lf(), isActive())}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -229,7 +229,7 @@ function DiscoverPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<text fg={focusFg(index(), lf(), isActive())}>
|
<text fg={focusFg(index(), lf(), isActive())}>
|
||||||
{index() === lf() ? "❯" : " "}
|
{index() === lf() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
{nerd && (
|
{nerd && (
|
||||||
<text fg={focusFg(index(), lf(), isActive())}>
|
<text fg={focusFg(index(), lf(), isActive())}>
|
||||||
@@ -268,7 +268,6 @@ function DiscoverPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
gap={0}
|
gap={0}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(index(), lf(), isActive())}
|
backgroundColor={focusBg(index(), lf(), isActive())}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -278,7 +277,7 @@ function DiscoverPage() {
|
|||||||
>
|
>
|
||||||
<box flexDirection="row" gap={1}>
|
<box flexDirection="row" gap={1}>
|
||||||
<text fg={focusFg(index(), lf(), isActive())}>
|
<text fg={focusFg(index(), lf(), isActive())}>
|
||||||
{index() === lf() ? "❯" : " "}
|
{index() === lf() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
<text fg={focusFg(index(), lf(), isActive())}>
|
<text fg={focusFg(index(), lf(), isActive())}>
|
||||||
{podcast.title}
|
{podcast.title}
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import { LoadingIndicator } from "@/components/LoadingIndicator";
|
|||||||
import { PaneRow } from "@/components/PaneRow";
|
import { PaneRow } from "@/components/PaneRow";
|
||||||
import { TabListPane } from "@/components/TabPanel";
|
import { TabListPane } from "@/components/TabPanel";
|
||||||
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
||||||
|
import { useSelectionMarker } from "@/hooks/useSelectionMarker";
|
||||||
|
|
||||||
export const FeedPaneCount = 1;
|
export const FeedPaneCount = 1;
|
||||||
|
|
||||||
@@ -55,6 +56,7 @@ function FeedPage() {
|
|||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const muted = () => theme.muted || theme.text;
|
const muted = () => theme.muted || theme.text;
|
||||||
const nav = useNavigation();
|
const nav = useNavigation();
|
||||||
|
const marker = useSelectionMarker();
|
||||||
|
|
||||||
// ── flat episode list (depth 0 — the only depth Feed has) ────────────────
|
// ── flat episode list (depth 0 — the only depth Feed has) ────────────────
|
||||||
const episodes = createMemo<EpItem[]>(
|
const episodes = createMemo<EpItem[]>(
|
||||||
@@ -257,7 +259,6 @@ function FeedPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
gap={0}
|
gap={0}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(index(), fi(), isActive())}
|
backgroundColor={focusBg(index(), fi(), isActive())}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -267,7 +268,7 @@ function FeedPage() {
|
|||||||
>
|
>
|
||||||
<box flexDirection="row" gap={1}>
|
<box flexDirection="row" gap={1}>
|
||||||
<text fg={focusFg(index(), fi(), isActive())}>
|
<text fg={focusFg(index(), fi(), isActive())}>
|
||||||
{index() === fi() ? "❯" : " "}
|
{index() === fi() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
<text fg={focusFg(index(), fi(), isActive())}>
|
<text fg={focusFg(index(), fi(), isActive())}>
|
||||||
{item.episode.episodeNumber
|
{item.episode.episodeNumber
|
||||||
@@ -304,7 +305,6 @@ function FeedPage() {
|
|||||||
ref={moreRef}
|
ref={moreRef}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
gap={1}
|
gap={1}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(episodes().length, focusedRow(), isActive())}
|
backgroundColor={focusBg(episodes().length, focusedRow(), isActive())}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -313,7 +313,7 @@ function FeedPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<text fg={focusFg(episodes().length, focusedRow(), isActive())}>
|
<text fg={focusFg(episodes().length, focusedRow(), isActive())}>
|
||||||
{focusedOnMore() ? "❯" : " "}
|
{focusedOnMore() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
{nerd && (
|
{nerd && (
|
||||||
<text fg={focusFg(episodes().length, focusedRow(), isActive())}>
|
<text fg={focusFg(episodes().length, focusedRow(), isActive())}>
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ import { LoadingIndicator } from "@/components/LoadingIndicator";
|
|||||||
import { PaneRow } from "@/components/PaneRow";
|
import { PaneRow } from "@/components/PaneRow";
|
||||||
import { TabListPane } from "@/components/TabPanel";
|
import { TabListPane } from "@/components/TabPanel";
|
||||||
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
||||||
|
import { useSelectionMarker } from "@/hooks/useSelectionMarker";
|
||||||
|
|
||||||
export const MyShowsPaneCount = 1;
|
export const MyShowsPaneCount = 1;
|
||||||
|
|
||||||
@@ -47,6 +48,7 @@ export function MyShowsPage() {
|
|||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const muted = () => theme.muted || theme.text;
|
const muted = () => theme.muted || theme.text;
|
||||||
const nav = useNavigation();
|
const nav = useNavigation();
|
||||||
|
const marker = useSelectionMarker();
|
||||||
|
|
||||||
const stack = nav.depthStack;
|
const stack = nav.depthStack;
|
||||||
const depth = nav.currentDepth;
|
const depth = nav.currentDepth;
|
||||||
@@ -254,12 +256,11 @@ export function MyShowsPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
gap={1}
|
gap={1}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(index(), lf(), false)}
|
backgroundColor={focusBg(index(), lf(), false)}
|
||||||
>
|
>
|
||||||
<text fg={focusFg(index(), lf(), false)}>
|
<text fg={focusFg(index(), lf(), false)}>
|
||||||
{index() === lf() ? "❯" : " "}
|
{index() === lf() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
<text fg={focusFg(index(), lf(), false)}>{showTitle(feed)}</text>
|
<text fg={focusFg(index(), lf(), false)}>{showTitle(feed)}</text>
|
||||||
<text fg={muted()}>({feed.episodes.length})</text>
|
<text fg={muted()}>({feed.episodes.length})</text>
|
||||||
@@ -299,7 +300,6 @@ export function MyShowsPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
gap={1}
|
gap={1}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(index(), lf(), isActive())}
|
backgroundColor={focusBg(index(), lf(), isActive())}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -308,7 +308,7 @@ export function MyShowsPage() {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<text fg={focusFg(index(), lf(), isActive())}>
|
<text fg={focusFg(index(), lf(), isActive())}>
|
||||||
{index() === lf() ? "❯" : " "}
|
{index() === lf() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
<text fg={focusFg(index(), lf(), isActive())}>
|
<text fg={focusFg(index(), lf(), isActive())}>
|
||||||
{showTitle(feed)}
|
{showTitle(feed)}
|
||||||
@@ -354,7 +354,6 @@ export function MyShowsPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
gap={0}
|
gap={0}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(index(), lf(), isActive())}
|
backgroundColor={focusBg(index(), lf(), isActive())}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -364,7 +363,7 @@ export function MyShowsPage() {
|
|||||||
>
|
>
|
||||||
<box flexDirection="row" gap={1}>
|
<box flexDirection="row" gap={1}>
|
||||||
<text fg={focusFg(index(), lf(), isActive())}>
|
<text fg={focusFg(index(), lf(), isActive())}>
|
||||||
{index() === lf() ? "❯" : " "}
|
{index() === lf() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
<text fg={focusFg(index(), lf(), isActive())}>
|
<text fg={focusFg(index(), lf(), isActive())}>
|
||||||
{ep.episodeNumber ? `#${ep.episodeNumber} ` : ""}
|
{ep.episodeNumber ? `#${ep.episodeNumber} ` : ""}
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ import { PaneRow } from "@/components/PaneRow";
|
|||||||
import { TabListPane } from "@/components/TabPanel";
|
import { TabListPane } from "@/components/TabPanel";
|
||||||
import { LoadingIndicator } from "@/components/LoadingIndicator";
|
import { LoadingIndicator } from "@/components/LoadingIndicator";
|
||||||
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
||||||
|
import { useSelectionMarker } from "@/hooks/useSelectionMarker";
|
||||||
|
|
||||||
export const SearchPaneCount = 1;
|
export const SearchPaneCount = 1;
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ function SearchPage() {
|
|||||||
const { theme } = useTheme();
|
const { theme } = useTheme();
|
||||||
const muted = () => theme.muted || theme.text;
|
const muted = () => theme.muted || theme.text;
|
||||||
const nav = useNavigation();
|
const nav = useNavigation();
|
||||||
|
const marker = useSelectionMarker();
|
||||||
|
|
||||||
const stack = nav.depthStack;
|
const stack = nav.depthStack;
|
||||||
const depth = nav.currentDepth;
|
const depth = nav.currentDepth;
|
||||||
@@ -288,7 +290,6 @@ function SearchPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
gap={1}
|
gap={1}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={
|
backgroundColor={
|
||||||
typing()
|
typing()
|
||||||
@@ -311,7 +312,7 @@ function SearchPage() {
|
|||||||
: focusFg(index(), lf(), isActive())
|
: focusFg(index(), lf(), isActive())
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
{index() === lf() && !typing() ? "❯" : " "}
|
{index() === lf() && !typing() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
<text
|
<text
|
||||||
fg={
|
fg={
|
||||||
@@ -365,7 +366,6 @@ function SearchPage() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="column"
|
flexDirection="column"
|
||||||
gap={0}
|
gap={0}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={focusBg(index(), fi(), isActive())}
|
backgroundColor={focusBg(index(), fi(), isActive())}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -375,7 +375,7 @@ function SearchPage() {
|
|||||||
>
|
>
|
||||||
<box flexDirection="row" gap={1}>
|
<box flexDirection="row" gap={1}>
|
||||||
<text fg={focusFg(index(), fi(), isActive())}>
|
<text fg={focusFg(index(), fi(), isActive())}>
|
||||||
{index() === fi() ? "❯" : " "}
|
{index() === fi() ? marker() : " "}
|
||||||
</text>
|
</text>
|
||||||
<text fg={focusFg(index(), fi(), isActive())}>
|
<text fg={focusFg(index(), fi(), isActive())}>
|
||||||
{result.podcast.title}
|
{result.podcast.title}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import { useFeedStore } from "@/stores/feed";
|
|||||||
import { useTheme } from "@/context/ThemeContext";
|
import { useTheme } from "@/context/ThemeContext";
|
||||||
import { useInputFocusNav } from "@/hooks/useInputFocusNav";
|
import { useInputFocusNav } from "@/hooks/useInputFocusNav";
|
||||||
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
||||||
|
import { useSelectionMarker } from "@/hooks/useSelectionMarker";
|
||||||
import {
|
import {
|
||||||
NavMode,
|
NavMode,
|
||||||
useNavigation,
|
useNavigation,
|
||||||
@@ -88,6 +89,18 @@ export function usePreferencesItems(): SettingItem[] {
|
|||||||
transparentBackground: !settings().transparentBackground,
|
transparentBackground: !settings().transparentBackground,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "showSelectionMarker",
|
||||||
|
label: "Selection Marker",
|
||||||
|
kind: "toggle",
|
||||||
|
display: () => (settings().showSelectionMarker ? "On" : "Off"),
|
||||||
|
help: () =>
|
||||||
|
`Show the ❯ marker on the focused row of every list (tabs, shows, episodes, results).\nType: toggle\nDefault: off\nCurrent: ${settings().showSelectionMarker ? "On" : "Off"}\nSpace/Enter to toggle.`,
|
||||||
|
toggle: () =>
|
||||||
|
app.updateSettings({
|
||||||
|
showSelectionMarker: !settings().showSelectionMarker,
|
||||||
|
}),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "fontSize",
|
id: "fontSize",
|
||||||
label: "Font Size",
|
label: "Font Size",
|
||||||
@@ -427,6 +440,7 @@ function WhitelistEditor() {
|
|||||||
const focused = () =>
|
const focused = () =>
|
||||||
!nav.inputFocused() && index() === wlCursorClamped();
|
!nav.inputFocused() && index() === wlCursorClamped();
|
||||||
const ref = useScrollIntoView(focused);
|
const ref = useScrollIntoView(focused);
|
||||||
|
const marker = useSelectionMarker();
|
||||||
const bg = () => (focused() ? theme.primary : undefined);
|
const bg = () => (focused() ? theme.primary : undefined);
|
||||||
const fg = () => (focused() ? theme.surface : theme.text);
|
const fg = () => (focused() ? theme.surface : theme.text);
|
||||||
return (
|
return (
|
||||||
@@ -434,7 +448,6 @@ function WhitelistEditor() {
|
|||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
gap={1}
|
gap={1}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={bg()}
|
backgroundColor={bg()}
|
||||||
onMouseDown={() => {
|
onMouseDown={() => {
|
||||||
@@ -445,7 +458,7 @@ function WhitelistEditor() {
|
|||||||
wlToggle(feed.id);
|
wlToggle(feed.id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<text fg={fg()}>{focused() ? "❯" : " "}</text>
|
<text fg={fg()}>{focused() ? marker() : " "}</text>
|
||||||
<text fg={fg()}>{inList(feed.id) ? "●" : "○"}</text>
|
<text fg={fg()}>{inList(feed.id) ? "●" : "○"}</text>
|
||||||
<text fg={fg()}>
|
<text fg={fg()}>
|
||||||
{feed.customName || feed.podcast.title}
|
{feed.customName || feed.podcast.title}
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import { useDownloadItems } from "./DownloadManager";
|
|||||||
import { PaneRow } from "@/components/PaneRow";
|
import { PaneRow } from "@/components/PaneRow";
|
||||||
import { TabListPane } from "@/components/TabPanel";
|
import { TabListPane } from "@/components/TabPanel";
|
||||||
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
import { useScrollIntoView } from "@/hooks/useScrollIntoView";
|
||||||
|
import { useSelectionMarker } from "@/hooks/useSelectionMarker";
|
||||||
|
|
||||||
export const SettingsPaneCount = 1;
|
export const SettingsPaneCount = 1;
|
||||||
|
|
||||||
@@ -436,17 +437,17 @@ function Row(props: {
|
|||||||
? theme.selectedListItemText ?? theme.text
|
? theme.selectedListItemText ?? theme.text
|
||||||
: theme.text;
|
: theme.text;
|
||||||
const ref = useScrollIntoView(() => props.focused);
|
const ref = useScrollIntoView(() => props.focused);
|
||||||
|
const marker = useSelectionMarker();
|
||||||
return (
|
return (
|
||||||
<box
|
<box
|
||||||
ref={ref}
|
ref={ref}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
gap={1}
|
gap={1}
|
||||||
paddingLeft={1}
|
|
||||||
paddingRight={1}
|
paddingRight={1}
|
||||||
backgroundColor={bg()}
|
backgroundColor={bg()}
|
||||||
onMouseDown={props.onMouseDown}
|
onMouseDown={props.onMouseDown}
|
||||||
>
|
>
|
||||||
<text fg={fg()}>{props.focused ? "❯" : " "}</text>
|
<text fg={fg()}>{props.focused ? marker() : " "}</text>
|
||||||
{props.icon && nerd && <text fg={fg()}>{props.icon}</text>}
|
{props.icon && nerd && <text fg={fg()}>{props.icon}</text>}
|
||||||
<text fg={fg()}>{props.label}</text>
|
<text fg={fg()}>{props.label}</text>
|
||||||
<Show when={props.value}>
|
<Show when={props.value}>
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ const defaultSettings: AppSettings = {
|
|||||||
playbackSpeed: 1,
|
playbackSpeed: 1,
|
||||||
downloadPath: "",
|
downloadPath: "",
|
||||||
transparentBackground: false,
|
transparentBackground: false,
|
||||||
|
showSelectionMarker: false,
|
||||||
visualizer: defaultVisualizerSettings,
|
visualizer: defaultVisualizerSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ export type AppSettings = {
|
|||||||
downloadPath: string;
|
downloadPath: string;
|
||||||
/** Render the app background transparent (let the terminal's own bg show). */
|
/** Render the app background transparent (let the terminal's own bg show). */
|
||||||
transparentBackground: boolean;
|
transparentBackground: boolean;
|
||||||
|
/** Show the `❯` cursor marker on the focused row of every list (default: off). */
|
||||||
|
showSelectionMarker: boolean;
|
||||||
visualizer: VisualizerSettings;
|
visualizer: VisualizerSettings;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ const defaultSettings: AppSettings = {
|
|||||||
playbackSpeed: 1,
|
playbackSpeed: 1,
|
||||||
downloadPath: "",
|
downloadPath: "",
|
||||||
transparentBackground: false,
|
transparentBackground: false,
|
||||||
|
showSelectionMarker: false,
|
||||||
visualizer: defaultVisualizerSettings,
|
visualizer: defaultVisualizerSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user