new features context to render features correctly on change
This commit is contained in:
parent
f17bac399a
commit
e71f262b79
46
src/App.tsx
46
src/App.tsx
@ -1,4 +1,4 @@
|
|||||||
import React from 'react';
|
import React, {useContext} from 'react';
|
||||||
import HomePage from './pages/HomePage/HomePage';
|
import HomePage from './pages/HomePage/HomePage';
|
||||||
import RandomPage from './pages/RandomPage/RandomPage';
|
import RandomPage from './pages/RandomPage/RandomPage';
|
||||||
import GlobalInfos from './utils/GlobalInfos';
|
import GlobalInfos from './utils/GlobalInfos';
|
||||||
@ -18,6 +18,7 @@ import AuthenticationPage from './pages/AuthenticationPage/AuthenticationPage';
|
|||||||
import TVShowPage from './pages/TVShowPage/TVShowPage';
|
import TVShowPage from './pages/TVShowPage/TVShowPage';
|
||||||
import TVPlayer from './pages/TVShowPage/TVPlayer';
|
import TVPlayer from './pages/TVShowPage/TVPlayer';
|
||||||
import {LoginContextProvider} from './utils/context/LoginContextProvider';
|
import {LoginContextProvider} from './utils/context/LoginContextProvider';
|
||||||
|
import {FeatureContext} from './utils/context/FeatureContext';
|
||||||
|
|
||||||
interface state {
|
interface state {
|
||||||
mediacentername: string;
|
mediacentername: string;
|
||||||
@ -48,13 +49,7 @@ class App extends React.Component<{}, state> {
|
|||||||
<LoginContextProvider>
|
<LoginContextProvider>
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path='/login'>
|
<Route path='/login'>
|
||||||
<AuthenticationPage
|
<AuthenticationPage />
|
||||||
onSuccessLogin={(): void => {
|
|
||||||
// this.setState({password: false});
|
|
||||||
// reinit general infos
|
|
||||||
// this.initialAPICall();
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</Route>
|
</Route>
|
||||||
<Route path='/media'>
|
<Route path='/media'>
|
||||||
{this.navBar()}
|
{this.navBar()}
|
||||||
@ -63,32 +58,10 @@ class App extends React.Component<{}, state> {
|
|||||||
</Switch>
|
</Switch>
|
||||||
</LoginContextProvider>
|
</LoginContextProvider>
|
||||||
);
|
);
|
||||||
|
|
||||||
// if (this.state.password === true) {
|
|
||||||
// // render authentication page if auth is neccessary
|
|
||||||
// return (
|
|
||||||
// <AuthenticationPage
|
|
||||||
// onSuccessLogin={(): void => {
|
|
||||||
// this.setState({password: false});
|
|
||||||
// // reinit general infos
|
|
||||||
// this.initialAPICall();
|
|
||||||
// }}
|
|
||||||
// />
|
|
||||||
// );
|
|
||||||
// } else if (this.state.password === false) {
|
|
||||||
// return (
|
|
||||||
// <Router>
|
|
||||||
// <div className={style.app}>
|
|
||||||
// {this.navBar()}
|
|
||||||
// {this.routing()}
|
|
||||||
// </div>
|
|
||||||
// </Router>
|
|
||||||
// );
|
|
||||||
// } else {
|
|
||||||
// return <>still loading...</>;
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static contextType = FeatureContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* render the top navigation bar
|
* render the top navigation bar
|
||||||
*/
|
*/
|
||||||
@ -115,7 +88,7 @@ class App extends React.Component<{}, state> {
|
|||||||
Categories
|
Categories
|
||||||
</NavLink>
|
</NavLink>
|
||||||
|
|
||||||
{GlobalInfos.isTVShowEnabled() ? (
|
{this.context.TVShowEnabled ? (
|
||||||
<NavLink
|
<NavLink
|
||||||
className={[style.navitem, themeStyle.navitem].join(' ')}
|
className={[style.navitem, themeStyle.navitem].join(' ')}
|
||||||
to={'/media/tvshows'}
|
to={'/media/tvshows'}
|
||||||
@ -137,6 +110,7 @@ class App extends React.Component<{}, state> {
|
|||||||
|
|
||||||
const MyRouter = (): JSX.Element => {
|
const MyRouter = (): JSX.Element => {
|
||||||
const match = useRouteMatch();
|
const match = useRouteMatch();
|
||||||
|
const features = useContext(FeatureContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
@ -159,13 +133,13 @@ const MyRouter = (): JSX.Element => {
|
|||||||
<ActorPage />
|
<ActorPage />
|
||||||
</Route>
|
</Route>
|
||||||
|
|
||||||
{GlobalInfos.isTVShowEnabled() ? (
|
{features.TVShowEnabled ? (
|
||||||
<Route exact path={`${match.url}/tvshows`}>
|
<Route path={`${match.url}/tvshows`}>
|
||||||
<TVShowPage />
|
<TVShowPage />
|
||||||
</Route>
|
</Route>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
{GlobalInfos.isTVShowEnabled() ? (
|
{features.TVShowEnabled ? (
|
||||||
<Route exact path={`${match.url}/tvplayer/:id`}>
|
<Route exact path={`${match.url}/tvplayer/:id`}>
|
||||||
<TVPlayer />
|
<TVPlayer />
|
||||||
</Route>
|
</Route>
|
||||||
|
@ -2,6 +2,7 @@ import React from 'react';
|
|||||||
import ReactDOM from 'react-dom';
|
import ReactDOM from 'react-dom';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import {BrowserRouter} from 'react-router-dom';
|
import {BrowserRouter} from 'react-router-dom';
|
||||||
|
import {FeatureContextProvider} from './utils/context/FeatureContext';
|
||||||
|
|
||||||
// don't allow console logs within production env
|
// don't allow console logs within production env
|
||||||
global.console.log = process.env.NODE_ENV !== 'development' ? (_: string | number | boolean): void => {} : global.console.log;
|
global.console.log = process.env.NODE_ENV !== 'development' ? (_: string | number | boolean): void => {} : global.console.log;
|
||||||
@ -9,7 +10,9 @@ global.console.log = process.env.NODE_ENV !== 'development' ? (_: string | numbe
|
|||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<React.StrictMode>
|
<React.StrictMode>
|
||||||
<BrowserRouter>
|
<BrowserRouter>
|
||||||
<App />
|
<FeatureContextProvider>
|
||||||
|
<App />
|
||||||
|
</FeatureContextProvider>
|
||||||
</BrowserRouter>
|
</BrowserRouter>
|
||||||
</React.StrictMode>,
|
</React.StrictMode>,
|
||||||
document.getElementById('root')
|
document.getElementById('root')
|
||||||
|
@ -13,9 +13,7 @@ interface state {
|
|||||||
wrongPWDInfo: boolean;
|
wrongPWDInfo: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Props {
|
interface Props {}
|
||||||
onSuccessLogin: () => void;
|
|
||||||
}
|
|
||||||
|
|
||||||
class AuthenticationPage extends React.Component<Props, state> {
|
class AuthenticationPage extends React.Component<Props, state> {
|
||||||
constructor(props: Props) {
|
constructor(props: Props) {
|
||||||
|
@ -22,6 +22,7 @@ import {Button} from '../../elements/GPElements/Button';
|
|||||||
import {VideoTypes} from '../../types/ApiTypes';
|
import {VideoTypes} from '../../types/ApiTypes';
|
||||||
import GlobalInfos from '../../utils/GlobalInfos';
|
import GlobalInfos from '../../utils/GlobalInfos';
|
||||||
import {ButtonPopup} from '../../elements/Popups/ButtonPopup/ButtonPopup';
|
import {ButtonPopup} from '../../elements/Popups/ButtonPopup/ButtonPopup';
|
||||||
|
import {FeatureContext} from '../../utils/context/FeatureContext';
|
||||||
|
|
||||||
interface Props extends RouteComponentProps<{id: string}> {}
|
interface Props extends RouteComponentProps<{id: string}> {}
|
||||||
|
|
||||||
@ -65,6 +66,8 @@ export class Player extends React.Component<Props, mystate> {
|
|||||||
this.quickAddTag = this.quickAddTag.bind(this);
|
this.quickAddTag = this.quickAddTag.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static contextType = FeatureContext;
|
||||||
|
|
||||||
componentDidMount(): void {
|
componentDidMount(): void {
|
||||||
// initial fetch of current movie data
|
// initial fetch of current movie data
|
||||||
this.fetchMovieData();
|
this.fetchMovieData();
|
||||||
@ -205,7 +208,7 @@ export class Player extends React.Component<Props, mystate> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
renderDeletePopup(): JSX.Element {
|
renderDeletePopup(): JSX.Element {
|
||||||
if (GlobalInfos.isVideoFulldeleteable()) {
|
if (this.context.VideosFullyDeleteable) {
|
||||||
return (
|
return (
|
||||||
<ButtonPopup
|
<ButtonPopup
|
||||||
onDeny={(): void => this.setState({deletepopupvisible: false})}
|
onDeny={(): void => this.setState({deletepopupvisible: false})}
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import React from 'react';
|
import React, {useContext} from 'react';
|
||||||
import MovieSettings from './MovieSettings';
|
import MovieSettings from './MovieSettings';
|
||||||
import GeneralSettings from './GeneralSettings';
|
import GeneralSettings from './GeneralSettings';
|
||||||
import style from './SettingsPage.module.css';
|
import style from './SettingsPage.module.css';
|
||||||
import GlobalInfos from '../../utils/GlobalInfos';
|
import GlobalInfos from '../../utils/GlobalInfos';
|
||||||
import {NavLink, Redirect, Route, Switch, useRouteMatch} from 'react-router-dom';
|
import {NavLink, Redirect, Route, Switch, useRouteMatch} from 'react-router-dom';
|
||||||
|
import {FeatureContext} from '../../utils/context/FeatureContext';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The Settingspage handles all kinds of settings for the mediacenter
|
* The Settingspage handles all kinds of settings for the mediacenter
|
||||||
@ -12,6 +13,7 @@ import {NavLink, Redirect, Route, Switch, useRouteMatch} from 'react-router-dom'
|
|||||||
const SettingsPage = (): JSX.Element => {
|
const SettingsPage = (): JSX.Element => {
|
||||||
const themestyle = GlobalInfos.getThemeStyle();
|
const themestyle = GlobalInfos.getThemeStyle();
|
||||||
const match = useRouteMatch();
|
const match = useRouteMatch();
|
||||||
|
const features = useContext(FeatureContext);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
@ -23,7 +25,7 @@ const SettingsPage = (): JSX.Element => {
|
|||||||
<NavLink to='/media/settings/movies'>
|
<NavLink to='/media/settings/movies'>
|
||||||
<div className={style.SettingSidebarElement}>Movies</div>
|
<div className={style.SettingSidebarElement}>Movies</div>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
{GlobalInfos.isTVShowEnabled() ? (
|
{features.TVShowEnabled ? (
|
||||||
<NavLink to='/media/settings/tv'>
|
<NavLink to='/media/settings/tv'>
|
||||||
<div className={style.SettingSidebarElement}>TV Shows</div>
|
<div className={style.SettingSidebarElement}>TV Shows</div>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
@ -37,7 +39,7 @@ const SettingsPage = (): JSX.Element => {
|
|||||||
<Route path={`${match.url}/movies`}>
|
<Route path={`${match.url}/movies`}>
|
||||||
<MovieSettings />
|
<MovieSettings />
|
||||||
</Route>
|
</Route>
|
||||||
{GlobalInfos.isTVShowEnabled() ? (
|
{features.TVShowEnabled ? (
|
||||||
<Route path={`${match.url}/tv`}>
|
<Route path={`${match.url}/tv`}>
|
||||||
<span />
|
<span />
|
||||||
</Route>
|
</Route>
|
||||||
|
@ -72,7 +72,7 @@ export default function (): JSX.Element {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Switch>
|
<Switch>
|
||||||
<Route path={`${match.path}/:id`}>
|
<Route exact path={`${match.path}/:id`}>
|
||||||
<EpisodePage />
|
<EpisodePage />
|
||||||
</Route>
|
</Route>
|
||||||
<Route path={match.path}>
|
<Route path={match.path}>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import GlobalInfos from './GlobalInfos';
|
|
||||||
import {cookie} from './context/Cookie';
|
import {cookie} from './context/Cookie';
|
||||||
|
|
||||||
const APIPREFIX: string = '/api/';
|
const APIPREFIX: string = '/api/';
|
||||||
@ -84,13 +83,7 @@ function generalAPICall<T>(
|
|||||||
}
|
}
|
||||||
} else if (response.status === 400) {
|
} else if (response.status === 400) {
|
||||||
// Bad Request --> invalid token
|
// Bad Request --> invalid token
|
||||||
console.log('loading Password page.');
|
console.log('bad request todo sth here');
|
||||||
// load password page
|
|
||||||
if (GlobalInfos.loadPasswordPage) {
|
|
||||||
GlobalInfos.loadPasswordPage(() => {
|
|
||||||
callAPI(apinode, fd, callback, errorcallback);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
console.log('Error: ' + response.statusText);
|
console.log('Error: ' + response.statusText);
|
||||||
if (errorcallback) {
|
if (errorcallback) {
|
||||||
|
@ -49,6 +49,7 @@ class StaticInfos {
|
|||||||
/**
|
/**
|
||||||
* set the current videopath
|
* set the current videopath
|
||||||
* @param vidpath videopath with beginning and ending slash
|
* @param vidpath videopath with beginning and ending slash
|
||||||
|
* @param tvshowpath
|
||||||
*/
|
*/
|
||||||
setVideoPaths(vidpath: string, tvshowpath: string): void {
|
setVideoPaths(vidpath: string, tvshowpath: string): void {
|
||||||
this.videopath = vidpath;
|
this.videopath = vidpath;
|
||||||
@ -68,27 +69,6 @@ class StaticInfos {
|
|||||||
getTVShowPath(): string {
|
getTVShowPath(): string {
|
||||||
return this.tvshowpath;
|
return this.tvshowpath;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* load the Password page manually
|
|
||||||
*/
|
|
||||||
loadPasswordPage: ((callback?: () => void) => void) | undefined = undefined;
|
|
||||||
|
|
||||||
setTVShowsEnabled(TVShowEnabled: boolean): void {
|
|
||||||
this.TVShowsEnabled = TVShowEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
isTVShowEnabled(): boolean {
|
|
||||||
return this.TVShowsEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
setFullDeleteEnabled(FullDeleteEnabled: boolean): void {
|
|
||||||
this.fullDeleteable = FullDeleteEnabled;
|
|
||||||
}
|
|
||||||
|
|
||||||
isVideoFulldeleteable(): boolean {
|
|
||||||
return this.fullDeleteable;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default new StaticInfos();
|
export default new StaticInfos();
|
||||||
|
32
src/utils/context/FeatureContext.tsx
Normal file
32
src/utils/context/FeatureContext.tsx
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
import React, {FunctionComponent, useState} from 'react';
|
||||||
|
|
||||||
|
export interface FeatureContextType {
|
||||||
|
setTVShowEnabled: (enabled: boolean) => void;
|
||||||
|
TVShowEnabled: boolean;
|
||||||
|
setVideosFullyDeleteable: (fullyDeletable: boolean) => void;
|
||||||
|
VideosFullyDeleteable: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A global context providing a way to interact with user login states
|
||||||
|
*/
|
||||||
|
export const FeatureContext = React.createContext<FeatureContextType>({
|
||||||
|
setTVShowEnabled: (_) => {},
|
||||||
|
TVShowEnabled: false,
|
||||||
|
setVideosFullyDeleteable: (_) => {},
|
||||||
|
VideosFullyDeleteable: false
|
||||||
|
});
|
||||||
|
|
||||||
|
export const FeatureContextProvider: FunctionComponent = (props): JSX.Element => {
|
||||||
|
const [tvshowenabled, settvshowenabled] = useState(false);
|
||||||
|
const [fullydeletablevids, setfullydeleteable] = useState(false);
|
||||||
|
|
||||||
|
const value: FeatureContextType = {
|
||||||
|
VideosFullyDeleteable: fullydeletablevids,
|
||||||
|
TVShowEnabled: tvshowenabled,
|
||||||
|
setTVShowEnabled: (e) => settvshowenabled(e),
|
||||||
|
setVideosFullyDeleteable: (e) => setfullydeleteable(e)
|
||||||
|
};
|
||||||
|
|
||||||
|
return <FeatureContext.Provider value={value}>{props.children}</FeatureContext.Provider>;
|
||||||
|
};
|
@ -5,18 +5,21 @@ import {cookie} from './Cookie';
|
|||||||
import {APINode, callAPI} from '../Api';
|
import {APINode, callAPI} from '../Api';
|
||||||
import {SettingsTypes} from '../../types/ApiTypes';
|
import {SettingsTypes} from '../../types/ApiTypes';
|
||||||
import GlobalInfos from '../GlobalInfos';
|
import GlobalInfos from '../GlobalInfos';
|
||||||
|
import {FeatureContext} from './FeatureContext';
|
||||||
|
|
||||||
export const LoginContextProvider: FunctionComponent = (props): JSX.Element => {
|
export const LoginContextProvider: FunctionComponent = (props): JSX.Element => {
|
||||||
let initialLoginState = LoginState.LoggedIn;
|
let initialLoginState = LoginState.LoggedIn;
|
||||||
let initialUserPerm = LoginPerm.User;
|
let initialUserPerm = LoginPerm.User;
|
||||||
|
|
||||||
|
const features = useContext(FeatureContext);
|
||||||
|
|
||||||
const t = cookie.Load();
|
const t = cookie.Load();
|
||||||
// we are already logged in so we can set the token and redirect to dashboard
|
// we are already logged in so we can set the token and redirect to dashboard
|
||||||
if (t !== null) {
|
if (t !== null) {
|
||||||
initialLoginState = LoginState.LoggedIn;
|
initialLoginState = LoginState.LoggedIn;
|
||||||
}
|
}
|
||||||
|
|
||||||
const initialAPICall = (): void => {
|
useEffect(() => {
|
||||||
// this is the first api call so if it fails we know there is no connection to backend
|
// this is the first api call so if it fails we know there is no connection to backend
|
||||||
callAPI(
|
callAPI(
|
||||||
APINode.Settings,
|
APINode.Settings,
|
||||||
@ -27,9 +30,9 @@ export const LoginContextProvider: FunctionComponent = (props): JSX.Element => {
|
|||||||
|
|
||||||
GlobalInfos.setVideoPaths(result.VideoPath, result.TVShowPath);
|
GlobalInfos.setVideoPaths(result.VideoPath, result.TVShowPath);
|
||||||
|
|
||||||
GlobalInfos.setTVShowsEnabled(result.TVShowEnabled);
|
features.setTVShowEnabled(result.TVShowEnabled);
|
||||||
GlobalInfos.setFullDeleteEnabled(result.FullDeleteEnabled);
|
features.setVideosFullyDeleteable(result.FullDeleteEnabled);
|
||||||
//
|
|
||||||
// this.setState({
|
// this.setState({
|
||||||
// mediacentername: result.MediacenterName
|
// mediacentername: result.MediacenterName
|
||||||
// });
|
// });
|
||||||
@ -42,11 +45,7 @@ export const LoginContextProvider: FunctionComponent = (props): JSX.Element => {
|
|||||||
setLoginState(LoginState.LoggedOut);
|
setLoginState(LoginState.LoggedOut);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
};
|
}, [features]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
initialAPICall();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const [loginState, setLoginState] = useState<LoginState>(initialLoginState);
|
const [loginState, setLoginState] = useState<LoginState>(initialLoginState);
|
||||||
const [permission, setPermission] = useState<LoginPerm>(initialUserPerm);
|
const [permission, setPermission] = useState<LoginPerm>(initialUserPerm);
|
||||||
|
Loading…
Reference in New Issue
Block a user