Compare commits
	
		
			5 Commits
		
	
	
		
			newdeploy
			...
			rememberLo
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 9b23666fe6 | |||
| 1adafef4e1 | |||
| 43091ff7ed | |||
| 12dc8427aa | |||
| 23d91973d7 | 
@@ -2,6 +2,7 @@ package api
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"math/rand"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"openmediacenter/apiGo/api/api"
 | 
						"openmediacenter/apiGo/api/api"
 | 
				
			||||||
	"openmediacenter/apiGo/api/types"
 | 
						"openmediacenter/apiGo/api/types"
 | 
				
			||||||
@@ -163,18 +164,25 @@ 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
 | 
				
			||||||
 | 
								Seed   *int
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		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")
 | 
				
			||||||
			return
 | 
								return
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// if Seed argument not passed generate random seed
 | 
				
			||||||
 | 
							if args.Seed == nil {
 | 
				
			||||||
 | 
								r := rand.Int()
 | 
				
			||||||
 | 
								args.Seed = &r
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var result struct {
 | 
							var result struct {
 | 
				
			||||||
			Tags   []types.Tag
 | 
								Tags   []types.Tag
 | 
				
			||||||
			Videos []types.VideoUnloadedType
 | 
								Videos []types.VideoUnloadedType
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		query := fmt.Sprintf("SELECT movie_id,movie_name FROM videos ORDER BY RAND() LIMIT %d", args.Number)
 | 
							query := fmt.Sprintf("SELECT movie_id,movie_name FROM videos ORDER BY RAND(%d) LIMIT %d", *args.Seed, args.Number)
 | 
				
			||||||
		result.Videos = readVideosFromResultset(database.Query(query))
 | 
							result.Videos = readVideosFromResultset(database.Query(query))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var ids string
 | 
							var ids string
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,7 +19,7 @@ describe('<App/>', function () {
 | 
				
			|||||||
    it('are navlinks correct', function () {
 | 
					    it('are navlinks correct', function () {
 | 
				
			||||||
        const wrapper = shallow(<App/>);
 | 
					        const wrapper = shallow(<App/>);
 | 
				
			||||||
        wrapper.setState({password: false});
 | 
					        wrapper.setState({password: false});
 | 
				
			||||||
        expect(wrapper.find('.navitem')).toHaveLength(4);
 | 
					        expect(wrapper.find('.navitem')).toHaveLength(5);
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    it('test render of password page', function () {
 | 
					    it('test render of password page', function () {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -88,6 +88,13 @@ class App extends React.Component<{}, state> {
 | 
				
			|||||||
                    Categories
 | 
					                    Categories
 | 
				
			||||||
                </NavLink>
 | 
					                </NavLink>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                <NavLink
 | 
				
			||||||
 | 
					                    className={[style.navitem, themeStyle.navitem].join(' ')}
 | 
				
			||||||
 | 
					                    to={'/media/actors'}
 | 
				
			||||||
 | 
					                    activeStyle={{opacity: '0.85'}}>
 | 
				
			||||||
 | 
					                    Actors
 | 
				
			||||||
 | 
					                </NavLink>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                {this.context.TVShowEnabled ? (
 | 
					                {this.context.TVShowEnabled ? (
 | 
				
			||||||
                    <NavLink
 | 
					                    <NavLink
 | 
				
			||||||
                        className={[style.navitem, themeStyle.navitem].join(' ')}
 | 
					                        className={[style.navitem, themeStyle.navitem].join(' ')}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -17,7 +17,7 @@ class Tag extends React.Component<props> {
 | 
				
			|||||||
        if (this.props.onclick) {
 | 
					        if (this.props.onclick) {
 | 
				
			||||||
            return this.renderButton();
 | 
					            return this.renderButton();
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            return <Link to={'/categories/' + this.props.tagInfo.TagId}>{this.renderButton()}</Link>;
 | 
					            return <Link to={'/media/categories/' + this.props.tagInfo.TagId}>{this.renderButton()}</Link>;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -37,7 +37,7 @@ export class ActorPage extends React.Component<Props, state> {
 | 
				
			|||||||
            <>
 | 
					            <>
 | 
				
			||||||
                <PageTitle title={this.state.actor.Name} subtitle={this.state.data ? this.state.data.length + ' videos' : null}>
 | 
					                <PageTitle title={this.state.actor.Name} subtitle={this.state.data ? this.state.data.length + ' videos' : null}>
 | 
				
			||||||
                    <span className={style.overviewbutton}>
 | 
					                    <span className={style.overviewbutton}>
 | 
				
			||||||
                        <Link to='/actors'>
 | 
					                        <Link to='/media/actors'>
 | 
				
			||||||
                            <Button onClick={(): void => {}} title='Go to Actor overview' />
 | 
					                            <Button onClick={(): void => {}} title='Go to Actor overview' />
 | 
				
			||||||
                        </Link>
 | 
					                        </Link>
 | 
				
			||||||
                    </span>
 | 
					                    </span>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,14 +90,12 @@ describe('<HomePage/>', function () {
 | 
				
			|||||||
        const wrapper = shallow(<HomePage/>);
 | 
					        const wrapper = shallow(<HomePage/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // expect those default values
 | 
					        // expect those default values
 | 
				
			||||||
        expect(wrapper.state().sortby).toBe('Date Added');
 | 
					        expect(wrapper.state().sortby).toBe(0);
 | 
				
			||||||
        expect(wrapper.instance().sortState).toBe(SortBy.date);
 | 
					 | 
				
			||||||
        expect(wrapper.instance().tagState).toBe(DefaultTags.all);
 | 
					        expect(wrapper.instance().tagState).toBe(DefaultTags.all);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        wrapper.instance().onDropDownItemClick(SortBy.name, 'namesort');
 | 
					        wrapper.instance().onDropDownItemClick(SortBy.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.state().sortby).toBe('namesort');
 | 
					        expect(wrapper.state().sortby).toBe(SortBy.name);
 | 
				
			||||||
        expect(wrapper.instance().sortState).toBe(SortBy.name);
 | 
					 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -29,7 +29,7 @@ interface state {
 | 
				
			|||||||
    subtitle: string;
 | 
					    subtitle: string;
 | 
				
			||||||
    data: VideoTypes.VideoUnloadedType[];
 | 
					    data: VideoTypes.VideoUnloadedType[];
 | 
				
			||||||
    selectionnr: number;
 | 
					    selectionnr: number;
 | 
				
			||||||
    sortby: string;
 | 
					    sortby: SortBy;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -39,9 +39,33 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
    /** keyword variable needed temporary store search keyword */
 | 
					    /** keyword variable needed temporary store search keyword */
 | 
				
			||||||
    keyword = '';
 | 
					    keyword = '';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /**
 | 
				
			||||||
 | 
					     * get text label from sort type
 | 
				
			||||||
 | 
					     * @param type SortBy type
 | 
				
			||||||
 | 
					     */
 | 
				
			||||||
 | 
					    getLabelFromSortType(type: SortBy): String {
 | 
				
			||||||
 | 
					        switch (type) {
 | 
				
			||||||
 | 
					            case SortBy.date:
 | 
				
			||||||
 | 
					                return 'Date Added';
 | 
				
			||||||
 | 
					            case SortBy.length:
 | 
				
			||||||
 | 
					                return 'Length';
 | 
				
			||||||
 | 
					            case SortBy.likes:
 | 
				
			||||||
 | 
					                return 'Most likes';
 | 
				
			||||||
 | 
					            case SortBy.name:
 | 
				
			||||||
 | 
					                return 'Name';
 | 
				
			||||||
 | 
					            case SortBy.random:
 | 
				
			||||||
 | 
					                return 'Random';
 | 
				
			||||||
 | 
					            default:
 | 
				
			||||||
 | 
					                return '';
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(props: Props) {
 | 
					    constructor(props: Props) {
 | 
				
			||||||
        super(props);
 | 
					        super(props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // get previously stored location from localstorage
 | 
				
			||||||
 | 
					        const storedSelection = global.localStorage.getItem('sortby');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.state = {
 | 
					        this.state = {
 | 
				
			||||||
            sideinfo: {
 | 
					            sideinfo: {
 | 
				
			||||||
                VideoNr: 0,
 | 
					                VideoNr: 0,
 | 
				
			||||||
@@ -54,11 +78,10 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
            subtitle: 'All Videos',
 | 
					            subtitle: 'All Videos',
 | 
				
			||||||
            data: [],
 | 
					            data: [],
 | 
				
			||||||
            selectionnr: 0,
 | 
					            selectionnr: 0,
 | 
				
			||||||
            sortby: 'Date Added'
 | 
					            sortby: storedSelection == null ? SortBy.date : parseInt(storedSelection, 10)
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sortState = SortBy.date;
 | 
					 | 
				
			||||||
    tagState = DefaultTags.all;
 | 
					    tagState = DefaultTags.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentDidMount(): void {
 | 
					    componentDidMount(): void {
 | 
				
			||||||
@@ -87,7 +110,7 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
    fetchVideoData(): void {
 | 
					    fetchVideoData(): void {
 | 
				
			||||||
        callAPI(
 | 
					        callAPI(
 | 
				
			||||||
            APINode.Video,
 | 
					            APINode.Video,
 | 
				
			||||||
            {action: 'getMovies', Tag: this.tagState.TagId, Sort: this.sortState},
 | 
					            {action: 'getMovies', Tag: this.tagState.TagId, Sort: this.state.sortby},
 | 
				
			||||||
            (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => {
 | 
					            (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => {
 | 
				
			||||||
                this.setState({
 | 
					                this.setState({
 | 
				
			||||||
                    data: result.Videos,
 | 
					                    data: result.Videos,
 | 
				
			||||||
@@ -190,15 +213,25 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
                    <span className={style.sortbyLabel}>Sort By: </span>
 | 
					                    <span className={style.sortbyLabel}>Sort By: </span>
 | 
				
			||||||
                    <div className={style.dropdown}>
 | 
					                    <div className={style.dropdown}>
 | 
				
			||||||
                        <span className={style.dropbtn}>
 | 
					                        <span className={style.dropbtn}>
 | 
				
			||||||
                            <span>{this.state.sortby}</span>
 | 
					                            <span>{this.getLabelFromSortType(this.state.sortby)}</span>
 | 
				
			||||||
                            <FontAwesomeIcon style={{marginLeft: 3, paddingBottom: 3}} icon={faSortDown} size='1x' />
 | 
					                            <FontAwesomeIcon style={{marginLeft: 3, paddingBottom: 3}} icon={faSortDown} size='1x' />
 | 
				
			||||||
                        </span>
 | 
					                        </span>
 | 
				
			||||||
                        <div className={style.dropdownContent}>
 | 
					                        <div className={style.dropdownContent}>
 | 
				
			||||||
                            <span onClick={(): void => this.onDropDownItemClick(SortBy.date, 'Date Added')}>Date Added</span>
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.date)}>
 | 
				
			||||||
                            <span onClick={(): void => this.onDropDownItemClick(SortBy.likes, 'Most likes')}>Most likes</span>
 | 
					                                {this.getLabelFromSortType(SortBy.date)}
 | 
				
			||||||
                            <span onClick={(): void => this.onDropDownItemClick(SortBy.random, 'Random')}>Random</span>
 | 
					                            </span>
 | 
				
			||||||
                            <span onClick={(): void => this.onDropDownItemClick(SortBy.name, 'Name')}>Name</span>
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.likes)}>
 | 
				
			||||||
                            <span onClick={(): void => this.onDropDownItemClick(SortBy.length, 'Length')}>Length</span>
 | 
					                                {this.getLabelFromSortType(SortBy.likes)}
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.random)}>
 | 
				
			||||||
 | 
					                                {this.getLabelFromSortType(SortBy.random)}
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.name)}>
 | 
				
			||||||
 | 
					                                {this.getLabelFromSortType(SortBy.name)}
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.length)}>
 | 
				
			||||||
 | 
					                                {this.getLabelFromSortType(SortBy.length)}
 | 
				
			||||||
 | 
					                            </span>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
@@ -214,10 +247,12 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
     * @param type type of sort action
 | 
					     * @param type type of sort action
 | 
				
			||||||
     * @param name new header title
 | 
					     * @param name new header title
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    onDropDownItemClick(type: SortBy, name: string): void {
 | 
					    onDropDownItemClick(type: SortBy): void {
 | 
				
			||||||
        this.sortState = type;
 | 
					        this.setState({sortby: type}, (): void => {
 | 
				
			||||||
        this.setState({sortby: name});
 | 
					            global.localStorage.setItem('sortby', type.toString());
 | 
				
			||||||
        this.fetchVideoData();
 | 
					
 | 
				
			||||||
 | 
					            this.fetchVideoData();
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,9 +25,18 @@ interface GetRandomMoviesType {
 | 
				
			|||||||
class RandomPage extends React.Component<{}, state> {
 | 
					class RandomPage extends React.Component<{}, state> {
 | 
				
			||||||
    readonly LoadNR = 3;
 | 
					    readonly LoadNR = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // random seed to load videos, remains page reload.
 | 
				
			||||||
 | 
					    seed = this.genRandInt();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    constructor(props: {}) {
 | 
					    constructor(props: {}) {
 | 
				
			||||||
        super(props);
 | 
					        super(props);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // get previously stored location from localstorage
 | 
				
			||||||
 | 
					        const storedseed = global.localStorage.getItem('randpageseed');
 | 
				
			||||||
 | 
					        if (storedseed != null) {
 | 
				
			||||||
 | 
					            this.seed = parseInt(storedseed, 10);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.state = {
 | 
					        this.state = {
 | 
				
			||||||
            videos: [],
 | 
					            videos: [],
 | 
				
			||||||
            tags: []
 | 
					            tags: []
 | 
				
			||||||
@@ -36,6 +45,10 @@ class RandomPage extends React.Component<{}, state> {
 | 
				
			|||||||
        this.keypress = this.keypress.bind(this);
 | 
					        this.keypress = this.keypress.bind(this);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    genRandInt(): number {
 | 
				
			||||||
 | 
					        return Math.floor(Math.random() * 2147483647) + 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentDidMount(): void {
 | 
					    componentDidMount(): void {
 | 
				
			||||||
        addKeyHandler(this.keypress);
 | 
					        addKeyHandler(this.keypress);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -77,15 +90,21 @@ class RandomPage extends React.Component<{}, state> {
 | 
				
			|||||||
     * click handler for shuffle btn
 | 
					     * click handler for shuffle btn
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    shuffleclick(): void {
 | 
					    shuffleclick(): void {
 | 
				
			||||||
 | 
					        this.genSeed();
 | 
				
			||||||
        this.loadShuffledvideos(this.LoadNR);
 | 
					        this.loadShuffledvideos(this.LoadNR);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    genSeed(): void {
 | 
				
			||||||
 | 
					        this.seed = this.genRandInt();
 | 
				
			||||||
 | 
					        global.localStorage.setItem('randpageseed', this.seed.toString());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * 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>(APINode.Video, {action: 'getRandomMovies', Number: nr, Seed: this.seed}, (result) => {
 | 
				
			||||||
            this.setState({videos: []}); // needed to trigger rerender of main videoview
 | 
					            this.setState({videos: []}); // needed to trigger rerender of main videoview
 | 
				
			||||||
            this.setState({
 | 
					            this.setState({
 | 
				
			||||||
                videos: result.Videos,
 | 
					                videos: result.Videos,
 | 
				
			||||||
@@ -101,7 +120,8 @@ class RandomPage extends React.Component<{}, state> {
 | 
				
			|||||||
    private keypress(event: KeyboardEvent): void {
 | 
					    private keypress(event: KeyboardEvent): void {
 | 
				
			||||||
        // bind s to shuffle
 | 
					        // bind s to shuffle
 | 
				
			||||||
        if (event.key === 's') {
 | 
					        if (event.key === 's') {
 | 
				
			||||||
            this.loadShuffledvideos(4);
 | 
					            this.genSeed();
 | 
				
			||||||
 | 
					            this.loadShuffledvideos(this.LoadNR);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -103,5 +103,5 @@ export enum APINode {
 | 
				
			|||||||
    Tags = 'tags',
 | 
					    Tags = 'tags',
 | 
				
			||||||
    Actor = 'actor',
 | 
					    Actor = 'actor',
 | 
				
			||||||
    Video = 'video',
 | 
					    Video = 'video',
 | 
				
			||||||
    TVShow = 'tvshow'
 | 
					    TVShow = 'tv'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user