Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 35 additions & 35 deletions client/src/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,64 +5,64 @@ import './App.css';

function App() {
const [response, setResponse] = useState({});
const [show, setShow] = useState(false);
const [loading, setLoading] = useState(false);
const [fetchError, setFetchError] = useState('');
const [pdfBlob, setPdfBlob] = useState(null);
const [buffer, setBuffer] = useState(null);

const loadURL = (url, width, height) => {
setShow(true);
fetch(
`http://127.0.0.1:3001/website?url=${url}&width=${width}&height=${height}`
)
.then(async (response) => {
if (response.ok) {
const json = await response.json();
if (json.data.url) {
json.data.url = `http://localhost:3000/redirect/${json.data.url}`;
}
setResponse({
url: json.data.url,
width,
height,
thumb: json.data.thumb,
origUrl: url
});
setShow(false);
const PORT = 3100;
const PATH = `0.0.0.0:${PORT}`;


const loadURL = (url) => {
setLoading(true);
setFetchError('');
fetch(`http://${PATH}/website-proxy-pdftron?url=${url}`)
.then(async (res) => {
var size = { width: 1800, height: 7000 };
try {
size = JSON.parse(res.statusText);
} catch (e) {
}
setResponse({
url: `http://${PATH}`,
thumb: '',
...size,
origUrl: `http://${PATH}`,
});
setLoading(false);
})
.catch((err) => {
setShow(false);
setLoading(false);
setFetchError(
'Trouble fetching the URL, please make sure the server is running. `cd server && npm start`'
);
});
};

const downloadPDF = () => {
setShow(true);
if (response.url) {
const urlArray = response.url.split('/');
fetch(
`http://127.0.0.1:3001/getpdf?url=${urlArray[4]}&width=${response.width}&height=${response.height}`
).then((res) => {
return res.blob('application/pdf');
}).then((blob) => {
console.log(blob);
setPdfBlob(blob);
});
setLoading(true);
fetch(`http://${PATH}/pdftron-pdf`)
.then(async (res) => {
console.log(res);
setBuffer(res);
setLoading(false);
}).catch(err => console.log(err));
}
setShow(false);
};

// receive new loading state from Viewer as loadDocAndAnnots takes a while
const loadingFromViewer = (value) => setLoading(value);

return (
<div className="App">
<Nav
handleSubmit={loadURL}
fetchError={fetchError}
showSpinner={show}
showSpinner={loading}
handleDownload={downloadPDF}
/>
<Viewer res={response} loadURL={loadURL} pdf={pdfBlob} />
<Viewer res={response} loadURL={loadURL} buffer={buffer} loading={loadingFromViewer} />
</div>
);
}
Expand Down
47 changes: 15 additions & 32 deletions client/src/components/navigation/Nav.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,54 +14,39 @@ import './Nav.css';

const Nav = ({ handleSubmit, fetchError, showSpinner, handleDownload }) => {
const [url, setUrl] = useState('');
const [width, setWidth] = useState(1000);
const [height, setHeight] = useState(2000);
const [error, setError] = useState(false);

// test is URL (without https://) is valid https://regexr.com/3e6m0
const isValidURL = (url) => {
// eslint-disable-next-line no-useless-escape
return /(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/gi.test(url);
}

return (
<div className="Nav">
<Heading size="md">WebViewer HTML</Heading>
<Text py={5}>
In this demo, you can pass any URL. The URL passed in will be scraped
and saved server-side as a snapshot in time. Then you will be annotate
that copy here.
In this demo, you can pass any URL. The URL passed in will be proxied
and you will be able to annotate directly here.
</Text>
<FormControl id="domain">
<FormLabel>URL of the page</FormLabel>
<InputGroup
onChange={(e) => {
setUrl(`http://${e.target.value}`);
setUrl(e.target.value);
}}
>
<InputLeftAddon children="http://" />
<InputLeftAddon children="https://" />
<Input placeholder="mysite" />
</InputGroup>
</FormControl>
<FormControl id="width">
<FormLabel>Width of the page</FormLabel>
<Input
size="md"
onChange={(e) => {
setWidth(e.target.value);
}}
value={width}
/>
</FormControl>
<FormControl id="height">
<FormLabel>Height of the page</FormLabel>
<Input
size="md"
onChange={(e) => {
setHeight(e.target.value);
}}
placeholder="2000"
value={height}
/>
<FormControl>
<Button
my={3}
onClick={() => {
if (url !== '' && width !== 0 && height !== 0) {
handleSubmit(url, width, height);
setError(false);
if (!!url && isValidURL(url)) {
handleSubmit(`https://${url}`);
} else {
setError(true);
}
Expand All @@ -70,8 +55,6 @@ const Nav = ({ handleSubmit, fetchError, showSpinner, handleDownload }) => {
{showSpinner && <Spinner mx={1} label="Loading website" />}Load the
website
</Button>
</FormControl>
<FormControl id="downloadPDF">
<Button my={3} onClick={() => handleDownload()}>
{showSpinner && <Spinner mx={1} label="Loading website" />}Download
annotated PDF
Expand All @@ -80,7 +63,7 @@ const Nav = ({ handleSubmit, fetchError, showSpinner, handleDownload }) => {

{error && (
<Text color="red">
Please enter a valid URL, width and height and try again.
Please enter a valid URL try again.
</Text>
)}
{fetchError ? <Text color="red">{fetchError}</Text> : null}
Expand Down
31 changes: 21 additions & 10 deletions client/src/components/viewer/Viewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,11 @@ import { initializeHTMLViewer } from '@pdftron/webviewer-html';
import { useEffect, useRef, useState } from 'react';
import './Viewer.css';

const Viewer = ({ res, loadURL, pdf }) => {
const Viewer = ({ res, loadURL, buffer, loading }) => {
const viewer = useRef(null);
const [HTMLModule, setHTMLModule] = useState(null);
const [instance, setInstance] = useState(null);
const [size, setSize] = useState({});

useEffect(() => {
WebViewer(
Expand All @@ -17,7 +18,7 @@ const Viewer = ({ res, loadURL, pdf }) => {
).then(async (instance) => {
const { FitMode, docViewer } = instance;
setInstance(instance);
instance.setFitMode(FitMode.FitPage);
instance.setFitMode(FitMode.FitWidth);
// disable some incompatible tools
instance.disableElements([
'highlightToolGroupButton',
Expand All @@ -35,47 +36,57 @@ const Viewer = ({ res, loadURL, pdf }) => {

docViewer.on('documentLoaded', () => {
setTimeout(() => {
instance.setFitMode(FitMode.FitPage);
if (instance.getFitMode() !== FitMode.FitWidth) {
instance.setFitMode(FitMode.FitWidth);
}
}, 1500);
});

setHTMLModule(htmlModule);

loadURL(`https://www.pdftron.com/`, 1800, 1100);
loadURL(`https://www.pdftron.com/`);
});
// eslint-disable-next-line
}, []);

useEffect(() => {
if (HTMLModule && Object.keys(res).length > 0) {
const { url, width, height, thumb, origUrl } = res;
setSize({width, height});
HTMLModule.loadHTMLPage({ url, width, height, thumb, origUrl });
}
}, [HTMLModule, res]);

useEffect(() => {
const loadDocAndAnnots = async () => {
const doc = await instance.CoreControls.createDocument(pdf);
loading(true);
const doc = await instance.Core.createDocument(buffer, {
extension: 'png',
pageSizes: [size],
});

// exportAnnotations as xfdfString seem to misplace annotations
const xfdf = await instance.docViewer
.getAnnotationManager()
.exportAnnotations();
const data = await doc.getFileData({ xfdfString: xfdf });
const arr = new Uint8Array(data);
const blob = new Blob([arr], { type: 'application/pdf' });
const blob = new Blob([data], { type: 'application/pdf' });
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = 'annotated';
a.click();
a.remove();
loading(false);
// in case the Blob uses a lot of memory
setTimeout(() => URL.revokeObjectURL(url), 7000);
setTimeout(() => URL.revokeObjectURL(url), 5000);
};

if (instance && pdf) {
if (instance && buffer) {
loadDocAndAnnots();
}
}, [instance, pdf]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [instance, buffer]);

return <div ref={viewer} className="HTMLViewer"></div>;
};
Expand Down
12 changes: 0 additions & 12 deletions client/src/setupProxy.js

This file was deleted.

Loading