Merge branch 'csstheming' into 'master'
Csstheming See merge request lukas/openmediacenter!8
This commit is contained in:
		@@ -22,13 +22,15 @@ class Settings extends RequestBase {
 | 
				
			|||||||
            $videopath = $_POST['videopath'];
 | 
					            $videopath = $_POST['videopath'];
 | 
				
			||||||
            $tvshowpath = $_POST['tvshowpath'];
 | 
					            $tvshowpath = $_POST['tvshowpath'];
 | 
				
			||||||
            $tmdbsupport = $_POST['tmdbsupport'];
 | 
					            $tmdbsupport = $_POST['tmdbsupport'];
 | 
				
			||||||
 | 
					            $darkmodeenabled = $_POST['darkmodeenabled'];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $query = "UPDATE settings SET 
 | 
					            $query = "UPDATE settings SET 
 | 
				
			||||||
                        video_path='$videopath',
 | 
					                        video_path='$videopath',
 | 
				
			||||||
                        episode_path='$tvshowpath',
 | 
					                        episode_path='$tvshowpath',
 | 
				
			||||||
                        password='$password',
 | 
					                        password='$password',
 | 
				
			||||||
                        mediacenter_name='$mediacentername',
 | 
					                        mediacenter_name='$mediacentername',
 | 
				
			||||||
                        TMDB_grabbing=$tmdbsupport
 | 
					                        TMDB_grabbing=$tmdbsupport, 
 | 
				
			||||||
 | 
					                        DarkMode=$darkmodeenabled
 | 
				
			||||||
                    WHERE 1";
 | 
					                    WHERE 1";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if ($this->conn->query($query) === true) {
 | 
					            if ($this->conn->query($query) === true) {
 | 
				
			||||||
@@ -44,12 +46,10 @@ class Settings extends RequestBase {
 | 
				
			|||||||
            $result = $this->conn->query($query);
 | 
					            $result = $this->conn->query($query);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            $r = mysqli_fetch_assoc($result);
 | 
					            $r = mysqli_fetch_assoc($result);
 | 
				
			||||||
            if ($r['password'] != "-1") {
 | 
					
 | 
				
			||||||
                $r['passwordEnabled'] = true;
 | 
					            $r['passwordEnabled'] = $r['password'] != "-1";
 | 
				
			||||||
            } else {
 | 
					 | 
				
			||||||
                $r['passwordEnabled'] = false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            unset($r['password']);
 | 
					            unset($r['password']);
 | 
				
			||||||
 | 
					            $r['DarkMode'] = (bool)($r['DarkMode'] != '0');
 | 
				
			||||||
            echo json_encode($r);
 | 
					            echo json_encode($r);
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,6 +36,8 @@ create table settings
 | 
				
			|||||||
    episode_path     varchar(255)                          null,
 | 
					    episode_path     varchar(255)                          null,
 | 
				
			||||||
    password         varchar(32) default '-1'              null,
 | 
					    password         varchar(32) default '-1'              null,
 | 
				
			||||||
    mediacenter_name varchar(32) default 'OpenMediaCenter' null,
 | 
					    mediacenter_name varchar(32) default 'OpenMediaCenter' null,
 | 
				
			||||||
 | 
					    TMDB_grabbing    tinyint           null,
 | 
				
			||||||
 | 
					    DarkMode         tinyint default 0 null
 | 
				
			||||||
    PRIMARY KEY (id)
 | 
					    PRIMARY KEY (id)
 | 
				
			||||||
);
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										12
									
								
								src/App.css
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								src/App.css
									
									
									
									
									
								
							@@ -1,12 +0,0 @@
 | 
				
			|||||||
.nav-item {
 | 
					 | 
				
			||||||
    cursor: pointer;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.nav-link {
 | 
					 | 
				
			||||||
    color: rgba(255, 255, 255, .5);
 | 
					 | 
				
			||||||
    font-weight: bold;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.nav-link:hover {
 | 
					 | 
				
			||||||
    color: rgba(255, 255, 255, 1);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										55
									
								
								src/App.js
									
									
									
									
									
								
							
							
						
						
									
										55
									
								
								src/App.js
									
									
									
									
									
								
							@@ -1,10 +1,12 @@
 | 
				
			|||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
import "./App.css"
 | 
					 | 
				
			||||||
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 "./GlobalInfos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// include bootstraps css
 | 
					// include bootstraps css
 | 
				
			||||||
import 'bootstrap/dist/css/bootstrap.min.css';
 | 
					import 'bootstrap/dist/css/bootstrap.min.css';
 | 
				
			||||||
 | 
					import style from './App.module.css'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import SettingsPage from "./pages/SettingsPage/SettingsPage";
 | 
					import SettingsPage from "./pages/SettingsPage/SettingsPage";
 | 
				
			||||||
import CategoryPage from "./pages/CategoryPage/CategoryPage";
 | 
					import CategoryPage from "./pages/CategoryPage/CategoryPage";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,7 +34,9 @@ class App extends React.Component {
 | 
				
			|||||||
        fetch('/api/Settings.php', {method: 'POST', body: updateRequest})
 | 
					        fetch('/api/Settings.php', {method: 'POST', body: updateRequest})
 | 
				
			||||||
            .then((response) => response.json()
 | 
					            .then((response) => response.json()
 | 
				
			||||||
                .then((result) => {
 | 
					                .then((result) => {
 | 
				
			||||||
                    console.log(result);
 | 
					                    // set theme
 | 
				
			||||||
 | 
					                    GlobalInfos.enableDarkTheme(result.DarkMode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    this.setState({
 | 
					                    this.setState({
 | 
				
			||||||
                        generalSettingsLoaded: true,
 | 
					                        generalSettingsLoaded: true,
 | 
				
			||||||
                        passwordsupport: result.passwordEnabled,
 | 
					                        passwordsupport: result.passwordEnabled,
 | 
				
			||||||
@@ -79,38 +83,27 @@ class App extends React.Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
 | 
					        // add the main theme to the page body
 | 
				
			||||||
 | 
					        document.body.className = themeStyle.backgroundcolor;
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className="App">
 | 
					            <div className="App">
 | 
				
			||||||
                <nav className="navbar navbar-expand-sm bg-primary navbar-dark">
 | 
					                <div className={[style.navcontainer, themeStyle.backgroundcolor, themeStyle.textcolor, themeStyle.hrcolor].join(' ')}>
 | 
				
			||||||
                    <div className="navbar-brand">{this.state.mediacentername}</div>
 | 
					                    <div className={style.navbrand}>{this.state.mediacentername}</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    <ul className="navbar-nav">
 | 
					                    <div className={[style.navitem, themeStyle.navitem, this.state.page === "default" ? style.navitemselected : {}].join(' ')}
 | 
				
			||||||
                        <li className="nav-item">
 | 
					                         onClick={() => this.setState({page: "default"})}>Home
 | 
				
			||||||
                            <div className="nav-link"
 | 
					                    </div>
 | 
				
			||||||
                                 style={this.state.page === "default" ? {color: "rgba(255,255,255,.75"} : {}}
 | 
					                    <div className={[style.navitem, themeStyle.navitem, this.state.page === "random" ? style.navitemselected : {}].join(' ')}
 | 
				
			||||||
                                 onClick={() => this.setState({page: "default"})}>Home
 | 
					                         onClick={() => this.setState({page: "random"})}>Random Video
 | 
				
			||||||
                            </div>
 | 
					                    </div>
 | 
				
			||||||
                        </li>
 | 
					                    <div className={[style.navitem, themeStyle.navitem, this.state.page === "categories" ? style.navitemselected : {}].join(' ')}
 | 
				
			||||||
                        <li className="nav-item">
 | 
					                         onClick={() => this.setState({page: "categories"})}>Categories
 | 
				
			||||||
                            <div className="nav-link"
 | 
					                    </div>
 | 
				
			||||||
                                 style={this.state.page === "random" ? {color: "rgba(255,255,255,.75"} : {}}
 | 
					                    <div className={[style.navitem, themeStyle.navitem, this.state.page === "settings" ? style.navitemselected : {}].join(' ')}
 | 
				
			||||||
                                 onClick={() => this.setState({page: "random"})}>Random Video
 | 
					                         onClick={() => this.setState({page: "settings"})}>Settings
 | 
				
			||||||
                            </div>
 | 
					                    </div>
 | 
				
			||||||
                        </li>
 | 
					                </div>
 | 
				
			||||||
                        <li className="nav-item">
 | 
					 | 
				
			||||||
                            <div className="nav-link"
 | 
					 | 
				
			||||||
                                 style={this.state.page === "categories" ? {color: "rgba(255,255,255,.75"} : {}}
 | 
					 | 
				
			||||||
                                 onClick={() => this.setState({page: "categories"})}>Categories
 | 
					 | 
				
			||||||
                            </div>
 | 
					 | 
				
			||||||
                        </li>
 | 
					 | 
				
			||||||
                        <li className="nav-item">
 | 
					 | 
				
			||||||
                            <div className="nav-link"
 | 
					 | 
				
			||||||
                                 style={this.state.page === "settings" ? {color: "rgba(255,255,255,.75"} : {}}
 | 
					 | 
				
			||||||
                                 onClick={() => this.setState({page: "settings"})}>Settings
 | 
					 | 
				
			||||||
                            </div>
 | 
					 | 
				
			||||||
                        </li>
 | 
					 | 
				
			||||||
                    </ul>
 | 
					 | 
				
			||||||
                </nav>
 | 
					 | 
				
			||||||
                {this.state.generalSettingsLoaded ? this.MainBody() : "loading"}
 | 
					                {this.state.generalSettingsLoaded ? this.MainBody() : "loading"}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										54
									
								
								src/App.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								src/App.module.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,54 @@
 | 
				
			|||||||
 | 
					.navitem {
 | 
				
			||||||
 | 
					    float: left;
 | 
				
			||||||
 | 
					    margin-left: 20px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    opacity: 0.6;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    font-size: large;
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					    text-transform: capitalize;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navitem:hover {
 | 
				
			||||||
 | 
					    opacity: 1;
 | 
				
			||||||
 | 
					    transition: opacity .5s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navitem::after {
 | 
				
			||||||
 | 
					    content: '';
 | 
				
			||||||
 | 
					    display: block;
 | 
				
			||||||
 | 
					    width: 0;
 | 
				
			||||||
 | 
					    height: 2px;
 | 
				
			||||||
 | 
					    transition: width .3s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navitem:hover::after {
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navitemselected {
 | 
				
			||||||
 | 
					    opacity: 0.85;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navcontainer {
 | 
				
			||||||
 | 
					    padding-top: 20px;
 | 
				
			||||||
 | 
					    width: 100%;
 | 
				
			||||||
 | 
					    padding-bottom: 40px;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    border-width: 0;
 | 
				
			||||||
 | 
					    border-style: dotted;
 | 
				
			||||||
 | 
					    border-bottom-width: 2px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navbrand {
 | 
				
			||||||
 | 
					    margin-left: 20px;
 | 
				
			||||||
 | 
					    margin-right: 20px;
 | 
				
			||||||
 | 
					    font-size: large;
 | 
				
			||||||
 | 
					    font-weight: bold;
 | 
				
			||||||
 | 
					    text-transform: capitalize;
 | 
				
			||||||
 | 
					    float: left;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -10,19 +10,19 @@ describe('<App/>', function () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    it('renders title', () => {
 | 
					    it('renders title', () => {
 | 
				
			||||||
        const wrapper = shallow(<App/>);
 | 
					        const wrapper = shallow(<App/>);
 | 
				
			||||||
        expect(wrapper.find('.navbar-brand').text()).toBe('OpenMediaCenter');
 | 
					        expect(wrapper.find('.navbrand').text()).toBe('OpenMediaCenter');
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('are navlinks correct', function () {
 | 
					    it('are navlinks correct', function () {
 | 
				
			||||||
        const wrapper = shallow(<App/>);
 | 
					        const wrapper = shallow(<App/>);
 | 
				
			||||||
        expect(wrapper.find('nav').find('li')).toHaveLength(4);
 | 
					        expect(wrapper.find('.navitem')).toHaveLength(4);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('simulate video view change ', function () {
 | 
					    it('simulate video view change ', function () {
 | 
				
			||||||
        const wrapper = shallow(<App/>);
 | 
					        const wrapper = shallow(<App/>);
 | 
				
			||||||
        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
					        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        wrapper.instance().changeRootElement(<div id='testit'></div>);
 | 
					        wrapper.instance().changeRootElement(<div id='testit'/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.find("#testit")).toHaveLength(1);
 | 
					        expect(wrapper.find("#testit")).toHaveLength(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
@@ -31,7 +31,7 @@ describe('<App/>', function () {
 | 
				
			|||||||
        const wrapper = shallow(<App/>);
 | 
					        const wrapper = shallow(<App/>);
 | 
				
			||||||
        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
					        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        wrapper.instance().changeRootElement(<div id='testit'></div>);
 | 
					        wrapper.instance().changeRootElement(<div id='testit'/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.find("#testit")).toHaveLength(1);
 | 
					        expect(wrapper.find("#testit")).toHaveLength(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -44,9 +44,9 @@ describe('<App/>', function () {
 | 
				
			|||||||
        const wrapper = shallow(<App/>);
 | 
					        const wrapper = shallow(<App/>);
 | 
				
			||||||
        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
					        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        wrapper.find(".nav-link").findWhere(t => t.text() === "Random Video" && t.type() === "div").simulate("click");
 | 
					        wrapper.find(".navitem").findWhere(t => t.text() === "Random Video" && t.type() === "div").simulate("click");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        wrapper.instance().changeRootElement(<div id='testit'></div>);
 | 
					        wrapper.instance().changeRootElement(<div id='testit'/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.find("#testit")).toHaveLength(1);
 | 
					        expect(wrapper.find("#testit")).toHaveLength(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -61,7 +61,7 @@ describe('<App/>', function () {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        wrapper.setState({page: "wrongvalue"});
 | 
					        wrapper.setState({page: "wrongvalue"});
 | 
				
			||||||
        expect(wrapper.find("HomePage")).toHaveLength(0);
 | 
					        expect(wrapper.find("HomePage")).toHaveLength(0);
 | 
				
			||||||
        wrapper.find(".nav-link").findWhere(t => t.text() === "Home" && t.type() === "div").simulate("click");
 | 
					        wrapper.find(".navitem").findWhere(t => t.text() === "Home" && t.type() === "div").simulate("click");
 | 
				
			||||||
        expect(wrapper.find("HomePage")).toHaveLength(1);
 | 
					        expect(wrapper.find("HomePage")).toHaveLength(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -70,7 +70,7 @@ describe('<App/>', function () {
 | 
				
			|||||||
        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
					        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.find("CategoryPage")).toHaveLength(0);
 | 
					        expect(wrapper.find("CategoryPage")).toHaveLength(0);
 | 
				
			||||||
        wrapper.find(".nav-link").findWhere(t => t.text() === "Categories" && t.type() === "div").simulate("click");
 | 
					        wrapper.find(".navitem").findWhere(t => t.text() === "Categories" && t.type() === "div").simulate("click");
 | 
				
			||||||
        expect(wrapper.find("CategoryPage")).toHaveLength(1);
 | 
					        expect(wrapper.find("CategoryPage")).toHaveLength(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -79,7 +79,7 @@ describe('<App/>', function () {
 | 
				
			|||||||
        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
					        wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.find("SettingsPage")).toHaveLength(0);
 | 
					        expect(wrapper.find("SettingsPage")).toHaveLength(0);
 | 
				
			||||||
        wrapper.find(".nav-link").findWhere(t => t.text() === "Settings" && t.type() === "div").simulate("click");
 | 
					        wrapper.find(".navitem").findWhere(t => t.text() === "Settings" && t.type() === "div").simulate("click");
 | 
				
			||||||
        expect(wrapper.find("SettingsPage")).toHaveLength(1);
 | 
					        expect(wrapper.find("SettingsPage")).toHaveLength(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										40
									
								
								src/AppDarkTheme.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/AppDarkTheme.module.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The coloring elements for dark theme
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.backgroundcolor {
 | 
				
			||||||
 | 
					    background-color: #141520;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.textcolor {
 | 
				
			||||||
 | 
					    color: white;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.subtextcolor {
 | 
				
			||||||
 | 
					    color: #dedad6;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.lighttextcolor {
 | 
				
			||||||
 | 
					    color: #d5d5d5;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navitem::after {
 | 
				
			||||||
 | 
					    background: white;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hrcolor {
 | 
				
			||||||
 | 
					    border-color: rgba(255, 255, 255, .1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.secbackground {
 | 
				
			||||||
 | 
					    background-color: #3c3d48;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.thirdbackground {
 | 
				
			||||||
 | 
					    background-color: #141520;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.preview:hover {
 | 
				
			||||||
 | 
					    box-shadow: rgba(255, 255, 255, 0.7) 0 0 0 5px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
							
								
								
									
										39
									
								
								src/AppLightTheme.module.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/AppLightTheme.module.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,39 @@
 | 
				
			|||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * The coloring elements for light theme
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.navitem::after {
 | 
				
			||||||
 | 
					    background: black;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.backgroundcolor {
 | 
				
			||||||
 | 
					    background-color: white;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.textcolor {
 | 
				
			||||||
 | 
					    color: black;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.subtextcolor {
 | 
				
			||||||
 | 
					    color: #212529;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.lighttextcolor {
 | 
				
			||||||
 | 
					    color: #3d3d3d;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hrcolor {
 | 
				
			||||||
 | 
					    border-color: rgba(0, 0, 0, 0.1);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.secbackground {
 | 
				
			||||||
 | 
					    background-color: #a8c3ff;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.thirdbackground {
 | 
				
			||||||
 | 
					    background-color: #8ca3fc;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.preview:hover {
 | 
				
			||||||
 | 
					    box-shadow: rgba(2, 12, 27, 0.7) 0 0 0 5px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										23
									
								
								src/GlobalInfos.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/GlobalInfos.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,23 @@
 | 
				
			|||||||
 | 
					import darktheme from "./AppDarkTheme.module.css";
 | 
				
			||||||
 | 
					import lighttheme from "./AppLightTheme.module.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class StaticInfos {
 | 
				
			||||||
 | 
					    #darktheme = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    isDarkTheme() {
 | 
				
			||||||
 | 
					        return this.#darktheme;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    enableDarkTheme(enable = true){
 | 
				
			||||||
 | 
					        this.#darktheme = enable;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getThemeStyle(){
 | 
				
			||||||
 | 
					        return this.isDarkTheme() ? darktheme : lighttheme;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const GlobalInfos = new StaticInfos();
 | 
				
			||||||
 | 
					//Object.freeze(StaticInfos);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default GlobalInfos;
 | 
				
			||||||
							
								
								
									
										24
									
								
								src/GlobalInfos.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/GlobalInfos.test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import GlobalInfos from "./GlobalInfos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					describe('<GlobalInfos/>', function () {
 | 
				
			||||||
 | 
					    it('always same instance ', function () {
 | 
				
			||||||
 | 
					        GlobalInfos.enableDarkTheme(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(GlobalInfos.isDarkTheme()).toBe(true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        GlobalInfos.enableDarkTheme(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(GlobalInfos.isDarkTheme()).toBe(false);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test default theme', function () {
 | 
				
			||||||
 | 
					        expect(GlobalInfos.isDarkTheme()).toBe(false);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test receive of stylesheet', function () {
 | 
				
			||||||
 | 
					        const style = GlobalInfos.getThemeStyle();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        expect(style.navitem).not.toBeNull();
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import style from "./PageTitle.module.css"
 | 
					import style from "./PageTitle.module.css"
 | 
				
			||||||
 | 
					import GlobalInfos from "../../GlobalInfos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PageTitle extends React.Component {
 | 
					class PageTitle extends React.Component {
 | 
				
			||||||
    constructor(props) {
 | 
					    constructor(props) {
 | 
				
			||||||
@@ -10,17 +11,33 @@ class PageTitle extends React.Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className={style.pageheader}>
 | 
					            <div className={style.pageheader + ' ' + themeStyle.backgroundcolor}>
 | 
				
			||||||
                <span className={style.pageheadertitle}>{this.props.title}</span>
 | 
					                <span className={style.pageheadertitle + ' ' + themeStyle.textcolor}>{this.props.title}</span>
 | 
				
			||||||
                <span className={style.pageheadersubtitle}>{this.props.subtitle}</span>
 | 
					                <span className={style.pageheadersubtitle + ' ' + themeStyle.textcolor}>{this.props.subtitle}</span>
 | 
				
			||||||
                <>
 | 
					                <>
 | 
				
			||||||
                    {this.props.children}
 | 
					                    {this.props.children}
 | 
				
			||||||
                </>
 | 
					                </>
 | 
				
			||||||
                <hr/>
 | 
					                <Line/>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/**
 | 
				
			||||||
 | 
					 * class to override default <hr> color and styling
 | 
				
			||||||
 | 
					 * use this for horizontal lines to use the current active theming
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					export class Line extends React.Component {
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <>
 | 
				
			||||||
 | 
					                <hr className={themeStyle.hrcolor}/>
 | 
				
			||||||
 | 
					            </>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default PageTitle;
 | 
					export default PageTitle;
 | 
				
			||||||
@@ -1,8 +1,5 @@
 | 
				
			|||||||
.pageheader {
 | 
					.pageheader {
 | 
				
			||||||
    margin-bottom: 20px;
 | 
					    padding: 20px 12% 20px 22%;
 | 
				
			||||||
    margin-top: 20px;
 | 
					 | 
				
			||||||
    padding-left: 22%;
 | 
					 | 
				
			||||||
    padding-right: 12%;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pageheadertitle {
 | 
					.pageheadertitle {
 | 
				
			||||||
@@ -11,7 +8,7 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pageheadersubtitle {
 | 
					.pageheadersubtitle {
 | 
				
			||||||
    font-size: 23pt;
 | 
					 | 
				
			||||||
    margin-left: 20px;
 | 
					    margin-left: 20px;
 | 
				
			||||||
 | 
					    font-size: 23pt;
 | 
				
			||||||
    opacity: 0.6;
 | 
					    opacity: 0.6;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ describe('<Preview/>', function () {
 | 
				
			|||||||
    it('renders pagetitle prop', function () {
 | 
					    it('renders pagetitle prop', function () {
 | 
				
			||||||
        const wrapper = shallow(<PageTitle title='testtitle'/>);
 | 
					        const wrapper = shallow(<PageTitle title='testtitle'/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.find(".pageheader").text()).toBe("testtitle");
 | 
					        expect(wrapper.find(".pageheader").text()).toBe("testtitle<Line />");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('renders subtitle prop', function () {
 | 
					    it('renders subtitle prop', function () {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ import React from "react";
 | 
				
			|||||||
import style from "./Preview.module.css";
 | 
					import style from "./Preview.module.css";
 | 
				
			||||||
import Player from "../../pages/Player/Player";
 | 
					import Player from "../../pages/Player/Player";
 | 
				
			||||||
import {Spinner} from "react-bootstrap";
 | 
					import {Spinner} from "react-bootstrap";
 | 
				
			||||||
 | 
					import GlobalInfos from "../../GlobalInfos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Preview extends React.Component {
 | 
					class Preview extends React.Component {
 | 
				
			||||||
    constructor(props, context) {
 | 
					    constructor(props, context) {
 | 
				
			||||||
@@ -33,9 +34,10 @@ class Preview extends React.Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className={style.videopreview} onClick={() => this.itemClick()}>
 | 
					            <div className={style.videopreview + ' ' + themeStyle.secbackground + ' '+ themeStyle.preview} onClick={() => this.itemClick()}>
 | 
				
			||||||
                <div className={style.previewtitle}>{this.state.name}</div>
 | 
					                <div className={style.previewtitle + ' '+ themeStyle.lighttextcolor}>{this.state.name}</div>
 | 
				
			||||||
                <div className={style.previewpic}>
 | 
					                <div className={style.previewpic}>
 | 
				
			||||||
                    {this.state.previewpicture !== null ?
 | 
					                    {this.state.previewpicture !== null ?
 | 
				
			||||||
                        <img className={style.previewimage}
 | 
					                        <img className={style.previewimage}
 | 
				
			||||||
@@ -63,9 +65,10 @@ class Preview extends React.Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export class TagPreview extends React.Component {
 | 
					export class TagPreview extends React.Component {
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className={style.videopreview + ' ' + style.tagpreview} onClick={() => this.itemClick()}>
 | 
					            <div className={style.videopreview + ' ' + style.tagpreview + ' ' + themeStyle.secbackground + ' '+ themeStyle.preview} onClick={() => this.itemClick()}>
 | 
				
			||||||
                <div className={style.tagpreviewtitle}>
 | 
					                <div className={style.tagpreviewtitle + ' ' + themeStyle.lighttextcolor}>
 | 
				
			||||||
                    {this.props.name}
 | 
					                    {this.props.name}
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,6 @@
 | 
				
			|||||||
.previewtitle {
 | 
					.previewtitle {
 | 
				
			||||||
    color: #3d3d3d;
 | 
					    height: 20px;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
    font-size: smaller;
 | 
					    font-size: smaller;
 | 
				
			||||||
    font-weight: bold;
 | 
					    font-weight: bold;
 | 
				
			||||||
    height: 20px;
 | 
					    height: 20px;
 | 
				
			||||||
@@ -33,10 +34,8 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.videopreview {
 | 
					.videopreview {
 | 
				
			||||||
    background-color: #a8c3ff;
 | 
					 | 
				
			||||||
    border-radius: 20px;
 | 
					    border-radius: 20px;
 | 
				
			||||||
    cursor: pointer;
 | 
					    cursor: pointer;
 | 
				
			||||||
    /*background-color: #7F7F7F;*/
 | 
					 | 
				
			||||||
    float: left;
 | 
					    float: left;
 | 
				
			||||||
    margin-left: 25px;
 | 
					    margin-left: 25px;
 | 
				
			||||||
    margin-top: 25px;
 | 
					    margin-top: 25px;
 | 
				
			||||||
@@ -44,7 +43,6 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.videopreview:hover {
 | 
					.videopreview:hover {
 | 
				
			||||||
    box-shadow: rgba(2, 12, 27, 0.7) 0 0 0 5px;
 | 
					 | 
				
			||||||
    opacity: 1;
 | 
					    opacity: 1;
 | 
				
			||||||
    transition: all 300ms;
 | 
					    transition: all 300ms;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,11 @@
 | 
				
			|||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import style from "./SideBar.module.css"
 | 
					import style from "./SideBar.module.css"
 | 
				
			||||||
 | 
					import GlobalInfos from "../../GlobalInfos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SideBar extends React.Component {
 | 
					class SideBar extends React.Component {
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
        return (<div className={style.sideinfo}>
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
 | 
					        return (<div className={style.sideinfo + ' '+ themeStyle.secbackground}>
 | 
				
			||||||
            {this.props.children}
 | 
					            {this.props.children}
 | 
				
			||||||
        </div>);
 | 
					        </div>);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -11,16 +13,18 @@ class SideBar extends React.Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
export class SideBarTitle extends React.Component {
 | 
					export class SideBarTitle extends React.Component {
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className={style.sidebartitle}>{this.props.children}</div>
 | 
					            <div className={style.sidebartitle + ' '+ themeStyle.subtextcolor}>{this.props.children}</div>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export class SideBarItem extends React.Component {
 | 
					export class SideBarItem extends React.Component {
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div className={style.sidebarinfo}>{this.props.children}</div>
 | 
					            <div className={style.sidebarinfo + ' ' + themeStyle.thirdbackground + ' ' + themeStyle.lighttextcolor}>{this.props.children}</div>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,5 +1,4 @@
 | 
				
			|||||||
.sideinfo {
 | 
					.sideinfo {
 | 
				
			||||||
    background-color: #b4c7fe;
 | 
					 | 
				
			||||||
    border: 2px #3574fe solid;
 | 
					    border: 2px #3574fe solid;
 | 
				
			||||||
    border-radius: 20px;
 | 
					    border-radius: 20px;
 | 
				
			||||||
    float: left;
 | 
					    float: left;
 | 
				
			||||||
@@ -16,7 +15,6 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.sidebarinfo {
 | 
					.sidebarinfo {
 | 
				
			||||||
    background-color: #8ca3fc;
 | 
					 | 
				
			||||||
    border-radius: 5px;
 | 
					    border-radius: 5px;
 | 
				
			||||||
    margin-top: 5px;
 | 
					    margin-top: 5px;
 | 
				
			||||||
    padding: 2px 10px 2px 15px;
 | 
					    padding: 2px 10px 2px 15px;
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
body {
 | 
					 | 
				
			||||||
    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
 | 
					 | 
				
			||||||
    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
 | 
					 | 
				
			||||||
    sans-serif;
 | 
					 | 
				
			||||||
    -webkit-font-smoothing: antialiased;
 | 
					 | 
				
			||||||
    margin: 0;
 | 
					 | 
				
			||||||
    -moz-osx-font-smoothing: grayscale;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
@@ -1,6 +1,5 @@
 | 
				
			|||||||
import React from 'react';
 | 
					import React from 'react';
 | 
				
			||||||
import ReactDOM from 'react-dom';
 | 
					import ReactDOM from 'react-dom';
 | 
				
			||||||
import './index.css';
 | 
					 | 
				
			||||||
import App from './App';
 | 
					import App from './App';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ReactDOM.render(
 | 
					ReactDOM.render(
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,7 +5,7 @@ import videocontainerstyle from "../../elements/VideoContainer/VideoContainer.mo
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import {TagPreview} from "../../elements/Preview/Preview";
 | 
					import {TagPreview} from "../../elements/Preview/Preview";
 | 
				
			||||||
import NewTagPopup from "../../elements/NewTagPopup/NewTagPopup";
 | 
					import NewTagPopup from "../../elements/NewTagPopup/NewTagPopup";
 | 
				
			||||||
import PageTitle from "../../elements/PageTitle/PageTitle";
 | 
					import PageTitle, {Line} from "../../elements/PageTitle/PageTitle";
 | 
				
			||||||
import VideoContainer from "../../elements/VideoContainer/VideoContainer";
 | 
					import VideoContainer from "../../elements/VideoContainer/VideoContainer";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CategoryPage extends React.Component {
 | 
					class CategoryPage extends React.Component {
 | 
				
			||||||
@@ -56,7 +56,7 @@ class CategoryPage extends React.Component {
 | 
				
			|||||||
                            this.loadTag(e.props.category)
 | 
					                            this.loadTag(e.props.category)
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
                    }}>HD</Tag>
 | 
					                    }}>HD</Tag>
 | 
				
			||||||
                    <hr/>
 | 
					                    <Line/>
 | 
				
			||||||
                    <button data-testid='btnaddtag' className='btn btn-success' onClick={() => {
 | 
					                    <button data-testid='btnaddtag' className='btn btn-success' onClick={() => {
 | 
				
			||||||
                        this.setState({popupvisible: true})
 | 
					                        this.setState({popupvisible: true})
 | 
				
			||||||
                    }}>Add a new Tag!
 | 
					                    }}>Add a new Tag!
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,7 +4,7 @@ import Tag from "../../elements/Tag/Tag";
 | 
				
			|||||||
import VideoContainer from "../../elements/VideoContainer/VideoContainer";
 | 
					import VideoContainer from "../../elements/VideoContainer/VideoContainer";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import style from "./HomePage.module.css"
 | 
					import style from "./HomePage.module.css"
 | 
				
			||||||
import PageTitle from "../../elements/PageTitle/PageTitle";
 | 
					import PageTitle, {Line} from "../../elements/PageTitle/PageTitle";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HomePage extends React.Component {
 | 
					class HomePage extends React.Component {
 | 
				
			||||||
    /** keyword variable needed temporary store search keyword */
 | 
					    /** keyword variable needed temporary store search keyword */
 | 
				
			||||||
@@ -138,13 +138,13 @@ class HomePage extends React.Component {
 | 
				
			|||||||
                </PageTitle>
 | 
					                </PageTitle>
 | 
				
			||||||
                <SideBar>
 | 
					                <SideBar>
 | 
				
			||||||
                    <SideBarTitle>Infos:</SideBarTitle>
 | 
					                    <SideBarTitle>Infos:</SideBarTitle>
 | 
				
			||||||
                    <hr/>
 | 
					                    <Line/>
 | 
				
			||||||
                    <SideBarItem><b>{this.state.sideinfo.videonr}</b> Videos Total!</SideBarItem>
 | 
					                    <SideBarItem><b>{this.state.sideinfo.videonr}</b> Videos Total!</SideBarItem>
 | 
				
			||||||
                    <SideBarItem><b>{this.state.sideinfo.fullhdvideonr}</b> FULL-HD Videos!</SideBarItem>
 | 
					                    <SideBarItem><b>{this.state.sideinfo.fullhdvideonr}</b> FULL-HD Videos!</SideBarItem>
 | 
				
			||||||
                    <SideBarItem><b>{this.state.sideinfo.hdvideonr}</b> HD Videos!</SideBarItem>
 | 
					                    <SideBarItem><b>{this.state.sideinfo.hdvideonr}</b> HD Videos!</SideBarItem>
 | 
				
			||||||
                    <SideBarItem><b>{this.state.sideinfo.sdvideonr}</b> SD Videos!</SideBarItem>
 | 
					                    <SideBarItem><b>{this.state.sideinfo.sdvideonr}</b> SD Videos!</SideBarItem>
 | 
				
			||||||
                    <SideBarItem><b>{this.state.sideinfo.tagnr}</b> different Tags!</SideBarItem>
 | 
					                    <SideBarItem><b>{this.state.sideinfo.tagnr}</b> different Tags!</SideBarItem>
 | 
				
			||||||
                    <hr/>
 | 
					                    <Line/>
 | 
				
			||||||
                    <SideBarTitle>Default Tags:</SideBarTitle>
 | 
					                    <SideBarTitle>Default Tags:</SideBarTitle>
 | 
				
			||||||
                    <Tag viewbinding={this.props.viewbinding}>All</Tag>
 | 
					                    <Tag viewbinding={this.props.viewbinding}>All</Tag>
 | 
				
			||||||
                    <Tag viewbinding={this.props.viewbinding}>FullHd</Tag>
 | 
					                    <Tag viewbinding={this.props.viewbinding}>FullHd</Tag>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,11 @@
 | 
				
			|||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import style from "./Player.module.css"
 | 
					import style from "./Player.module.css"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import {PlyrComponent} from 'plyr-react';
 | 
					import {PlyrComponent} from 'plyr-react';
 | 
				
			||||||
import SideBar, {SideBarItem, SideBarTitle} from "../../elements/SideBar/SideBar";
 | 
					import SideBar, {SideBarItem, SideBarTitle} from "../../elements/SideBar/SideBar";
 | 
				
			||||||
import Tag from "../../elements/Tag/Tag";
 | 
					import Tag from "../../elements/Tag/Tag";
 | 
				
			||||||
import AddTagPopup from "../../elements/AddTagPopup/AddTagPopup";
 | 
					import AddTagPopup from "../../elements/AddTagPopup/AddTagPopup";
 | 
				
			||||||
import PageTitle from "../../elements/PageTitle/PageTitle";
 | 
					import PageTitle, {Line} from "../../elements/PageTitle/PageTitle";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Player extends React.Component {
 | 
					class Player extends React.Component {
 | 
				
			||||||
@@ -53,14 +54,13 @@ class Player extends React.Component {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
                <SideBar>
 | 
					                <SideBar>
 | 
				
			||||||
                    <SideBarTitle>Infos:</SideBarTitle>
 | 
					                    <SideBarTitle>Infos:</SideBarTitle>
 | 
				
			||||||
                    <hr/>
 | 
					                    <Line/>
 | 
				
			||||||
                    <SideBarItem><b>{this.state.likes}</b> Likes!</SideBarItem>
 | 
					                    <SideBarItem><b>{this.state.likes}</b> Likes!</SideBarItem>
 | 
				
			||||||
                    {this.state.quality !== 0 ?
 | 
					                    {this.state.quality !== 0 ?
 | 
				
			||||||
                        <SideBarItem><b>{this.state.quality}p</b> Quality!</SideBarItem> : null}
 | 
					                        <SideBarItem><b>{this.state.quality}p</b> Quality!</SideBarItem> : null}
 | 
				
			||||||
                    {this.state.length !== 0 ?
 | 
					                    {this.state.length !== 0 ?
 | 
				
			||||||
                        <SideBarItem><b>{Math.round(this.state.length / 60)}</b> Minutes of
 | 
					                        <SideBarItem><b>{Math.round(this.state.length / 60)}</b> Minutes of length!</SideBarItem>: null}
 | 
				
			||||||
                            length!</SideBarItem> : null}
 | 
					                    <Line/>
 | 
				
			||||||
                    <hr/>
 | 
					 | 
				
			||||||
                    <SideBarTitle>Tags:</SideBarTitle>
 | 
					                    <SideBarTitle>Tags:</SideBarTitle>
 | 
				
			||||||
                    {this.state.tags.map((m) => (
 | 
					                    {this.state.tags.map((m) => (
 | 
				
			||||||
                        <Tag
 | 
					                        <Tag
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@
 | 
				
			|||||||
    margin-left: 20px;
 | 
					    margin-left: 20px;
 | 
				
			||||||
    margin-top: 25px;
 | 
					    margin-top: 25px;
 | 
				
			||||||
    width: 60%;
 | 
					    width: 60%;
 | 
				
			||||||
 | 
					    margin-top: 20px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.videoactions {
 | 
					.videoactions {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import {Button, Col, Form} from "react-bootstrap";
 | 
					import {Button, Col, Form} from "react-bootstrap";
 | 
				
			||||||
import style from "./GeneralSettings.module.css"
 | 
					import style from "./GeneralSettings.module.css"
 | 
				
			||||||
 | 
					import GlobalInfos from "../../GlobalInfos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class GeneralSettings extends React.Component {
 | 
					class GeneralSettings extends React.Component {
 | 
				
			||||||
    constructor(props) {
 | 
					    constructor(props) {
 | 
				
			||||||
@@ -37,9 +38,10 @@ class GeneralSettings extends React.Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themeStyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <>
 | 
					            <>
 | 
				
			||||||
                <div className={style.GeneralForm}>
 | 
					                <div className={style.GeneralForm + ' ' + themeStyle.subtextcolor}>
 | 
				
			||||||
                    <Form data-testid='mainformsettings' onSubmit={(e) => {
 | 
					                    <Form data-testid='mainformsettings' onSubmit={(e) => {
 | 
				
			||||||
                        e.preventDefault();
 | 
					                        e.preventDefault();
 | 
				
			||||||
                        this.saveSettings();
 | 
					                        this.saveSettings();
 | 
				
			||||||
@@ -70,6 +72,14 @@ class GeneralSettings extends React.Component {
 | 
				
			|||||||
                            }}
 | 
					                            }}
 | 
				
			||||||
                        />
 | 
					                        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        {this.state.passwordsupport ?
 | 
				
			||||||
 | 
					                            <Form.Group data-testid="passwordfield">
 | 
				
			||||||
 | 
					                                <Form.Label>Password</Form.Label>
 | 
				
			||||||
 | 
					                                <Form.Control type="password" placeholder="**********" value={this.state.password}
 | 
				
			||||||
 | 
					                                              onChange={(e) => this.setState({password: e.target.value})}/>
 | 
				
			||||||
 | 
					                            </Form.Group> : null
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        <Form.Check
 | 
					                        <Form.Check
 | 
				
			||||||
                            type="switch"
 | 
					                            type="switch"
 | 
				
			||||||
                            id="custom-switch-2"
 | 
					                            id="custom-switch-2"
 | 
				
			||||||
@@ -81,13 +91,18 @@ class GeneralSettings extends React.Component {
 | 
				
			|||||||
                            }}
 | 
					                            }}
 | 
				
			||||||
                        />
 | 
					                        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        {this.state.passwordsupport ?
 | 
					                        <Form.Check
 | 
				
			||||||
                            <Form.Group data-testid="passwordfield">
 | 
					                            type="switch"
 | 
				
			||||||
                                <Form.Label>Password</Form.Label>
 | 
					                            id="custom-switch-3"
 | 
				
			||||||
                                <Form.Control type="password" placeholder="**********" value={this.state.password}
 | 
					                            data-testid='darktheme-switch'
 | 
				
			||||||
                                              onChange={(e) => this.setState({password: e.target.value})}/>
 | 
					                            label="Enable Dark-Theme"
 | 
				
			||||||
                            </Form.Group> : null
 | 
					                            checked={GlobalInfos.isDarkTheme()}
 | 
				
			||||||
                        }
 | 
					                            onChange={() => {
 | 
				
			||||||
 | 
					                                GlobalInfos.enableDarkTheme(!GlobalInfos.isDarkTheme());
 | 
				
			||||||
 | 
					                                this.forceUpdate();
 | 
				
			||||||
 | 
					                                // todo initiate rerender
 | 
				
			||||||
 | 
					                            }}
 | 
				
			||||||
 | 
					                        />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        <Form.Group className={style.mediacenternameform} data-testid="nameform">
 | 
					                        <Form.Group className={style.mediacenternameform} data-testid="nameform">
 | 
				
			||||||
                            <Form.Label>The name of the Mediacenter</Form.Label>
 | 
					                            <Form.Label>The name of the Mediacenter</Form.Label>
 | 
				
			||||||
@@ -113,6 +128,7 @@ class GeneralSettings extends React.Component {
 | 
				
			|||||||
        updateRequest.append('tvshowpath', this.state.tvshowpath);
 | 
					        updateRequest.append('tvshowpath', this.state.tvshowpath);
 | 
				
			||||||
        updateRequest.append('mediacentername', this.state.mediacentername);
 | 
					        updateRequest.append('mediacentername', this.state.mediacentername);
 | 
				
			||||||
        updateRequest.append("tmdbsupport", this.state.tmdbsupport);
 | 
					        updateRequest.append("tmdbsupport", this.state.tmdbsupport);
 | 
				
			||||||
 | 
					        updateRequest.append("darkmodeenabled", GlobalInfos.isDarkTheme());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        fetch('/api/Settings.php', {method: 'POST', body: updateRequest})
 | 
					        fetch('/api/Settings.php', {method: 'POST', body: updateRequest})
 | 
				
			||||||
            .then((response) => response.json()
 | 
					            .then((response) => response.json()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,6 +1,7 @@
 | 
				
			|||||||
import {shallow} from "enzyme";
 | 
					import {shallow} from "enzyme";
 | 
				
			||||||
import React from "react";
 | 
					import React from "react";
 | 
				
			||||||
import GeneralSettings from "./GeneralSettings";
 | 
					import GeneralSettings from "./GeneralSettings";
 | 
				
			||||||
 | 
					import GlobalInfos from "../../GlobalInfos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
describe('<GeneralSettings/>', function () {
 | 
					describe('<GeneralSettings/>', function () {
 | 
				
			||||||
    it('renders without crashing ', function () {
 | 
					    it('renders without crashing ', function () {
 | 
				
			||||||
@@ -17,6 +18,15 @@ describe('<GeneralSettings/>', function () {
 | 
				
			|||||||
        expect(wrapper.find("[data-testid='passwordfield']")).toHaveLength(1);
 | 
					        expect(wrapper.find("[data-testid='passwordfield']")).toHaveLength(1);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    it('test theme switchbutton', function () {
 | 
				
			||||||
 | 
					        const wrapper = shallow(<GeneralSettings/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        GlobalInfos.enableDarkTheme(false);
 | 
				
			||||||
 | 
					        expect(GlobalInfos.isDarkTheme()).toBe(false);
 | 
				
			||||||
 | 
					        wrapper.find("[data-testid='darktheme-switch']").simulate("change");
 | 
				
			||||||
 | 
					        expect(GlobalInfos.isDarkTheme()).toBe(true);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('test savesettings', done => {
 | 
					    it('test savesettings', done => {
 | 
				
			||||||
        const wrapper = shallow(<GeneralSettings/>);
 | 
					        const wrapper = shallow(<GeneralSettings/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ import React 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 "../../GlobalInfos";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SettingsPage extends React.Component {
 | 
					class SettingsPage extends React.Component {
 | 
				
			||||||
@@ -27,10 +28,11 @@ class SettingsPage extends React.Component {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    render() {
 | 
					    render() {
 | 
				
			||||||
 | 
					        const themestyle = GlobalInfos.getThemeStyle();
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div>
 | 
					            <div>
 | 
				
			||||||
                <div className={style.SettingsSidebar}>
 | 
					                <div className={style.SettingsSidebar + ' ' + themestyle.secbackground}>
 | 
				
			||||||
                    <div className={style.SettingsSidebarTitle}>Settings</div>
 | 
					                    <div className={style.SettingsSidebarTitle + ' ' + themestyle.lighttextcolor}>Settings</div>
 | 
				
			||||||
                    <div onClick={() => this.setState({currentpage: "general"})}
 | 
					                    <div onClick={() => this.setState({currentpage: "general"})}
 | 
				
			||||||
                         className={style.SettingSidebarElement}>General
 | 
					                         className={style.SettingSidebarElement}>General
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,7 +1,8 @@
 | 
				
			|||||||
.SettingsSidebar {
 | 
					.SettingsSidebar {
 | 
				
			||||||
    background-color: #d3dcef;
 | 
					    border-bottom-right-radius: 10px;
 | 
				
			||||||
 | 
					    border-top-right-radius: 10px;
 | 
				
			||||||
    float: left;
 | 
					    float: left;
 | 
				
			||||||
    min-height: calc(100vh - 56px);
 | 
					    min-height: calc(100vh - 62px);
 | 
				
			||||||
    min-width: 110px;
 | 
					    min-width: 110px;
 | 
				
			||||||
    padding-top: 20px;
 | 
					    padding-top: 20px;
 | 
				
			||||||
    width: 10%;
 | 
					    width: 10%;
 | 
				
			||||||
@@ -23,7 +24,7 @@
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.SettingSidebarElement {
 | 
					.SettingSidebarElement {
 | 
				
			||||||
    background-color: #a8b2de;
 | 
					    background-color: #919fd9;
 | 
				
			||||||
    border-radius: 7px;
 | 
					    border-radius: 7px;
 | 
				
			||||||
    font-weight: bold;
 | 
					    font-weight: bold;
 | 
				
			||||||
    margin: 10px 5px 5px;
 | 
					    margin: 10px 5px 5px;
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user