frontend/app/Entry/details/MetadataTable.tsx (135 lines of code) (raw):
import React, {useState, useEffect} from "react";
import MediaDurationComponent from "../../common/MediaDurationComponent";
import FileSizeView from "../FileSizeView";
import {ArchiveEntry} from "../../types";
import {IconButton, makeStyles} from "@material-ui/core";
import clsx from "clsx";
import PathDisplayComponent from "../../browse/PathDisplayComponent";
import {FileInfo, extractFileInfo} from "../../common/Fileinfo";
import {Launch} from "@material-ui/icons";
interface MetadataTableProps {
entry: ArchiveEntry;
tableRowsInsert?: React.ReactFragment[];
openClicked?: (itemId:string)=>void;
}
const useStyles = makeStyles({
metadataTable: {
marginTop: "1em",
border: "none"
},
metadataHeading: {
fontWeight: "bold",
border: "none",
textAlign: "right",
paddingRight: "0.8em",
paddingTop: 0,
paddingBottom: 0
},
metadataEntry: {
border: "none",
textAlign: "left",
paddingTop: 0,
paddingBottom: 0
},
spaceBelow: {
paddingBottom: "0.8em"
}
});
const MetadataTable:React.FC<MetadataTableProps> = (props) => {
const [firstVideoStream, setFirstVideoStream] = useState<any|undefined>(undefined);
const [firstAudioStream, setFirstAudioStream] = useState<any|undefined>(undefined);
const [videoStreamCount, setVideoStreamCount] = useState(0);
const [audioStreamCount, setAudioStreamCount] = useState(0);
const classes = useStyles();
/**
* cache some information that is more expensive to obtain
*/
useEffect(()=>{
if(props.entry.mediaMetadata ) {
const vStreams = props.entry.mediaMetadata.streams.filter(entry => entry.codec_type === "video");
const aStreams = props.entry.mediaMetadata.streams.filter(entry => entry.codec_type === "audio");
setFirstVideoStream(vStreams.length > 0 ? vStreams[0] : undefined);
setFirstAudioStream(aStreams.length > 0 ? aStreams[0] : undefined);
setVideoStreamCount(vStreams.length);
setAudioStreamCount(aStreams.length);
} else {
setFirstAudioStream(undefined);
setFirstAudioStream(undefined);
setVideoStreamCount(0);
setAudioStreamCount(0);
}
}, [props.entry]);
const fileinfo:FileInfo = extractFileInfo(props.entry.path);
return <table className={classes.metadataTable}>
<tbody>
{
props.openClicked ? <tr>
<td className={clsx(classes.metadataHeading, classes.spaceBelow)}>Open</td>
<td className={classes.metadataEntry}>
<IconButton onClick={()=>props.openClicked ? props.openClicked(props.entry.id) : null}>
<Launch/>
</IconButton>
</td>
</tr> : null
}
<tr>
<td className={clsx(classes.metadataHeading, classes.spaceBelow)}>Name</td>
<td className={classes.metadataEntry}>{fileinfo.filename}</td>
</tr>
<tr>
<td className={clsx(classes.metadataHeading, classes.spaceBelow)}>Catalogue</td>
<td className={classes.metadataEntry}>{props.entry.bucket}</td>
</tr>
<tr>
<td className={classes.metadataHeading}>Channels</td>
<td className={classes.metadataEntry}>
<span>{videoStreamCount} video, {audioStreamCount} audio</span>
</td>
</tr>
<tr>
<td className={classes.metadataHeading}>Format</td>
<td className={classes.metadataEntry}>
<span>{firstVideoStream ? firstVideoStream.codec_name : "(none)"} / {firstAudioStream ? firstAudioStream.codec_name : "(none)"}</span>
</td>
</tr>
<tr>
<td className={classes.metadataHeading}>Resolution</td>
<td className={classes.metadataEntry}>{
firstVideoStream ? <span>{firstVideoStream.width} x {firstVideoStream.height}</span> :
<p className="information dont-expand">no data</p>
}</td>
</tr>
<tr>
<td className={classes.metadataHeading}>Duration</td>
<td className={classes.metadataEntry}>{
props.entry.mediaMetadata && props.entry.mediaMetadata.format ?
<MediaDurationComponent value={props.entry.mediaMetadata.format.duration}/> :
<p className="information dont-expand">no data</p>
}</td>
</tr>
<tr>
<td className={clsx(classes.metadataHeading, classes.spaceBelow)}>Audio</td>
<td className={classes.metadataEntry}>{
firstAudioStream ? firstAudioStream.channel_layout :
<p className="information dont-expand">no data</p>
}</td>
</tr>
<tr>
<td className={classes.metadataHeading}>File path</td>
<td className={classes.metadataEntry}>{fileinfo.filepath==="" ? <i>root</i> : <PathDisplayComponent path={fileinfo.filepath}/>}</td>
</tr>
<tr>
<td className={clsx(classes.metadataHeading, classes.spaceBelow)}>File size</td>
<td className={classes.metadataEntry}><FileSizeView rawSize={props.entry.size}/></td>
</tr>
<tr>
<td className={classes.metadataHeading}>Data type</td>
<td className={classes.metadataEntry}>{props.entry.mimeType.major}/{props.entry.mimeType.minor}</td>
</tr>
<tr>
<td className={classes.metadataHeading}>Storage class</td>
<td className={classes.metadataEntry}>{props.entry.storageClass}</td>
</tr>
{ props.tableRowsInsert ? props.tableRowsInsert : null }
</tbody>
</table>
}
export {extractFileInfo};
export default MetadataTable;