Displaying helpful error when iframes do not load.

This commit is contained in:
Roland 2024-06-17 10:40:30 -06:00
parent 0bee458b79
commit bd431165e5
No known key found for this signature in database
GPG key ID: 9D6DBD3ACF11AB93
8 changed files with 97 additions and 18 deletions

View file

@ -127,6 +127,7 @@ Steps necessary to initialize your WROLPi after installing the Raspberry Pi imag
1. Storage is cheaper than power.
2. Two is one, one is none.
3. Run silently.
4. Primary, secondary, tertiary.
## Physical properties

View file

@ -13,7 +13,7 @@ import {FilesRoute} from "./components/Files";
import {QueryProvider, StatusProvider} from "./hooks/customHooks";
import {MapRoute} from "./components/Map";
import {MediaContextProvider, mediaStyles, StatusContext, ThemeContext} from "./contexts/contexts";
import {Header, ThemeProvider} from "./components/Theme";
import {Header, Segment, ThemeProvider} from "./components/Theme";
import {DashboardPage} from "./DashboardPage";
import {DonatePage} from "./components/DonatePage";
import {useEventsInterval} from "./Events";
@ -21,7 +21,7 @@ import {SemanticToastContainer} from "react-semantic-toasts-2";
import {FilePreviewProvider} from "./components/FilePreview";
import {TagsProvider} from "./Tags";
import {ZimRoute} from "./components/Zim";
import {HELP_VIEWER_URI} from "./components/Common";
import {HELP_VIEWER_URI, IframeViewer} from "./components/Common";
function PageNotFound() {
const {t} = useContext(ThemeContext);
@ -50,15 +50,18 @@ function Footer() {
}
function HelpPage() {
return <iframe
title='map'
src={HELP_VIEWER_URI}
style={{
position: 'fixed',
height: '100%',
width: '100%',
border: 'none',
}}/>
const fallback = <Segment>
<Header as='h3'>Failed to fetch Help service.</Header>
<p>You may need to give permission to access the page: <a href={HELP_VIEWER_URI}>{HELP_VIEWER_URI}</a></p>
<p>If the above does not work, try starting the service:</p>
<pre>sudo systemctl start wrolpi-kiwix</pre>
<p>Check the logs</p>
<pre>journalctl -u wrolpi-kiwix</pre>
</Segment>;
return <IframeViewer title='help' src={HELP_VIEWER_URI} fallback={fallback}/>
}
function Root() {

View file

@ -5,6 +5,7 @@ import {
Card,
Confirm,
Container,
Dimmer, DimmerDimmable,
Icon as SIcon,
IconGroup,
Input,
@ -34,6 +35,7 @@ import {
Header,
Icon,
lightTheme,
Loader,
Menu,
Modal,
ModalActions,
@ -41,6 +43,7 @@ import {
ModalDescription,
ModalHeader,
Popup,
Segment,
Statistic
} from "./Theme";
import {FilePreviewContext} from "./FilePreview";
@ -1690,13 +1693,44 @@ export const monthNames = [
'December',
];
export function IframeViewer({title, viewerUrl}) {
export function IframeViewer({title, src, fallback, timeout = 5000}) {
// Bottom of iframe is hidden when height is 100%. These values display the entire iframe.
return <>
const [contentAvailable, setContentAvailable] = useState(false);
const [loading, setLoading] = useState(true);
const {s} = React.useContext(ThemeContext);
fallback = fallback || <pre {...s}>Frame could not load.</pre>;
useEffect(() => {
const controller = new AbortController(); // To manage fetch timeout
const timeoutId = setTimeout(() => {
controller.abort(); // Abort the fetch after 5 seconds
}, timeout);
fetch(src, {signal: controller.signal})
.then(response => {
if (response.ok) {
setContentAvailable(true); // If fetch is successful and response is ok, set to load the iframe
} else {
setContentAvailable(false); // If response is not ok, do not load the iframe
}
})
.catch(() => {
setContentAvailable(false); // Handle fetch errors (including aborts)
})
.finally(() => {
setLoading(false); // Update loading state regardless of result
clearTimeout(timeoutId); // Clear the timeout
});
return () => clearTimeout(timeoutId); // Cleanup timeout on unmount
}, [src]);
const iframeMedia = <>
<Media at='mobile'>
<iframe
title={title}
src={viewerUrl}
src={src}
style={{
position: 'fixed',
height: '80%',
@ -1709,7 +1743,7 @@ export function IframeViewer({title, viewerUrl}) {
<Media greaterThan='mobile'>
<iframe
title={title}
src={viewerUrl}
src={src}
style={{
position: 'fixed',
height: '93%',
@ -1719,6 +1753,14 @@ export function IframeViewer({title, viewerUrl}) {
backgroundColor: '#FFFFFF',
}}/>
</Media>
</>;
const dimmer = <DimmerDimmable as={Segment} dimmed={true}><Dimmer active><Loader/></Dimmer></DimmerDimmable>;
return <>
{loading ? dimmer
: contentAvailable ? iframeMedia
: fallback
}
</>
}

View file

@ -29,7 +29,7 @@ import {
TableRow
} from "semantic-ui-react";
import Message from "semantic-ui-react/dist/commonjs/collections/Message";
import {Loader, Placeholder, Table} from "./Theme";
import {Header, Loader, Placeholder, Segment, Table} from "./Theme";
import {StatusContext} from "../contexts/contexts";
import _ from "lodash";
@ -291,7 +291,20 @@ class ManageMap extends React.Component {
}
function MapPage() {
return <IframeViewer title='map' viewerUrl={MAP_VIEWER_URI}/>
const fallback = <Segment>
<Header as='h3'>Failed to fetch Map service.</Header>
<p>You may need to give permission to access the page: <a href={MAP_VIEWER_URI}>{MAP_VIEWER_URI}</a></p>
<p>If the above does not work, try starting the service:</p>
<pre>sudo systemctl start renderd</pre>
<pre>sudo systemctl start apache2</pre>
<p>Check the logs</p>
<pre>journalctl -u renderd</pre>
<pre>sudo tail -f /var/log/apache2/*lo</pre>
</Segment>;
return <IframeViewer title='map' src={MAP_VIEWER_URI} fallback={fallback}/>
}
export function MapRoute() {

View file

@ -535,7 +535,18 @@ class ManageZim extends React.Component {
}
function ZimViewer() {
return <IframeViewer title='zim' viewerUrl={ZIM_VIEWER_URI}/>
const fallback = <Segment>
<Header as='h3'>Failed to fetch Zim service.</Header>
<p>You may need to give permission to access the page: <a href={ZIM_VIEWER_URI}>{ZIM_VIEWER_URI}</a></p>
<p>If the above does not work, try starting the service:</p>
<pre>sudo systemctl start wrolpi-kiwix</pre>
<p>Check the logs</p>
<pre>journalctl -u wrolpi-kiwix</pre>
</Segment>;
return <IframeViewer title='zim' src={ZIM_VIEWER_URI} fallback={fallback}/>
}
export function ZimRoute() {

View file

@ -7,12 +7,15 @@ http {
ssl_certificate /cert.crt;
ssl_certificate_key /cert.key;
add_header 'Access-Control-Allow-Origin' '*';
location / {
proxy_pass http://help:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header 'Access-Control-Allow-Origin' '*';
}
}
}

View file

@ -7,12 +7,15 @@ http {
ssl_certificate /cert.crt;
ssl_certificate_key /cert.key;
add_header 'Access-Control-Allow-Origin' '*';
location / {
proxy_pass http://map:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header 'Access-Control-Allow-Origin' '*';
}
}
}

View file

@ -7,12 +7,15 @@ http {
ssl_certificate /cert.crt;
ssl_certificate_key /cert.key;
add_header 'Access-Control-Allow-Origin' '*';
location / {
proxy_pass http://zim:80;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_set_header 'Access-Control-Allow-Origin' '*';
}
}
}