From 2b772e30170a594d81ee9c7648b1bb618fc40fc0 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 1 Dec 2017 10:14:22 +0100 Subject: [PATCH 01/23] Long overdue, now we define our database schema so we can finally build our database, and not just move it around. --- seasoned_api/src/database/schema/setup.sql | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 seasoned_api/src/database/schema/setup.sql diff --git a/seasoned_api/src/database/schema/setup.sql b/seasoned_api/src/database/schema/setup.sql new file mode 100644 index 0000000..5d9d8fd --- /dev/null +++ b/seasoned_api/src/database/schema/setup.sql @@ -0,0 +1,57 @@ +CREATE TABLE IF NOT EXISTS user ( + user_name varchar(127) UNIQUE, + password varchar(127), + email varchar(127) UNIQUE, + primary key (user_name) +); + +CREATE TABLE IF NOT EXISTS cache ( + key varchar(255), + value blob, + time_to_live INTEGER DEFAULT 60, + created_at DATE DEFAULT (datetime('now','localtime')), + primary key(key) +); + +CREATE TABLE IF NOT EXISTS search_history ( + id integer, + user_name varchar(127), + search_query varchar(255), + primary key (id), + foreign key(user_name) REFERENCES user(user_name) ON DELETE CASCADE +); + +CREATE TABLE IF NOT EXISTS requests( + id TEXT, + name TEXT, + year NUMBER, + poster_path TEXT DEFAULT NULL, + background_path TEXT DEFAULT NULL, + requested_by TEXT, + ip TEXT, + requested_date DATE DEFAULT CURRENT_DATE NOT NULL, + status CHAR(25) DEFAULT 'requested' NOT NULL, + user_agent CHAR(255) DEFAULT NULL, + type CHAR(50) DEFAULT 'movie' +); + + +CREATE TABLE IF NOT EXISTS stray_eps( + id TEXT UNIQUE, + parent TEXT, + path TEXT, + name TEXT, + season NUMBER, + episode NUMBER, + video_files TEXT, + subtitles TEXT, + trash TEXT, + verified BOOLEAN DEFAULT 0, + primary key(id) +); + +CREATE TABLE IF NOT EXISTS shows( + show_names TEXT, + date_added DATE, + date_modified DATE DEFUALT CURRENT_DATE NOT NULL +); \ No newline at end of file -- 2.34.1 From ac6bbe6ac66d752fa204ba0a42a76e155dfae117 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 1 Dec 2017 10:19:22 +0100 Subject: [PATCH 02/23] Now we can build or database by reading schema files. Also added doc strings to all the functions. This is a much better definition of a database script for our usecases.. --- seasoned_api/src/database/sqliteDatabase.js | 88 ++++++++++++++++----- 1 file changed, 69 insertions(+), 19 deletions(-) diff --git a/seasoned_api/src/database/sqliteDatabase.js b/seasoned_api/src/database/sqliteDatabase.js index 3d0c5a4..5ac1330 100644 --- a/seasoned_api/src/database/sqliteDatabase.js +++ b/seasoned_api/src/database/sqliteDatabase.js @@ -4,30 +4,80 @@ const sqlite = require('sqlite'); class SqliteDatabase { - constructor(host) { - this.host = host; - this.connection = sqlite; + constructor(host) { + this.host = host; + this.connection = sqlite; + this.schemaDirectory = path.join(__dirname, 'schemas'); + } - // this.schemaDirectory = path.join(__dirname, 'schemas'); - } + /** + * Connect to the database. + * @returns {Promise} succeeds if connection was established + */ + connect() { + return Promise.resolve() + .then(() => sqlite.open(this.host)) + .then(() => sqlite.exec('pragma foreign_keys = on;')); + } - connect() { - return Promise.resolve() - .then(() => sqlite.open(this.host)) - .then(() => sqlite.exec('pragma foreign_keys = on;')); - } + /** + * Run a SQL query against the database. + * @param {String} sql SQL query + * @param {Array} parameters in the SQL query + * @returns {Promise} + */ + run(sql, parameters) { + return this.connection.run(sql, parameters); + } - all(sql, parameters) { - return this.connection.all(sql, parameters); - } + /** + * Run a SQL query against the database and retrieve all the rows. + * @param {String} sql SQL query + * @param {Array} parameters in the SQL query + * @returns {Promise} + */ + all(sql, parameters) { + return this.connection.all(sql, parameters); + } - get(sql, parameters) { - return this.connection.get(sql, parameters); - } + /** + * Run a SQL query against the database and retrieve one row. + * @param {String} sql SQL query + * @param {Array} parameters in the SQL query + * @returns {Promise} + */ + get(sql, parameters) { + return this.connection.get(sql, parameters); + } - run(sql, parameters) { - return this.connection.run(sql, parameters); - } + /** + * Run a SQL query against the database and retrieve the status. + * @param {String} sql SQL query + * @param {Array} parameters in the SQL query + * @returns {Promise} + */ + execute(sql) { + return this.connection.exec(sql); + } + + /** + * Setup the database by running setup.sql file in schemas/. + * @returns {Promise} + */ + setUp() { + const setupSchema = this.readSqlFile('setup.sql'); + return this.execute(setupSchema); + } + + /** + * Returns the file contents of a SQL file in schemas/. + * @returns {String} + */ + readSqlFile(filename) { + const schemaPath = path.join(this.schemaDirectory, filename); + const schema = fs.readFileSync(schemaPath).toString('utf-8'); + return schema; + } } module.exports = SqliteDatabase; -- 2.34.1 From b8647f982d71d2f657795db23210f6840518c8f0 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 1 Dec 2017 10:27:46 +0100 Subject: [PATCH 03/23] This is where we use our setup function to add tables if none are present in our database file. --- seasoned_api/src/database/database.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seasoned_api/src/database/database.js b/seasoned_api/src/database/database.js index 00c9d98..8e509df 100644 --- a/seasoned_api/src/database/database.js +++ b/seasoned_api/src/database/database.js @@ -10,6 +10,6 @@ const database = new SqliteDatabase(configuration.get('database', 'host')); */ Promise.resolve() .then(() => database.connect()) -// .then(() => database.setUp()); +.then(() => database.setUp()); module.exports = database; -- 2.34.1 From db11c968a3db67782adf14f4f3d90ed917baa844 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 1 Dec 2017 10:28:29 +0100 Subject: [PATCH 04/23] Renamed folder the plural. --- seasoned_api/src/database/{schema => schemas}/setup.sql | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename seasoned_api/src/database/{schema => schemas}/setup.sql (100%) diff --git a/seasoned_api/src/database/schema/setup.sql b/seasoned_api/src/database/schemas/setup.sql similarity index 100% rename from seasoned_api/src/database/schema/setup.sql rename to seasoned_api/src/database/schemas/setup.sql -- 2.34.1 From d0597b4e1e650d606710910d0b08c91d82eee929 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Fri, 1 Dec 2017 10:34:09 +0100 Subject: [PATCH 05/23] This is our main focus on changing, this is where we add a background parameter in our database entry. --- seasoned_api/src/plex/requestRepository.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/seasoned_api/src/plex/requestRepository.js b/seasoned_api/src/plex/requestRepository.js index 94bfdc8..ffddd12 100644 --- a/seasoned_api/src/plex/requestRepository.js +++ b/seasoned_api/src/plex/requestRepository.js @@ -22,7 +22,7 @@ class RequestRepository { constructor(cache, database) { this.database = database || establishedDatabase; this.queries = { - 'insertRequest': "INSERT INTO requests VALUES (?, ?, ?, ?, ?, ?, CURRENT_DATE, 'requested', ?, ?)", + 'insertRequest': "INSERT INTO requests VALUES (?, ?, ?, ?, ?, ?, ?, CURRENT_DATE, 'requested', ?, ?)", 'fetchRequstedItems': "SELECT * FROM requests", 'updateRequestedById': "UPDATE requests SET status = ? WHERE id is ? AND type is ?", } @@ -117,7 +117,7 @@ class RequestRepository { user = 'NULL'; console.log(user) // Add request to database - this.database.run(this.queries.insertRequest, [movie.id, movie.title, movie.year, movie.poster, user, ip, user_agent, movie.type]) + this.database.run(this.queries.insertRequest, [movie.id, movie.title, movie.year, movie.poster, movie.background, user, ip, user_agent, movie.type]) // create reusable transporter object using the default SMTP transport -- 2.34.1 From f7b772a170844936d077ca8ad368631a43ad2ee3 Mon Sep 17 00:00:00 2001 From: Kevin Midboe Date: Fri, 1 Dec 2017 10:46:50 +0100 Subject: [PATCH 06/23] Changed the default cache TTL from 7 days to 2 days. --- seasoned_api/src/tmdb/cache.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/seasoned_api/src/tmdb/cache.js b/seasoned_api/src/tmdb/cache.js index 1a55117..4c8b62e 100644 --- a/seasoned_api/src/tmdb/cache.js +++ b/seasoned_api/src/tmdb/cache.js @@ -33,7 +33,7 @@ class Cache { * @param {Number} timeToLive the number of seconds before entry expires * @returns {Object} */ - set(key, value, timeToLive = 86400) { + set(key, value, timeToLive = 172800) { const json = JSON.stringify(value); return Promise.resolve() .then(() => this.database.run(this.queries.create, [key, json, timeToLive])) @@ -41,4 +41,4 @@ class Cache { } } -module.exports = Cache; \ No newline at end of file +module.exports = Cache; -- 2.34.1 From 7d44f1518f19cbeb7c295c04ed5ec74d98687586 Mon Sep 17 00:00:00 2001 From: Kevin Midboe Date: Fri, 1 Dec 2017 10:57:28 +0100 Subject: [PATCH 07/23] Updated gitignore to ignore conf folder and deleted the contents of conf. --- seasoned_api/.gitignore | 2 +- seasoned_api/conf/development.json | 24 ------------------------ seasoned_api/conf/output.log | 1 - seasoned_api/src/webserver/access.log | 4 ---- 4 files changed, 1 insertion(+), 30 deletions(-) delete mode 100644 seasoned_api/conf/development.json delete mode 100644 seasoned_api/conf/output.log delete mode 100644 seasoned_api/src/webserver/access.log diff --git a/seasoned_api/.gitignore b/seasoned_api/.gitignore index 922c3ee..436d607 100644 --- a/seasoned_api/.gitignore +++ b/seasoned_api/.gitignore @@ -61,4 +61,4 @@ typings/ # - - - - - # My own gitignore files and folders shows.db -conf +conf/ diff --git a/seasoned_api/conf/development.json b/seasoned_api/conf/development.json deleted file mode 100644 index e349515..0000000 --- a/seasoned_api/conf/development.json +++ /dev/null @@ -1,24 +0,0 @@ -{ - "database": { - "host": "../shows.db" - }, - "webserver": { - "port": 31459 - }, - "tmdb": { - "apiKey": "" - }, - "raven": { - "DSN": "" - }, - "mail": { - "host": "", - "user": "", - "password": "", - "user_pi": "", - "password_pi": "" - }, - "authentication": { - "secret": "" - } -} diff --git a/seasoned_api/conf/output.log b/seasoned_api/conf/output.log deleted file mode 100644 index 8b13789..0000000 --- a/seasoned_api/conf/output.log +++ /dev/null @@ -1 +0,0 @@ - diff --git a/seasoned_api/src/webserver/access.log b/seasoned_api/src/webserver/access.log deleted file mode 100644 index 87ba069..0000000 --- a/seasoned_api/src/webserver/access.log +++ /dev/null @@ -1,4 +0,0 @@ -::1 - - [02/Jun/2017:06:34:49 +0000] "GET /api/v1/seasoned/all HTTP/1.1" 200 1016 "-" "curl/7.51.0" -::1 - - [02/Jun/2017:06:34:50 +0000] "GET /api/v1/seasoned/all HTTP/1.1" 200 1016 "-" "curl/7.51.0" -::1 - - [02/Jun/2017:06:45:59 +0000] "GET /api/v1/seasoned/all HTTP/1.1" 200 1016 "-" "curl/7.51.0" -::1 - - [02/Jun/2017:06:48:30 +0000] "GET /api/v1/seasoned/all HTTP/1.1" 200 1016 "-" "curl/7.51.0" -- 2.34.1 From 8542da34cd4d41fd144177a38d39d1c1e2d2a067 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 10:37:31 +0100 Subject: [PATCH 08/23] Added a separate stylesheet for our buttons. --- client/app/components/styles/buttons.jsx | 80 ++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 client/app/components/styles/buttons.jsx diff --git a/client/app/components/styles/buttons.jsx b/client/app/components/styles/buttons.jsx new file mode 100644 index 0000000..a27fdba --- /dev/null +++ b/client/app/components/styles/buttons.jsx @@ -0,0 +1,80 @@ + +export default { + + submit: { + color: '#e9a131', + marginRight: '10px', + backgroundColor: 'white', + border: '#e9a131 2px solid', + borderColor: '#e9a131', + borderRadius: '4px', + textAlign: 'center', + padding: '10px', + minWidth: '100px', + float: 'left', + fontSize: '13px', + fontWeight: '800', + cursor: 'pointer', + }, + + submit_hover: { + backgroundColor: '#e9a131', + color: 'white', + }, + + info: { + color: '#00d17c', + marginRight: '10px', + backgroundColor: 'white', + border: '#00d17c 2px solid', + borderRadius: '4px', + textAlign: 'center', + padding: '10px', + minWidth: '100px', + float: 'left', + fontSize: '13px', + fontWeight: '800', + cursor: 'pointer', + }, + + info_hover: { + backgroundColor: '#00d17c', + color: 'white', + }, + + edit: { + color: '#4a95da', + marginRight: '10px', + backgroundColor: 'white', + border: '#4a95da 2px solid', + borderRadius: '4px', + textAlign: 'center', + padding: '10px', + minWidth: '100px', + float: 'left', + fontSize: '13px', + fontWeight: '800', + cursor: 'pointer', + }, + + edit_small: { + color: '#4a95da', + marginRight: '10px', + backgroundColor: 'white', + border: '#4a95da 2px solid', + borderRadius: '4px', + textAlign: 'center', + padding: '4px', + minWidth: '50px', + float: 'left', + fontSize: '13px', + fontWeight: '800', + cursor: 'pointer', + }, + + edit_hover: { + backgroundColor: '#4a95da', + color: 'white', + }, + +} \ No newline at end of file -- 2.34.1 From e1fed24fc02b4a8f9b91987ac81d686024b82485 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 10:39:18 +0100 Subject: [PATCH 09/23] Added a loading image to pirateSearch. Now we get feedback when waiting for response from the api. --- client/app/components/admin/PirateSearch.jsx | 32 +++++++++++++++--- client/app/components/images/loading.jsx | 34 ++++++++++++++++++++ client/app/components/images/loading.svg | 7 ++++ 3 files changed, 69 insertions(+), 4 deletions(-) create mode 100644 client/app/components/images/loading.jsx create mode 100644 client/app/components/images/loading.svg diff --git a/client/app/components/admin/PirateSearch.jsx b/client/app/components/admin/PirateSearch.jsx index b1d5191..25917fa 100644 --- a/client/app/components/admin/PirateSearch.jsx +++ b/client/app/components/admin/PirateSearch.jsx @@ -1,18 +1,25 @@ import React, { Component } from 'react'; import { fetchJSON } from '../http.jsx'; +// Stylesheets +import btnStylesheet from '../styles/buttons.jsx'; + +// Interactive button +import Interactive from 'react-interactive'; + +import Loading from '../images/loading.jsx' + class PirateSearch extends Component { constructor() { super(); this.state = { response: [], name: '', + loading: '', } } sendToDownload(torrent) { - console.log(torrent.magnet) - let data = {magnet: torrent.magnet} fetchJSON('https://apollo.kevinmidboe.com/api/v1/pirate/add', 'POST', data) .then((response) => { @@ -24,10 +31,15 @@ class PirateSearch extends Component { const query = this.props.name; const type = this.props.type; + this.setState({ + loading: + }) + fetchJSON('https://apollo.kevinmidboe.com/api/v1/pirate/search?query='+query+'&type='+type, 'GET') .then((response) => { console.log(response.torrents) this.setState({ + loading: '', response: response.torrents.map((torrent, index) => { return (
@@ -46,8 +58,20 @@ class PirateSearch extends Component { render() { return (
- {this.props.name} - +
+ {this.searchTheBay()}} + style={btnStylesheet.submit} + focus={btnStylesheet.submit_hover} + hover={btnStylesheet.submit_hover}> + + Search for torrents + +
+ + { this.state.loading } + {this.state.response}
) diff --git a/client/app/components/images/loading.jsx b/client/app/components/images/loading.jsx new file mode 100644 index 0000000..455e39c --- /dev/null +++ b/client/app/components/images/loading.jsx @@ -0,0 +1,34 @@ +import React from 'react'; + +function Loading() { + return ( +
+ + + + + + +
+ + ) +} + +export default Loading; \ No newline at end of file diff --git a/client/app/components/images/loading.svg b/client/app/components/images/loading.svg new file mode 100644 index 0000000..c8f7e85 --- /dev/null +++ b/client/app/components/images/loading.svg @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file -- 2.34.1 From 5fb1e7ba2ed6a4e78f28c0b2437a0d724d7ff3ea Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 11:20:26 +0100 Subject: [PATCH 10/23] Sidebar is now redesigned with color indicators, filtering name by search query or filtering status by dropdown. Moved CSS to a separate stylesheet. --- client/app/components/admin/Sidebar.jsx | 248 ++++++++++++++---- client/app/components/styles/adminSidebar.jsx | 50 ++++ 2 files changed, 252 insertions(+), 46 deletions(-) create mode 100644 client/app/components/styles/adminSidebar.jsx diff --git a/client/app/components/admin/Sidebar.jsx b/client/app/components/admin/Sidebar.jsx index 5d001b0..7d48397 100644 --- a/client/app/components/admin/Sidebar.jsx +++ b/client/app/components/admin/Sidebar.jsx @@ -1,57 +1,213 @@ import React, { Component } from 'react'; import { Link } from 'react-router-dom'; +import Interactive from 'react-interactive'; + +import sidebarCSS from '../styles/adminSidebar.jsx' + class SidebarComponent extends Component { - generateListElements(index, item) { - if (index == this.props.listItemSelected) - return ( - {item.name} - ) - else - return ( - {item.name} - ) - } - - displayRequestedElementsInfo() { - if (this.props.requested_objects) { - let requestedElement = this.props.requested_objects.map((item, index) => { - return ( - - { this.generateListElements(index, item) } - {item.status} - {item.requested_date} - - ) - }) - - return ( - - - - - - - - - - {requestedElement} - -
NameStatusDate
- ) + constructor(props){ + super(props) + // Constructor with states holding the search query and the element of reponse. + this.state = { + filterValue: '', + filterQuery: '', + requestItemsToBeDisplayed: [], + listItemSelected: '', } } - render() { - console.log('sidebar: ', this.props.requested_objects) - return ( -
-

Hello from the sidebar:

- { this.displayRequestedElementsInfo() } -
- ); - } + // Where we wait for api response to be delivered from parent through props + componentWillReceiveProps(props) { + this.state.listItemSelected = props.listItemSelected; + this.displayRequestedElementsInfo(props.requested_objects); + } + + // Inputs a date and returns a text string that matches how long it was since + convertDateToDaysSince(date) { + var oneDay = 24*60*60*1000; + var firstDate = new Date(date); + var secondDate = new Date(); + + var diffDays = Math.round(Math.abs((firstDate.getTime() - secondDate.getTime()) / oneDay)); + + switch (diffDays) { + case 0: + return 'Today'; + case 1: + return '1 day ago' + default: + return diffDays + ' days ago' + } + } + + // Called from our dropdown, receives a filter string and checks it with status field + // of our request objects. + filterItems(filterValue) { + let filteredRequestElements = this.props.requested_objects.map((item, index) => { + if (item.status === filterValue || filterValue === 'all') + return this.generateListElements(index, item); + }) + + this.setState({ + requestItemsToBeDisplayed: filteredRequestElements, + filterValue: filterValue, + }) + } + + + // Updates the internal state of the query filter and updates the list to only + // display names matching the query. This is real-time filtering. + updateFilterQuery(event) { + const query = event.target.value; + + let filteredByQuery = this.props.requested_objects.map((item, index) => { + if (item.name.toLowerCase().indexOf(query.toLowerCase()) != -1) + return this.generateListElements(index, item); + }) + + this.setState({ + requestItemsToBeDisplayed: filteredByQuery, + filterQuery: query, + }); + } + + + generateFilterDropdown() { + return ( + + ) + } + + generateFilterSearchbar() { + return ( + this.updateFilterQuery(event)} + value={this.state.filterQuery}/> + ) + } + + // A colored bar indicating the status of a item by color. + generateRequestIndicator(status) { + let statusColor; + + switch (status) { + case 'requested': + // Yellow + statusColor = '#ffe14d'; + break; + case 'downloading': + // Blue + statusColor = '#3fc3f3'; + break; + case 'downloaded': + // Green + statusColor = '#6be682'; + break; + default: + statusColor = 'grey'; + } + + const indicatorCSS = { + width: '100%', + height: '4px', + marginTop: '3px', + backgroundColor: statusColor, + } + + return ( +
+ ) + } + + + generateListElements(index, item) { + if (index == this.state.listItemSelected) { + return ( +
+
+ {item.name } +
+ { this.convertDateToDaysSince(item.requested_date) } +
+
+ Status: { item.status } +
+ Matches found: 0 + { this.generateRequestIndicator(item.status) } +
+ ) + } + else + return ( + + + + {item.name } +
+ { this.convertDateToDaysSince(item.requested_date) } +
+
+ { this.generateRequestIndicator(item.status) } +
+ + ) + } + + // This is our main loader that gets called when we receive api response through props from parent + displayRequestedElementsInfo(requested_objects) { + let requestedElement = requested_objects.map((item, index) => { + if (['requested', 'downloading', 'downloaded'].indexOf(this.state.filterValue) != -1) { + if (item.status === this.state.filterValue){ + return this.generateListElements(index, item); + } + } + + else if (this.state.filterQuery !== '') { + if (item.name.toLowerCase().indexOf(this.state.filterQuery.toLowerCase()) != -1) + return this.generateListElements(index, item); + } + + else + return this.generateListElements(index, item); + }) + + this.setState({ + requestItemsToBeDisplayed: requestedElement, + }) + } + + render() { + let bodyCSS = sidebarCSS.body; + if (typeof InstallTrigger !== 'undefined') + bodyCSS.width = '-moz-min-content'; + + return ( +
+

Hello from the sidebar:

+ { this.generateFilterDropdown() } + { this.generateFilterSearchbar() } +
+ { this.state.requestItemsToBeDisplayed } +
+
+ ); + } } export default SidebarComponent; \ No newline at end of file diff --git a/client/app/components/styles/adminSidebar.jsx b/client/app/components/styles/adminSidebar.jsx new file mode 100644 index 0000000..c10fe49 --- /dev/null +++ b/client/app/components/styles/adminSidebar.jsx @@ -0,0 +1,50 @@ +export default { + body: { + backgroundColor: 'white', + width: 'min-content', + }, + + parentElement: { + display: 'inline-block', + width: '300px', + border: '1px solid black', + borderRadius: '2px', + padding: '4px', + margin: '4px', + marginLeft: '4px', + backgroundColor: 'white', + }, + + parentElement_hover: { + marginLeft: '10px', + }, + + parentElement_active: { + textDecoration: 'none', + }, + + parentElement_selected: { + display: 'inline-block', + width: '300px', + border: '1px solid black', + borderRadius: '2px', + padding: '4px', + margin: '4px 0px 4px 4px', + marginLeft: '10px', + backgroundColor: 'white', + }, + + title: { + maxWidth: '70%', + display: 'inline-flex', + }, + + link: { + color: 'black', + textDecoration: 'none', + }, + + rightContainer: { + float: 'right', + }, +} \ No newline at end of file -- 2.34.1 From 3fe8f46dd49e9589daf74011e14b8bcc527dfdc7 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 11:31:25 +0100 Subject: [PATCH 11/23] Viewport changes to limit zoom in on mobile the typing in a search bar. --- client/app/index.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/app/index.html b/client/app/index.html index 3ab7f3f..3ec9c02 100644 --- a/client/app/index.html +++ b/client/app/index.html @@ -4,7 +4,7 @@ - + seasoned Shows -- 2.34.1 From 8695a553d641894d2cb82f81afef9a716825372a Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 11:32:49 +0100 Subject: [PATCH 12/23] Admin page is our landing page for admin panel, now it passes our api response to sidebar and info panel when we get the response back from the api. Some renaming of stylesheet variable. --- client/app/components/admin/Admin.jsx | 30 +++++++------------ .../app/components/styles/adminComponent.jsx | 8 +++++ 2 files changed, 19 insertions(+), 19 deletions(-) create mode 100644 client/app/components/styles/adminComponent.jsx diff --git a/client/app/components/admin/Admin.jsx b/client/app/components/admin/Admin.jsx index 47d941a..50047b1 100644 --- a/client/app/components/admin/Admin.jsx +++ b/client/app/components/admin/Admin.jsx @@ -1,10 +1,5 @@ -/* - ./app/components/App.jsx - - -*/ + import React from 'react'; -import { HashRouter as Router, Route, Switch, IndexRoute } from 'react-router-dom'; import LoginForm from './LoginForm/LoginForm.jsx'; import { Provider } from 'react-redux'; @@ -16,6 +11,8 @@ import { fetchJSON } from '../http.jsx'; import Sidebar from './Sidebar.jsx'; import AdminRequestInfo from './AdminRequestInfo.jsx'; +import adminCSS from '../styles/adminComponent.jsx' + class AdminComponent extends React.Component { constructor(props) { @@ -25,6 +22,7 @@ class AdminComponent extends React.Component { } } + // Fetches all requested elements and updates the state with response componentWillMount() { fetchJSON('https://apollo.kevinmidboe.com/api/v1/plex/requests/all', 'GET') .then(result => { @@ -34,16 +32,9 @@ class AdminComponent extends React.Component { }) } + // Displays loginform if not logged in and passes response from + // api call to sidebar and infoPanel through props verifyLoggedIn() { - let adminComponentStyle = { - sidebar: { - float: 'left', - }, - selectedObjectPanel: { - float: 'left', - } - } - const logged_in = getCookie('logged_in'); if (!logged_in) { return @@ -53,20 +44,21 @@ class AdminComponent extends React.Component { let listItemSelected = undefined; const requestParam = this.props.match.params.request; + if (requestParam && this.state.requested_objects !== '') { selectedRequest = this.state.requested_objects[requestParam] - listItemSelected = requestParam + listItemSelected = requestParam; } return (
-
+
+ />
-
+
Date: Sat, 2 Dec 2017 11:35:10 +0100 Subject: [PATCH 13/23] Deleted unused svg image. --- client/app/components/images/loading.svg | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 client/app/components/images/loading.svg diff --git a/client/app/components/images/loading.svg b/client/app/components/images/loading.svg deleted file mode 100644 index c8f7e85..0000000 --- a/client/app/components/images/loading.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file -- 2.34.1 From 9fcc82d7cf24fa02facc8b8dd9dab74eb6affee3 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 11:35:39 +0100 Subject: [PATCH 14/23] Put both jsx and js varaibles on same line in config file. --- client/webpack.common.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/webpack.common.js b/client/webpack.common.js index 114c775..0fd9a5f 100644 --- a/client/webpack.common.js +++ b/client/webpack.common.js @@ -21,8 +21,7 @@ module.exports = { ], module: { loaders: [ - { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, - { test: /\.jsx$/, loader: 'babel-loader', exclude: /node_modules/ }, + { test: /\.(js|jsx)$/, loader: 'babel-loader', exclude: /node_modules/ }, ] }, -- 2.34.1 From 187ac6317e33a930855c9cc7bdb8798aef848672 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 12:01:49 +0100 Subject: [PATCH 15/23] Still a bit messy, but removed unsued sections and redid the naming schema for css items. --- client/app/components/MovieObject.jsx | 231 ++++++++++++-------------- 1 file changed, 106 insertions(+), 125 deletions(-) diff --git a/client/app/components/MovieObject.jsx b/client/app/components/MovieObject.jsx index d78747e..9f13a46 100644 --- a/client/app/components/MovieObject.jsx +++ b/client/app/components/MovieObject.jsx @@ -3,154 +3,135 @@ import React from 'react'; import Notifications, {notify} from 'react-notify-toast'; // StyleComponents -import movieStyle from './styles/movieObjectStyle.jsx'; +import searchResultCSS from './styles/searchResult.jsx'; +import buttonsCSS from './styles/buttons.jsx'; var MediaQuery = require('react-responsive'); -import RequestButton from './buttons/request_button.jsx'; - import { fetchJSON } from './http.jsx'; import Interactive from 'react-interactive'; class MovieObject { - constructor(object) { - this.id = object.id; - this.title = object.title; - this.year = object.year; - this.type = object.type; - // Check if object.poster != undefined - this.rating = object.rating; - this.poster = object.poster; - this.background = object.background; - this.matchedInPlex = object.matchedInPlex; - this.summary = object.summary; - } + constructor(object) { + this.id = object.id; + this.title = object.title; + this.year = object.year; + this.type = object.type; + this.rating = object.rating; + this.poster = object.poster; + this.background = object.background; + this.matchedInPlex = object.matchedInPlex; + this.summary = object.summary; + } - requestExisting(movie) { - console.log('Exists', movie); - } + requestExisting(movie) { + console.log('Exists', movie); + } - requestMovie() { - // fetch('http://localhost:31459/api/v1/plex/request/' + this.id + '?type='+this.type, { - // fetch('https://apollo.kevinmidboe.com/api/v1/plex/request/' + this.id + '?type='+this.type, { - // method: 'POST' - // }); - fetchJSON('https://apollo.kevinmidboe.com/api/v1/plex/request/' + this.id + '?type='+this.type, 'POST') - .then((response) => { - console.log(response); - }) + requestMovie() { + fetchJSON('https://apollo.kevinmidboe.com/api/v1/plex/request/' + this.id + '?type='+this.type, 'POST') + .then((response) => { + console.log(response); + notify.show(this.title + ' requested!', 'success', 3000); + }) + .catch((e) => { + console.error('Request movie fetch went wrong: '+ e); + }) - notify.show(this.title + ' requested!', 'success', 3000); - } + } - invertButtonColors(event) { - const event_type = event.type; - if (event_type) - console.log('test') - console.log(event.type) - } + getElement(index) { + const element_key = index + this.id; - getElement(index) { - const element_key = index + this.id; + if (this.poster == null || this.poster == undefined) { + var posterPath = 'https://openclipart.org/image/2400px/svg_to_png/211479/Simple-Image-Not-Found-Icon.png' + } else { + var posterPath = 'https://image.tmdb.org/t/p/w300' + this.poster; + } + var backgroundPath = 'https://image.tmdb.org/t/p/w640_and_h360_bestv2/' + this.background; - // TODO set the poster image async by updating the dom after this is returned - if (this.poster == null || this.poster == undefined) { - var posterPath = 'https://openclipart.org/image/2400px/svg_to_png/211479/Simple-Image-Not-Found-Icon.png' - } else { - var posterPath = 'https://image.tmdb.org/t/p/w300' + this.poster; - } - var backgroundPath = 'https://image.tmdb.org/t/p/w640_and_h360_bestv2/' + this.background; + var foundInPlex; + if (this.matchedInPlex) { + foundInPlex = {this.requestExisting(this)}} + style={buttonsCSS.submit} + focus={buttonsCSS.submit_hover} + hover={buttonsCSS.submit_hover}> - var foundInPlex; - if (this.matchedInPlex) { - foundInPlex = {this.requestExisting(this)}} - style={movieStyle.requestButton}> - - Request Anyway - ; - } else { - foundInPlex = {this.requestMovie()}} - onMouseOver={() => {this.invertButtonColors(event)}} - style={movieStyle.requestButton}> + Request Anyway + ; + } else { + foundInPlex = {this.requestMovie()}} + style={buttonsCSS.submit} + focus={buttonsCSS.submit_hover} + hover={buttonsCSS.submit_hover}> - + Request - ; - } + + Request + ; + } - if (this.type === 'movie') - var themoviedbLink = 'https://www.themoviedb.org/movie/' + this.id - else if (this.type === 'show') - var themoviedbLink = 'https://www.themoviedb.org/tv/' + this.id + if (this.type === 'movie') + var themoviedbLink = 'https://www.themoviedb.org/movie/' + this.id + else if (this.type === 'show') + var themoviedbLink = 'https://www.themoviedb.org/tv/' + this.id - + // TODO go away from using mediaQuery, and create custom resizer + return ( +
+ + +
+ +
+ +
+ {this.title} +

+ Released: { this.year } | Rating: {this.rating} +

+ {this.summary} +

+
- // TODO add request button class - return ( -
- -
- -
- -
-
-
- - {this.title} -

- Released: { this.year } | Rating: {this.rating} -

- {this.summary} -

-
+ + + {this.title} +

+ Released: {this.year} | Rating: {this.rating} +
+ +
+ + +
+
+ +
+
+
+
+ ) - - - - - -
- {foundInPlex} - - - - Info - - -
-
-
- -

-
-
-
-
-
) - - } + } } export default MovieObject; \ No newline at end of file -- 2.34.1 From e55067025ec5fd0060b910ad4d078911665e66b0 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 12:05:17 +0100 Subject: [PATCH 16/23] Renamed movieObject to searchObject, same with css. --- .../{MovieObject.jsx => SearchObject.jsx} | 26 ++-- .../components/styles/movieObjectStyle.jsx | 112 ------------------ client/app/components/styles/searchObject.jsx | 58 +++++++++ 3 files changed, 71 insertions(+), 125 deletions(-) rename client/app/components/{MovieObject.jsx => SearchObject.jsx} (81%) delete mode 100644 client/app/components/styles/movieObjectStyle.jsx create mode 100644 client/app/components/styles/searchObject.jsx diff --git a/client/app/components/MovieObject.jsx b/client/app/components/SearchObject.jsx similarity index 81% rename from client/app/components/MovieObject.jsx rename to client/app/components/SearchObject.jsx index 9f13a46..b06208c 100644 --- a/client/app/components/MovieObject.jsx +++ b/client/app/components/SearchObject.jsx @@ -3,7 +3,7 @@ import React from 'react'; import Notifications, {notify} from 'react-notify-toast'; // StyleComponents -import searchResultCSS from './styles/searchResult.jsx'; +import searchObjectCSS from './styles/searchObject.jsx'; import buttonsCSS from './styles/buttons.jsx'; var MediaQuery = require('react-responsive'); @@ -85,27 +85,27 @@ class MovieObject {
-
+
-
- +
+
- {this.title} + {this.title}

