diff --git a/api/SSettings.php b/api/SSettings.php new file mode 100644 index 0000000..965ba0b --- /dev/null +++ b/api/SSettings.php @@ -0,0 +1,39 @@ +database = Database::getInstance(); + } + + public function getVideoPath() { + $query = "SELECT video_path from settings"; + + $result = $this->database->getConnection()->query($query); + + $r = mysqli_fetch_assoc($result); + return $r['video_path']; + } + + /** + * check if TMDB is enableds + * @return bool isenabled? + */ + public function isTMDBGrabbingEnabled(): bool + { + $query = "SELECT TMDB_grabbing from settings"; + + $result = $this->database->getConnection()->query($query); + if(!$result){ + return true; // if undefined in db --> default true + }else{ + $r = mysqli_fetch_assoc($result); + return $r['TMDB_grabbing'] == '1'; + } + } +} \ No newline at end of file diff --git a/api/Settings.php b/api/Settings.php new file mode 100644 index 0000000..273446e --- /dev/null +++ b/api/Settings.php @@ -0,0 +1,65 @@ +getConnection(); +$settings = new SSettings(); + +if (isset($_POST['action'])) { + $action = $_POST['action']; + switch ($action) { + case "loadGeneralSettings": + $query = "SELECT * from settings"; + + $result = $conn->query($query); + if ($result->num_rows > 1) { + // todo throw error + } + + $r = mysqli_fetch_assoc($result); + // booleans need to be set manually + $r['passwordEnabled'] = $r['password'] != "-1"; + $r['TMDB_grabbing'] = ($r['TMDB_grabbing'] != '0'); + + echo json_encode($r); + break; + case "saveGeneralSettings": + $mediacentername = $_POST['mediacentername']; + $password = $_POST['password']; + $videopath = $_POST['videopath']; + $tvshowpath = $_POST['tvshowpath']; + $tmdbsupport = $_POST['tmdbsupport']; + + $query = "UPDATE settings SET + video_path='$videopath', + episode_path='$tvshowpath', + password='$password', + mediacenter_name='$mediacentername', + TMDB_grabbing=$tmdbsupport + WHERE 1"; + + if ($conn->query($query) === true) { + echo '{"success": true}'; + } else { + echo '{"success": true}'; + } + break; + case "loadInitialData": + $query = "SELECT * from settings"; + + $result = $conn->query($query); + if ($result->num_rows > 1) { + // todo throw error + } + + $r = mysqli_fetch_assoc($result); + if ($r['password'] != "-1") { + $r['passwordEnabled'] = true; + } else { + $r['passwordEnabled'] = false; + } + unset($r['password']); + echo json_encode($r); + break; + } +} diff --git a/api/extractvideopreviews.php b/api/extractvideopreviews.php index db0cc92..eb47c2c 100755 --- a/api/extractvideopreviews.php +++ b/api/extractvideopreviews.php @@ -1,6 +1,7 @@ getAllGenres(); $conn = Database::getInstance()->getConnection(); +$settings = new SSettings(); -$scandir = "../videos/prn/"; +// load video path from settings +$scandir = "../" . $settings->getVideoPath(); $arr = scandir($scandir); +$TMDB_enabled = $settings->isTMDBGrabbingEnabled(); $all = 0; $added = 0; @@ -33,14 +37,21 @@ foreach ($arr as $elem) { $poster = -1; $genres = -1; if (!is_null($dta = $tmdb->searchMovie($moviename))) { - $pic = file_get_contents($tmdb->picturebase . $dta->poster_path); $poster = shell_exec("ffmpeg -hide_banner -loglevel panic -ss 00:04:00 -i \"../videos/prn/$elem\" -vframes 1 -q:v 2 -f singlejpeg pipe:1 2>/dev/null"); - // error handling for download error - if (!$pic) { + // check if tmdb support is enabled + if ($TMDB_enabled) { + $pic = file_get_contents($tmdb->picturebase . $dta->poster_path); + + // error handling for download error + if (!$pic) { + $pic = $poster; + $poster = -1; + echo "Failed to load Picture from TMDB! \n"; + } + } else { $pic = $poster; $poster = -1; - echo "Failed to load Picture from TMDB! \n"; } $genres = $dta->genre_ids; diff --git a/api/videoload.php b/api/videoload.php index 7796caf..800258e 100755 --- a/api/videoload.php +++ b/api/videoload.php @@ -1,9 +1,15 @@ getConnection(); +$settings = new SSettings(); + +// load video path from settings +$videopath = $settings->getVideoPath(); + -//$_POST['action'] = "getRandomMovies";$_POST['number'] =6; if (isset($_POST['action'])) { $action = $_POST['action']; switch ($action) { @@ -84,7 +90,9 @@ if (isset($_POST['action'])) { $arr["movie_id"] = $row["movie_id"]; $arr["movie_name"] = $row["movie_name"]; - $arr["movie_url"] = str_replace("?","%3F",$row["movie_url"]); + // todo drop video url from db -- maybe one with and one without extension + // extension hardcoded here!!! + $arr["movie_url"] = str_replace("?", "%3F", $videopath . $row["movie_name"] . ".mp4"); $arr["likes"] = $row["likes"]; $arr["quality"] = $row["quality"]; $arr["length"] = $row["length"]; diff --git a/database.sql b/database.sql index 2005183..ba71abd 100644 --- a/database.sql +++ b/database.sql @@ -29,9 +29,22 @@ create table if not exists video_tags foreign key (video_id) references videos (movie_id) ); +create table settings +( + id enum(1) NOT NULL default 0, + video_path varchar(255) null, + episode_path varchar(255) null, + password varchar(32) default '-1' null, + mediacenter_name varchar(32) default 'OpenMediaCenter' null, + PRIMARY KEY (id) +); + INSERT INTO tags (tag_id, tag_name) VALUES (2, 'fullhd'); INSERT INTO tags (tag_id, tag_name) VALUES (3, 'lowquality'); INSERT INTO tags (tag_id, tag_name) VALUES (4, 'hd'); + +INSERT INTO settings (video_path, episode_path, password, mediacenter_name) +VALUES ('./videos/', './tvshows/', -1, 'OpenMediaCenter'); diff --git a/src/App.js b/src/App.js index 4beed12..56a9467 100644 --- a/src/App.js +++ b/src/App.js @@ -11,37 +11,57 @@ import CategoryPage from "./pages/CategoryPage/CategoryPage"; class App extends React.Component { constructor(props, context) { super(props, context); - this.state = {page: "default"}; + this.state = { + page: "default", + generalSettingsLoaded: false, + passwordsupport: null, + mediacentername: "OpenMediaCenter" + }; // bind this to the method for being able to call methods such as this.setstate this.changeRootElement = this.changeRootElement.bind(this); this.returnToLastElement = this.returnToLastElement.bind(this); } + componentDidMount() { + const updateRequest = new FormData(); + updateRequest.append('action', 'loadInitialData'); + + fetch('/api/Settings.php', {method: 'POST', body: updateRequest}) + .then((response) => response.json() + .then((result) => { + console.log(result); + this.setState({ + generalSettingsLoaded: true, + passwordsupport: result.passwordEnabled, + mediacentername: result.mediacenter_name + }); + console.log(this.state); + })); + } + newElement = null; + constructViewBinding() { + return { + changeRootElement: this.changeRootElement, + returnToLastElement: this.returnToLastElement + }; + } + MainBody() { let page; if (this.state.page === "default") { - page = ; + page = ; this.mypage = page; } else if (this.state.page === "random") { - page = ; + page = ; this.mypage = page; } else if (this.state.page === "settings") { page = ; this.mypage = page; } else if (this.state.page === "categories") { - page = ; + page = ; this.mypage = page; } else if (this.state.page === "video") { // show videoelement if neccessary @@ -61,7 +81,7 @@ class App extends React.Component { return (
- {this.MainBody()} + {this.state.generalSettingsLoaded ? this.MainBody() : "loading"}
); } diff --git a/src/App.test.js b/src/App.test.js index a4bbdb1..d69a1f0 100644 --- a/src/App.test.js +++ b/src/App.test.js @@ -2,6 +2,14 @@ import React from 'react'; import App from './App'; import {shallow} from 'enzyme' +function prepareFetchApi(response) { + const mockJsonPromise = Promise.resolve(response); + const mockFetchPromise = Promise.resolve({ + json: () => mockJsonPromise, + }); + return (jest.fn().mockImplementation(() => mockFetchPromise)); +} + describe('', function () { it('renders without crashing ', function () { const wrapper = shallow(); @@ -20,6 +28,7 @@ describe('', function () { it('simulate video view change ', function () { const wrapper = shallow(); + wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed wrapper.instance().changeRootElement(
); @@ -28,6 +37,7 @@ describe('', function () { it('test hide video again', function () { const wrapper = shallow(); + wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed wrapper.instance().changeRootElement(
); @@ -40,6 +50,7 @@ describe('', function () { it('test fallback to last loaded page', function () { const wrapper = shallow(); + 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"); @@ -54,6 +65,8 @@ describe('', function () { it('test home click', function () { const wrapper = shallow(); + wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed + wrapper.setState({page: "wrongvalue"}); expect(wrapper.find("HomePage")).toHaveLength(0); wrapper.find(".nav-link").findWhere(t => t.text() === "Home" && t.type() === "div").simulate("click"); @@ -62,6 +75,7 @@ describe('', function () { it('test category click', function () { const wrapper = shallow(); + wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed expect(wrapper.find("CategoryPage")).toHaveLength(0); wrapper.find(".nav-link").findWhere(t => t.text() === "Categories" && t.type() === "div").simulate("click"); @@ -70,9 +84,33 @@ describe('', function () { it('test settings click', function () { const wrapper = shallow(); + wrapper.setState({generalSettingsLoaded: true}); // simulate fetch to have already finisheed expect(wrapper.find("SettingsPage")).toHaveLength(0); wrapper.find(".nav-link").findWhere(t => t.text() === "Settings" && t.type() === "div").simulate("click"); expect(wrapper.find("SettingsPage")).toHaveLength(1); }); + + it('test initial fetch from api', done => { + global.fetch = prepareFetchApi({ + generalSettingsLoaded: true, + passwordsupport: true, + mediacentername: "testname" + }); + + const wrapper = shallow(); + + + const func = jest.fn(); + wrapper.instance().setState = func; + + expect(global.fetch).toBeCalledTimes(1); + + process.nextTick(() => { + expect(func).toBeCalledTimes(1); + + global.fetch.mockClear(); + done(); + }); + }); }); diff --git a/src/elements/Preview/Preview.js b/src/elements/Preview/Preview.js index 03bbf9b..a373f8d 100644 --- a/src/elements/Preview/Preview.js +++ b/src/elements/Preview/Preview.js @@ -13,10 +13,6 @@ class Preview extends React.Component { }; } - componentWillUnmount() { - this.setState({}); - } - componentDidMount() { this.setState({ previewpicture: null, @@ -30,9 +26,9 @@ class Preview extends React.Component { fetch('/api/videoload.php', {method: 'POST', body: updateRequest}) .then((response) => response.text() .then((result) => { - this.setState(prevState => ({ - ...prevState.previewpicture, previewpicture: result - })); + this.setState({ + previewpicture: result + }); })); } diff --git a/src/pages/CategoryPage/CategoryPage.test.js b/src/pages/CategoryPage/CategoryPage.test.js index 1821c1e..1f739fa 100644 --- a/src/pages/CategoryPage/CategoryPage.test.js +++ b/src/pages/CategoryPage/CategoryPage.test.js @@ -1,7 +1,6 @@ -import {shallow, mount} from "enzyme"; +import {mount, shallow} from "enzyme"; import React from "react"; import CategoryPage from "./CategoryPage"; -import VideoContainer from "../../elements/VideoContainer/VideoContainer"; function prepareFetchApi(response) { const mockJsonPromise = Promise.resolve(response); @@ -111,4 +110,21 @@ describe('', function () { expect(func).toBeCalledTimes(1); }); + + it('test sidebar tag clicks', function () { + const func = jest.fn(); + + const wrapper = mount(); + wrapper.instance().loadTag = func; + + console.log(wrapper.debug()); + + expect(func).toBeCalledTimes(0); + wrapper.find("SideBar").find("Tag").forEach(e => { + e.simulate("click"); + }) + + expect(func).toBeCalledTimes(4); + + }); }); diff --git a/src/pages/SettingsPage/GeneralSettings.js b/src/pages/SettingsPage/GeneralSettings.js new file mode 100644 index 0000000..5eb211d --- /dev/null +++ b/src/pages/SettingsPage/GeneralSettings.js @@ -0,0 +1,131 @@ +import React from "react"; +import {Button, Col, Form} from "react-bootstrap"; +import style from "./GeneralSettings.module.css" + +class GeneralSettings extends React.Component { + constructor(props) { + super(props); + + this.state = { + passwordsupport: false, + tmdbsupport: null, + + videopath: "", + tvshowpath: "", + mediacentername: "", + password: "" + }; + } + + componentDidMount() { + const updateRequest = new FormData(); + updateRequest.append('action', 'loadGeneralSettings'); + + fetch('/api/Settings.php', {method: 'POST', body: updateRequest}) + .then((response) => response.json() + .then((result) => { + console.log(result); + this.setState({ + videopath: result.video_path, + tvshowpath: result.episode_path, + mediacentername: result.mediacenter_name, + password: result.password, + passwordsupport: result.passwordEnabled, + tmdbsupport: result.TMDB_grabbing + }); + })); + } + + render() { + return ( + <> +
+
{ + e.preventDefault(); + this.saveSettings(); + }}> + + + Video Path + this.setState({videopath: ee.target.value})}/> + + + + TV Show Path + this.setState({tvshowpath: e.target.value})}/> + + + + { + this.setState({passwordsupport: !this.state.passwordsupport}) + }} + /> + + { + this.setState({tmdbsupport: !this.state.tmdbsupport}) + }} + /> + + {this.state.passwordsupport ? + + Password + this.setState({password: e.target.value})}/> + : null + } + + + The name of the Mediacenter + this.setState({mediacentername: e.target.value})}/> + + + + +
+ + ); + } + + saveSettings() { + const updateRequest = new FormData(); + updateRequest.append('action', 'saveGeneralSettings'); + + updateRequest.append('password', this.state.passwordsupport ? this.state.password : "-1"); + updateRequest.append('videopath', this.state.videopath); + updateRequest.append('tvshowpath', this.state.tvshowpath); + updateRequest.append('mediacentername', this.state.mediacentername); + updateRequest.append("tmdbsupport", this.state.tmdbsupport); + + fetch('/api/Settings.php', {method: 'POST', body: updateRequest}) + .then((response) => response.json() + .then((result) => { + if (result.success) { + console.log("successfully saved settings"); + // todo 2020-07-10: popup success + } else { + console.log("failed to save settings"); + // todo 2020-07-10: popup error + } + })); + } +} + +export default GeneralSettings; diff --git a/src/pages/SettingsPage/GeneralSettings.module.css b/src/pages/SettingsPage/GeneralSettings.module.css new file mode 100644 index 0000000..2f9cb81 --- /dev/null +++ b/src/pages/SettingsPage/GeneralSettings.module.css @@ -0,0 +1,8 @@ +.GeneralForm { + width: 60%; +} + +.mediacenternameform { + margin-top: 25px; + width: 40%; +} diff --git a/src/pages/SettingsPage/GeneralSettings.test.js b/src/pages/SettingsPage/GeneralSettings.test.js new file mode 100644 index 0000000..89e63bb --- /dev/null +++ b/src/pages/SettingsPage/GeneralSettings.test.js @@ -0,0 +1,110 @@ +import {shallow} from "enzyme"; +import React from "react"; +import GeneralSettings from "./GeneralSettings"; + +function prepareFetchApi(response) { + const mockJsonPromise = Promise.resolve(response); + const mockFetchPromise = Promise.resolve({ + json: () => mockJsonPromise, + }); + return (jest.fn().mockImplementation(() => mockFetchPromise)); +} + +describe('', function () { + it('renders without crashing ', function () { + const wrapper = shallow(); + wrapper.unmount(); + }); + + it('test password hide/show switchbutton', function () { + const wrapper = shallow(); + + expect(wrapper.find("[data-testid='passwordfield']")).toHaveLength(0); + wrapper.find("FormCheck").findWhere(it => it.props().label === "Enable Password support").simulate("change"); + + expect(wrapper.find("[data-testid='passwordfield']")).toHaveLength(1); + }); + + it('test savesettings', done => { + const wrapper = shallow(); + + global.fetch = prepareFetchApi({success: true}); + + expect(global.fetch).toBeCalledTimes(0); + const fakeEvent = {preventDefault: () => console.log('preventDefault')}; + wrapper.find("[data-testid='mainformsettings']").simulate("submit", fakeEvent); + expect(global.fetch).toBeCalledTimes(1); + + process.nextTick(() => { + // todo 2020-07-13: test popup of error success here + + global.fetch.mockClear(); + done(); + }); + }); + + it('test failing savesettings', done => { + const wrapper = shallow(); + + global.fetch = prepareFetchApi({success: false}); + + expect(global.fetch).toBeCalledTimes(0); + const fakeEvent = {preventDefault: () => console.log('preventDefault')}; + wrapper.find("[data-testid='mainformsettings']").simulate("submit", fakeEvent); + expect(global.fetch).toBeCalledTimes(1); + + process.nextTick(() => { + // todo 2020-07-13: test error popup here! + + global.fetch.mockClear(); + done(); + }); + }); + + it('test videopath change event', function () { + const wrapper = shallow(); + + expect(wrapper.state().videopath).not.toBe("test"); + + const event = {target: {name: "pollName", value: "test"}}; + wrapper.find("[data-testid='videpathform']").find("FormControl").simulate("change", event); + expect(wrapper.state().videopath).toBe("test"); + }); + + it('test tvshowpath change event', function () { + const wrapper = shallow(); + + const event = {target: {name: "pollName", value: "test"}}; + expect(wrapper.state().tvshowpath).not.toBe("test"); + wrapper.find("[data-testid='tvshowpath']").find("FormControl").simulate("change", event); + expect(wrapper.state().tvshowpath).toBe("test"); + }); + + it('test mediacentername-form change event', function () { + const wrapper = shallow(); + + const event = {target: {name: "pollName", value: "test"}}; + expect(wrapper.state().mediacentername).not.toBe("test"); + wrapper.find("[data-testid='nameform']").find("FormControl").simulate("change", event); + expect(wrapper.state().mediacentername).toBe("test"); + }); + + it('test password-form change event', function () { + const wrapper = shallow(); + wrapper.setState({passwordsupport: true}); + + const event = {target: {name: "pollName", value: "test"}}; + expect(wrapper.state().password).not.toBe("test"); + wrapper.find("[data-testid='passwordfield']").find("FormControl").simulate("change", event); + expect(wrapper.state().password).toBe("test"); + }); + + it('test tmdbsupport change event', function () { + const wrapper = shallow(); + wrapper.setState({tmdbsupport: true}); + + expect(wrapper.state().tmdbsupport).toBe(true); + wrapper.find("[data-testid='tmdb-switch']").simulate("change"); + expect(wrapper.state().tmdbsupport).toBe(false); + }); +}); diff --git a/src/pages/SettingsPage/MovieSettings.js b/src/pages/SettingsPage/MovieSettings.js new file mode 100644 index 0000000..f563ec0 --- /dev/null +++ b/src/pages/SettingsPage/MovieSettings.js @@ -0,0 +1,89 @@ +import React from "react"; +import style from "./MovieSettings.module.css" + +class MovieSettings extends React.Component { + constructor(props) { + super(props); + + this.state = { + text: [], + startbtnDisabled: false + }; + } + + componentDidMount() { + if (this.myinterval) { + clearInterval(this.myinterval); + } + this.myinterval = setInterval(this.updateStatus, 1000); + } + + componentWillUnmount() { + clearInterval(this.myinterval); + } + + render() { + return ( + <> + +
{this.state.text.map(m => ( +
{m}
+ ))}
+ + ); + } + + startReindex() { + // clear output text before start + this.setState({text: []}); + + this.setState({startbtnDisabled: true}); + + console.log("starting"); + const updateRequest = new FormData(); + // fetch all videos available + fetch('/api/extractvideopreviews.php', {method: 'POST', body: updateRequest}) + .then((response) => response.json() + .then((result) => { + // todo 2020-07-4: some kind of start event + console.log("returned"); + })) + .catch(() => { + console.log("no connection to backend"); + }); + if (this.myinterval) { + clearInterval(this.myinterval); + } + this.myinterval = setInterval(this.updateStatus, 1000); + } + + updateStatus = () => { + const updateRequest = new FormData(); + fetch('/api/extractionData.php', {method: 'POST', body: updateRequest}) + .then((response) => response.json() + .then((result) => { + if (result.contentAvailable === true) { + console.log(result); + // todo 2020-07-4: scroll to bottom of div here + this.setState({ + // insert a string for each line + text: [...result.message.split("\n"), + ...this.state.text] + }); + } else { + // clear refresh interval if no content available + clearInterval(this.myinterval); + + this.setState({startbtnDisabled: false}); + } + })) + .catch(() => { + console.log("no connection to backend"); + }); + }; +} + +export default MovieSettings; diff --git a/src/pages/SettingsPage/MovieSettings.module.css b/src/pages/SettingsPage/MovieSettings.module.css new file mode 100644 index 0000000..4551e8d --- /dev/null +++ b/src/pages/SettingsPage/MovieSettings.module.css @@ -0,0 +1,13 @@ +.indextextarea { + margin-top: 15px; + padding: 10px; + + overflow-y: scroll; + overflow-x: auto; + + min-height: 100px; + max-height: 300px; + width: 50%; + background-color: #c2c2c2; + border-radius: 5px; +} diff --git a/src/pages/SettingsPage/MovieSettings.test.js b/src/pages/SettingsPage/MovieSettings.test.js new file mode 100644 index 0000000..51d38c3 --- /dev/null +++ b/src/pages/SettingsPage/MovieSettings.test.js @@ -0,0 +1,62 @@ +import {shallow} from "enzyme"; +import React from "react"; +import MovieSettings from "./MovieSettings"; + +function prepareFetchApi(response) { + const mockJsonPromise = Promise.resolve(response); + const mockFetchPromise = Promise.resolve({ + json: () => mockJsonPromise, + }); + return (jest.fn().mockImplementation(() => mockFetchPromise)); +} + +describe('', function () { + it('renders without crashing ', function () { + const wrapper = shallow(); + wrapper.unmount(); + }); + + it('received text renders into dom', function () { + const wrapper = shallow(); + + wrapper.setState({ + text: [ + "firstline", + "secline" + ] + }); + + expect(wrapper.find(".indextextarea").find(".textarea-element")).toHaveLength(2); + }); + + it('test simulate reindex', function () { + global.fetch = prepareFetchApi({}); + const wrapper = shallow(); + + wrapper.find(".reindexbtn").simulate("click"); + + // initial send of reindex request to server + expect(global.fetch).toBeCalledTimes(1); + }); + + it('content available received and in state', done => { + global.fetch = prepareFetchApi({ + contentAvailable: true, + message: "firstline\nsecondline" + }); + const wrapper = shallow(); + wrapper.instance().updateStatus(); + + process.nextTick(() => { + expect(wrapper.state()).toMatchObject({ + text: [ + "firstline", + "secondline" + ] + }); + + global.fetch.mockClear(); + done(); + }); + }); +}); diff --git a/src/pages/SettingsPage/SettingsPage.js b/src/pages/SettingsPage/SettingsPage.js index 776dae8..d93954b 100644 --- a/src/pages/SettingsPage/SettingsPage.js +++ b/src/pages/SettingsPage/SettingsPage.js @@ -1,82 +1,52 @@ import React from "react"; -import PageTitle from "../../elements/PageTitle/PageTitle"; +import MovieSettings from "./MovieSettings"; +import GeneralSettings from "./GeneralSettings"; +import style from "./SettingsPage.module.css" class SettingsPage extends React.Component { constructor(props, context) { super(props, context); + this.state = { - text: [] + currentpage: "general" }; } - updateStatus = () => { - const updateRequest = new FormData(); - fetch('/api/extractionData.php', {method: 'POST', body: updateRequest}) - .then((response) => response.json() - .then((result) => { - if (result.contentAvailable === true) { - console.log(result); - this.setState({ - text: [...result.message.split("\n"), - ...this.state.text] - }); - } else { - clearInterval(this.myinterval); - } - })) - .catch(() => { - console.log("no connection to backend"); - }); - }; - - componentDidMount() { - if (this.myinterval) { - clearInterval(this.myinterval); + getContent() { + switch (this.state.currentpage) { + case "general": + return ; + case "movies": + return ; + case "tv": + return ; // todo this page + default: + return "unknown button clicked"; } - this.myinterval = setInterval(this.updateStatus, 1000); - } - - componentWillUnmount() { - clearInterval(this.myinterval); } render() { return (
- - - -
{this.state.text.map(m => ( -
{m}
- ))}
+
+
Settings
+
this.setState({currentpage: "general"})} + className={style.SettingSidebarElement}>General +
+
this.setState({currentpage: "movies"})} + className={style.SettingSidebarElement}>Movies +
+
this.setState({currentpage: "tv"})} + className={style.SettingSidebarElement}>TV Shows +
+
+
+ {this.getContent()} +
); } - - startReindex() { - console.log("starting"); - const updateRequest = new FormData(); - // fetch all videos available - fetch('/api/extractvideopreviews.php', {method: 'POST', body: updateRequest}) - .then((response) => response.json() - .then((result) => { - console.log("returned"); - })) - .catch(() => { - console.log("no connection to backend"); - }); - if (this.myinterval) { - clearInterval(this.myinterval); - } - this.myinterval = setInterval(this.updateStatus, 1000); - console.log("sent"); - } } export default SettingsPage; diff --git a/src/pages/SettingsPage/SettingsPage.module.css b/src/pages/SettingsPage/SettingsPage.module.css new file mode 100644 index 0000000..b958e19 --- /dev/null +++ b/src/pages/SettingsPage/SettingsPage.module.css @@ -0,0 +1,40 @@ +.SettingsSidebar { + padding-top: 20px; + float: left; + width: 10%; + background-color: #d3dcef; + min-height: calc(100vh - 56px); + min-width: 110px; +} + +.SettingsSidebarTitle { + text-align: center; + font-weight: bold; + text-transform: uppercase; + font-size: larger; + margin-bottom: 25px; +} + +.SettingsContent { + float: left; + width: 80%; + padding-left: 30px; + padding-top: 30px; +} + +.SettingSidebarElement { + margin: 10px 5px 5px; + padding: 5px; + background-color: #a8b2de; + text-align: center; + font-weight: bold; + border-radius: 7px; +} + +.SettingSidebarElement:hover { + font-weight: bolder; + background-color: #7d8dd4; + box-shadow: #7d8dd4 0 0 0 5px; + transition: all 300ms; + cursor: pointer; +} \ No newline at end of file diff --git a/src/pages/SettingsPage/SettingsPage.test.js b/src/pages/SettingsPage/SettingsPage.test.js index a842d0c..735cea9 100644 --- a/src/pages/SettingsPage/SettingsPage.test.js +++ b/src/pages/SettingsPage/SettingsPage.test.js @@ -16,26 +16,33 @@ describe('', function () { wrapper.unmount(); }); - it('received text renders into dom', function () { + it('simulate topic clicka', function () { const wrapper = shallow(); - wrapper.setState({ - text: [ - "firstline", - "secline" - ] - }); + simulateSideBarClick("General", wrapper); + expect(wrapper.state().currentpage).toBe("general"); + expect(wrapper.find(".SettingsContent").find("GeneralSettings")).toHaveLength(1); - expect(wrapper.find(".indextextarea").find(".textarea-element")).toHaveLength(2); + simulateSideBarClick("Movies", wrapper); + expect(wrapper.state().currentpage).toBe("movies"); + expect(wrapper.find(".SettingsContent").find("MovieSettings")).toHaveLength(1); + + simulateSideBarClick("TV Shows", wrapper); + expect(wrapper.state().currentpage).toBe("tv"); + expect(wrapper.find(".SettingsContent").find("span")).toHaveLength(1); }); - it('test simulate reindex', function () { - global.fetch = prepareFetchApi({}); + function simulateSideBarClick(name, wrapper) { + wrapper.find(".SettingSidebarElement").findWhere(it => + it.text() === name && + it.type() === "div").simulate("click"); + } + + it('simulate unknown topic', function () { const wrapper = shallow(); + wrapper.setState({currentpage: "unknown"}); - wrapper.find(".reindexbtn").simulate("click"); + expect(wrapper.find(".SettingsContent").text()).toBe("unknown button clicked"); - // initial send of reindex request to server - expect(global.fetch).toBeCalledTimes(1); }); });