From b57aec113ea93044039cc80339ef37d96dd6f482 Mon Sep 17 00:00:00 2001 From: npeter83 Date: Sat, 15 Aug 2026 01:01:03 +0200 Subject: [PATCH] refactor(ui): close the sort/layout reuse-gaps (R13 S2c step 5) Two surfaces reinvented controls the app already consolidated: - PlaylistsRail sort (a bespoke setPlSort({ ...plSort, key: e.target.value as PlSort["key"] })} - aria-label={t("playlists.sortLabel")} - className="flex-1 min-w-0 bg-surface border border-border rounded-md px-1.5 py-1 text-2xs focus:outline-hidden focus:ring-2 focus:ring-accent/40" - > - - - - - - - - + + next && setPlSort({ ...plSort, key: next.key as PlSort["key"], dir: next.dir }) + } + trailing={ + + } + /> )}
{ diff --git a/frontend/src/components/PlexPlaylistView.tsx b/frontend/src/components/PlexPlaylistView.tsx index 60ca7dac..f77e9606 100644 --- a/frontend/src/components/PlexPlaylistView.tsx +++ b/frontend/src/components/PlexPlaylistView.tsx @@ -1,4 +1,4 @@ -import { useEffect, useMemo, useState, type ReactNode } from "react"; +import { useEffect, useMemo, useState } from "react"; import { qk } from "../lib/queryKeys"; import { useTranslation } from "react-i18next"; import { useQuery, useQueryClient } from "@tanstack/react-query"; @@ -35,6 +35,7 @@ import { api, type PlexCard } from "../lib/api"; import { getAccountRaw, LS, setAccountRaw } from "../lib/storage"; import { useConfirm } from "./ConfirmProvider"; import { LoadingState, StateMessage } from "./QueryState"; +import ViewSwitcher, { type ViewOption } from "./ViewSwitcher"; // A playlist's items, grouped for readability: movies stay standalone, while a run of episodes from the // same show collapses into a season/show group so a whole series doesn't sprawl into an endless flat @@ -499,18 +500,10 @@ export default function PlexPlaylistView({ onRemove, }; - const LayoutBtn = ({ v, icon, label }: { v: Layout; icon: ReactNode; label: string }) => ( - - ); + const layoutOptions: ViewOption[] = [ + { id: "accordion", label: t("plex.playlist.layoutAccordion"), icon: Rows3 }, + { id: "tree", label: t("plex.playlist.layoutTree"), icon: ListTree }, + ]; return (
@@ -536,19 +529,13 @@ export default function PlexPlaylistView({ ) : (

{q.data?.title ?? " "}

)} - {/* Layout preference: Accordion (A) or Tree (C). */} -
- } - label={t("plex.playlist.layoutAccordion")} - /> - } - label={t("plex.playlist.layoutTree")} - /> -
+ {/* Layout preference: Accordion or Tree — the shared list-view switcher. */} +