- Released: { this.year } | Rating: {this.rating} + Released: { this.year } | Rating: {this.rating}

- {this.summary} + {this.summary}

- - {this.title} + + {this.title}

- Released: {this.year} | Rating: {this.rating} + Released: {this.year} | Rating: {this.rating}
-
+
{foundInPlex} @@ -125,8 +125,8 @@ class MovieObject {
-
-
+
+
) diff --git a/client/app/components/styles/movieObjectStyle.jsx b/client/app/components/styles/movieObjectStyle.jsx deleted file mode 100644 index c16a89f..0000000 --- a/client/app/components/styles/movieObjectStyle.jsx +++ /dev/null @@ -1,112 +0,0 @@ - -export default { - resultItem: { - maxWidth: '95%', - margin: '0 auto', - minHeight: '230px' - }, - - movie_content: { - marginLeft: '15px' - }, - - resultTitleLarge: { - color: 'black', - fontSize: '2em', - }, - - resultTitleSmall: { - color: 'black', - fontSize: '22px', - }, - - yearRatingLarge: { - fontSize: '0.8em' - }, - - resultPoster: { - float: 'left', - zIndex: '3', - position: 'relative', - marginRight: '30px' - }, - - background: { - width: '100%' - }, - - yearRatingSmall: { - marginTop: '5px', - fontSize: '0.8em' - }, - - resultPosterImg: { - border: '2px none', - borderRadius: '2px', - width: '150px' - }, - - cornerRibbon: { - position: 'absolute', - width: '450px', - }, - - summary: { - fontSize: '15px', - }, - - buttons: { - paddingTop: '20px' - }, - - requestButton: { - color: '#e9a131', - marginRight: '10px', - backgroundColor: 'white', - border: '#e9a131 2px solid', - borderColor: '#e9a131', - borderRadius: '4px', - textAlign: 'center', - padding: '10px', - minWidth: '100px', - float: 'left', - fontSize: '13px', - fontWeight: '800', - cursor: 'pointer' - }, - - requestButton_hover: { - backgroundColor: '#e9a131', - color: 'white', - }, - - tmdbButton: { - color: '#00d17c', - marginRight: '10px', - backgroundColor: 'white', - border: '#00d17c 2px solid', - borderRadius: '4px', - textAlign: 'center', - padding: '10px', - minWidth: '100px', - float: 'left', - fontSize: '13px', - fontWeight: '800', - cursor: 'pointer' - }, - - tmdbButton_hover: { - backgroundColor: '#00d17c', - color: 'white', - }, - - row: { - width: '100%' - }, - - itemDivider: { - width: '90%', - borderBottom: '1px solid grey', - margin: '2rem auto' - } -} \ No newline at end of file diff --git a/client/app/components/styles/searchObject.jsx b/client/app/components/styles/searchObject.jsx new file mode 100644 index 0000000..4d4ed72 --- /dev/null +++ b/client/app/components/styles/searchObject.jsx @@ -0,0 +1,58 @@ + +export default { + container: { + maxWidth: '95%', + margin: '0 auto', + minHeight: '230px' + }, + + title_large: { + color: 'black', + fontSize: '2em', + }, + + title_small: { + color: 'black', + fontSize: '22px', + }, + + stats_large: { + fontSize: '0.8em' + }, + + stats_small: { + marginTop: '5px', + fontSize: '0.8em' + }, + + posterContainer: { + float: 'left', + zIndex: '3', + position: 'relative', + marginRight: '30px' + }, + + posterImage: { + border: '2px none', + borderRadius: '2px', + width: '150px' + }, + + backgroundImage: { + width: '100%' + }, + + summary: { + fontSize: '15px', + }, + + dividerRow: { + width: '100%' + }, + + itemDivider: { + width: '90%', + borderBottom: '1px solid grey', + margin: '2rem auto' + } +} \ No newline at end of file -- 2.34.1 From fd0a2c9d50cff4d38a170f360078ca265e4ed49c Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 12:08:47 +0100 Subject: [PATCH 17/23] Renamed the exporting class name to match the file name. --- client/app/components/SearchObject.jsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/client/app/components/SearchObject.jsx b/client/app/components/SearchObject.jsx index b06208c..2be95d3 100644 --- a/client/app/components/SearchObject.jsx +++ b/client/app/components/SearchObject.jsx @@ -13,7 +13,7 @@ import { fetchJSON } from './http.jsx'; import Interactive from 'react-interactive'; -class MovieObject { +class SearchObject { constructor(object) { this.id = object.id; this.title = object.title; @@ -134,4 +134,4 @@ class MovieObject { } } -export default MovieObject; \ No newline at end of file +export default SearchObject; \ No newline at end of file -- 2.34.1 From 45db534681f77c7d5248cc9f2816cb63dc0d9918 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 12:17:00 +0100 Subject: [PATCH 18/23] When a requested element from the sidebar is selected this is where the detailed info is displayed. Now it is possible to change the status of a item by using the dropdown. This is where piratesearch also gets the query name through props. --- .../app/components/admin/AdminRequestInfo.jsx | 143 ++++++++++++------ .../components/styles/adminRequestInfo.jsx | 11 ++ 2 files changed, 105 insertions(+), 49 deletions(-) create mode 100644 client/app/components/styles/adminRequestInfo.jsx diff --git a/client/app/components/admin/AdminRequestInfo.jsx b/client/app/components/admin/AdminRequestInfo.jsx index a3a89f4..2f51113 100644 --- a/client/app/components/admin/AdminRequestInfo.jsx +++ b/client/app/components/admin/AdminRequestInfo.jsx @@ -1,10 +1,31 @@ import React, { Component } from 'react'; + +import { fetchJSON } from '../http.jsx'; + import PirateSearch from './PirateSearch.jsx' +// Stylesheets +import requestInfoCSS from '../styles/adminRequestInfo.jsx' +import buttonsCSS from '../styles/buttons.jsx'; + +// Interactive button +import Interactive from 'react-interactive'; + class AdminRequestInfo extends Component { constructor() { super(); + + this.state = { + statusValue: '', + } + + this.requestInfo = ''; + } + + componentWillReceiveProps(props) { + this.requestInfo = props.selectedRequest; + this.state.statusValue = this.requestInfo.status; } userAgent(agent) { @@ -19,6 +40,35 @@ class AdminRequestInfo extends Component { return ''; } + generateStatusDropdown() { + return ( + + ) + } + + updateRequestStatus(event) { + const eventValue = event.target.value; + const itemID = this.requestInfo.id; + + const apiData = { + type: this.requestInfo.type, + status: eventValue, + } + + fetchJSON('https://apollo.kevinmidboe.com/api/v1/plex/request/' + itemID, 'PUT', apiData) + .then((response) => { + console.log('Response, updateRequestStatus: ', response) + }) + + this.setState({ + statusValue: eventValue + }) + } + requested_by_user(request_user) { if (request_user === 'NULL') return undefined @@ -28,57 +78,52 @@ class AdminRequestInfo extends Component { ) } - displayInfo() { - let adminIndexStyle = { - wrapper: { - width: '100%', - }, - headerWrapper: { - width: '100%', - }, - poster: { - float: 'left', - minHeight: '450px', - }, - info: { - float: 'left', - minHeight: '450px', - } - } - const request = this.props.selectedRequest; + displayInfo() { + const request = this.props.selectedRequest; - if (request) { - return ( -
-
- {request.name} - {request.year} -
-
- -
-
- type: {request.type}
- status: {request.status}
- ip: {request.ip}
- user_agent: {this.userAgent(request.user_agent)}
- request_date: {request.requested_date}
- { this.requested_by_user(request.requested_by) } -
- - - -
- ) - } - } + if (request) { + return ( +
+
+ {request.name} + {request.year} +
- render() { - return ( -
{this.displayInfo()}
- ); - } +
+ type: {request.type}
+ + {this.generateStatusDropdown()}
+ + status: {request.status}
+ ip: {request.ip}
+ user_agent: {this.userAgent(request.user_agent)}
+ request_date: {request.requested_date}
+ { this.requested_by_user(request.requested_by) } +
+ +
+ {}} + style={buttonsCSS.edit} + focus={buttonsCSS.edit_hover} + hover={buttonsCSS.edit_hover}> + + Show info + + + +
+
+ ) + } + } + + render() { + return ( +
{this.displayInfo()}
+ ); + } } export default AdminRequestInfo; \ No newline at end of file diff --git a/client/app/components/styles/adminRequestInfo.jsx b/client/app/components/styles/adminRequestInfo.jsx new file mode 100644 index 0000000..e11b3d4 --- /dev/null +++ b/client/app/components/styles/adminRequestInfo.jsx @@ -0,0 +1,11 @@ +export default = { + wrapper: { + width: '100%', + }, + headerWrapper: { + width: '100%', + }, + poster: { + minHeight: '450px', + }, +} \ No newline at end of file -- 2.34.1 From 7bde2821d0b1973c1324860ea1a85980c6d97acd Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 13:13:35 +0100 Subject: [PATCH 19/23] Followed with the renaming of MovieObject to now be refered to as SearchObject. Also change the loading animation for InfiniteScroll. It is the same loading animation imported as we have in torrent search. --- client/app/components/SearchRequest.jsx | 48 ++++++++++++------------- 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/client/app/components/SearchRequest.jsx b/client/app/components/SearchRequest.jsx index dcd1cdd..b5b6554 100644 --- a/client/app/components/SearchRequest.jsx +++ b/client/app/components/SearchRequest.jsx @@ -1,14 +1,14 @@ import React from 'react'; -import MovieObject from './MovieObject.jsx'; - -// StyleComponents -import searchStyle from './styles/searchRequestStyle.jsx'; -import movieStyle from './styles/movieObjectStyle.jsx'; - import URI from 'urijs'; import InfiniteScroll from 'react-infinite-scroller'; +// StyleComponents +import searchStyle from './styles/searchRequestStyle.jsx'; + +import SearchObject from './SearchObject.jsx'; +import Loading from './images/loading.jsx' + import { fetchJSON } from './http.jsx'; import { getCookie } from './Cookie.jsx'; @@ -29,7 +29,8 @@ class SearchRequest extends React.Component { page: 1, resultHeader: '', loadResults: false, - scrollHasMore: true + scrollHasMore: true, + loading: false, } this.allowedListTypes = ['discover', 'popular', 'nowplaying', 'upcoming'] @@ -88,9 +89,9 @@ class SearchRequest extends React.Component { this.state.page = 1; } - writeLoading() { + setLoading(value) { this.setState({ - responseMovieList: 'Loading...' + loading: value }); } @@ -122,10 +123,7 @@ class SearchRequest extends React.Component { // Here we first call api for a search with the input uri, handle any errors // and fill the reponseData from api into the state of reponseMovieList as movieObjects - callSearchFillMovieList(uri) { - // Write loading animation - // this.writeLoading(); - + callSearchFillMovieList(uri) { Promise.resolve() .then(() => this.callURI(uri, 'GET')) .then(response => { @@ -152,7 +150,7 @@ class SearchRequest extends React.Component { } // Convert to json and update the state of responseMovieList with the results of the api call - // mapped as a movieObject. + // mapped as a SearchObject. response.json() .then(responseData => { if (this.state.page === 1) { @@ -180,7 +178,6 @@ class SearchRequest extends React.Component { callListFillMovieList(uri) { // Write loading animation - // this.writeLoading(); Promise.resolve() .then(() => this.callURI(uri, 'GET', undefined)) @@ -198,7 +195,7 @@ class SearchRequest extends React.Component { } // Convert to json and update the state of responseMovieList with the results of the api call - // mapped as a movieObject. + // mapped as a SearchObject. response.json() .then(responseData => { if (this.state.page === 1) { @@ -218,6 +215,7 @@ class SearchRequest extends React.Component { }) .catch((error) => { console.log('Something went wrong when fetching query.', error) + }) } @@ -287,10 +285,10 @@ class SearchRequest extends React.Component { } } - // When called passes the variable to MovieObject and calls it's interal function for + // When called passes the variable to SearchObject and calls it's interal function for // generating the wanted HTML createMovieObjects(item, index) { - let movie = new MovieObject(item); + let movie = new SearchObject(item); return movie.getElement(index); } @@ -379,7 +377,7 @@ class SearchRequest extends React.Component { pageStart={0} loadMore={this.pageForwards.bind(this)} hasMore={this.state.scrollHasMore} - loader={loader} + loader={} initialLoad={this.state.loadResults}> @@ -403,10 +401,10 @@ class SearchRequest extends React.Component {
- {this.state.resultHeader} -



