Compare commits
	
		
			1 Commits
		
	
	
		
			master
			...
			dependency
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 6e0928a97a | 
| @@ -25,7 +25,7 @@ func getActorsFromDB() { | ||||
| 	 * @apiSuccess {string} .Thumbnail Portrait Thumbnail | ||||
| 	 */ | ||||
| 	api.AddHandler("getAllActors", api.ActorNode, api.PermUser, func(context api.Context) { | ||||
| 		query := "SELECT actor_id, name, thumbnail FROM actors ORDER BY name ASC" | ||||
| 		query := "SELECT actor_id, name, thumbnail FROM actors" | ||||
| 		context.Json(readActorsFromResultset(database.Query(query))) | ||||
| 	}) | ||||
|  | ||||
|   | ||||
| @@ -7,6 +7,7 @@ import ( | ||||
| 	"openmediacenter/apiGo/database" | ||||
| 	"openmediacenter/apiGo/videoparser" | ||||
| 	"os" | ||||
| 	"path/filepath" | ||||
| ) | ||||
|  | ||||
| func addUploadHandler() { | ||||
| @@ -30,11 +31,11 @@ func addUploadHandler() { | ||||
| 				break | ||||
| 			} | ||||
|  | ||||
| 			// todo allow more video formats than mp4 | ||||
| 			// only allow valid extensions | ||||
| 			if !videoparser.ValidVideoSuffix(part.FileName()) { | ||||
| 			if filepath.Ext(part.FileName()) != ".mp4" { | ||||
| 				continue | ||||
| 			} | ||||
|  | ||||
| 			vidpath := PathPrefix + mSettings.VideoPath + part.FileName() | ||||
| 			dst, err := os.OpenFile(vidpath, os.O_WRONLY|os.O_CREATE, 0644) | ||||
| 			if err != nil { | ||||
|   | ||||
| @@ -78,7 +78,7 @@ func getFromDB() { | ||||
| 	 * @apiSuccess {string} TagName name of the Tag | ||||
| 	 */ | ||||
| 	api.AddHandler("getAllTags", api.TagNode, api.PermUser, func(context api.Context) { | ||||
| 		query := "SELECT tag_id,tag_name from tags ORDER BY tag_name ASC" | ||||
| 		query := "SELECT tag_id,tag_name from tags ORDER BY tag_name" | ||||
| 		context.Json(readTagsFromResultset(database.Query(query))) | ||||
| 	}) | ||||
| } | ||||
|   | ||||
| @@ -21,7 +21,7 @@ func (p Perm) String() string { | ||||
| } | ||||
|  | ||||
| const SignKey = "89013f1753a6890c6090b09e3c23ff43" | ||||
| const TokenExpireHours = 8760 | ||||
| const TokenExpireHours = 24 | ||||
|  | ||||
| type Token struct { | ||||
| 	Token     string | ||||
|   | ||||
| @@ -5,6 +5,7 @@ import ( | ||||
| 	"encoding/json" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"reflect" | ||||
| ) | ||||
|  | ||||
| func Jsonify(v interface{}) []byte { | ||||
| @@ -29,3 +30,45 @@ func DecodeRequest(request *http.Request, arg interface{}) error { | ||||
|  | ||||
| 	return err | ||||
| } | ||||
|  | ||||
| // setField set a specific field of an object with an object provided | ||||
| func setField(obj interface{}, name string, value interface{}) error { | ||||
| 	structValue := reflect.ValueOf(obj).Elem() | ||||
| 	structFieldValue := structValue.FieldByName(name) | ||||
|  | ||||
| 	if !structFieldValue.IsValid() { | ||||
| 		return fmt.Errorf("no such field: %s in obj", name) | ||||
| 	} | ||||
|  | ||||
| 	if !structFieldValue.CanSet() { | ||||
| 		return fmt.Errorf("cannot set %s field value", name) | ||||
| 	} | ||||
|  | ||||
| 	structFieldType := structFieldValue.Type() | ||||
| 	val := reflect.ValueOf(value) | ||||
|  | ||||
| 	if structFieldType != val.Type() { | ||||
| 		if val.Type().ConvertibleTo(structFieldType) { | ||||
| 			// if type is convertible - convert and set | ||||
| 			structFieldValue.Set(val.Convert(structFieldType)) | ||||
| 		} else { | ||||
| 			return fmt.Errorf("provided value %s type didn't match obj field type and isn't convertible", name) | ||||
| 		} | ||||
| 	} else { | ||||
| 		// set value if type is the same | ||||
| 		structFieldValue.Set(val) | ||||
| 	} | ||||
|  | ||||
| 	return nil | ||||
| } | ||||
|  | ||||
| // FillStruct fill a custom struct with objects of a map | ||||
| func FillStruct(i interface{}, m map[string]interface{}) error { | ||||
| 	for k, v := range m { | ||||
| 		err := setField(i, k, v) | ||||
| 		if err != nil { | ||||
| 			return err | ||||
| 		} | ||||
| 	} | ||||
| 	return nil | ||||
| } | ||||
|   | ||||
| @@ -25,18 +25,20 @@ func startTVShowReindex(files []Show) { | ||||
| } | ||||
|  | ||||
| func insertEpisodesIfNotExisting(show Show) { | ||||
| 	query := "SELECT filename FROM tvshow_episodes JOIN tvshow t on t.id = tvshow_episodes.tvshow_id WHERE t.name=?" | ||||
| 	query := "SELECT tvshow_episodes.name, season, episode FROM tvshow_episodes JOIN tvshow t on t.id = tvshow_episodes.tvshow_id WHERE t.name=?" | ||||
| 	rows := database.Query(query, show.Name) | ||||
|  | ||||
| 	var dbepisodes []string | ||||
| 	for rows.Next() { | ||||
| 		var filename string | ||||
| 		err := rows.Scan(&filename) | ||||
| 		var epname string | ||||
| 		var season int | ||||
| 		var episode int | ||||
| 		err := rows.Scan(&epname, &season, &episode) | ||||
| 		if err != nil { | ||||
| 			fmt.Println(err.Error()) | ||||
| 		} | ||||
|  | ||||
| 		dbepisodes = append(dbepisodes, filename) | ||||
| 		dbepisodes = append(dbepisodes, fmt.Sprintf("%s S%02dE%02d.mp4", epname, season, episode)) | ||||
| 	} | ||||
|  | ||||
| 	// get those episodes that are missing in db | ||||
| @@ -81,10 +83,6 @@ VALUES (?, ?, ?, (SELECT tvshow.id FROM tvshow WHERE tvshow.name=?), ?, ?)` | ||||
|  | ||||
| // difference returns the elements in `a` that aren't in `b`. | ||||
| func difference(a, b []string) []string { | ||||
| 	if b == nil || len(b) == 0 { | ||||
| 		return a | ||||
| 	} | ||||
|  | ||||
| 	mb := make(map[string]struct{}, len(b)) | ||||
| 	for _, x := range b { | ||||
| 		mb[x] = struct{}{} | ||||
| @@ -131,10 +129,7 @@ func getAllTVShows() *[]string { | ||||
| 	var res []string | ||||
| 	for rows.Next() { | ||||
| 		var show string | ||||
| 		err := rows.Scan(&show) | ||||
| 		if err != nil { | ||||
| 			continue | ||||
| 		} | ||||
| 		rows.Scan(&show) | ||||
|  | ||||
| 		res = append(res, show) | ||||
| 	} | ||||
|   | ||||
| @@ -14,20 +14,6 @@ type StatusMessage struct { | ||||
| 	ContentAvailable bool | ||||
| } | ||||
|  | ||||
| func getVideoTypes() []string { | ||||
| 	return []string{".mp4", ".mov", ".mkv", ".flv", ".avi", ".mpeg", ".m4v"} | ||||
| } | ||||
|  | ||||
| func ValidVideoSuffix(filename string) bool { | ||||
| 	validExts := getVideoTypes() | ||||
| 	for _, validExt := range validExts { | ||||
| 		if strings.HasSuffix(filename, validExt) { | ||||
| 			return true | ||||
| 		} | ||||
| 	} | ||||
| 	return false | ||||
| } | ||||
|  | ||||
| func StartReindex() bool { | ||||
| 	fmt.Println("starting reindex..") | ||||
| 	SendEvent("start") | ||||
| @@ -54,7 +40,7 @@ func StartReindex() bool { | ||||
|  | ||||
| 	var files []string | ||||
| 	for _, file := range filelist { | ||||
| 		if !file.IsDir() && ValidVideoSuffix(file.Name()) { | ||||
| 		if !file.IsDir() && strings.HasSuffix(file.Name(), ".mp4") { | ||||
| 			files = append(files, file.Name()) | ||||
| 		} | ||||
| 	} | ||||
| @@ -117,7 +103,7 @@ func StartTVShowReindex() { | ||||
| 			} | ||||
|  | ||||
| 			for _, epfile := range episodefiles { | ||||
| 				if ValidVideoSuffix(epfile.Name()) { | ||||
| 				if strings.HasSuffix(epfile.Name(), ".mp4") { | ||||
| 					elem.files = append(elem.files, epfile.Name()) | ||||
| 				} | ||||
| 			} | ||||
|   | ||||
							
								
								
									
										52
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										52
									
								
								package.json
									
									
									
									
									
								
							| @@ -8,17 +8,17 @@ | ||||
|     "url": "https://heili.eu" | ||||
|   }, | ||||
|   "dependencies": { | ||||
|     "@fortawesome/fontawesome-svg-core": "^1.2.32", | ||||
|     "@fortawesome/free-regular-svg-icons": "^5.15.1", | ||||
|     "@fortawesome/free-solid-svg-icons": "^5.15.1", | ||||
|     "@fortawesome/react-fontawesome": "^0.1.13", | ||||
|     "@fortawesome/fontawesome-svg-core": "^6.2.0", | ||||
|     "@fortawesome/free-regular-svg-icons": "^6.2.0", | ||||
|     "@fortawesome/free-solid-svg-icons": "^6.2.0", | ||||
|     "@fortawesome/react-fontawesome": "^0.2.0", | ||||
|     "bootstrap": "^5.0.2", | ||||
|     "plyr-react": "^3.0.7", | ||||
|     "react": "^17.0.1", | ||||
|     "react-bootstrap": "^1.4.0", | ||||
|     "react-dom": "^17.0.1", | ||||
|     "react-router": "^5.2.0", | ||||
|     "react-router-dom": "^5.2.0", | ||||
|     "plyr-react": "^5.1.0", | ||||
|     "react": "^18.2.0", | ||||
|     "react-bootstrap": "^2.5.0", | ||||
|     "react-dom": "^18.2.0", | ||||
|     "react-router": "^6.4.0", | ||||
|     "react-router-dom": "^6.4.0", | ||||
|     "typescript": "^4.3.5" | ||||
|   }, | ||||
|   "scripts": { | ||||
| @@ -54,31 +54,31 @@ | ||||
|   }, | ||||
|   "devDependencies": { | ||||
|     "@testing-library/jest-dom": "^5.14.1", | ||||
|     "@testing-library/react": "^12.0.0", | ||||
|     "@testing-library/user-event": "^13.2.1", | ||||
|     "@types/jest": "^26.0.24", | ||||
|     "@types/node": "^16.4.7", | ||||
|     "@types/react": "^17.0.15", | ||||
|     "@types/react-dom": "^17.0.9", | ||||
|     "@types/react-router": "5.1.16", | ||||
|     "@testing-library/react": "^13.4.0", | ||||
|     "@testing-library/user-event": "^14.4.3", | ||||
|     "@types/jest": "^29.0.3", | ||||
|     "@types/node": "^18.7.18", | ||||
|     "@types/react": "^18.0.20", | ||||
|     "@types/react-dom": "^18.0.6", | ||||
|     "@types/react-router": "5.1.19", | ||||
|     "@types/react-router-dom": "^5.1.8", | ||||
|     "@typescript-eslint/eslint-plugin": "^4.28.5", | ||||
|     "@typescript-eslint/parser": "^4.28.5", | ||||
|     "apidoc": "^0.28.1", | ||||
|     "@typescript-eslint/eslint-plugin": "^5.38.0", | ||||
|     "@typescript-eslint/parser": "^5.38.0", | ||||
|     "apidoc": "^0.53.0", | ||||
|     "enzyme": "^3.11.0", | ||||
|     "enzyme-adapter-react-16": "^1.15.5", | ||||
|     "eslint": "^7.31.0", | ||||
|     "eslint": "^8.23.1", | ||||
|     "eslint-config-prettier": "^8.1.0", | ||||
|     "eslint-formatter-gitlab": "^2.2.0", | ||||
|     "eslint-formatter-gitlab": "^3.0.0", | ||||
|     "eslint-plugin-eslint-comments": "^3.2.0", | ||||
|     "eslint-plugin-jest": "^24.4.0", | ||||
|     "eslint-plugin-prettier": "^3.3.1", | ||||
|     "eslint-plugin-jest": "^27.0.4", | ||||
|     "eslint-plugin-prettier": "^4.2.1", | ||||
|     "eslint-plugin-react": "^7.22.0", | ||||
|     "eslint-plugin-react-hooks": "^4.2.0", | ||||
|     "jest-junit": "^12.0.0", | ||||
|     "jest-junit": "^14.0.1", | ||||
|     "prettier": "^2.3.2", | ||||
|     "prettier-config": "^1.0.0", | ||||
|     "react-scripts": "4.0.3" | ||||
|     "react-scripts": "5.0.1" | ||||
|   }, | ||||
|   "apidoc": { | ||||
|     "name": "OpenMediaCenter", | ||||
|   | ||||
| @@ -15,6 +15,10 @@ | ||||
|     text-decoration: none; | ||||
| } | ||||
|  | ||||
| .navitem-active { | ||||
|     opacity: 0.85; | ||||
| } | ||||
|  | ||||
| .navitem:hover { | ||||
|     opacity: 1; | ||||
|     text-decoration: none; | ||||
|   | ||||
							
								
								
									
										35
									
								
								src/App.tsx
									
									
									
									
									
								
							
							
						
						
									
										35
									
								
								src/App.tsx
									
									
									
									
									
								
							| @@ -10,7 +10,7 @@ import style from './App.module.css'; | ||||
| import SettingsPage from './pages/SettingsPage/SettingsPage'; | ||||
| import CategoryPage from './pages/CategoryPage/CategoryPage'; | ||||
|  | ||||
| import {NavLink, Route, Switch, useRouteMatch} from 'react-router-dom'; | ||||
| import {NavLink, Route, Routes} from 'react-router-dom'; | ||||
| import Player from './pages/Player/Player'; | ||||
| import ActorOverviewPage from './pages/ActorOverviewPage/ActorOverviewPage'; | ||||
| import ActorPage from './pages/ActorPage/ActorPage'; | ||||
| @@ -47,7 +47,7 @@ class App extends React.Component<{}, state> { | ||||
|  | ||||
|         return ( | ||||
|             <LoginContextProvider> | ||||
|                 <Switch> | ||||
|                 <Routes> | ||||
|                     <Route path='/login'> | ||||
|                         <AuthenticationPage /> | ||||
|                     </Route> | ||||
| @@ -55,13 +55,19 @@ class App extends React.Component<{}, state> { | ||||
|                         {this.navBar()} | ||||
|                         <MyRouter /> | ||||
|                     </Route> | ||||
|                 </Switch> | ||||
|                 </Routes> | ||||
|             </LoginContextProvider> | ||||
|         ); | ||||
|     } | ||||
|  | ||||
|     static contextType = FeatureContext; | ||||
|  | ||||
|     activeTab(history, path) { | ||||
|         if (history.location.pathname === path) { | ||||
|             return { color: "red" }; | ||||
|         } | ||||
|     }; | ||||
|  | ||||
|     /** | ||||
|      * render the top navigation bar | ||||
|      */ | ||||
| @@ -75,39 +81,34 @@ class App extends React.Component<{}, state> { | ||||
|                     Home | ||||
|                 </NavLink> | ||||
|                 <NavLink | ||||
|                     className={[style.navitem, themeStyle.navitem].join(' ')} | ||||
|                     to={'/media/random'} | ||||
|                     activeStyle={{opacity: '0.85'}}> | ||||
|                     className={({ isActive }) => [style.navitem, themeStyle.navitem, (isActive ? 'navitem-active' : '')].join(' ')}> | ||||
|                     Random Video | ||||
|                 </NavLink> | ||||
|  | ||||
|                 <NavLink | ||||
|                     className={[style.navitem, themeStyle.navitem].join(' ')} | ||||
|                     to={'/media/categories'} | ||||
|                     activeStyle={{opacity: '0.85'}}> | ||||
|                     className={({ isActive }) => [style.navitem, themeStyle.navitem, (isActive ? 'navitem-active' : '')].join(' ')} | ||||
|                     to={'/media/categories'}> | ||||
|                     Categories | ||||
|                 </NavLink> | ||||
|  | ||||
|                 <NavLink | ||||
|                     className={[style.navitem, themeStyle.navitem].join(' ')} | ||||
|                     to={'/media/actors'} | ||||
|                     activeStyle={{opacity: '0.85'}}> | ||||
|                     className={({ isActive }) => [style.navitem, themeStyle.navitem, (isActive ? 'navitem-active' : '')].join(' ')} | ||||
|                     to={'/media/actors'}> | ||||
|                     Actors | ||||
|                 </NavLink> | ||||
|  | ||||
|                 {this.context.TVShowEnabled ? ( | ||||
|                     <NavLink | ||||
|                         className={[style.navitem, themeStyle.navitem].join(' ')} | ||||
|                         to={'/media/tvshows'} | ||||
|                         activeStyle={{opacity: '0.85'}}> | ||||
|                         className={({ isActive }) => [style.navitem, themeStyle.navitem, (isActive ? 'navitem-active' : '')].join(' ')} | ||||
|                         to={'/media/tvshows'}> | ||||
|                         TV Shows | ||||
|                     </NavLink> | ||||
|                 ) : null} | ||||
|  | ||||
|                 <NavLink | ||||
|                     className={[style.navitem, themeStyle.navitem].join(' ')} | ||||
|                     to={'/media/settings'} | ||||
|                     activeStyle={{opacity: '0.85'}}> | ||||
|                     className={({ isActive }) => [style.navitem, themeStyle.navitem, (isActive ? 'navitem-active' : '')].join(' ')} | ||||
|                     to={'/media/settings'}> | ||||
|                     Settings | ||||
|                 </NavLink> | ||||
|             </div> | ||||
|   | ||||
| @@ -1,8 +1,8 @@ | ||||
| import React from 'react'; | ||||
| import React, {PropsWithChildren} from 'react'; | ||||
| import style from './SideBar.module.css'; | ||||
| import GlobalInfos from '../../utils/GlobalInfos'; | ||||
|  | ||||
| interface SideBarProps { | ||||
| interface SideBarProps extends  PropsWithChildren{ | ||||
|     hiddenFrame?: boolean; | ||||
|     width?: string; | ||||
| } | ||||
|   | ||||
| @@ -58,7 +58,7 @@ export class HomePage extends React.Component<Props, state> { | ||||
|         }; | ||||
|     } | ||||
|  | ||||
|     sortState = SortBy.random; | ||||
|     sortState = SortBy.date; | ||||
|     tagState = DefaultTags.all; | ||||
|  | ||||
|     componentDidMount(): void { | ||||
|   | ||||
| @@ -66,7 +66,7 @@ export class EpisodePage extends React.Component<Props, State> { | ||||
| export const EpisodeTile = (props: {episode: Episode}): JSX.Element => { | ||||
|     const themestyle = GlobalInfos.getThemeStyle(); | ||||
|     return ( | ||||
|         <Link to={'/media/tvplayer/' + props.episode.ID}> | ||||
|         <Link to={'/tvplayer/' + props.episode.ID}> | ||||
|             <div className={tileStyle.tile + ' ' + themestyle.secbackground + ' ' + themestyle.textcolor}> | ||||
|                 <FontAwesomeIcon | ||||
|                     style={{ | ||||
|   | ||||
| @@ -94,7 +94,7 @@ export class TVPlayer extends React.Component<Props, State> { | ||||
|     } | ||||
|  | ||||
|     private closebtn(): void { | ||||
|         this.props.history.goBack(); | ||||
|         this.props.goBack(); | ||||
|     } | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -3,10 +3,11 @@ import Preview from '../../elements/Preview/Preview'; | ||||
| import {APINode, callAPI, callAPIPlain} from '../../utils/Api'; | ||||
| import {TVShow} from '../../types/ApiTypes'; | ||||
| import DynamicContentContainer from '../../elements/DynamicContentContainer/DynamicContentContainer'; | ||||
| import {Route, Switch, useRouteMatch} from 'react-router-dom'; | ||||
| import {Route, Routes, useMatch} from 'react-router-dom'; | ||||
| import EpisodePage from './EpisodePage'; | ||||
| import PageTitle, {Line} from '../../elements/PageTitle/PageTitle'; | ||||
| import SideBar, {SideBarItem, SideBarTitle} from '../../elements/SideBar/SideBar'; | ||||
| import {useLocation} from "react-router"; | ||||
|  | ||||
| interface State { | ||||
|     loading: boolean; | ||||
| @@ -68,16 +69,16 @@ export class TVShowPage extends React.Component<Props, State> { | ||||
| } | ||||
|  | ||||
| export default function (): JSX.Element { | ||||
|     let match = useRouteMatch(); | ||||
|     const { pathname } = useLocation(); | ||||
|  | ||||
|     return ( | ||||
|         <Switch> | ||||
|             <Route exact path={`${match.path}/:id`}> | ||||
|         <Routes> | ||||
|             <Route path={`${pathname}/:id`}> | ||||
|                 <EpisodePage /> | ||||
|             </Route> | ||||
|             <Route path={match.path}> | ||||
|             <Route path={pathname}> | ||||
|                 <TVShowPage /> | ||||
|             </Route> | ||||
|         </Switch> | ||||
|         </Routes> | ||||
|     ); | ||||
| } | ||||
|   | ||||
| @@ -78,8 +78,8 @@ function generalAPICall<T>( | ||||
|                 // decode json or text | ||||
|                 const data = json ? await response.json() : await response.text(); | ||||
|                 callback(data); | ||||
|             } catch (e) { | ||||
|                 errorcallback(e); | ||||
|             } catch (e: any) { | ||||
|                 errorcallback(e.toString()); | ||||
|             } | ||||
|         } else if (response.status === 400) { | ||||
|             // Bad Request --> invalid token | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| import React, {FunctionComponent, useState} from 'react'; | ||||
| import React, {FunctionComponent, PropsWithChildren, useState} from 'react'; | ||||
|  | ||||
| export interface FeatureContextType { | ||||
|     setTVShowEnabled: (enabled: boolean) => void; | ||||
| @@ -17,7 +17,7 @@ export const FeatureContext = React.createContext<FeatureContextType>({ | ||||
|     VideosFullyDeleteable: false | ||||
| }); | ||||
|  | ||||
| export const FeatureContextProvider: FunctionComponent = (props): JSX.Element => { | ||||
| export const FeatureContextProvider: FunctionComponent<PropsWithChildren> = (props): JSX.Element => { | ||||
|     const [tvshowenabled, settvshowenabled] = useState(false); | ||||
|     const [fullydeletablevids, setfullydeleteable] = useState(false); | ||||
|  | ||||
|   | ||||
| @@ -1,13 +1,13 @@ | ||||
| import {LoginContext, LoginPerm, LoginState} from './LoginContext'; | ||||
| import React, {FunctionComponent, useContext, useEffect, useState} from 'react'; | ||||
| import {useHistory, useLocation} from 'react-router'; | ||||
| import React, {FunctionComponent, PropsWithChildren, useContext, useEffect, useState} from 'react'; | ||||
| import {useLocation, useNavigate} from 'react-router'; | ||||
| import {cookie} from './Cookie'; | ||||
| import {APINode, callAPI} from '../Api'; | ||||
| import {SettingsTypes} from '../../types/ApiTypes'; | ||||
| import GlobalInfos from '../GlobalInfos'; | ||||
| import {FeatureContext} from './FeatureContext'; | ||||
|  | ||||
| export const LoginContextProvider: FunctionComponent = (props): JSX.Element => { | ||||
| export const LoginContextProvider: FunctionComponent<PropsWithChildren> = (props): JSX.Element => { | ||||
|     let initialLoginState = LoginState.LoggedIn; | ||||
|     let initialUserPerm = LoginPerm.User; | ||||
|  | ||||
| @@ -50,7 +50,7 @@ export const LoginContextProvider: FunctionComponent = (props): JSX.Element => { | ||||
|         ); | ||||
|     }, [features, loginState]); | ||||
|  | ||||
|     const hist = useHistory(); | ||||
|     const navigate = useNavigate(); | ||||
|     const loc = useLocation(); | ||||
|  | ||||
|     // trigger redirect on loginstate change | ||||
| @@ -59,14 +59,14 @@ export const LoginContextProvider: FunctionComponent = (props): JSX.Element => { | ||||
|             // if we arent already in dashboard tree we want to redirect to default dashboard page | ||||
|             console.log('redirecting to dashboard' + loc.pathname); | ||||
|             if (!loc.pathname.startsWith('/media')) { | ||||
|                 hist.replace('/media'); | ||||
|                 navigate('/media'); | ||||
|             } | ||||
|         } else { | ||||
|             if (!loc.pathname.startsWith('/login')) { | ||||
|                 hist.replace('/login'); | ||||
|                 navigate('/login'); | ||||
|             } | ||||
|         } | ||||
|     }, [hist, loc.pathname, loginState]); | ||||
|     }, [navigate, loc.pathname, loginState]); | ||||
|  | ||||
|     const value = { | ||||
|         logout: (): void => { | ||||
| @@ -86,7 +86,7 @@ export const LoginContextProvider: FunctionComponent = (props): JSX.Element => { | ||||
|     return <LoginContext.Provider value={value}>{props.children}</LoginContext.Provider>; | ||||
| }; | ||||
|  | ||||
| interface Props { | ||||
| interface Props extends PropsWithChildren{ | ||||
|     perm: LoginPerm; | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user