app/Frontpage/ItemTile.tsx (148 lines of code) (raw):

import React, { CSSProperties, useContext } from "react"; import { VidispineItem } from "../vidispine/item/VidispineItem"; import { AccessTime, BathtubTwoTone, ComputerTwoTone, DescriptionTwoTone, MovieTwoTone, PanoramaTwoTone, Person, VolumeUpTwoTone, } from "@material-ui/icons"; import VidispineContext from "../Context/VidispineContext"; import { format, parseISO } from "date-fns"; import { makeStyles } from "@material-ui/core/styles"; interface ItemTileProps { item: VidispineItem; imageMaxWidth: number; imageMaxHeight: number; key?: string; style?: CSSProperties; onClick: (itemId: string) => void; } const mimeRegex = new RegExp("^([\\w\\d]+)/.*$"); const useStyles = makeStyles((theme) => ({ itemFilename: { whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", }, itemId: { fontSize: "13px", }, itemCreated: { fontSize: "13px", }, itemOwner: { fontSize: "13px", whiteSpace: "nowrap", overflow: "hidden", textOverflow: "ellipsis", }, inlineIcon: { maxHeight: "13px", marginRight: "0.2em", }, itemThumbnail: { display: "flex", justifyContent: "center", alignContent: "center", width: "240px", margin: "-8px", marginTop: "0!important", }, itemBox: { backgroundColor: theme.palette.type == "dark" ? "#222222" : "#DDDDDD", marginTop: "6px", marginBottom: "6px", borderRadius: "6px", width: "240px", display: "grid", cursor: "pointer", gridTemplateColumns: "200px", gridTemplateRows: "20px 18px 144px 20px", fontSize: "14px", padding: "8px", height: "240px", }, })); const ItemTile: React.FC<ItemTileProps> = (props) => { const classes = useStyles(); const maybeThumbnail = props.item.getMetadataString( "representativeThumbnailNoAuth" ); const vidispineContext = useContext(VidispineContext); /** * get the "major" portion of the mimetype, or undefined if it can't be found */ const getMimeMajorType = () => { const maybeMimeType = props.item.getMetadataString("mimeType"); const matches = maybeMimeType ? mimeRegex.exec(maybeMimeType) : undefined; return matches ? matches[1].toLowerCase() : undefined; }; /** * get an icon representing the mime type, or a default one otherwise */ const mediaTypeIcon = () => { switch (getMimeMajorType()) { case "video": return <MovieTwoTone style={{ width: "104px", height: "104px" }} />; case "audio": return <VolumeUpTwoTone style={{ width: "104px", height: "104px" }} />; case "text": return ( <DescriptionTwoTone style={{ width: "104px", height: "104px" }} /> ); case "application": return <ComputerTwoTone style={{ width: "104px", height: "104px" }} />; case "image": return <PanoramaTwoTone style={{ width: "104px", height: "104px" }} />; default: return <BathtubTwoTone style={{ width: "104px", height: "104px" }} />; } }; const formatCreatedDate = () => { const created = props.item.getMetadataString("created"); try { const createdDate = created ? parseISO(created) : undefined; return createdDate ? format(createdDate, "eee dd/MM/yyyy HH:mm:ss") : ""; } catch (err) { console.error(`could not parse and format ${created}: ${err}`); return "(invalid date)"; } }; return ( <div className={classes.itemBox} onClick={(evt) => props.onClick(props.item.id)} style={props.style} //this is set by react-window and allows us to virtualise a large number of tiles, i.e. only render what's visible > <div className={classes.itemFilename}> <strong> {props.item.getMetadataString("originalFilename") ?? props.item.getMetadataString("title")} </strong> </div> <div className={classes.itemId}>{props.item.id}</div> <div className={classes.itemThumbnail}> {maybeThumbnail && vidispineContext ? ( <img src={vidispineContext.baseUrl + maybeThumbnail} alt="Item thumbnail" style={{ maxWidth: props.imageMaxWidth, maxHeight: props.imageMaxHeight, }} className="thumbnail" /> ) : ( mediaTypeIcon() )} </div> <div className={classes.itemOwner}> <Person className={classes.inlineIcon} /> {props.item.getMetadataValuesInGroup("gnm_owner", "Asset")} </div> <div className={classes.itemCreated}> <AccessTime className={classes.inlineIcon} /> {formatCreatedDate()} </div> </div> ); }; export default ItemTile;