mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 21:04:37 +03:00
UI V2
Squashed commits: [e74bbf9] stuff [28476de] stuff [c7efb7b] stuff [2c78f94] stuff [f79338e] stuff [a697876] stuff [85bb60e] stuff [9f108b2] stuff [d8e00c0] stuff [7787ef9] stuff [f7f10b7] stuff [aa266f7] stuff [511ba6b] stuff [7453747] stuff [db55e2d] stuff [b362623] stuff [7288c17] stuff [86638cd] stuff [879dac4] stuff [65a4996] stuff [c6fb361] stuff [d449ce7] stuff [349dffa] stuff [84206ab] stuff [0253c65] stuff [cc0992e] stuff [3289e7d] stuff [d9ab290] stuff [dcc980d] stuff [7787da8] stuff [5bcf7cd] stuff [00e9316] stuff [54c9398] stuff [72b6ee1] stuff [4b4b26c] stuff [4cbdb06] stuff [1a240b3] stuff [650ea08] stuff [37440ef] stuff [9ee66ba] stuff [b430c86] stuff [37159c3] stuff [deba837] stuff [6ac65f6] stuff [a2ca1a1] stuff [c010229] stuff [3fd7306] stuff [cbe6efc] stuff [997a8d0] stuff [d0708a2] stuff [d316aba] stuff [4fe9900] Added initial files
This commit is contained in:
149
ui/v2/src/components/scenes/SceneCard.tsx
Normal file
149
ui/v2/src/components/scenes/SceneCard.tsx
Normal file
@@ -0,0 +1,149 @@
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Card,
|
||||
Divider,
|
||||
Elevation,
|
||||
H4,
|
||||
Popover,
|
||||
Tag,
|
||||
} from "@blueprintjs/core";
|
||||
import React, { FunctionComponent, RefObject, useEffect, useRef, useState } from "react";
|
||||
import { Link } from "react-router-dom";
|
||||
import * as GQL from "../../core/generated-graphql";
|
||||
import { VideoHoverHook } from "../../hooks/VideoHover";
|
||||
import { ColorUtils } from "../../utils/color";
|
||||
import { TextUtils } from "../../utils/text";
|
||||
import { SceneHelpers } from "./helpers";
|
||||
|
||||
interface ISceneCardProps {
|
||||
scene: GQL.SlimSceneDataFragment;
|
||||
}
|
||||
|
||||
export const SceneCard: FunctionComponent<ISceneCardProps> = (props: ISceneCardProps) => {
|
||||
const [previewPath, setPreviewPath] = useState<string | undefined>(undefined);
|
||||
const videoHoverHook = VideoHoverHook.useVideoHover();
|
||||
|
||||
function maybeRenderRatingBanner() {
|
||||
if (!props.scene.rating) { return; }
|
||||
return (
|
||||
<div className={`rating-banner ${ColorUtils.classForRating(props.scene.rating)}`}>
|
||||
RATING: {props.scene.rating}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function maybeRenderTagPopoverButton() {
|
||||
if (props.scene.tags.length <= 0) { return; }
|
||||
|
||||
const tags = props.scene.tags.map((tag) => (
|
||||
<Tag key={tag.id} className="tag-item">{tag.name}</Tag>
|
||||
));
|
||||
return (
|
||||
<Popover interactionKind={"hover"} position="bottom">
|
||||
<Button
|
||||
icon="tag"
|
||||
text={props.scene.tags.length}
|
||||
/>
|
||||
<>{tags}</>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
function maybeRenderPerformerPopoverButton() {
|
||||
if (props.scene.performers.length <= 0) { return; }
|
||||
|
||||
const performers = props.scene.performers.map((performer) => (
|
||||
<Tag key={performer.id} className="tag-item">{performer.name}</Tag>
|
||||
));
|
||||
return (
|
||||
<Popover interactionKind={"hover"} position="bottom">
|
||||
<Button
|
||||
icon="person"
|
||||
text={props.scene.performers.length}
|
||||
/>
|
||||
<>{performers}</>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
function maybeRenderSceneMarkerPopoverButton() {
|
||||
if (props.scene.scene_markers.length <= 0) { return; }
|
||||
|
||||
const sceneMarkers = props.scene.scene_markers.map((marker) => (
|
||||
<Tag key={marker.id} className="tag-item">{marker.title} - {TextUtils.secondsToTimestamp(marker.seconds)}</Tag>
|
||||
));
|
||||
return (
|
||||
<Popover interactionKind={"hover"} position="bottom">
|
||||
<Button
|
||||
icon="map-marker"
|
||||
text={props.scene.scene_markers.length}
|
||||
/>
|
||||
<>{sceneMarkers}</>
|
||||
</Popover>
|
||||
);
|
||||
}
|
||||
|
||||
function maybeRenderPopoverButtonGroup() {
|
||||
if (props.scene.tags.length > 0 ||
|
||||
props.scene.performers.length > 0 ||
|
||||
props.scene.scene_markers.length > 0) {
|
||||
return (
|
||||
<>
|
||||
<Divider />
|
||||
<ButtonGroup minimal={true} className="card-section centered">
|
||||
{maybeRenderTagPopoverButton()}
|
||||
{maybeRenderPerformerPopoverButton()}
|
||||
{maybeRenderSceneMarkerPopoverButton()}
|
||||
</ButtonGroup>
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function onMouseEnter() {
|
||||
if (!previewPath || previewPath === "") {
|
||||
setPreviewPath(props.scene.paths.preview || "");
|
||||
}
|
||||
VideoHoverHook.onMouseEnter(videoHoverHook);
|
||||
}
|
||||
function onMouseLeave() {
|
||||
VideoHoverHook.onMouseLeave(videoHoverHook);
|
||||
setPreviewPath("");
|
||||
}
|
||||
|
||||
return (
|
||||
<Card
|
||||
className="grid-item"
|
||||
elevation={Elevation.ONE}
|
||||
onMouseEnter={onMouseEnter}
|
||||
onMouseLeave={onMouseLeave}
|
||||
>
|
||||
<Link to={`/scenes/${props.scene.id}`} className="image previewable">
|
||||
{maybeRenderRatingBanner()}
|
||||
<video className="preview" loop={true} poster={props.scene.paths.screenshot || ""} ref={videoHoverHook.videoEl}>
|
||||
{!!previewPath ? <source src={previewPath} /> : ""}
|
||||
</video>
|
||||
</Link>
|
||||
<div className="card-section">
|
||||
<H4 style={{textOverflow: "ellipsis", overflow: "hidden"}}>
|
||||
{!!props.scene.title ? props.scene.title : TextUtils.fileNameFromPath(props.scene.path)}
|
||||
</H4>
|
||||
<span className="bp3-text-small bp3-text-muted">{props.scene.date}</span>
|
||||
<p>{TextUtils.truncate(props.scene.details, 100, "... (continued)")}</p>
|
||||
</div>
|
||||
|
||||
{maybeRenderPopoverButtonGroup()}
|
||||
|
||||
<Divider />
|
||||
<span className="card-section centered">
|
||||
{props.scene.file.size !== undefined ? TextUtils.fileSize(parseInt(props.scene.file.size, 10)) : ""}
|
||||
|
|
||||
{props.scene.file.duration !== undefined ? TextUtils.secondsToTimestamp(props.scene.file.duration) : ""}
|
||||
|
|
||||
{props.scene.file.width} x {props.scene.file.height}
|
||||
</span>
|
||||
{SceneHelpers.maybeRenderStudio(props.scene, 50, true)}
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user