Plex player: a finger's tap on the picture only shows or hides the controls, the hide timer starts with playback, a double-tap on a side third skips 10 s, the seek bar is a 2.75rem touch-none hit area with its head shown on touch. The row is play/pause, Back by position, Next only with a next item, mute, time, tracks, a fixed ⋯ (settings, media info, stats, shortcuts, download) and fullscreen; Stop, Restart and the ±10 s buttons are gone. A started card shows the video card's Continue + Restart pair (one shared MediaResumeButtons, beside the picture's button), and its menu lists the restart; the player opens that item at 0 (fromStart). YouTube modal: the description opens from an ⓘ, the queue arrows sit inside the screen.
67 lines
1.8 KiB
TypeScript
67 lines
1.8 KiB
TypeScript
import type { MouseEvent } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { Play, RotateCcw } from "lucide-react";
|
|
import { Button } from "./ui/Button";
|
|
import { IconButton } from "./ui/IconButton";
|
|
|
|
// The started card's hover pair (DESIGN "Players", C5: restarting lives on the card): Continue in the
|
|
// accent, Restart dark translucent. ONE component for the YouTube card and the Plex cards, so the one
|
|
// media card says the same two words in the same two looks. A small picture (a shelf's landscape, the
|
|
// dense video card) takes the icon-only pair, which fits beside the hover row. Touch has no hover: a
|
|
// tap on the picture continues, and the card's "…" carries the restart.
|
|
export function MediaResumeButtons({
|
|
small = false,
|
|
onContinue,
|
|
onRestart,
|
|
}: {
|
|
small?: boolean;
|
|
onContinue: (e: MouseEvent) => void;
|
|
onRestart: (e: MouseEvent) => void;
|
|
}) {
|
|
const { t } = useTranslation();
|
|
return small ? (
|
|
<>
|
|
<IconButton
|
|
variant="primary"
|
|
size="md"
|
|
round
|
|
onClick={onContinue}
|
|
label={t("card.continue")}
|
|
title={t("card.continueTitle")}
|
|
>
|
|
<Play className="fill-current" />
|
|
</IconButton>
|
|
<IconButton
|
|
variant="media"
|
|
size="md"
|
|
onClick={onRestart}
|
|
label={t("card.restart")}
|
|
title={t("card.restartTitle")}
|
|
>
|
|
<RotateCcw />
|
|
</IconButton>
|
|
</>
|
|
) : (
|
|
<>
|
|
<Button
|
|
size="sm"
|
|
round
|
|
onClick={onContinue}
|
|
title={t("card.continueTitle")}
|
|
icon={<Play className="fill-current" />}
|
|
>
|
|
{t("card.continue")}
|
|
</Button>
|
|
<Button
|
|
variant="media"
|
|
size="sm"
|
|
onClick={onRestart}
|
|
title={t("card.restartTitle")}
|
|
icon={<RotateCcw />}
|
|
>
|
|
{t("card.restart")}
|
|
</Button>
|
|
</>
|
|
);
|
|
}
|