make tags on random page filterable
This commit is contained in:
parent
43091ff7ed
commit
9715012685
@ -1,6 +1,7 @@
|
|||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/url"
|
"net/url"
|
||||||
"openmediacenter/apiGo/api/api"
|
"openmediacenter/apiGo/api/api"
|
||||||
@ -9,6 +10,7 @@ import (
|
|||||||
"openmediacenter/apiGo/database"
|
"openmediacenter/apiGo/database"
|
||||||
"os"
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func addVideoHandlers() {
|
func addVideoHandlers() {
|
||||||
@ -162,7 +164,8 @@ func getVideoHandlers() {
|
|||||||
*/
|
*/
|
||||||
api.AddHandler("getRandomMovies", api.VideoNode, api.PermUser, func(context api.Context) {
|
api.AddHandler("getRandomMovies", api.VideoNode, api.PermUser, func(context api.Context) {
|
||||||
var args struct {
|
var args struct {
|
||||||
Number int
|
Number int
|
||||||
|
TagFilter []uint32
|
||||||
}
|
}
|
||||||
if api.DecodeRequest(context.GetRequest(), &args) != nil {
|
if api.DecodeRequest(context.GetRequest(), &args) != nil {
|
||||||
context.Text("unable to decode request")
|
context.Text("unable to decode request")
|
||||||
@ -174,34 +177,52 @@ func getVideoHandlers() {
|
|||||||
Videos []types.VideoUnloadedType
|
Videos []types.VideoUnloadedType
|
||||||
}
|
}
|
||||||
|
|
||||||
query := fmt.Sprintf("SELECT movie_id,movie_name FROM videos ORDER BY RAND() LIMIT %d", args.Number)
|
whereclause := "WHERE 1"
|
||||||
result.Videos = readVideosFromResultset(database.Query(query))
|
if len(args.TagFilter) > 0 {
|
||||||
|
d, _ := json.Marshal(args.TagFilter)
|
||||||
|
vals := strings.Trim(string(d), "[]")
|
||||||
|
|
||||||
var ids string
|
whereclause = fmt.Sprintf("WHERE tag_id IN (%s)", vals)
|
||||||
for i := range result.Videos {
|
|
||||||
ids += "video_tags.video_id=" + strconv.Itoa(result.Videos[i].MovieId)
|
|
||||||
|
|
||||||
if i < len(result.Videos)-1 {
|
|
||||||
ids += " OR "
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the corresponding tags
|
query := fmt.Sprintf(`
|
||||||
query = fmt.Sprintf(`SELECT t.tag_name,t.tag_id FROM video_tags
|
SELECT video_tags.video_id,v.movie_name FROM video_tags join videos v on v.movie_id = video_tags.video_id
|
||||||
|
%s
|
||||||
|
group by video_id
|
||||||
|
ORDER BY RAND()
|
||||||
|
LIMIT %d`, whereclause, args.Number)
|
||||||
|
result.Videos = readVideosFromResultset(database.Query(query))
|
||||||
|
|
||||||
|
if len(result.Videos) > 0 {
|
||||||
|
var ids string
|
||||||
|
for i := range result.Videos {
|
||||||
|
ids += "video_tags.video_id=" + strconv.Itoa(result.Videos[i].MovieId)
|
||||||
|
|
||||||
|
if i < len(result.Videos)-1 {
|
||||||
|
ids += " OR "
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// add the corresponding tags
|
||||||
|
query = fmt.Sprintf(`SELECT t.tag_name,t.tag_id FROM video_tags
|
||||||
INNER JOIN tags t on video_tags.tag_id = t.tag_id
|
INNER JOIN tags t on video_tags.tag_id = t.tag_id
|
||||||
WHERE %s
|
WHERE %s
|
||||||
GROUP BY t.tag_id`, ids)
|
GROUP BY t.tag_id`, ids)
|
||||||
|
|
||||||
rows := database.Query(query)
|
rows := database.Query(query)
|
||||||
|
if rows != nil {
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var tag types.Tag
|
var tag types.Tag
|
||||||
err := rows.Scan(&tag.TagName, &tag.TagId)
|
err := rows.Scan(&tag.TagName, &tag.TagId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic(err.Error()) // proper Error handling instead of panic in your app
|
panic(err.Error()) // proper Error handling instead of panic in your app
|
||||||
|
}
|
||||||
|
// append to final array
|
||||||
|
result.Tags = append(result.Tags, tag)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// append to final array
|
} else {
|
||||||
result.Tags = append(result.Tags, tag)
|
result.Tags = []types.Tag{}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.Json(result)
|
context.Json(result)
|
||||||
|
@ -2,16 +2,21 @@ import React from 'react';
|
|||||||
import style from './RandomPage.module.css';
|
import style from './RandomPage.module.css';
|
||||||
import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
|
import SideBar, {SideBarTitle} from '../../elements/SideBar/SideBar';
|
||||||
import Tag from '../../elements/Tag/Tag';
|
import Tag from '../../elements/Tag/Tag';
|
||||||
import PageTitle from '../../elements/PageTitle/PageTitle';
|
import PageTitle, {Line} from '../../elements/PageTitle/PageTitle';
|
||||||
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
|
import VideoContainer from '../../elements/VideoContainer/VideoContainer';
|
||||||
import {APINode, callAPI} from '../../utils/Api';
|
import {APINode, callAPI} from '../../utils/Api';
|
||||||
import {TagType} from '../../types/VideoTypes';
|
import {TagType} from '../../types/VideoTypes';
|
||||||
import {VideoTypes} from '../../types/ApiTypes';
|
import {VideoTypes} from '../../types/ApiTypes';
|
||||||
import {addKeyHandler, removeKeyHandler} from '../../utils/ShortkeyHandler';
|
import {addKeyHandler, removeKeyHandler} from '../../utils/ShortkeyHandler';
|
||||||
|
import {IconButton} from '../../elements/GPElements/Button';
|
||||||
|
import {faPlusCircle} from '@fortawesome/free-solid-svg-icons';
|
||||||
|
import AddTagPopup from '../../elements/Popups/AddTagPopup/AddTagPopup';
|
||||||
|
|
||||||
interface state {
|
interface state {
|
||||||
videos: VideoTypes.VideoUnloadedType[];
|
videos: VideoTypes.VideoUnloadedType[];
|
||||||
tags: TagType[];
|
tags: TagType[];
|
||||||
|
filterTags: TagType[];
|
||||||
|
addTagPopup: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface GetRandomMoviesType {
|
interface GetRandomMoviesType {
|
||||||
@ -29,8 +34,10 @@ class RandomPage extends React.Component<{}, state> {
|
|||||||
super(props);
|
super(props);
|
||||||
|
|
||||||
this.state = {
|
this.state = {
|
||||||
|
addTagPopup: false,
|
||||||
videos: [],
|
videos: [],
|
||||||
tags: []
|
tags: [],
|
||||||
|
filterTags: []
|
||||||
};
|
};
|
||||||
|
|
||||||
this.keypress = this.keypress.bind(this);
|
this.keypress = this.keypress.bind(this);
|
||||||
@ -56,42 +63,56 @@ class RandomPage extends React.Component<{}, state> {
|
|||||||
{this.state.tags.map((m) => (
|
{this.state.tags.map((m) => (
|
||||||
<Tag key={m.TagId} tagInfo={m} />
|
<Tag key={m.TagId} tagInfo={m} />
|
||||||
))}
|
))}
|
||||||
|
<Line />
|
||||||
|
<SideBarTitle>Filter Tags:</SideBarTitle>
|
||||||
|
{this.state.filterTags.map((m) => (
|
||||||
|
<Tag key={m.TagId} tagInfo={m} />
|
||||||
|
))}
|
||||||
|
<IconButton
|
||||||
|
title='Add'
|
||||||
|
icon={faPlusCircle}
|
||||||
|
onClick={(): void => {
|
||||||
|
this.setState({addTagPopup: true});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
</SideBar>
|
</SideBar>
|
||||||
|
|
||||||
{this.state.videos.length !== 0 ? (
|
{this.state.videos.length !== 0 ? <VideoContainer data={this.state.videos} /> : <div>No Data found!</div>}
|
||||||
<VideoContainer data={this.state.videos}>
|
<div className={style.Shufflebutton}>
|
||||||
<div className={style.Shufflebutton}>
|
<button onClick={(): void => this.loadShuffledvideos(this.LoadNR)} className={style.btnshuffle}>
|
||||||
<button onClick={(): void => this.shuffleclick()} className={style.btnshuffle}>
|
Shuffle
|
||||||
Shuffle
|
</button>
|
||||||
</button>
|
</div>
|
||||||
</div>
|
{this.state.addTagPopup ? (
|
||||||
</VideoContainer>
|
<AddTagPopup
|
||||||
) : (
|
onHide={(): void => this.setState({addTagPopup: false})}
|
||||||
<div>No Data found!</div>
|
submit={(tagId: number, tagName: string): void => {
|
||||||
)}
|
this.setState({filterTags: [...this.state.filterTags, {TagId: tagId, TagName: tagName}]}, (): void => {
|
||||||
|
this.loadShuffledvideos(this.LoadNR);
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* click handler for shuffle btn
|
|
||||||
*/
|
|
||||||
shuffleclick(): void {
|
|
||||||
this.loadShuffledvideos(this.LoadNR);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* load random videos from backend
|
* load random videos from backend
|
||||||
* @param nr number of videos to load
|
* @param nr number of videos to load
|
||||||
*/
|
*/
|
||||||
loadShuffledvideos(nr: number): void {
|
loadShuffledvideos(nr: number): void {
|
||||||
callAPI<GetRandomMoviesType>(APINode.Video, {action: 'getRandomMovies', Number: nr}, (result) => {
|
callAPI<GetRandomMoviesType>(
|
||||||
this.setState({videos: []}); // needed to trigger rerender of main videoview
|
APINode.Video,
|
||||||
this.setState({
|
{action: 'getRandomMovies', Number: nr, TagFilter: this.state.filterTags.map((t) => t.TagId)},
|
||||||
videos: result.Videos,
|
(result) => {
|
||||||
tags: result.Tags
|
this.setState({videos: []}); // needed to trigger rerender of main videoview
|
||||||
});
|
this.setState({
|
||||||
});
|
videos: result.Videos,
|
||||||
|
tags: result.Tags
|
||||||
|
});
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user