add new sortby button and allow sorting on homepage

This commit is contained in:
lukas 2021-06-13 22:29:50 +02:00
parent d94b672a12
commit 8d50ec54e7
4 changed files with 162 additions and 20 deletions

View File

@ -31,23 +31,46 @@ func getVideoHandlers() {
*/ */
AddHandler("getMovies", VideoNode, func(info *HandlerInfo) []byte { AddHandler("getMovies", VideoNode, func(info *HandlerInfo) []byte {
var args struct { var args struct {
Tag int Tag uint32
Sort uint8
} }
if err := FillStruct(&args, info.Data); err != nil { if err := FillStruct(&args, info.Data); err != nil {
fmt.Println(err.Error()) fmt.Println(err.Error())
return nil 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 var query string
// 1 is the id of the ALL tag // 1 is the id of the ALL tag
if args.Tag != 1 { if args.Tag != 1 {
query = fmt.Sprintf(`SELECT movie_id,movie_name,t.tag_name FROM videos 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 video_tags vt on videos.movie_id = vt.video_id
INNER JOIN tags t on vt.tag_id = t.tag_id INNER JOIN tags t on vt.tag_id = t.tag_id
WHERE t.tag_id = %d WHERE t.tag_id = %d %s`, args.Tag, SortClause)
ORDER BY likes DESC, create_date, movie_name`, args.Tag)
} else { } 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 { var result struct {

View File

@ -41,18 +41,24 @@ class DynamicContentContainer<T> extends React.Component<Props<T>, state<T>> {
componentDidUpdate(prevProps: Props<T>): void { componentDidUpdate(prevProps: Props<T>): void {
// when source props change force update! // when source props change force update!
if (prevProps.data.length !== this.props.data.length) { if (
this.clean(); // 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); this.loadPreviewBlock(this.InitialLoadNR);
});
} }
} }
/** /**
* clear all elements rendered... * clear all elements rendered...
*/ */
clean(): void { clean(callback: () => void): void {
this.loadindex = 0; this.loadindex = 0;
this.setState({loadeditems: []}); this.setState({loadeditems: []}, callback);
} }
render(): JSX.Element { render(): JSX.Element {

View File

@ -7,3 +7,56 @@
float: right; float: right;
margin-top: 25px; 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 <div> - 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;
}

View File

@ -11,6 +11,16 @@ import {RouteComponentProps} from 'react-router';
import SearchHandling from './SearchHandling'; import SearchHandling from './SearchHandling';
import {VideoTypes} from '../../types/ApiTypes'; import {VideoTypes} from '../../types/ApiTypes';
import {DefaultTags} from '../../types/GeneralTypes'; 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 {} interface Props extends RouteComponentProps {}
@ -19,6 +29,7 @@ interface state {
subtitle: string; subtitle: string;
data: VideoTypes.VideoUnloadedType[]; data: VideoTypes.VideoUnloadedType[];
selectionnr: number; selectionnr: number;
sortby: string;
} }
/** /**
@ -42,13 +53,17 @@ export class HomePage extends React.Component<Props, state> {
}, },
subtitle: 'All Videos', subtitle: 'All Videos',
data: [], data: [],
selectionnr: 0 selectionnr: 0,
sortby: 'Date Added'
}; };
} }
sortState = SortBy.date;
tagState = DefaultTags.all;
componentDidMount(): void { componentDidMount(): void {
// initial get of all videos // initial get of all videos
this.fetchVideoData(DefaultTags.all.TagId); this.fetchVideoData();
this.fetchStartData(); this.fetchStartData();
} }
@ -58,14 +73,11 @@ export class HomePage extends React.Component<Props, state> {
* *
* @param tag tag to fetch videos * @param tag tag to fetch videos
*/ */
fetchVideoData(tag: number): void { fetchVideoData(): void {
callAPI( callAPI(
APINode.Video, APINode.Video,
{action: 'getMovies', Tag: tag}, {action: 'getMovies', Tag: this.tagState.TagId, Sort: this.sortState},
(result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => { (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => {
this.setState({
data: []
});
this.setState({ this.setState({
data: result.Videos, data: result.Videos,
selectionnr: result.Videos.length selectionnr: result.Videos.length
@ -135,32 +147,80 @@ export class HomePage extends React.Component<Props, state> {
<Tag <Tag
tagInfo={{TagName: 'All', TagId: DefaultTags.all.TagId}} tagInfo={{TagName: 'All', TagId: DefaultTags.all.TagId}}
onclick={(): void => { onclick={(): void => {
this.fetchVideoData(DefaultTags.all.TagId); this.tagState = DefaultTags.all;
this.fetchVideoData();
this.setState({subtitle: 'All Videos'}); this.setState({subtitle: 'All Videos'});
}} }}
/> />
<Tag <Tag
tagInfo={{TagName: 'Full Hd', TagId: DefaultTags.fullhd.TagId}} tagInfo={{TagName: 'Full Hd', TagId: DefaultTags.fullhd.TagId}}
onclick={(): void => { onclick={(): void => {
this.fetchVideoData(DefaultTags.fullhd.TagId); this.tagState = DefaultTags.fullhd;
this.fetchVideoData();
this.setState({subtitle: 'Full Hd Videos'}); this.setState({subtitle: 'Full Hd Videos'});
}} }}
/> />
<Tag <Tag
tagInfo={{TagName: 'Low Quality', TagId: DefaultTags.lowq.TagId}} tagInfo={{TagName: 'Low Quality', TagId: DefaultTags.lowq.TagId}}
onclick={(): void => { onclick={(): void => {
this.fetchVideoData(DefaultTags.lowq.TagId); this.tagState = DefaultTags.lowq;
this.fetchVideoData();
this.setState({subtitle: 'Low Quality Videos'}); this.setState({subtitle: 'Low Quality Videos'});
}} }}
/> />
<Tag <Tag
tagInfo={{TagName: 'HD', TagId: DefaultTags.hd.TagId}} tagInfo={{TagName: 'HD', TagId: DefaultTags.hd.TagId}}
onclick={(): void => { onclick={(): void => {
this.fetchVideoData(DefaultTags.hd.TagId); this.tagState = DefaultTags.hd;
this.fetchVideoData();
this.setState({subtitle: 'HD Videos'}); this.setState({subtitle: 'HD Videos'});
}} }}
/> />
</SideBar> </SideBar>
<div>
<span style={{color: 'grey', marginRight: 5}}>Sort By: </span>
<div className={style.dropdown}>
<span className={style.dropbtn}>
<span>{this.state.sortby}</span>
<FontAwesomeIcon style={{marginLeft: 3, paddingBottom: 3}} icon={faSortDown} size='1x' />
</span>
<div className={style.dropdownContent}>
<span
onClick={(): void => {
this.sortState = SortBy.date;
this.setState({sortby: 'Date Added '});
this.fetchVideoData();
}}>
Date Added
</span>
<span
onClick={(): void => {
this.sortState = SortBy.likes;
this.setState({sortby: 'Most likes'});
this.fetchVideoData();
}}>
Most likes
</span>
<span
onClick={(): void => {
this.sortState = SortBy.random;
this.setState({sortby: 'Random'});
this.fetchVideoData();
}}>
Random
</span>
<span
onClick={(): void => {
this.sortState = SortBy.name;
this.setState({sortby: 'Name'});
this.fetchVideoData();
}}>
Name
</span>
</div>
</div>
</div>
<VideoContainer data={this.state.data} /> <VideoContainer data={this.state.data} />
<div className={style.rightinfo} /> <div className={style.rightinfo} />
</Route> </Route>