Skip to content

Commit

Permalink
Rewrite previewers (#3)
Browse files Browse the repository at this point in the history
* audio as placeholder

* rewrite audio and video

* enable thumbnail previewer

* pagination works but needs polish

* next page works; not previous page

* bug
  • Loading branch information
longshuicy authored Aug 17, 2021
1 parent 361ec32 commit df78ed9
Show file tree
Hide file tree
Showing 11 changed files with 138 additions and 67 deletions.
6 changes: 4 additions & 2 deletions src/actions/dataset.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,10 @@ export function receiveDatasets(type, json){
});
};
}
export function fetchDatasets(){
let url = `${config.hostname}/clowder/api/datasets?superAdmin=true&limit=10`;
export function fetchDatasets(when, date, limit="5"){
let url = `${config.hostname}/clowder/api/datasets?superAdmin=true&limit=${limit}`;
if (date) url = `${url}&date=${date}`;
if (when) url = `${url}&when=${when}`;
return (dispatch) => {
return fetch(url, {mode:"cors", headers: getHeader()})
.then((response) => {
Expand Down
26 changes: 23 additions & 3 deletions src/components/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ export default function App(props) {
const [fileMetadataList, setFileMetadataList] = useState([]);
const [fileThumbnailList, setFileThumbnailList] = useState([]);
const [datasetThumbnailList, setDatasetThumbnailList] = useState([]);
const [lastDataset, setLastDataset] = useState([]);
const [firstDataset, setFirstDataset] = useState([]);
const [limit, setLimit] = useState(5);

const [paths, setPaths] = useState([]);

Expand All @@ -40,11 +43,10 @@ export default function App(props) {

// component did mount
useEffect(() => {
listDatasets();
listDatasets(null, null, limit);
}, []);

useEffect(() => {

(async () => {
if (datasets !== undefined && datasets.length > 0) {

Expand All @@ -57,6 +59,11 @@ export default function App(props) {
}
}));
setDatasetThumbnailList(datasetThumbnailListTemp);

// find last and first dataset for pagination
setFirstDataset(datasets[0])
setLastDataset(datasets[datasets.length - 1]);

}
})();
}, [datasets])
Expand Down Expand Up @@ -87,6 +94,16 @@ export default function App(props) {
})();
}, [filesInDataset])

const previous = () => {
let date = firstDataset["created"] !== undefined? new Date(firstDataset["created"]) : null;
if (date) listDatasets("b", date.toISOString(), limit);
}

const next = () => {
let date = lastDataset["created"] !== undefined? new Date(lastDataset["created"]) : null;
if (date) listDatasets("a", date.toISOString(), limit);
}

const selectDataset = (selectedDatasetId) => {
// pass that id to dataset component
setSelectedDatasetId(selectedDatasetId);
Expand Down Expand Up @@ -173,7 +190,10 @@ export default function App(props) {
(() => {
if (selectedDatasetId === "") {
return <Dashboard datasets={datasets} selectDataset={selectDataset}
thumbnails={datasetThumbnailList}/>
thumbnails={datasetThumbnailList}
previous={previous}
next={next}
/>
} else if (selectedFileId === "") {
return <Dataset files={filesInDataset} selectFile={selectFile}
thumbnails={fileThumbnailList} about={datasetAbout}/>
Expand Down
6 changes: 4 additions & 2 deletions src/components/Dashbard.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, {useState} from "react";
import {makeStyles} from "@material-ui/core/styles";
import {AppBar, Box, Link, Divider, Grid, ListItem, Tab, Tabs, Typography} from "@material-ui/core";
import {AppBar, Box, Link, Divider, Grid, ListItem, Tab, Tabs, Typography, Button} from "@material-ui/core";
import BusinessCenterIcon from '@material-ui/icons/BusinessCenter';

const useStyles = makeStyles((theme) => ({
Expand Down Expand Up @@ -42,7 +42,7 @@ const useStyles = makeStyles((theme) => ({
export default function Dashboard(props) {
const classes = useStyles();

const {datasets, selectDataset, thumbnails, ...other} = props;
const {datasets, selectDataset, thumbnails, previous, next, ...other} = props;

const [selectedTabIndex, setSelectedTabIndex] = useState(0);

Expand Down Expand Up @@ -97,6 +97,8 @@ export default function Dashboard(props) {
:
<></>
}
<Button onClick={previous}>Prev</Button>
<Button onClick={next}>Next</Button>
</TabPanel>
<TabPanel value={selectedTabIndex} index={1}></TabPanel>
<TabPanel value={selectedTabIndex} index={2}></TabPanel>
Expand Down
102 changes: 46 additions & 56 deletions src/components/File.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@ import {AppBar, Box, Divider, Grid, Tab, Tabs, Typography} from "@material-ui/co
import {makeStyles} from "@material-ui/core/styles";
import {ClowderInput} from "./styledComponents/ClowderInput";
import {ClowderButton} from "./styledComponents/ClowderButton";
import Audio from "./previewers/Audio";
import Video from "./previewers/Video";
import {downloadResource} from "../utils/common";
import Thumbnail from "./previewers/Thumbnail";

const useStyles = makeStyles((theme) => ({
appBar: {
Expand All @@ -25,47 +29,42 @@ export default function File(props) {
const {fileMetadata, fileExtractedMetadata, fileMetadataJsonld, filePreviews, fileId, ...other} = props;

const [selectedTabIndex, setSelectedTabIndex] = useState(0);
const [previews, setPreviews] = useState([]);

// component did mount
useEffect(() => {
// attach helper jquery
const script = document.createElement("script");
script.src = `../public/clowder/assets/javascripts/previewers/helper.js`;
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
}
}, []);
// // component did mount
// useEffect(() => {
// // attach helper jquery
// const script = document.createElement("script");
// script.src = `../public/clowder/assets/javascripts/previewers/helper.js`;
// script.async = true;
// document.body.appendChild(script);
// return () => {
// document.body.removeChild(script);
// }
// }, []);

useEffect(() => {
// remove last previewer script attached
const previewerScripts = document.getElementsByClassName("previewer-script");
while (previewerScripts.length > 0) {
previewerScripts[0].parentNode.removeChild(previewerScripts[0]);
}
(async () => {
if (filePreviews !== undefined && filePreviews.length > 0 && filePreviews[0].previews !== undefined) {
let previewsTemp = [];
await Promise.all(filePreviews[0].previews.map(async (filePreview) => {
// download resources
let Configuration = {};
Configuration.previewType = filePreview["p_id"].replace(" ", "-").toLowerCase();
Configuration.url = `${config.hostname}${filePreview["pv_route"]}?superAdmin=true`;
Configuration.fileid = filePreview["pv_id"];
Configuration.previewer = `/public${filePreview["p_path"]}/`;
Configuration.fileType = filePreview["pv_contenttype"];

if (filePreviews !== undefined && filePreviews.length > 0 && filePreviews[0].previews !== undefined) {
let uniquePid = [];
// look at which previewer to load
filePreviews[0].previews.map((filePreview, index) => {
let resourceURL = `${config.hostname}${filePreview["pv_route"]}?superAdmin=true`;
Configuration.resource = await downloadResource(resourceURL);

// do not attach same previewer twice
if (uniquePid.indexOf(filePreview["p_id"]) === -1) {
uniquePid.push(filePreview["p_id"]);
previewsTemp.push(Configuration);

// attach previwer jquery
const script = document.createElement("script");
script.className = "previewer-script";
script.src = `../public${filePreview["p_path"]}/${filePreview["p_main"]}`;
script.async = true;
document.body.appendChild(script);
return () => {
document.body.removeChild(script);
}
}
});
}
}));
setPreviews(previewsTemp);
}
})();
}, [filePreviews]);

const handleTabChange = (event, newTabIndex) => {
Expand All @@ -87,27 +86,18 @@ export default function File(props) {
</AppBar>
<TabPanel value={selectedTabIndex} index={0}>
{
filePreviews !== undefined && filePreviews.length > 0 && filePreviews[0].previews !== undefined
?
filePreviews[0].previews.map((filePreview, index) => {
const Configuration = {};
Configuration.tab = `#previewer_${filePreviews[0]["file_id"]}_${index}`;
Configuration.url = `${config.hostname}${filePreview["pv_route"]}?superAdmin=true`;
Configuration.fileid = filePreview["pv_id"];
Configuration.previewer = `/public${filePreview["p_path"]}/`;
Configuration.fileType = filePreview["pv_contenttype"];
Configuration.APIKEY = config.apikey;
Configuration.authenticated = true;
// Configuration.metadataJsonld = fileMetadataJsonld;

let previewId = filePreview["p_id"].replace(" ", "-").toLowerCase();
return (<div className={`configuration ${previewId}`}
data-configuration={JSON.stringify(Configuration)}>
<div id={Configuration.tab.slice(1)}></div>
</div>);
})
:
<></>
previews.map((preview) =>{
if (preview["previewType"] === "audio"){
return <Audio fileId={preview["fileid"]} audioSrc={preview["resource"]} />;
}
else if (preview["previewType"] === "video"){
return <Video fileId={preview["fileid"]} videoSrc={preview["resource"]} />;
}
else if (preview["previewType"] === "thumbnail"){
return <Thumbnail fileId={preview["fileid"]} fileType={preview["fileType"]}
imgSrc={preview["resource"]} />;
}
})
}
</TabPanel>
<TabPanel value={selectedTabIndex} index={1}>
Expand Down
1 change: 0 additions & 1 deletion src/components/childComponents/BreadCrumb.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const useStyles = makeStyles((theme) => ({
fontWeight: "600",
fontSize: "24px",
color: "#6C757D",
textTransform: "capitalize"
}
}));

Expand Down
6 changes: 6 additions & 0 deletions src/components/previewers/Audio.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import React from "react";

export default function Audio(props) {
const {fileId, audioSrc, ...other} = props;
return <audio controls><source id={fileId} src={audioSrc} /></audio>
}
22 changes: 22 additions & 0 deletions src/components/previewers/Thumbnail.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import React from "react";
import { Typography } from "@material-ui/core";

export default function Thumbnail(props){
const {fileId, imgSrc, fileType, ...other} = props;
return (
(() => {
if (fileType === "image/jpeg" || fileType === "image/jpg" || fileType === "image/png"
|| fileType === "image/gif" || fileType === "image/bmp"){
return <img className="rubberbandimage" src={imgSrc} alt="img" id={`rubberbandCanvas-${fileId}`}/>;
}
else if (fileType === "image/tiff"){
return <embed alt="No plugin capable of displaying TIFF images was found."
width={750} height={550} src={imgSrc} type="image/tiff" negative="no" id="embedded" />;
}
else{
return <Typography>ERROR: Unrecognised image format.</Typography>;
}

})()
)
}
8 changes: 8 additions & 0 deletions src/components/previewers/Video.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import React from "react";

export default function Video(props) {
const {fileId, videoSrc, ...other} = props;
return (<video width='100%' id='ourvideo' controls>
<source id={fileId} src={videoSrc}></source>
</video>);
}
4 changes: 2 additions & 2 deletions src/containers/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ const mapDispatchToProps = (dispatch) => {
listDatasetAbout: (datasetId) => {
dispatch(fetchDatasetAbout(datasetId));
},
listDatasets: () =>{
dispatch(fetchDatasets());
listDatasets: (when, date, limit) =>{
dispatch(fetchDatasets(when, date, limit));
}
};
};
Expand Down
2 changes: 1 addition & 1 deletion src/reducers/dataset.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { RECEIVE_FILES_IN_DATASET, RECEIVE_DATASET_ABOUT, RECEIVE_DATASETS} from "../actions/dataset";

const defaultState = {files: []};
const defaultState = {files: [], about: {}, datasets: []};

const dataset = (state=defaultState, action) => {
switch(action.type) {
Expand Down
22 changes: 22 additions & 0 deletions src/utils/common.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,28 @@ export function getHeader() {
// });
}

export async function downloadResource(url){
let authHeader = getHeader();
let response = await fetch(url, {
method: "GET",
mode: "cors",
headers: authHeader,
});

if (response.status === 200){
let blob = await response.blob();
return window.URL.createObjectURL(blob);
}
else if (response.status === 401){
// TODO handle error
return null;
}
else {
// TODO handle error
return null;
}
}

// get current username
// export function getCurrUsername(){
// if (process.env.DEPLOY_ENV === "local"){
Expand Down

0 comments on commit df78ed9

Please sign in to comment.