- - {this.state.responseMovieList} + {this.state.resultHeader} +



+ + {this.state.responseMovieList}
@@ -435,7 +433,7 @@ class SearchRequest extends React.Component { {this.state.resultHeader}



- {this.state.responseMovieList} + {this.state.responseMovieList}
@@ -446,4 +444,4 @@ class SearchRequest extends React.Component { } -export default SearchRequest; \ No newline at end of file +export default SearchRequest; -- 2.34.1 From 580cdc430f550444a248bce19d20a779bb47b9fd Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 13:15:23 +0100 Subject: [PATCH 20/23] Removed a lot of unused css classes. --- .../components/styles/searchRequestStyle.jsx | 75 ++----------------- 1 file changed, 5 insertions(+), 70 deletions(-) diff --git a/client/app/components/styles/searchRequestStyle.jsx b/client/app/components/styles/searchRequestStyle.jsx index 45d5cff..17b5b11 100644 --- a/client/app/components/styles/searchRequestStyle.jsx +++ b/client/app/components/styles/searchRequestStyle.jsx @@ -11,12 +11,13 @@ export default { backgroundLargeHeader: { width: '100%', minHeight: '400px', - backgroundColor: '#011c23', + backgroundColor: 'rgb(1, 28, 35)', + // backgroundImage: 'radial-gradient(circle, #004c67 0, #005771 120%)', zIndex: 1, marginBottom: '-100px' }, - backgroundSmallHeader: { + backgroundSmallHeader: { width: '100%', minHeight: '300px', backgroundColor: '#011c23', @@ -31,7 +32,7 @@ export default { backgroundColor: 'white', position: 'relative', zIndex: '10', - boxShadow: '0 4px 2px black' + boxShadow: '0 1px 2px grey', }, pageTitle: { @@ -43,7 +44,7 @@ export default { pageTitleLargeSpan: { color: 'white', - fontSize: '3em', + fontSize: '4em', marginTop: '4vh', marginBottom: '6vh' }, @@ -133,70 +134,4 @@ export default { color: 'black', fontSize: '1.4em', }, - - row: { - width: '100%' - }, - - itemDivider: { - width: '90%', - borderBottom: '1px solid grey', - margin: '1rem auto' - }, - - - pageNavigationBar: { - width: '100%', - display: 'flex', - alignItems: 'center', - justifyContent: 'center' - }, - - pageNavigationButton: { - margin: '0 auto', - }, - - hvrUnderlineFromCenter: { - color: 'white', - fontSize: '1em', - paddingTop: '12px', - marginBottom: '12px', - marginLeft: '10px', - cursor: 'pointer', - display: 'inline-block', - verticalAlign: 'middle', - WebkitTransform: 'perspective(1px) translateZ(0)', - transform: 'perspective(1px) translateZ(0)', - boxShadow: '0 0 1px transparent', - position: 'relative', - overflow: 'hidden', - ':before': { - content: "", - position: 'absolute', - zIndex: '-1', - left: '50%', - right: '50%', - bottom: '0', - background: '#00d17c', - height: '2px', - WebkitTransitionProperty: 'left, right', - transitionProperty: 'left, right', - WebkitTransitionDuration: '0.3s', - transitionDuration: '0.3s', - WebkitTransitionTimingFunction: 'ease-out', - transitionTimingFunction: 'ease-out' - }, - ':hover:before': { - left: 0, - right: 0 - }, - 'focus:before': { - left: 0, - right: 0 - }, - 'active:before': { - left: 0, - right: 0 - } - } } \ No newline at end of file -- 2.34.1 From 246abd7020c5df5847827922495bf14034193370 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 13:16:57 +0100 Subject: [PATCH 21/23] Renamed the variable name for our stylesheet. --- client/app/components/SearchRequest.jsx | 50 ++++++++++++------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/client/app/components/SearchRequest.jsx b/client/app/components/SearchRequest.jsx index b5b6554..39cdce2 100644 --- a/client/app/components/SearchRequest.jsx +++ b/client/app/components/SearchRequest.jsx @@ -4,7 +4,7 @@ import URI from 'urijs'; import InfiniteScroll from 'react-infinite-scroller'; // StyleComponents -import searchStyle from './styles/searchRequestStyle.jsx'; +import searchRequestCSS from './styles/searchRequestStyle.jsx'; import SearchObject from './SearchObject.jsx'; import Loading from './images/loading.jsx' @@ -343,12 +343,12 @@ class SearchRequest extends React.Component { movieToggle() { if (this.state.movieFilter) - return {this.toggleFilter('movies')}} id="category_active">Movies else - return {this.toggleFilter('movies')}} id="category_active">Movies @@ -356,12 +356,12 @@ class SearchRequest extends React.Component { showToggle() { if (this.state.showFilter) - return {this.toggleFilter('shows')}} id="category_active">TV Shows else - return {this.toggleFilter('shows')}} id="category_active">TV Shows @@ -381,17 +381,17 @@ class SearchRequest extends React.Component { initialLoad={this.state.loadResults}> -
-
-
- Request new content +
+
+
+ Request new content
-
-
- +
+
+ - this._handleQueryKeyPress(event)} onChange={event => this.updateQueryState(event)} value={this.state.searchQuery}/> @@ -400,8 +400,8 @@ class SearchRequest extends React.Component {
-
- {this.state.resultHeader} +
+ {this.state.resultHeader}



{this.state.responseMovieList} @@ -410,17 +410,17 @@ class SearchRequest extends React.Component { -
-
-
- Request new content +
+
+
+ Request new content
-
-
- +
+
+ - this._handleQueryKeyPress(event)} onChange={event => this.updateQueryState(event)} value={this.state.searchQuery}/> @@ -429,8 +429,8 @@ class SearchRequest extends React.Component {
-
- {this.state.resultHeader} +
+ {this.state.resultHeader}



{this.state.responseMovieList} -- 2.34.1 From 7849a8ce3f93d1a3a6bac880da4624d7f8aa23cc Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 13:17:17 +0100 Subject: [PATCH 22/23] Fixed syntax error. --- client/app/components/styles/adminRequestInfo.jsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/app/components/styles/adminRequestInfo.jsx b/client/app/components/styles/adminRequestInfo.jsx index e11b3d4..0d13af2 100644 --- a/client/app/components/styles/adminRequestInfo.jsx +++ b/client/app/components/styles/adminRequestInfo.jsx @@ -1,4 +1,4 @@ -export default = { +export default { wrapper: { width: '100%', }, -- 2.34.1 From c65cdd84b7f185d1a3d3bf6c35c0a13a93e61d80 Mon Sep 17 00:00:00 2001 From: KevinMidboe Date: Sat, 2 Dec 2017 13:18:20 +0100 Subject: [PATCH 23/23] Changed our gitignore file for the api folder. --- seasoned_api/.gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seasoned_api/.gitignore b/seasoned_api/.gitignore index 9f7246b..ef087ec 100644 --- a/seasoned_api/.gitignore +++ b/seasoned_api/.gitignore @@ -60,4 +60,4 @@ typings/ # - - - - - # My own gitignore files and folders -conf +conf/ -- 2.34.1