feat(player): a roomier YouTube player, its panel shut on demand
- The full-height previous/next strips beside the card are gone: the panel's transport row and Shift+arrows step on their own, and the video gains the 7rem the strips' gutters took. - Close is one icon in the card's top-right corner (the wide panel's head, the stacked card's title row). - The panel's description is cut to three lines with More / Less (ClampedText now takes the linked text as children). - Wide, the panel shuts to a 2.75rem strip (close, open, previous, next) for a bigger video; it stays shut while the queue steps on, and a video opened from a card starts it open. Focus moves to the counterpart toggle. - The wheel has one meaning per place: over a panel (or the stacked card) with something to scroll it only scrolls, never falling through to the volume at the end; over the video, or a panel that fits, it is the volume. - A long channel name is cut on the panel's line instead of running the 20rem panel into a sideways scroll.
This commit is contained in:
@@ -5,6 +5,7 @@ import type { VideoDetail } from "../lib/api";
|
||||
import type { AutoMode, LoopMode } from "../lib/playerModes";
|
||||
import { Button } from "./ui/Button";
|
||||
import { StateMessage } from "./ui/QueryState";
|
||||
import { ClampedText } from "./ui/ClampedText";
|
||||
import { renderDescription } from "./descriptionLinks";
|
||||
|
||||
// Presentational controls for the YouTube modal player (PlayerModal), split out of the god component —
|
||||
@@ -109,7 +110,8 @@ export function PlayerTransportControls({
|
||||
/** The description, said the same way in its two places (the popover under 1280 px, the panel beside
|
||||
* the video above it): loading, failed with a retry, the text in the caller's box, or none. One
|
||||
* ladder, so the two cannot drift (the failed state was once tested in the panel only).
|
||||
* `ref` / `style` / `className` dress the text's box only. */
|
||||
* `ref` / `style` / `className` dress the text's box only. `clamp` cuts it to three lines with a
|
||||
* More / Less (the panel, where the description sits under the actions and is rarely read whole). */
|
||||
export function PlayerDescription({
|
||||
detail,
|
||||
currentId,
|
||||
@@ -118,6 +120,7 @@ export function PlayerDescription({
|
||||
className,
|
||||
style,
|
||||
ref,
|
||||
clamp = false,
|
||||
}: {
|
||||
detail: { isLoading: boolean; isError: boolean; data?: VideoDetail; refetch: () => unknown };
|
||||
currentId: string;
|
||||
@@ -126,6 +129,7 @@ export function PlayerDescription({
|
||||
className: string;
|
||||
style?: CSSProperties;
|
||||
ref?: Ref<HTMLDivElement>;
|
||||
clamp?: boolean;
|
||||
}) {
|
||||
const { t } = useTranslation();
|
||||
if (detail.isLoading) return <div className="text-sm text-muted">{t("player.loading")}</div>;
|
||||
@@ -137,6 +141,18 @@ export function PlayerDescription({
|
||||
);
|
||||
const text = detail.data?.description;
|
||||
if (!text) return <div className="text-sm text-muted">{t("player.noDescription")}</div>;
|
||||
if (clamp)
|
||||
return (
|
||||
<ClampedText
|
||||
text={text}
|
||||
lines={3}
|
||||
moreLabel={t("player.descriptionMore")}
|
||||
lessLabel={t("player.descriptionLess")}
|
||||
textClassName={className}
|
||||
>
|
||||
{renderDescription(text, { currentId, onSeek, onLoadVideo, t })}
|
||||
</ClampedText>
|
||||
);
|
||||
return (
|
||||
<div ref={ref} style={style} className={className}>
|
||||
{renderDescription(text, { currentId, onSeek, onLoadVideo, t })}
|
||||
|
||||
Reference in New Issue
Block a user