style(frontend): Prettier config + one-time repo-wide format pass

Prettier 3 (pinned), printWidth 100, double quotes — chosen to match the existing
hand-formatting and minimise reflow. This commit is ONLY the mechanical format pass
(`prettier --write`) plus the config/ignore/scripts, isolated so it never pollutes a
feature diff. Verified behaviour-neutral: typecheck, eslint (0 errors), and vitest
all green before and after. See .git-blame-ignore-revs — `git blame` skips this sha.
This commit is contained in:
2026-07-21 02:26:40 +02:00
parent 04ecd8b3a7
commit e257e2aca0
101 changed files with 4388 additions and 2641 deletions
+38 -19
View File
@@ -45,7 +45,14 @@ import { PageToolbar } from "./PageShell";
import { useChoice, useConfirm } from "./ConfirmProvider";
import { usePlaylists, usePlaylistsActions } from "./PlaylistsProvider";
import { useMe } from "../lib/useMe";
import { ColumnHead, alignClass, filterRows, isActive, type Column, type FilterMap } from "./tableHeader";
import {
ColumnHead,
alignClass,
filterRows,
isActive,
type Column,
type FilterMap,
} from "./tableHeader";
import { GRIP_KEY, playlistColumns } from "./playlistColumns";
// The playlist detail is a HYBRID table (E4 S4): real sortable/filterable column headers over a
@@ -158,7 +165,7 @@ export default function Playlists() {
api
.reorderPlaylist(
selectedId,
next.map((v) => v.id)
next.map((v) => v.id),
)
.then(() => {
// Refresh the sidebar (cover may change) and the detail (so the now-dirty state,
@@ -253,13 +260,13 @@ export default function Playlists() {
const columns = useMemo(
() => playlistColumns({ t, indexOf: storedIndex, onPlay, onRemove, canEdit }),
[t, storedIndex, onPlay, onRemove, canEdit]
[t, storedIndex, onPlay, onRemove, canEdit],
);
const filterActive = Object.values(filters).some(isActive);
const shown = useMemo(
() => applyView(filterRows(items, columns, filters), columns, viewSort, groupBy),
[items, columns, filters, viewSort, groupBy]
[items, columns, filters, viewSort, groupBy],
);
// Read by the drag announcements, which must report the CURRENT positions without making the
// announcement closures a render dependency of DndContext.
@@ -291,21 +298,32 @@ export default function Playlists() {
const sensors = useSensors(
useSensor(PointerSensor, { activationConstraint: { distance: 4 } }),
// The grip was focusable and called itself "reorder", but only a pointer could move it.
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates })
useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }),
);
const posOf = (id: string | number) => shownRef.current.findIndex((v) => v.id === id) + 1;
const titleOf = (id: string | number) =>
shownRef.current.find((v) => v.id === id)?.title ?? "";
const titleOf = (id: string | number) => shownRef.current.find((v) => v.id === id)?.title ?? "";
const total = () => shownRef.current.length;
const screenReaderInstructions = { draggable: t("playlists.dndInstructions") };
const announcements = {
onDragStart: ({ active }: { active: { id: string | number } }) =>
t("playlists.dndPickedUp", { title: titleOf(active.id), pos: posOf(active.id), total: total() }),
t("playlists.dndPickedUp", {
title: titleOf(active.id),
pos: posOf(active.id),
total: total(),
}),
onDragOver: ({ active }: { active: { id: string | number } }) =>
t("playlists.dndMovedOver", { title: titleOf(active.id), pos: posOf(active.id), total: total() }),
t("playlists.dndMovedOver", {
title: titleOf(active.id),
pos: posOf(active.id),
total: total(),
}),
onDragEnd: ({ active }: { active: { id: string | number } }) =>
t("playlists.dndDropped", { title: titleOf(active.id), pos: posOf(active.id), total: total() }),
t("playlists.dndDropped", {
title: titleOf(active.id),
pos: posOf(active.id),
total: total(),
}),
onDragCancel: ({ active }: { active: { id: string | number } }) =>
t("playlists.dndCancelled", { title: titleOf(active.id), pos: posOf(active.id) }),
};
@@ -493,11 +511,12 @@ export default function Playlists() {
const closePlayer = useCallback(() => setPlayingId(null), []);
// Name the current view in the user's terms: "Title ↑", "grouped by channel", or both.
const sortLabel = viewSort && !isStoredSort(viewSort)
? `${columns.find((c) => c.key === viewSort.key)?.header ?? viewSort.key} ${
viewSort.dir === "asc" ? "↑" : "↓"
}`
: null;
const sortLabel =
viewSort && !isStoredSort(viewSort)
? `${columns.find((c) => c.key === viewSort.key)?.header ?? viewSort.key} ${
viewSort.dir === "asc" ? "↑" : "↓"
}`
: null;
const viewName = groupBy
? sortLabel
? t("playlists.viewGroupedAnd", { sort: sortLabel })
@@ -615,7 +634,9 @@ export default function Playlists() {
onClick={pushToYoutube}
disabled={pushing}
title={linked ? t("playlists.pushToYoutube") : t("playlists.exportToYoutube")}
aria-label={linked ? t("playlists.pushToYoutube") : t("playlists.exportToYoutube")}
aria-label={
linked ? t("playlists.pushToYoutube") : t("playlists.exportToYoutube")
}
className={`inline-flex items-center justify-center p-2 rounded-lg border transition disabled:opacity-40 ${
detail.dirty
? "border-accent text-accent hover:bg-accent/10"
@@ -698,9 +719,7 @@ export default function Playlists() {
stored order ALREADY matches the sort produced a warning, no Save button and no
visible change, which reads as a malfunction. Now the line says which of the three
situations you are in; the disabled grip still explains itself on hover/focus. */}
{viewActive && (
<span className="text-[11px] text-muted/80">{viewStatus}</span>
)}
{viewActive && <span className="text-[11px] text-muted/80">{viewStatus}</span>}
{canEdit && (
<div className="ml-auto">
<UndoToolbar