make tags on random page filterable
This commit is contained in:
		@@ -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
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user