mirror of
https://github.com/Stremio/stremio-web.git
synced 2026-04-28 23:04:08 +00:00
handle core initialization error with a ui dialog
This commit is contained in:
parent
0ea77ede67
commit
2a8d7ab0cb
5 changed files with 141 additions and 18 deletions
|
|
@ -7,6 +7,7 @@ const { Core, Shell, Chromecast, KeyboardShortcuts, ServicesProvider } = require
|
||||||
const { NotFound } = require('stremio/routes');
|
const { NotFound } = require('stremio/routes');
|
||||||
const { ToastProvider, sanitizeLocationPath, CONSTANTS } = require('stremio/common');
|
const { ToastProvider, sanitizeLocationPath, CONSTANTS } = require('stremio/common');
|
||||||
const CoreEventsToaster = require('./CoreEventsToaster');
|
const CoreEventsToaster = require('./CoreEventsToaster');
|
||||||
|
const ErrorDialog = require('./ErrorDialog');
|
||||||
const routerViewsConfig = require('./routerViewsConfig');
|
const routerViewsConfig = require('./routerViewsConfig');
|
||||||
const styles = require('./styles');
|
const styles = require('./styles');
|
||||||
|
|
||||||
|
|
@ -26,8 +27,7 @@ const App = () => {
|
||||||
chromecast: new Chromecast(),
|
chromecast: new Chromecast(),
|
||||||
keyboardShortcuts: new KeyboardShortcuts()
|
keyboardShortcuts: new KeyboardShortcuts()
|
||||||
}), []);
|
}), []);
|
||||||
const [coreInitialized, setCoreInitialized] = React.useState(false);
|
const [initialized, setInitialized] = React.useState(false);
|
||||||
const [shellInitialized, setShellInitialized] = React.useState(false);
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
let prevPath = window.location.hash.slice(1);
|
let prevPath = window.location.hash.slice(1);
|
||||||
const onLocationHashChange = () => {
|
const onLocationHashChange = () => {
|
||||||
|
|
@ -46,13 +46,16 @@ const App = () => {
|
||||||
}, []);
|
}, []);
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const onCoreStateChanged = () => {
|
const onCoreStateChanged = () => {
|
||||||
setCoreInitialized(services.core.active);
|
setInitialized(
|
||||||
if (services.core.error) {
|
(services.core.active || services.core.error instanceof Error) &&
|
||||||
alert(services.core.error);
|
(services.shell.active || services.shell.error instanceof Error)
|
||||||
}
|
);
|
||||||
};
|
};
|
||||||
const onShellStateChanged = () => {
|
const onShellStateChanged = () => {
|
||||||
setShellInitialized(services.shell.active || services.shell.error instanceof Error);
|
setInitialized(
|
||||||
|
(services.core.active || services.core.error instanceof Error) &&
|
||||||
|
(services.shell.active || services.shell.error instanceof Error)
|
||||||
|
);
|
||||||
};
|
};
|
||||||
const onChromecastStateChange = () => {
|
const onChromecastStateChange = () => {
|
||||||
if (services.chromecast.active) {
|
if (services.chromecast.active) {
|
||||||
|
|
@ -86,17 +89,20 @@ const App = () => {
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<ServicesProvider services={services}>
|
<ServicesProvider services={services}>
|
||||||
{
|
{
|
||||||
coreInitialized && shellInitialized ?
|
initialized ?
|
||||||
<ToastProvider className={styles['toasts-container']}>
|
services.core.error instanceof Error ?
|
||||||
<CoreEventsToaster />
|
<ErrorDialog className={styles['error-container']} />
|
||||||
<Router
|
:
|
||||||
className={styles['router']}
|
<ToastProvider className={styles['toasts-container']}>
|
||||||
viewsConfig={routerViewsConfig}
|
<CoreEventsToaster />
|
||||||
onPathNotMatch={onPathNotMatch}
|
<Router
|
||||||
/>
|
className={styles['router']}
|
||||||
</ToastProvider>
|
viewsConfig={routerViewsConfig}
|
||||||
|
onPathNotMatch={onPathNotMatch}
|
||||||
|
/>
|
||||||
|
</ToastProvider>
|
||||||
:
|
:
|
||||||
<div className={styles['app-loader']} />
|
<div className={styles['loader-container']} />
|
||||||
}
|
}
|
||||||
</ServicesProvider>
|
</ServicesProvider>
|
||||||
</React.StrictMode>
|
</React.StrictMode>
|
||||||
|
|
|
||||||
42
src/App/ErrorDialog/ErrorDialog.js
Normal file
42
src/App/ErrorDialog/ErrorDialog.js
Normal file
|
|
@ -0,0 +1,42 @@
|
||||||
|
// Copyright (C) 2017-2020 Smart code 203358507
|
||||||
|
|
||||||
|
const React = require('react');
|
||||||
|
const PropTypes = require('prop-types');
|
||||||
|
const classnames = require('classnames');
|
||||||
|
const { Button, Image } = require('stremio/common');
|
||||||
|
const styles = require('./styles');
|
||||||
|
|
||||||
|
const ErrorDialog = ({ className }) => {
|
||||||
|
const reload = React.useCallback(() => {
|
||||||
|
window.location.reload();
|
||||||
|
}, []);
|
||||||
|
const clearData = React.useCallback(() => {
|
||||||
|
window.localStorage.clear();
|
||||||
|
}, []);
|
||||||
|
return (
|
||||||
|
<div className={classnames(className, styles['error-container'])}>
|
||||||
|
<Image
|
||||||
|
className={styles['error-image']}
|
||||||
|
src={require('/images/empty.png')}
|
||||||
|
alt={' '}
|
||||||
|
/>
|
||||||
|
<div className={styles['error-message']}>Something went wrong!</div>
|
||||||
|
<div className={styles['buttons-container']}>
|
||||||
|
<Button className={styles['button-container']} title={'Try again'} onClick={reload}>
|
||||||
|
<div className={styles['label']}>Try again</div>
|
||||||
|
</Button>
|
||||||
|
<Button className={styles['button-container']} title={'Clear data'} onClick={clearData}>
|
||||||
|
<div className={styles['label']}>Clear data</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
ErrorDialog.displayName = 'ErrorDialog';
|
||||||
|
|
||||||
|
ErrorDialog.propTypes = {
|
||||||
|
className: PropTypes.string
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports = ErrorDialog;
|
||||||
5
src/App/ErrorDialog/index.js
Normal file
5
src/App/ErrorDialog/index.js
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
// Copyright (C) 2017-2020 Smart code 203358507
|
||||||
|
|
||||||
|
const ErrorDialog = require('./ErrorDialog');
|
||||||
|
|
||||||
|
module.exports = ErrorDialog;
|
||||||
70
src/App/ErrorDialog/styles.less
Normal file
70
src/App/ErrorDialog/styles.less
Normal file
|
|
@ -0,0 +1,70 @@
|
||||||
|
// Copyright (C) 2017-2020 Smart code 203358507
|
||||||
|
|
||||||
|
@import (reference) '~@stremio/stremio-colors/less/stremio-colors.less';
|
||||||
|
|
||||||
|
.error-container {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.error-image {
|
||||||
|
flex: none;
|
||||||
|
width: 12rem;
|
||||||
|
height: 12rem;
|
||||||
|
margin-bottom: 1rem;
|
||||||
|
object-fit: contain;
|
||||||
|
object-position: center;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error-message {
|
||||||
|
flex: none;
|
||||||
|
padding: 0 3rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
max-height: 3.6em;
|
||||||
|
text-align: center;
|
||||||
|
color: @color-surface-light5-90;
|
||||||
|
}
|
||||||
|
|
||||||
|
.buttons-container {
|
||||||
|
flex: none;
|
||||||
|
align-self: stretch;
|
||||||
|
margin: 0 2rem;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
flex-wrap: wrap;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
.button-container {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-basis: auto;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
margin: 2rem 1rem 0;
|
||||||
|
padding: 0 1rem;
|
||||||
|
min-width: 8rem;
|
||||||
|
height: 3rem;
|
||||||
|
background-color: @color-accent3;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: @color-accent3-light1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.label {
|
||||||
|
flex-grow: 0;
|
||||||
|
flex-shrink: 1;
|
||||||
|
flex-basis: auto;
|
||||||
|
max-height: 2.4em;
|
||||||
|
font-size: 1.1rem;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
color: @color-surface-light5-90;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -104,7 +104,7 @@ html {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-loader {
|
.loader-container, .error-container {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
background-color: @color-background-dark2;
|
background-color: @color-background-dark2;
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue