Compare commits
	
		
			6 Commits
		
	
	
		
			rememberLo
			...
			settings_r
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7cd9cd7d89 | |||
| 11c1e25de5 | |||
| 3d845aaf04 | |||
| 7f98528fbe | |||
| 191fa5386d | |||
| 9715012685 | 
@@ -108,18 +108,13 @@ Debian_Server:
 | 
				
			|||||||
      - Minimize_Frontend
 | 
					      - Minimize_Frontend
 | 
				
			||||||
      - Build_Backend
 | 
					      - Build_Backend
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Test_Server:
 | 
					.Test_Server_Common:
 | 
				
			||||||
  stage: deploy
 | 
					  stage: deploy
 | 
				
			||||||
  image: luki42/ssh:latest
 | 
					  image: luki42/ssh:latest
 | 
				
			||||||
  needs:
 | 
					  needs:
 | 
				
			||||||
    - Frontend_Tests
 | 
					    - Frontend_Tests
 | 
				
			||||||
    - Backend_Tests
 | 
					    - Backend_Tests
 | 
				
			||||||
    - Debian_Server
 | 
					    - Debian_Server
 | 
				
			||||||
  rules:
 | 
					 | 
				
			||||||
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH # run this always on default branch
 | 
					 | 
				
			||||||
    - if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH # allow triggering this manually
 | 
					 | 
				
			||||||
      when: manual
 | 
					 | 
				
			||||||
      allow_failure: true
 | 
					 | 
				
			||||||
  script:
 | 
					  script:
 | 
				
			||||||
    - eval $(ssh-agent -s)
 | 
					    - eval $(ssh-agent -s)
 | 
				
			||||||
    - echo "$SSH_PRIVATE_KEY" | ssh-add -
 | 
					    - echo "$SSH_PRIVATE_KEY" | ssh-add -
 | 
				
			||||||
@@ -129,18 +124,23 @@ Test_Server:
 | 
				
			|||||||
    - ssh root@192.168.0.42 "DEBIAN_FRONTEND=noninteractive apt-get --reinstall  -y -qq install /tmp/OpenMediaCenter-*.deb && rm /tmp/OpenMediaCenter-*.deb"
 | 
					    - ssh root@192.168.0.42 "DEBIAN_FRONTEND=noninteractive apt-get --reinstall  -y -qq install /tmp/OpenMediaCenter-*.deb && rm /tmp/OpenMediaCenter-*.deb"
 | 
				
			||||||
  allow_failure: true
 | 
					  allow_failure: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Test_Server_2:
 | 
					Test_Server_CD:
 | 
				
			||||||
 | 
					  extends: .Test_Server_Common
 | 
				
			||||||
 | 
					  only:
 | 
				
			||||||
 | 
					    refs:
 | 
				
			||||||
 | 
					      - master
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_Server_MANUAL:
 | 
				
			||||||
 | 
					  extends: .Test_Server_Common
 | 
				
			||||||
 | 
					  when: manual
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.Test_Server_2_Common:
 | 
				
			||||||
  stage: deploy
 | 
					  stage: deploy
 | 
				
			||||||
  image: luki42/ssh:latest
 | 
					  image: luki42/ssh:latest
 | 
				
			||||||
  needs:
 | 
					  needs:
 | 
				
			||||||
    - Frontend_Tests
 | 
					    - Frontend_Tests
 | 
				
			||||||
    - Backend_Tests
 | 
					    - Backend_Tests
 | 
				
			||||||
    - Debian_Server
 | 
					    - Debian_Server
 | 
				
			||||||
  rules:
 | 
					 | 
				
			||||||
    - if: $CI_COMMIT_REF_NAME == $CI_DEFAULT_BRANCH # run this always on default branch
 | 
					 | 
				
			||||||
    - if: $CI_COMMIT_REF_NAME != $CI_DEFAULT_BRANCH # allow triggering this manually
 | 
					 | 
				
			||||||
      when: manual
 | 
					 | 
				
			||||||
      allow_failure: true
 | 
					 | 
				
			||||||
  script:
 | 
					  script:
 | 
				
			||||||
    - eval $(ssh-agent -s)
 | 
					    - eval $(ssh-agent -s)
 | 
				
			||||||
    - echo "$SSH_PRIVATE_KEY_2" | ssh-add -
 | 
					    - echo "$SSH_PRIVATE_KEY_2" | ssh-add -
 | 
				
			||||||
@@ -150,3 +150,12 @@ Test_Server_2:
 | 
				
			|||||||
    - ssh root@192.168.0.209 "DEBIAN_FRONTEND=noninteractive apt-get --reinstall  -y -qq install /tmp/OpenMediaCenter-*.deb && rm /tmp/OpenMediaCenter-*.deb"
 | 
					    - ssh root@192.168.0.209 "DEBIAN_FRONTEND=noninteractive apt-get --reinstall  -y -qq install /tmp/OpenMediaCenter-*.deb && rm /tmp/OpenMediaCenter-*.deb"
 | 
				
			||||||
  allow_failure: true
 | 
					  allow_failure: true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_Server_2_CD:
 | 
				
			||||||
 | 
					  extends: .Test_Server_2_Common
 | 
				
			||||||
 | 
					  only:
 | 
				
			||||||
 | 
					    refs:
 | 
				
			||||||
 | 
					      - master
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Test_Server_2_MANUAL:
 | 
				
			||||||
 | 
					  extends: .Test_Server_2_Common
 | 
				
			||||||
 | 
					  when: manual
 | 
				
			||||||
@@ -74,6 +74,7 @@ func getSettingsFromDB() {
 | 
				
			|||||||
			TVShowPath        string
 | 
								TVShowPath        string
 | 
				
			||||||
			TVShowEnabled     bool
 | 
								TVShowEnabled     bool
 | 
				
			||||||
			FullDeleteEnabled bool
 | 
								FullDeleteEnabled bool
 | 
				
			||||||
 | 
								RandomNR          uint32
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		regexMatchUrl := regexp.MustCompile("^http(|s)://([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}:[0-9]{1,5}")
 | 
							regexMatchUrl := regexp.MustCompile("^http(|s)://([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}\\.([0-9]){1,3}:[0-9]{1,5}")
 | 
				
			||||||
@@ -90,6 +91,7 @@ func getSettingsFromDB() {
 | 
				
			|||||||
			TVShowPath:        serverTVShowPath,
 | 
								TVShowPath:        serverTVShowPath,
 | 
				
			||||||
			TVShowEnabled:     !config.GetConfig().Features.DisableTVSupport,
 | 
								TVShowEnabled:     !config.GetConfig().Features.DisableTVSupport,
 | 
				
			||||||
			FullDeleteEnabled: config.GetConfig().Features.FullyDeletableVideos,
 | 
								FullDeleteEnabled: config.GetConfig().Features.FullyDeletableVideos,
 | 
				
			||||||
 | 
								RandomNR:          sett.RandomNR,
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		context.Json(res)
 | 
							context.Json(res)
 | 
				
			||||||
@@ -127,12 +129,13 @@ func saveSettingsToDB() {
 | 
				
			|||||||
                        password=?,
 | 
					                        password=?,
 | 
				
			||||||
                        mediacenter_name=?,
 | 
					                        mediacenter_name=?,
 | 
				
			||||||
                        TMDB_grabbing=?, 
 | 
					                        TMDB_grabbing=?, 
 | 
				
			||||||
                        DarkMode=?
 | 
					                        DarkMode=?,
 | 
				
			||||||
 | 
											random_nr=?
 | 
				
			||||||
                    WHERE 1`
 | 
					                    WHERE 1`
 | 
				
			||||||
		// todo avoid conversion
 | 
							// todo avoid conversion
 | 
				
			||||||
		context.Text(string(database.SuccessQuery(query,
 | 
							context.Text(string(database.SuccessQuery(query,
 | 
				
			||||||
			args.VideoPath, args.EpisodePath, args.Password,
 | 
								args.VideoPath, args.EpisodePath, args.Password,
 | 
				
			||||||
			args.MediacenterName, args.TMDBGrabbing, args.DarkMode)))
 | 
								args.MediacenterName, args.TMDBGrabbing, args.DarkMode, args.RandomNR)))
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,8 +1,8 @@
 | 
				
			|||||||
package api
 | 
					package api
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"math/rand"
 | 
					 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"openmediacenter/apiGo/api/api"
 | 
						"openmediacenter/apiGo/api/api"
 | 
				
			||||||
	"openmediacenter/apiGo/api/types"
 | 
						"openmediacenter/apiGo/api/types"
 | 
				
			||||||
@@ -10,6 +10,7 @@ import (
 | 
				
			|||||||
	"openmediacenter/apiGo/database"
 | 
						"openmediacenter/apiGo/database"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strconv"
 | 
						"strconv"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func addVideoHandlers() {
 | 
					func addVideoHandlers() {
 | 
				
			||||||
@@ -164,27 +165,35 @@ 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
 | 
								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")
 | 
				
			||||||
			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(%d) LIMIT %d", *args.Seed, args.Number)
 | 
							whereclause := "WHERE 1"
 | 
				
			||||||
 | 
							if len(args.TagFilter) > 0 {
 | 
				
			||||||
 | 
								d, _ := json.Marshal(args.TagFilter)
 | 
				
			||||||
 | 
								vals := strings.Trim(string(d), "[]")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								whereclause = fmt.Sprintf("WHERE tag_id IN (%s)", vals)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							query := fmt.Sprintf(`
 | 
				
			||||||
 | 
					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))
 | 
							result.Videos = readVideosFromResultset(database.Query(query))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if len(result.Videos) > 0 {
 | 
				
			||||||
			var ids string
 | 
								var ids string
 | 
				
			||||||
			for i := range result.Videos {
 | 
								for i := range result.Videos {
 | 
				
			||||||
				ids += "video_tags.video_id=" + strconv.Itoa(result.Videos[i].MovieId)
 | 
									ids += "video_tags.video_id=" + strconv.Itoa(result.Videos[i].MovieId)
 | 
				
			||||||
@@ -201,7 +210,7 @@ func getVideoHandlers() {
 | 
				
			|||||||
									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)
 | 
				
			||||||
@@ -211,6 +220,10 @@ func getVideoHandlers() {
 | 
				
			|||||||
					// append to final array
 | 
										// append to final array
 | 
				
			||||||
					result.Tags = append(result.Tags, tag)
 | 
										result.Tags = append(result.Tags, tag)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								result.Tags = []types.Tag{}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		context.Json(result)
 | 
							context.Json(result)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,6 +48,7 @@ type SettingsType struct {
 | 
				
			|||||||
	PasswordEnabled bool
 | 
						PasswordEnabled bool
 | 
				
			||||||
	TMDBGrabbing    bool
 | 
						TMDBGrabbing    bool
 | 
				
			||||||
	DarkMode        bool
 | 
						DarkMode        bool
 | 
				
			||||||
 | 
						RandomNR        uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type SettingsSizeType struct {
 | 
					type SettingsSizeType struct {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -126,7 +126,7 @@ func GetSettings() (result types.SettingsType, PathPrefix string, sizes types.Se
 | 
				
			|||||||
                           SELECT COUNT(*)
 | 
					                           SELECT COUNT(*)
 | 
				
			||||||
                           FROM video_tags
 | 
					                           FROM video_tags
 | 
				
			||||||
                       ) AS tagsadded,
 | 
					                       ) AS tagsadded,
 | 
				
			||||||
                       video_path, episode_path, password, mediacenter_name, TMDB_grabbing, DarkMode
 | 
					                       video_path, episode_path, password, mediacenter_name, TMDB_grabbing, DarkMode, random_nr
 | 
				
			||||||
                FROM settings
 | 
					                FROM settings
 | 
				
			||||||
                LIMIT 1`, DBName)
 | 
					                LIMIT 1`, DBName)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -134,7 +134,7 @@ func GetSettings() (result types.SettingsType, PathPrefix string, sizes types.Se
 | 
				
			|||||||
	var TMDBGrabbing int
 | 
						var TMDBGrabbing int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := QueryRow(query).Scan(&sizes.VideoNr, &sizes.DBSize, &sizes.DifferentTags, &sizes.TagsAdded,
 | 
						err := QueryRow(query).Scan(&sizes.VideoNr, &sizes.DBSize, &sizes.DifferentTags, &sizes.TagsAdded,
 | 
				
			||||||
		&result.VideoPath, &result.EpisodePath, &result.Password, &result.MediacenterName, &TMDBGrabbing, &DarkMode)
 | 
							&result.VideoPath, &result.EpisodePath, &result.Password, &result.MediacenterName, &TMDBGrabbing, &DarkMode, &result.RandomNR)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println(err.Error())
 | 
							fmt.Println(err.Error())
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										11
									
								
								apiGo/database/migrations/20220505195845_randomnr.sql
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								apiGo/database/migrations/20220505195845_randomnr.sql
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,11 @@
 | 
				
			|||||||
 | 
					-- +goose Up
 | 
				
			||||||
 | 
					-- +goose StatementBegin
 | 
				
			||||||
 | 
					alter table settings
 | 
				
			||||||
 | 
					    add random_nr int default  3 null;
 | 
				
			||||||
 | 
					-- +goose StatementEnd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					-- +goose Down
 | 
				
			||||||
 | 
					-- +goose StatementBegin
 | 
				
			||||||
 | 
					alter table settings
 | 
				
			||||||
 | 
					    drop random_nr;
 | 
				
			||||||
 | 
					-- +goose StatementEnd
 | 
				
			||||||
@@ -20,15 +20,16 @@ type SettingsType struct {
 | 
				
			|||||||
	MediacenterName string
 | 
						MediacenterName string
 | 
				
			||||||
	VideoPath       string
 | 
						VideoPath       string
 | 
				
			||||||
	TVShowPath      string
 | 
						TVShowPath      string
 | 
				
			||||||
 | 
						RandomNR        uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func LoadSettings() *SettingsType {
 | 
					func LoadSettings() *SettingsType {
 | 
				
			||||||
	query := "SELECT DarkMode, password, mediacenter_name, video_path, episode_path from settings"
 | 
						query := "SELECT DarkMode, password, mediacenter_name, video_path, episode_path, random_nr from settings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	result := SettingsType{}
 | 
						result := SettingsType{}
 | 
				
			||||||
	var darkmode uint8
 | 
						var darkmode uint8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := database.QueryRow(query).Scan(&darkmode, &result.Pasword, &result.MediacenterName, &result.VideoPath, &result.TVShowPath)
 | 
						err := database.QueryRow(query).Scan(&darkmode, &result.Pasword, &result.MediacenterName, &result.VideoPath, &result.TVShowPath, &result.RandomNR)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println("error while parsing db data: " + err.Error())
 | 
							fmt.Println("error while parsing db data: " + err.Error())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -90,12 +90,14 @@ describe('<HomePage/>', function () {
 | 
				
			|||||||
        const wrapper = shallow(<HomePage/>);
 | 
					        const wrapper = shallow(<HomePage/>);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // expect those default values
 | 
					        // expect those default values
 | 
				
			||||||
        expect(wrapper.state().sortby).toBe(0);
 | 
					        expect(wrapper.state().sortby).toBe('Date Added');
 | 
				
			||||||
 | 
					        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);
 | 
					        wrapper.instance().onDropDownItemClick(SortBy.name, 'namesort');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        expect(wrapper.state().sortby).toBe(SortBy.name);
 | 
					        expect(wrapper.state().sortby).toBe('namesort');
 | 
				
			||||||
 | 
					        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: SortBy;
 | 
					    sortby: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
@@ -39,33 +39,9 @@ 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,
 | 
				
			||||||
@@ -78,10 +54,11 @@ export class HomePage extends React.Component<Props, state> {
 | 
				
			|||||||
            subtitle: 'All Videos',
 | 
					            subtitle: 'All Videos',
 | 
				
			||||||
            data: [],
 | 
					            data: [],
 | 
				
			||||||
            selectionnr: 0,
 | 
					            selectionnr: 0,
 | 
				
			||||||
            sortby: storedSelection == null ? SortBy.date : parseInt(storedSelection, 10)
 | 
					            sortby: 'Date Added'
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sortState = SortBy.date;
 | 
				
			||||||
    tagState = DefaultTags.all;
 | 
					    tagState = DefaultTags.all;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentDidMount(): void {
 | 
					    componentDidMount(): void {
 | 
				
			||||||
@@ -110,7 +87,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.state.sortby},
 | 
					            {action: 'getMovies', Tag: this.tagState.TagId, Sort: this.sortState},
 | 
				
			||||||
            (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => {
 | 
					            (result: {Videos: VideoTypes.VideoUnloadedType[]; TagName: string}) => {
 | 
				
			||||||
                this.setState({
 | 
					                this.setState({
 | 
				
			||||||
                    data: result.Videos,
 | 
					                    data: result.Videos,
 | 
				
			||||||
@@ -213,25 +190,15 @@ 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.getLabelFromSortType(this.state.sortby)}</span>
 | 
					                            <span>{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)}>
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.date, 'Date Added')}>Date Added</span>
 | 
				
			||||||
                                {this.getLabelFromSortType(SortBy.date)}
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.likes, 'Most likes')}>Most likes</span>
 | 
				
			||||||
                            </span>
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.random, 'Random')}>Random</span>
 | 
				
			||||||
                            <span onClick={(): void => this.onDropDownItemClick(SortBy.likes)}>
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.name, 'Name')}>Name</span>
 | 
				
			||||||
                                {this.getLabelFromSortType(SortBy.likes)}
 | 
					                            <span onClick={(): void => this.onDropDownItemClick(SortBy.length, 'Length')}>Length</span>
 | 
				
			||||||
                            </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>
 | 
				
			||||||
@@ -247,12 +214,10 @@ 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): void {
 | 
					    onDropDownItemClick(type: SortBy, name: string): void {
 | 
				
			||||||
        this.setState({sortby: type}, (): void => {
 | 
					        this.sortState = type;
 | 
				
			||||||
            global.localStorage.setItem('sortby', type.toString());
 | 
					        this.setState({sortby: name});
 | 
				
			||||||
 | 
					 | 
				
			||||||
        this.fetchVideoData();
 | 
					        this.fetchVideoData();
 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,16 +2,22 @@ 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';
 | 
				
			||||||
 | 
					import GlobalInfos from '../../utils/GlobalInfos';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface state {
 | 
					interface state {
 | 
				
			||||||
    videos: VideoTypes.VideoUnloadedType[];
 | 
					    videos: VideoTypes.VideoUnloadedType[];
 | 
				
			||||||
    tags: TagType[];
 | 
					    tags: TagType[];
 | 
				
			||||||
 | 
					    filterTags: TagType[];
 | 
				
			||||||
 | 
					    addTagPopup: boolean;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
interface GetRandomMoviesType {
 | 
					interface GetRandomMoviesType {
 | 
				
			||||||
@@ -23,36 +29,23 @@ interface GetRandomMoviesType {
 | 
				
			|||||||
 * Randompage shuffles random viedeopreviews and provides a shuffle btn
 | 
					 * Randompage shuffles random viedeopreviews and provides a shuffle btn
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
class RandomPage extends React.Component<{}, state> {
 | 
					class RandomPage extends React.Component<{}, state> {
 | 
				
			||||||
    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 = {
 | 
				
			||||||
 | 
					            addTagPopup: false,
 | 
				
			||||||
            videos: [],
 | 
					            videos: [],
 | 
				
			||||||
            tags: []
 | 
					            tags: [],
 | 
				
			||||||
 | 
					            filterTags: []
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        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);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        this.loadShuffledvideos(this.LoadNR);
 | 
					        this.loadShuffledvideos();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    componentWillUnmount(): void {
 | 
					    componentWillUnmount(): void {
 | 
				
			||||||
@@ -62,55 +55,66 @@ class RandomPage extends React.Component<{}, state> {
 | 
				
			|||||||
    render(): JSX.Element {
 | 
					    render(): JSX.Element {
 | 
				
			||||||
        return (
 | 
					        return (
 | 
				
			||||||
            <div>
 | 
					            <div>
 | 
				
			||||||
                <PageTitle title='Random Videos' subtitle='4pc' />
 | 
					                <PageTitle title='Random Videos' subtitle={GlobalInfos.getRandomNR() + 'pc'} />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                <SideBar>
 | 
					                <SideBar>
 | 
				
			||||||
                    <SideBarTitle>Visible Tags:</SideBarTitle>
 | 
					                    <SideBarTitle>Visible Tags:</SideBarTitle>
 | 
				
			||||||
                    {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.shuffleclick()} className={style.btnshuffle}>
 | 
					                    <button onClick={(): void => this.loadShuffledvideos()} className={style.btnshuffle}>
 | 
				
			||||||
                        Shuffle
 | 
					                        Shuffle
 | 
				
			||||||
                    </button>
 | 
					                    </button>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                    </VideoContainer>
 | 
					                {this.state.addTagPopup ? (
 | 
				
			||||||
                ) : (
 | 
					                    <AddTagPopup
 | 
				
			||||||
                    <div>No Data found!</div>
 | 
					                        onHide={(): void => this.setState({addTagPopup: false})}
 | 
				
			||||||
                )}
 | 
					                        submit={(tagId: number, tagName: string): void => {
 | 
				
			||||||
 | 
					                            this.setState({filterTags: [...this.state.filterTags, {TagId: tagId, TagName: tagName}]}, (): void => {
 | 
				
			||||||
 | 
					                                this.loadShuffledvideos();
 | 
				
			||||||
 | 
					                            });
 | 
				
			||||||
 | 
					                        }}
 | 
				
			||||||
 | 
					                    />
 | 
				
			||||||
 | 
					                ) : null}
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        );
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					 | 
				
			||||||
     * click handler for shuffle btn
 | 
					 | 
				
			||||||
     */
 | 
					 | 
				
			||||||
    shuffleclick(): void {
 | 
					 | 
				
			||||||
        this.genSeed();
 | 
					 | 
				
			||||||
        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
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    loadShuffledvideos(nr: number): void {
 | 
					    loadShuffledvideos(): void {
 | 
				
			||||||
        callAPI<GetRandomMoviesType>(APINode.Video, {action: 'getRandomMovies', Number: nr, Seed: this.seed}, (result) => {
 | 
					        callAPI<GetRandomMoviesType>(
 | 
				
			||||||
 | 
					            APINode.Video,
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                action: 'getRandomMovies',
 | 
				
			||||||
 | 
					                Number: GlobalInfos.getRandomNR(),
 | 
				
			||||||
 | 
					                TagFilter: this.state.filterTags.map((t) => t.TagId)
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					            (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,
 | 
				
			||||||
                    tags: result.Tags
 | 
					                    tags: result.Tags
 | 
				
			||||||
                });
 | 
					                });
 | 
				
			||||||
        });
 | 
					            }
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
@@ -120,8 +124,7 @@ 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.genSeed();
 | 
					            this.loadShuffledvideos();
 | 
				
			||||||
            this.loadShuffledvideos(this.LoadNR);
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,7 +33,8 @@ class GeneralSettings extends React.Component<Props, state> {
 | 
				
			|||||||
                Password: '',
 | 
					                Password: '',
 | 
				
			||||||
                PasswordEnabled: false,
 | 
					                PasswordEnabled: false,
 | 
				
			||||||
                TMDBGrabbing: false,
 | 
					                TMDBGrabbing: false,
 | 
				
			||||||
                VideoPath: ''
 | 
					                VideoPath: '',
 | 
				
			||||||
 | 
					                RandomNR: 3
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
            sizes: {
 | 
					            sizes: {
 | 
				
			||||||
                DBSize: 0,
 | 
					                DBSize: 0,
 | 
				
			||||||
@@ -199,6 +200,23 @@ class GeneralSettings extends React.Component<Props, state> {
 | 
				
			|||||||
                            />
 | 
					                            />
 | 
				
			||||||
                        </Form.Group>
 | 
					                        </Form.Group>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <Form.Group className={style.mediacenternameform} data-testid='randnrform'>
 | 
				
			||||||
 | 
					                            <Form.Label>Number of random videos on Random page</Form.Label>
 | 
				
			||||||
 | 
					                            <Form.Control
 | 
				
			||||||
 | 
					                                type='number'
 | 
				
			||||||
 | 
					                                placeholder='2'
 | 
				
			||||||
 | 
					                                value={this.state.generalSettings.RandomNR}
 | 
				
			||||||
 | 
					                                onChange={(e): void =>
 | 
				
			||||||
 | 
					                                    this.setState({
 | 
				
			||||||
 | 
					                                        generalSettings: {
 | 
				
			||||||
 | 
					                                            ...this.state.generalSettings,
 | 
				
			||||||
 | 
					                                            RandomNR: parseInt(e.target.value, 10)
 | 
				
			||||||
 | 
					                                        }
 | 
				
			||||||
 | 
					                                    })
 | 
				
			||||||
 | 
					                                }
 | 
				
			||||||
 | 
					                            />
 | 
				
			||||||
 | 
					                        </Form.Group>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                        <Button variant='primary' type='submit'>
 | 
					                        <Button variant='primary' type='submit'>
 | 
				
			||||||
                            Submit
 | 
					                            Submit
 | 
				
			||||||
                        </Button>
 | 
					                        </Button>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,6 +40,7 @@ export namespace SettingsTypes {
 | 
				
			|||||||
        TVShowPath: string;
 | 
					        TVShowPath: string;
 | 
				
			||||||
        TVShowEnabled: boolean;
 | 
					        TVShowEnabled: boolean;
 | 
				
			||||||
        FullDeleteEnabled: boolean;
 | 
					        FullDeleteEnabled: boolean;
 | 
				
			||||||
 | 
					        RandomNR: number;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    export interface SettingsType {
 | 
					    export interface SettingsType {
 | 
				
			||||||
@@ -50,6 +51,7 @@ export namespace SettingsTypes {
 | 
				
			|||||||
        PasswordEnabled: boolean;
 | 
					        PasswordEnabled: boolean;
 | 
				
			||||||
        TMDBGrabbing: boolean;
 | 
					        TMDBGrabbing: boolean;
 | 
				
			||||||
        DarkMode: boolean;
 | 
					        DarkMode: boolean;
 | 
				
			||||||
 | 
					        RandomNR: number;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    export interface SizesType {
 | 
					    export interface SizesType {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,6 +11,7 @@ class StaticInfos {
 | 
				
			|||||||
    private tvshowpath: string = '';
 | 
					    private tvshowpath: string = '';
 | 
				
			||||||
    private TVShowsEnabled: boolean = false;
 | 
					    private TVShowsEnabled: boolean = false;
 | 
				
			||||||
    private fullDeleteable: boolean = false;
 | 
					    private fullDeleteable: boolean = false;
 | 
				
			||||||
 | 
					    private RandomNR: number = 3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /**
 | 
					    /**
 | 
				
			||||||
     * check if the current theme is the dark theme
 | 
					     * check if the current theme is the dark theme
 | 
				
			||||||
@@ -44,6 +45,7 @@ class StaticInfos {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    handlers: (() => void)[] = [];
 | 
					    handlers: (() => void)[] = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    onThemeChange(func: () => void): void {
 | 
					    onThemeChange(func: () => void): void {
 | 
				
			||||||
        this.handlers.push(func);
 | 
					        this.handlers.push(func);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@@ -71,6 +73,14 @@ class StaticInfos {
 | 
				
			|||||||
    getTVShowPath(): string {
 | 
					    getTVShowPath(): string {
 | 
				
			||||||
        return this.tvshowpath;
 | 
					        return this.tvshowpath;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    setRandomNR(nr: number): void {
 | 
				
			||||||
 | 
					        this.RandomNR = nr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    getRandomNR(): number {
 | 
				
			||||||
 | 
					        return this.RandomNR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export default new StaticInfos();
 | 
					export default new StaticInfos();
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,6 +32,7 @@ export const LoginContextProvider: FunctionComponent = (props): JSX.Element => {
 | 
				
			|||||||
                GlobalInfos.enableDarkTheme(result.DarkMode);
 | 
					                GlobalInfos.enableDarkTheme(result.DarkMode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                GlobalInfos.setVideoPaths(result.VideoPath, result.TVShowPath);
 | 
					                GlobalInfos.setVideoPaths(result.VideoPath, result.TVShowPath);
 | 
				
			||||||
 | 
					                GlobalInfos.setRandomNR(result.RandomNR);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                features.setTVShowEnabled(result.TVShowEnabled);
 | 
					                features.setTVShowEnabled(result.TVShowEnabled);
 | 
				
			||||||
                features.setVideosFullyDeleteable(result.FullDeleteEnabled);
 | 
					                features.setVideosFullyDeleteable(result.FullDeleteEnabled);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3538,9 +3538,9 @@ caniuse-api@^3.0.0:
 | 
				
			|||||||
    lodash.uniq "^4.5.0"
 | 
					    lodash.uniq "^4.5.0"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001219:
 | 
					caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30001109, caniuse-lite@^1.0.30001125, caniuse-lite@^1.0.30001219:
 | 
				
			||||||
  version "1.0.30001236"
 | 
					  version "1.0.30001336"
 | 
				
			||||||
  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001236.tgz#0a80de4cdf62e1770bb46a30d884fc8d633e3958"
 | 
					  resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001336.tgz"
 | 
				
			||||||
  integrity sha512-o0PRQSrSCGJKCPZcgMzl5fUaj5xHe8qA2m4QRvnyY4e1lITqoNkr7q/Oh1NcpGSy0Th97UZ35yoKcINPoq7YOQ==
 | 
					  integrity sha512-/YxSlBmL7iKXTbIJ48IQTnAOBk7XmWsxhBF1PZLOko5Dt9qc4Pl+84lfqG3Tc4EuavurRn1QLoVJGxY2iSycfw==
 | 
				
			||||||
 | 
					
 | 
				
			||||||
capture-exit@^2.0.0:
 | 
					capture-exit@^2.0.0:
 | 
				
			||||||
  version "2.0.0"
 | 
					  version "2.0.0"
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user