From 8d50ec54e768bcd13b5d201457c8f766a0e102bd Mon Sep 17 00:00:00 2001 From: lukas Date: Sun, 13 Jun 2021 22:29:50 +0200 Subject: [PATCH] add new sortby button and allow sorting on homepage --- apiGo/api/Video.go | 31 ++++++- .../DynamicContentContainer.tsx | 16 ++-- src/pages/HomePage/HomePage.module.css | 53 ++++++++++++ src/pages/HomePage/HomePage.tsx | 82 ++++++++++++++++--- 4 files changed, 162 insertions(+), 20 deletions(-) diff --git a/apiGo/api/Video.go b/apiGo/api/Video.go index 4412bc4..69429e4 100644 --- a/apiGo/api/Video.go +++ b/apiGo/api/Video.go @@ -31,23 +31,46 @@ func getVideoHandlers() { */ AddHandler("getMovies", VideoNode, func(info *HandlerInfo) []byte { var args struct { - Tag int + Tag uint32 + Sort uint8 } if err := FillStruct(&args, info.Data); err != nil { fmt.Println(err.Error()) return nil } + const ( + date = iota + likes = iota + random = iota + names = iota + ) + + var SortClause string + switch args.Sort { + case date: + SortClause = "ORDER BY create_date DESC, movie_name" + break + case likes: + SortClause = "ORDER BY likes DESC" + break + case random: + SortClause = "ORDER BY RAND()" + break + case names: + SortClause = "ORDER BY movie_name" + break + } + var query string // 1 is the id of the ALL tag if args.Tag != 1 { query = fmt.Sprintf(`SELECT movie_id,movie_name,t.tag_name FROM videos INNER JOIN video_tags vt on videos.movie_id = vt.video_id INNER JOIN tags t on vt.tag_id = t.tag_id - WHERE t.tag_id = %d - ORDER BY likes DESC, create_date, movie_name`, args.Tag) + WHERE t.tag_id = %d %s`, args.Tag, SortClause) } else { - query = "SELECT movie_id,movie_name, (SELECT 'All' as tag_name) FROM videos ORDER BY create_date DESC, movie_name" + query = fmt.Sprintf("SELECT movie_id,movie_name, (SELECT 'All' as tag_name) FROM videos %s", SortClause) } var result struct { diff --git a/src/elements/DynamicContentContainer/DynamicContentContainer.tsx b/src/elements/DynamicContentContainer/DynamicContentContainer.tsx index e83cebd..7462b74 100644 --- a/src/elements/DynamicContentContainer/DynamicContentContainer.tsx +++ b/src/elements/DynamicContentContainer/DynamicContentContainer.tsx @@ -41,18 +41,24 @@ class DynamicContentContainer extends React.Component, state> { componentDidUpdate(prevProps: Props): void { // when source props change force update! - if (prevProps.data.length !== this.props.data.length) { - this.clean(); - this.loadPreviewBlock(this.InitialLoadNR); + if ( + // diff the two arrays + this.props.data + .filter((x) => !prevProps.data.includes(x)) + .concat(prevProps.data.filter((x) => !this.props.data.includes(x))).length !== 0 + ) { + this.clean((): void => { + this.loadPreviewBlock(this.InitialLoadNR); + }); } } /** * clear all elements rendered... */ - clean(): void { + clean(callback: () => void): void { this.loadindex = 0; - this.setState({loadeditems: []}); + this.setState({loadeditems: []}, callback); } render(): JSX.Element { diff --git a/src/pages/HomePage/HomePage.module.css b/src/pages/HomePage/HomePage.module.css index 3b1a495..089df77 100644 --- a/src/pages/HomePage/HomePage.module.css +++ b/src/pages/HomePage/HomePage.module.css @@ -7,3 +7,56 @@ float: right; margin-top: 25px; } + + +/* Style The Dropdown Button */ +.dropbtn { + display: flex; + justify-content: center; + align-items: center; + flex-direction: row; + height: 100%; + cursor: pointer; + color: white; + text-align: center; +} + +/* The container
- needed to position the dropdown content */ +.dropdown { + position: relative; + display: inline-block; +} + +/* Dropdown Content (Hidden by Default) */ +.dropdownContent { + display: none; + position: absolute; + background-color: #f9f9f9; + min-width: 160px; + box-shadow: 0px 8px 16px 0px rgba(0,0,0,0.2); + z-index: 1; +} + +/* Links inside the dropdown */ +.dropdownContent span { + color: black; + padding: 12px 16px; + text-decoration: none; + display: block; + cursor: pointer; +} + +/* Change color of dropdown links on hover */ +.dropdownContent span:hover { + background-color: #f1f1f1; +} + +/* Show the dropdown menu on hover */ +.dropdown:hover .dropdownContent { + display: block; +} + +/* Change the background color of the dropdown button when the dropdown content is shown */ +.dropdown:hover .dropbtn { + background-color: #3574fe; +} diff --git a/src/pages/HomePage/HomePage.tsx b/src/pages/HomePage/HomePage.tsx index 21ce863..c3b1774 100644 --- a/src/pages/HomePage/HomePage.tsx +++ b/src/pages/HomePage/HomePage.tsx @@ -11,6 +11,16 @@ import {RouteComponentProps} from 'react-router'; import SearchHandling from './SearchHandling'; import {VideoTypes} from '../../types/ApiTypes'; import {DefaultTags} from '../../types/GeneralTypes'; +import {FontAwesomeIcon} from '@fortawesome/react-fontawesome'; +import {faSortDown} from '@fortawesome/free-solid-svg-icons'; + +// eslint-disable-next-line no-shadow +enum SortBy { + date, + likes, + random, + name +} interface Props extends RouteComponentProps {} @@ -19,6 +29,7 @@ interface state { subtitle: string; data: VideoTypes.VideoUnloadedType[]; selectionnr: number; + sortby: string; } /** @@ -42,13 +53,17 @@ export class HomePage extends React.Component { }, subtitle: 'All Videos', data: [], - selectionnr: 0 + selectionnr: 0, + sortby: 'Date Added' }; } + sortState = SortBy.date; + tagState = DefaultTags.all; + componentDidMount(): void { // initial get of all videos - this.fetchVideoData(DefaultTags.all.TagId); + this.fetchVideoData(); this.fetchStartData(); } @@ -58,14 +73,11 @@ export class HomePage extends React.Component { * * @param tag tag to fetch videos */ - fetchVideoData(tag: number): void { + fetchVideoData(): void { callAPI( APINode.Video, - {action: 'getMovies', Tag: tag}, + {action: 'getMovies', Tag: this.tagState.TagId, Sort: this.sortState}, (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => { - this.setState({ - data: [] - }); this.setState({ data: result.Videos, selectionnr: result.Videos.length @@ -135,32 +147,80 @@ export class HomePage extends React.Component { { - this.fetchVideoData(DefaultTags.all.TagId); + this.tagState = DefaultTags.all; + this.fetchVideoData(); this.setState({subtitle: 'All Videos'}); }} /> { - this.fetchVideoData(DefaultTags.fullhd.TagId); + this.tagState = DefaultTags.fullhd; + this.fetchVideoData(); this.setState({subtitle: 'Full Hd Videos'}); }} /> { - this.fetchVideoData(DefaultTags.lowq.TagId); + this.tagState = DefaultTags.lowq; + this.fetchVideoData(); this.setState({subtitle: 'Low Quality Videos'}); }} /> { - this.fetchVideoData(DefaultTags.hd.TagId); + this.tagState = DefaultTags.hd; + this.fetchVideoData(); this.setState({subtitle: 'HD Videos'}); }} /> +
+ Sort By: +
+ + {this.state.sortby} + + +
+ { + this.sortState = SortBy.date; + this.setState({sortby: 'Date Added '}); + this.fetchVideoData(); + }}> + Date Added + + { + this.sortState = SortBy.likes; + this.setState({sortby: 'Most likes'}); + this.fetchVideoData(); + }}> + Most likes + + { + this.sortState = SortBy.random; + this.setState({sortby: 'Random'}); + this.fetchVideoData(); + }}> + Random + + { + this.sortState = SortBy.name; + this.setState({sortby: 'Name'}); + this.fetchVideoData(); + }}> + Name + +
+
+
+