|
|
|
import PropTypes from 'prop-types';
|
|
|
|
import React, { Component } from 'react';
|
|
|
|
import { connect } from 'react-redux';
|
|
|
|
import { withRouter } from 'react-router-dom';
|
|
|
|
import { createSelector } from 'reselect';
|
|
|
|
import { saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
|
|
|
|
import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
|
|
|
|
import { fetchIndexers } from 'Store/Actions/indexerActions';
|
|
|
|
import { fetchIndexerStatus } from 'Store/Actions/indexerStatusActions';
|
|
|
|
import { fetchAppProfiles, fetchGeneralSettings, fetchIndexerCategories, fetchUISettings } from 'Store/Actions/settingsActions';
|
|
|
|
import { fetchStatus } from 'Store/Actions/systemActions';
|
|
|
|
import { fetchTags } from 'Store/Actions/tagActions';
|
|
|
|
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
|
|
|
|
import createSystemStatusSelector from 'Store/Selectors/createSystemStatusSelector';
|
|
|
|
import ErrorPage from './ErrorPage';
|
|
|
|
import LoadingPage from './LoadingPage';
|
|
|
|
import Page from './Page';
|
|
|
|
|
|
|
|
function testLocalStorage() {
|
|
|
|
const key = 'prowlarrTest';
|
|
|
|
|
|
|
|
try {
|
|
|
|
localStorage.setItem(key, key);
|
|
|
|
localStorage.removeItem(key);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
} catch (e) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const selectAppProps = createSelector(
|
|
|
|
(state) => state.app.isSidebarVisible,
|
|
|
|
(state) => state.app.version,
|
|
|
|
(state) => state.app.isUpdated,
|
|
|
|
(state) => state.app.isDisconnected,
|
|
|
|
(isSidebarVisible, version, isUpdated, isDisconnected) => {
|
|
|
|
return {
|
|
|
|
isSidebarVisible,
|
|
|
|
version,
|
|
|
|
isUpdated,
|
|
|
|
isDisconnected
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
const selectIsPopulated = createSelector(
|
|
|
|
(state) => state.customFilters.isPopulated,
|
|
|
|
(state) => state.tags.isPopulated,
|
|
|
|
(state) => state.settings.ui.isPopulated,
|
|
|
|
(state) => state.settings.general.isPopulated,
|
|
|
|
(state) => state.settings.appProfiles.isPopulated,
|
|
|
|
(state) => state.indexers.isPopulated,
|
|
|
|
(state) => state.indexerStatus.isPopulated,
|
|
|
|
(state) => state.settings.indexerCategories.isPopulated,
|
|
|
|
(state) => state.system.status.isPopulated,
|
|
|
|
(
|
|
|
|
customFiltersIsPopulated,
|
|
|
|
tagsIsPopulated,
|
|
|
|
uiSettingsIsPopulated,
|
|
|
|
generalSettingsIsPopulated,
|
|
|
|
appProfilesIsPopulated,
|
|
|
|
indexersIsPopulated,
|
|
|
|
indexerStatusIsPopulated,
|
|
|
|
indexerCategoriesIsPopulated,
|
|
|
|
systemStatusIsPopulated
|
|
|
|
) => {
|
|
|
|
return (
|
|
|
|
customFiltersIsPopulated &&
|
|
|
|
tagsIsPopulated &&
|
|
|
|
uiSettingsIsPopulated &&
|
|
|
|
generalSettingsIsPopulated &&
|
|
|
|
appProfilesIsPopulated &&
|
|
|
|
indexersIsPopulated &&
|
|
|
|
indexerStatusIsPopulated &&
|
|
|
|
indexerCategoriesIsPopulated &&
|
|
|
|
systemStatusIsPopulated
|
|
|
|
);
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
const selectErrors = createSelector(
|
|
|
|
(state) => state.customFilters.error,
|
|
|
|
(state) => state.tags.error,
|
|
|
|
(state) => state.settings.ui.error,
|
|
|
|
(state) => state.settings.general.error,
|
|
|
|
(state) => state.settings.appProfiles.error,
|
|
|
|
(state) => state.indexers.error,
|
|
|
|
(state) => state.indexerStatus.error,
|
|
|
|
(state) => state.settings.indexerCategories.error,
|
|
|
|
(state) => state.system.status.error,
|
|
|
|
(
|
|
|
|
customFiltersError,
|
|
|
|
tagsError,
|
|
|
|
uiSettingsError,
|
|
|
|
generalSettingsError,
|
|
|
|
appProfilesError,
|
|
|
|
indexersError,
|
|
|
|
indexerStatusError,
|
|
|
|
indexerCategoriesError,
|
|
|
|
systemStatusError
|
|
|
|
) => {
|
|
|
|
const hasError = !!(
|
|
|
|
customFiltersError ||
|
|
|
|
tagsError ||
|
|
|
|
uiSettingsError ||
|
|
|
|
generalSettingsError ||
|
|
|
|
appProfilesError ||
|
|
|
|
indexersError ||
|
|
|
|
indexerStatusError ||
|
|
|
|
indexerCategoriesError ||
|
|
|
|
systemStatusError
|
|
|
|
);
|
|
|
|
|
|
|
|
return {
|
|
|
|
hasError,
|
|
|
|
customFiltersError,
|
|
|
|
tagsError,
|
|
|
|
uiSettingsError,
|
|
|
|
generalSettingsError,
|
|
|
|
appProfilesError,
|
|
|
|
indexersError,
|
|
|
|
indexerStatusError,
|
|
|
|
indexerCategoriesError,
|
|
|
|
systemStatusError
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
|
|
|
|
|
|
|
function createMapStateToProps() {
|
|
|
|
return createSelector(
|
|
|
|
(state) => state.settings.ui.item.enableColorImpairedMode,
|
|
|
|
selectIsPopulated,
|
|
|
|
selectErrors,
|
|
|
|
selectAppProps,
|
|
|
|
createDimensionsSelector(),
|
|
|
|
createSystemStatusSelector(),
|
|
|
|
(
|
|
|
|
enableColorImpairedMode,
|
|
|
|
isPopulated,
|
|
|
|
errors,
|
|
|
|
app,
|
|
|
|
dimensions,
|
|
|
|
systemStatus
|
|
|
|
) => {
|
|
|
|
return {
|
|
|
|
...app,
|
|
|
|
...errors,
|
|
|
|
isPopulated,
|
|
|
|
isSmallScreen: dimensions.isSmallScreen,
|
|
|
|
authenticationEnabled: systemStatus.authentication !== 'none',
|
|
|
|
enableColorImpairedMode
|
|
|
|
};
|
|
|
|
}
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
function createMapDispatchToProps(dispatch, props) {
|
|
|
|
return {
|
|
|
|
dispatchFetchCustomFilters() {
|
|
|
|
dispatch(fetchCustomFilters());
|
|
|
|
},
|
|
|
|
dispatchFetchTags() {
|
|
|
|
dispatch(fetchTags());
|
|
|
|
},
|
|
|
|
dispatchFetchIndexers() {
|
|
|
|
dispatch(fetchIndexers());
|
|
|
|
},
|
|
|
|
dispatchFetchIndexerStatus() {
|
|
|
|
dispatch(fetchIndexerStatus());
|
|
|
|
},
|
|
|
|
dispatchFetchIndexerCategories() {
|
|
|
|
dispatch(fetchIndexerCategories());
|
|
|
|
},
|
|
|
|
dispatchFetchUISettings() {
|
|
|
|
dispatch(fetchUISettings());
|
|
|
|
},
|
|
|
|
dispatchFetchAppProfiles() {
|
|
|
|
dispatch(fetchAppProfiles());
|
|
|
|
},
|
|
|
|
dispatchFetchGeneralSettings() {
|
|
|
|
dispatch(fetchGeneralSettings());
|
|
|
|
},
|
|
|
|
dispatchFetchStatus() {
|
|
|
|
dispatch(fetchStatus());
|
|
|
|
},
|
|
|
|
onResize(dimensions) {
|
|
|
|
dispatch(saveDimensions(dimensions));
|
|
|
|
},
|
|
|
|
onSidebarVisibleChange(isSidebarVisible) {
|
|
|
|
dispatch(setIsSidebarVisible({ isSidebarVisible }));
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
class PageConnector extends Component {
|
|
|
|
|
|
|
|
//
|
|
|
|
// Lifecycle
|
|
|
|
|
|
|
|
constructor(props, context) {
|
|
|
|
super(props, context);
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
isLocalStorageSupported: testLocalStorage()
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
componentDidMount() {
|
|
|
|
if (!this.props.isPopulated) {
|
|
|
|
this.props.dispatchFetchCustomFilters();
|
|
|
|
this.props.dispatchFetchTags();
|
|
|
|
this.props.dispatchFetchAppProfiles();
|
|
|
|
this.props.dispatchFetchIndexers();
|
|
|
|
this.props.dispatchFetchIndexerStatus();
|
|
|
|
this.props.dispatchFetchIndexerCategories();
|
|
|
|
this.props.dispatchFetchUISettings();
|
|
|
|
this.props.dispatchFetchGeneralSettings();
|
|
|
|
this.props.dispatchFetchStatus();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Listeners
|
|
|
|
|
|
|
|
onSidebarToggle = () => {
|
|
|
|
this.props.onSidebarVisibleChange(!this.props.isSidebarVisible);
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// Render
|
|
|
|
|
|
|
|
render() {
|
|
|
|
const {
|
|
|
|
isPopulated,
|
|
|
|
hasError,
|
|
|
|
dispatchFetchTags,
|
|
|
|
dispatchFetchAppProfiles,
|
|
|
|
dispatchFetchIndexers,
|
|
|
|
dispatchFetchIndexerStatus,
|
|
|
|
dispatchFetchIndexerCategories,
|
|
|
|
dispatchFetchUISettings,
|
|
|
|
dispatchFetchGeneralSettings,
|
|
|
|
dispatchFetchStatus,
|
|
|
|
...otherProps
|
|
|
|
} = this.props;
|
|
|
|
|
|
|
|
if (hasError || !this.state.isLocalStorageSupported) {
|
|
|
|
return (
|
|
|
|
<ErrorPage
|
|
|
|
{...this.state}
|
|
|
|
{...otherProps}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isPopulated) {
|
|
|
|
return (
|
|
|
|
<Page
|
|
|
|
{...otherProps}
|
|
|
|
onSidebarToggle={this.onSidebarToggle}
|
|
|
|
/>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<LoadingPage />
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
PageConnector.propTypes = {
|
|
|
|
isPopulated: PropTypes.bool.isRequired,
|
|
|
|
hasError: PropTypes.bool.isRequired,
|
|
|
|
isSidebarVisible: PropTypes.bool.isRequired,
|
|
|
|
dispatchFetchCustomFilters: PropTypes.func.isRequired,
|
|
|
|
dispatchFetchTags: PropTypes.func.isRequired,
|
|
|
|
dispatchFetchAppProfiles: PropTypes.func.isRequired,
|
|
|
|
dispatchFetchIndexers: PropTypes.func.isRequired,
|
|
|
|
dispatchFetchIndexerStatus: PropTypes.func.isRequired,
|
|
|
|
dispatchFetchIndexerCategories: PropTypes.func.isRequired,
|
|
|
|
dispatchFetchUISettings: PropTypes.func.isRequired,
|
|
|
|
dispatchFetchGeneralSettings: PropTypes.func.isRequired,
|
|
|
|
dispatchFetchStatus: PropTypes.func.isRequired,
|
|
|
|
onSidebarVisibleChange: PropTypes.func.isRequired
|
|
|
|
};
|
|
|
|
|
|
|
|
export default withRouter(
|
|
|
|
connect(createMapStateToProps, createMapDispatchToProps)(PageConnector)
|
|
|
|
);
|