add new sortby button and allow sorting on homepage
This commit is contained in:
parent
d94b672a12
commit
8d50ec54e7
@ -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 {
|
||||||
|
@ -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.loadPreviewBlock(this.InitialLoadNR);
|
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...
|
* 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 {
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user