@@ -1,47 +0,0 @@
 | 
				
			|||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html lang="en" dir="ltr">
 | 
					 | 
				
			||||||
<head>
 | 
					 | 
				
			||||||
    <meta charset="utf-8">
 | 
					 | 
				
			||||||
    <title>hub</title>
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="css/plyr.css"/>
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="css/index.css">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Latest compiled and minified CSS -->
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- jQuery library -->
 | 
					 | 
				
			||||||
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Popper JS -->
 | 
					 | 
				
			||||||
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Latest compiled JavaScript -->
 | 
					 | 
				
			||||||
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script src="js/plyr.js"></script>
 | 
					 | 
				
			||||||
    <script src="js/index.js"></script>
 | 
					 | 
				
			||||||
</head>
 | 
					 | 
				
			||||||
<body>
 | 
					 | 
				
			||||||
<!-- Grey with black text -->
 | 
					 | 
				
			||||||
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
 | 
					 | 
				
			||||||
    <!-- Brand -->
 | 
					 | 
				
			||||||
    <a class="navbar-brand" href="#">Lukis Tube</a>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ul class="navbar-nav">
 | 
					 | 
				
			||||||
        <li class="nav-item ">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="index.html">Home</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li class="nav-item">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="random.html">Random Video</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li class="nav-item active">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="category.html">Categories</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
</nav>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										86
									
								
								index.html
									
									
									
									
									
								
							
							
						
						
									
										86
									
								
								index.html
									
									
									
									
									
								
							@@ -1,86 +0,0 @@
 | 
				
			|||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html lang="en" dir="ltr">
 | 
					 | 
				
			||||||
<head>
 | 
					 | 
				
			||||||
    <meta charset="utf-8">
 | 
					 | 
				
			||||||
    <title>hub</title>
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="css/plyr.css"/>
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="css/index.css">
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="css/video.css">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Latest compiled and minified CSS -->
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- jQuery library -->
 | 
					 | 
				
			||||||
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Popper JS -->
 | 
					 | 
				
			||||||
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Latest compiled JavaScript -->
 | 
					 | 
				
			||||||
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script src="js/plyr.js"></script>
 | 
					 | 
				
			||||||
    <script src="js/index.js"></script>
 | 
					 | 
				
			||||||
</head>
 | 
					 | 
				
			||||||
<body>
 | 
					 | 
				
			||||||
<!-- Grey with black text -->
 | 
					 | 
				
			||||||
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
 | 
					 | 
				
			||||||
    <!-- Brand -->
 | 
					 | 
				
			||||||
    <a class="navbar-brand" href="#">Lukis Tube</a>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ul class="navbar-nav">
 | 
					 | 
				
			||||||
        <li class="nav-item active">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="index.html">Home</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li class="nav-item">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="random.html">Random Video</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li class="nav-item">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="category.html">Categories</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
</nav>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="videopagewrapper hideit">
 | 
					 | 
				
			||||||
    <div class="row">
 | 
					 | 
				
			||||||
        <div class="col-sm-2">
 | 
					 | 
				
			||||||
            <div class="videoleftbanner">
 | 
					 | 
				
			||||||
                <div class="likefield">Likes: 10</div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="col-sm-8">
 | 
					 | 
				
			||||||
            <div class="videowrapper"></div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="col-sm-2">
 | 
					 | 
				
			||||||
            <div class="closebutton">Close</div>
 | 
					 | 
				
			||||||
            <div class="videorightbanner"></div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <div class="row">
 | 
					 | 
				
			||||||
        <div class="col-sm-5">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="col-sm-2">
 | 
					 | 
				
			||||||
            <button id="likebtn">Like it!</button>
 | 
					 | 
				
			||||||
            <button id="tagbutton">Tag it!</button>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="col-sm-5">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="previewcontainer">
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
							
								
								
									
										130
									
								
								js/index.js
									
									
									
									
									
								
							
							
						
						
									
										130
									
								
								js/index.js
									
									
									
									
									
								
							@@ -1,130 +0,0 @@
 | 
				
			|||||||
let videos;
 | 
					 | 
				
			||||||
let loadindex = 0;
 | 
					 | 
				
			||||||
let scrollposition = 0;
 | 
					 | 
				
			||||||
let loadedvideoid = -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$(document).ready(function () {
 | 
					 | 
				
			||||||
    $.post('php/videoload.php', 'action=getMovies', function (data) {
 | 
					 | 
				
			||||||
        videos = data;
 | 
					 | 
				
			||||||
        loadPreviewBlock(15);
 | 
					 | 
				
			||||||
    }, 'json');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $.post('php/videoload.php', 'action=getDbSize', function (data) {
 | 
					 | 
				
			||||||
        console.log(data);
 | 
					 | 
				
			||||||
    }, 'json');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $(".closebutton").click(function () {
 | 
					 | 
				
			||||||
        $("#likebtn").off();
 | 
					 | 
				
			||||||
        $("#tagbutton").off();
 | 
					 | 
				
			||||||
        $(".videopagewrapper").hide();
 | 
					 | 
				
			||||||
        $(".previewcontainer").show();
 | 
					 | 
				
			||||||
        // scroll back to last scroll position
 | 
					 | 
				
			||||||
        $(window).scrollTop(scrollposition);
 | 
					 | 
				
			||||||
        $(".videowrapper").html("");
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$(window).scroll(function () {
 | 
					 | 
				
			||||||
    if ($(window).scrollTop() >= (($(document).height() - $(window).height() - 60))) {
 | 
					 | 
				
			||||||
        if ($(".videowrapper").html() === "") {
 | 
					 | 
				
			||||||
            loadPreviewBlock(6);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function loadPreviewBlock(nr) {
 | 
					 | 
				
			||||||
    for (let i = 0; i < nr; i++) {
 | 
					 | 
				
			||||||
        if (loadindex + i < videos.length) {
 | 
					 | 
				
			||||||
            loadPreview(videos[loadindex + i]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    loadindex += nr;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function loadPreview(src) {
 | 
					 | 
				
			||||||
    $.post('php/videoload.php', 'action=readThumbnail&movieid=' + src.movie_id, function (data) {
 | 
					 | 
				
			||||||
        var preview = $(`
 | 
					 | 
				
			||||||
<div class='videopreview'>
 | 
					 | 
				
			||||||
    <div class='previewtitle'>${src.movie_name}</div>
 | 
					 | 
				
			||||||
    <div class='previewpic'>
 | 
					 | 
				
			||||||
        <img style='width:100%;height:100%' src="${data}" alt='no thumbnail found'/>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>`);
 | 
					 | 
				
			||||||
        preview.attr('movie_id', src.movie_id);
 | 
					 | 
				
			||||||
        preview.click(function () {
 | 
					 | 
				
			||||||
            console.log("preview clicked");
 | 
					 | 
				
			||||||
            scrollposition = $(window).scrollTop();
 | 
					 | 
				
			||||||
            loadedvideoid = $(this).attr("movie_id");
 | 
					 | 
				
			||||||
            loadVideo(loadedvideoid);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        $(".previewcontainer").append(preview);
 | 
					 | 
				
			||||||
    }, 'text');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function loadVideo(movieid) {
 | 
					 | 
				
			||||||
    $.post('php/videoload.php', 'action=loadVideo&movieid=' + movieid, function (data) {
 | 
					 | 
				
			||||||
        $(".videowrapper").html("<div class='myvideo'><video controls crossorigin playsinline id='player'></video></div>");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const player = new Plyr('#player');
 | 
					 | 
				
			||||||
        player.source = {
 | 
					 | 
				
			||||||
            type: 'video',
 | 
					 | 
				
			||||||
            sources: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    src: data.movie_url,
 | 
					 | 
				
			||||||
                    type: 'video/mp4',
 | 
					 | 
				
			||||||
                    size: 1080,
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            poster: data.thumbnail
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $(".likefield").html("Likes: " + data.likes);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $.post('php/videoload.php', 'action=getTags&movieid=' + loadedvideoid, function (data) {
 | 
					 | 
				
			||||||
            for (const tag in data.tags) {
 | 
					 | 
				
			||||||
                $(".videoleftbanner").append(`<div>${tag}</div>`);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            console.log(data);
 | 
					 | 
				
			||||||
        }, "json");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $("#likebtn").click(function () {
 | 
					 | 
				
			||||||
            console.log("likebtn clicked");
 | 
					 | 
				
			||||||
            $.post('php/videoload.php', 'action=addLike&movieid=' + loadedvideoid, function (data) {
 | 
					 | 
				
			||||||
                console.log(data);
 | 
					 | 
				
			||||||
            }, "json");
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $("#tagbutton").click(function () {
 | 
					 | 
				
			||||||
            console.log("tagbrn clicked");
 | 
					 | 
				
			||||||
            Swal.mixin({
 | 
					 | 
				
			||||||
                input: 'text',
 | 
					 | 
				
			||||||
                confirmButtonText: 'Next →',
 | 
					 | 
				
			||||||
                showCancelButton: true,
 | 
					 | 
				
			||||||
                progressSteps: ['1', '2', '3']
 | 
					 | 
				
			||||||
            }).queue([
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    title: 'Question 1',
 | 
					 | 
				
			||||||
                    text: 'Chaining swal2 modals is easy'
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                'Question 2',
 | 
					 | 
				
			||||||
                'Question 3'
 | 
					 | 
				
			||||||
            ]).then((result) => {
 | 
					 | 
				
			||||||
                if (result.value) {
 | 
					 | 
				
			||||||
                    const answers = JSON.stringify(result.value)
 | 
					 | 
				
			||||||
                    Swal.fire({
 | 
					 | 
				
			||||||
                        title: 'All done!',
 | 
					 | 
				
			||||||
                        html: `
 | 
					 | 
				
			||||||
        Your answers:
 | 
					 | 
				
			||||||
        <pre><code>${answers}</code></pre>
 | 
					 | 
				
			||||||
      `,
 | 
					 | 
				
			||||||
                        confirmButtonText: 'Lovely!'
 | 
					 | 
				
			||||||
                    })
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $(".videopagewrapper").show();
 | 
					 | 
				
			||||||
        $(".previewcontainer").hide();
 | 
					 | 
				
			||||||
    }, "json");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
							
								
								
									
										125
									
								
								js/random.js
									
									
									
									
									
								
							
							
						
						
									
										125
									
								
								js/random.js
									
									
									
									
									
								
							@@ -1,125 +0,0 @@
 | 
				
			|||||||
let videos;
 | 
					 | 
				
			||||||
let loadindex = 0;
 | 
					 | 
				
			||||||
let loadedvideoid = -1;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
$(document).ready(function () {
 | 
					 | 
				
			||||||
    $.post('php/videoload.php', 'action=getRandomMovies&number=6', function (data) {
 | 
					 | 
				
			||||||
        videos = data;
 | 
					 | 
				
			||||||
        loadPreviewBlock(6);
 | 
					 | 
				
			||||||
    }, 'json');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $(".closebutton").click(function () {
 | 
					 | 
				
			||||||
        $("#likebtn").off();
 | 
					 | 
				
			||||||
        $("#tagbutton").off();
 | 
					 | 
				
			||||||
        $(".videopagewrapper").hide();
 | 
					 | 
				
			||||||
        $(".previewcontainer").show();
 | 
					 | 
				
			||||||
        // scroll back to last scroll position
 | 
					 | 
				
			||||||
        $(window).scrollTop(scrollposition);
 | 
					 | 
				
			||||||
        $(".videowrapper").html("");
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    $("#shufflebtn").click(function () {
 | 
					 | 
				
			||||||
        $(".previewcontainer").html("");
 | 
					 | 
				
			||||||
        $.post('php/videoload.php', 'action=getRandomMovies&number=6', function (data) {
 | 
					 | 
				
			||||||
            videos = data;
 | 
					 | 
				
			||||||
            loadPreviewBlock(6);
 | 
					 | 
				
			||||||
        }, 'json');
 | 
					 | 
				
			||||||
    });
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function loadPreviewBlock(nr) {
 | 
					 | 
				
			||||||
    for (let i = 0; i < nr; i++) {
 | 
					 | 
				
			||||||
        if (loadindex + i < videos.length) {
 | 
					 | 
				
			||||||
            loadPreview(videos[loadindex + i]);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    loadindex += nr;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function loadPreview(src) {
 | 
					 | 
				
			||||||
    $.post('php/videoload.php', 'action=readThumbnail&movieid=' + src.movie_id, function (data) {
 | 
					 | 
				
			||||||
        var preview = $(`
 | 
					 | 
				
			||||||
<div class='videopreview'>
 | 
					 | 
				
			||||||
    <div class='previewtitle'>${src.movie_name}</div>
 | 
					 | 
				
			||||||
    <div class='previewpic'>
 | 
					 | 
				
			||||||
        <img style='width:100%;height:100%' src="${data}" alt='no thumbnail found'/>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>`);
 | 
					 | 
				
			||||||
        preview.attr('movie_id', src.movie_id);
 | 
					 | 
				
			||||||
        preview.click(function () {
 | 
					 | 
				
			||||||
            console.log("preview clicked");
 | 
					 | 
				
			||||||
            scrollposition = $(window).scrollTop();
 | 
					 | 
				
			||||||
            loadedvideoid = $(this).attr("movie_id");
 | 
					 | 
				
			||||||
            loadVideo(loadedvideoid);
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
        $(".previewcontainer").append(preview);
 | 
					 | 
				
			||||||
    }, 'text');
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function loadVideo(movieid) {
 | 
					 | 
				
			||||||
    $.post('php/videoload.php', 'action=loadVideo&movieid=' + movieid, function (data) {
 | 
					 | 
				
			||||||
        $(".videowrapper").html("<div class='myvideo'><video controls crossorigin playsinline id='player'></video></div>");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        const player = new Plyr('#player');
 | 
					 | 
				
			||||||
        player.source = {
 | 
					 | 
				
			||||||
            type: 'video',
 | 
					 | 
				
			||||||
            sources: [
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    src: data.movie_url,
 | 
					 | 
				
			||||||
                    type: 'video/mp4',
 | 
					 | 
				
			||||||
                    size: 1080,
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            ],
 | 
					 | 
				
			||||||
            poster: data.thumbnail
 | 
					 | 
				
			||||||
        };
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $(".likefield").html("Likes: " + data.likes);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $.post('php/videoload.php', 'action=getTags&movieid=' + loadedvideoid, function (data) {
 | 
					 | 
				
			||||||
            for (const tag in data.tags) {
 | 
					 | 
				
			||||||
                $(".videoleftbanner").append(`<div>${tag}</div>`);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
            console.log(data);
 | 
					 | 
				
			||||||
        }, "json");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $("#likebtn").click(function () {
 | 
					 | 
				
			||||||
            console.log("likebtn clicked");
 | 
					 | 
				
			||||||
            $.post('php/videoload.php', 'action=addLike&movieid=' + loadedvideoid, function (data) {
 | 
					 | 
				
			||||||
                console.log(data);
 | 
					 | 
				
			||||||
            }, "json");
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $("#tagbutton").click(function () {
 | 
					 | 
				
			||||||
            console.log("tagbrn clicked");
 | 
					 | 
				
			||||||
            Swal.mixin({
 | 
					 | 
				
			||||||
                input: 'text',
 | 
					 | 
				
			||||||
                confirmButtonText: 'Next →',
 | 
					 | 
				
			||||||
                showCancelButton: true,
 | 
					 | 
				
			||||||
                progressSteps: ['1', '2', '3']
 | 
					 | 
				
			||||||
            }).queue([
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    title: 'Question 1',
 | 
					 | 
				
			||||||
                    text: 'Chaining swal2 modals is easy'
 | 
					 | 
				
			||||||
                },
 | 
					 | 
				
			||||||
                'Question 2',
 | 
					 | 
				
			||||||
                'Question 3'
 | 
					 | 
				
			||||||
            ]).then((result) => {
 | 
					 | 
				
			||||||
                if (result.value) {
 | 
					 | 
				
			||||||
                    const answers = JSON.stringify(result.value)
 | 
					 | 
				
			||||||
                    Swal.fire({
 | 
					 | 
				
			||||||
                        title: 'All done!',
 | 
					 | 
				
			||||||
                        html: `
 | 
					 | 
				
			||||||
        Your answers:
 | 
					 | 
				
			||||||
        <pre><code>${answers}</code></pre>
 | 
					 | 
				
			||||||
      `,
 | 
					 | 
				
			||||||
                        confirmButtonText: 'Lovely!'
 | 
					 | 
				
			||||||
                    })
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            })
 | 
					 | 
				
			||||||
        });
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        $(".videopagewrapper").show();
 | 
					 | 
				
			||||||
        $(".previewcontainer").hide();
 | 
					 | 
				
			||||||
    }, "json");
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										14053
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
							
						
						
									
										14053
									
								
								package-lock.json
									
									
									
										generated
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										37
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								package.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "name": "untitled",
 | 
				
			||||||
 | 
					  "version": "0.1.0",
 | 
				
			||||||
 | 
					  "private": true,
 | 
				
			||||||
 | 
					  "dependencies": {
 | 
				
			||||||
 | 
					    "@testing-library/jest-dom": "^4.2.4",
 | 
				
			||||||
 | 
					    "@testing-library/react": "^9.5.0",
 | 
				
			||||||
 | 
					    "@testing-library/user-event": "^7.2.1",
 | 
				
			||||||
 | 
					    "bootstrap": "^4.5.0",
 | 
				
			||||||
 | 
					    "react": "^16.13.1",
 | 
				
			||||||
 | 
					    "react-dom": "^16.13.1",
 | 
				
			||||||
 | 
					    "react-scripts": "3.4.1",
 | 
				
			||||||
 | 
					    "plyr-react": "2.2.0"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "scripts": {
 | 
				
			||||||
 | 
					    "start": "react-scripts start",
 | 
				
			||||||
 | 
					    "build": "react-scripts build",
 | 
				
			||||||
 | 
					    "test": "react-scripts test",
 | 
				
			||||||
 | 
					    "eject": "react-scripts eject"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "proxy": "http://127.0.0.1:4000",
 | 
				
			||||||
 | 
					  "eslintConfig": {
 | 
				
			||||||
 | 
					    "extends": "react-app"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "browserslist": {
 | 
				
			||||||
 | 
					    "production": [
 | 
				
			||||||
 | 
					      ">0.2%",
 | 
				
			||||||
 | 
					      "not dead",
 | 
				
			||||||
 | 
					      "not op_mini all"
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
 | 
					    "development": [
 | 
				
			||||||
 | 
					      "last 1 chrome version",
 | 
				
			||||||
 | 
					      "last 1 firefox version",
 | 
				
			||||||
 | 
					      "last 1 safari version"
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/favicon.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 3.1 KiB  | 
							
								
								
									
										43
									
								
								public/index.html
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								public/index.html
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,43 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					  <head>
 | 
				
			||||||
 | 
					    <meta charset="utf-8" />
 | 
				
			||||||
 | 
					    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
 | 
				
			||||||
 | 
					    <meta name="viewport" content="width=device-width, initial-scale=1" />
 | 
				
			||||||
 | 
					    <meta name="theme-color" content="#000000" />
 | 
				
			||||||
 | 
					    <meta
 | 
				
			||||||
 | 
					      name="description"
 | 
				
			||||||
 | 
					      content="Web site created using create-react-app"
 | 
				
			||||||
 | 
					    />
 | 
				
			||||||
 | 
					    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
 | 
				
			||||||
 | 
					    <!--
 | 
				
			||||||
 | 
					      manifest.json provides metadata used when your web app is installed on a
 | 
				
			||||||
 | 
					      user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
 | 
				
			||||||
 | 
					    -->
 | 
				
			||||||
 | 
					    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
 | 
				
			||||||
 | 
					    <!--
 | 
				
			||||||
 | 
					      Notice the use of %PUBLIC_URL% in the tags above.
 | 
				
			||||||
 | 
					      It will be replaced with the URL of the `public` folder during the build.
 | 
				
			||||||
 | 
					      Only files inside the `public` folder can be referenced from the HTML.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
 | 
				
			||||||
 | 
					      work correctly both with client-side routing and a non-root public URL.
 | 
				
			||||||
 | 
					      Learn how to configure a non-root public URL by running `npm run build`.
 | 
				
			||||||
 | 
					    -->
 | 
				
			||||||
 | 
					    <title>React App</title>
 | 
				
			||||||
 | 
					  </head>
 | 
				
			||||||
 | 
					  <body>
 | 
				
			||||||
 | 
					    <noscript>You need to enable JavaScript to run this app.</noscript>
 | 
				
			||||||
 | 
					    <div id="root"></div>
 | 
				
			||||||
 | 
					    <!--
 | 
				
			||||||
 | 
					      This HTML file is a template.
 | 
				
			||||||
 | 
					      If you open it directly in the browser, you will see an empty page.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      You can add webfonts, meta tags, or analytics to this file.
 | 
				
			||||||
 | 
					      The build step will place the bundled scripts into the <body> tag.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      To begin the development, run `npm start` or `yarn start`.
 | 
				
			||||||
 | 
					      To create a production bundle, use `npm run build` or `yarn build`.
 | 
				
			||||||
 | 
					    -->
 | 
				
			||||||
 | 
					  </body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								public/logo192.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/logo192.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 5.2 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								public/logo512.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								public/logo512.png
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 9.4 KiB  | 
							
								
								
									
										25
									
								
								public/manifest.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								public/manifest.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "short_name": "React App",
 | 
				
			||||||
 | 
					  "name": "Create React App Sample",
 | 
				
			||||||
 | 
					  "icons": [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "src": "favicon.ico",
 | 
				
			||||||
 | 
					      "sizes": "64x64 32x32 24x24 16x16",
 | 
				
			||||||
 | 
					      "type": "image/x-icon"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "src": "logo192.png",
 | 
				
			||||||
 | 
					      "type": "image/png",
 | 
				
			||||||
 | 
					      "sizes": "192x192"
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "src": "logo512.png",
 | 
				
			||||||
 | 
					      "type": "image/png",
 | 
				
			||||||
 | 
					      "sizes": "512x512"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ],
 | 
				
			||||||
 | 
					  "start_url": ".",
 | 
				
			||||||
 | 
					  "display": "standalone",
 | 
				
			||||||
 | 
					  "theme_color": "#000000",
 | 
				
			||||||
 | 
					  "background_color": "#ffffff"
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										3
									
								
								public/robots.txt
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								public/robots.txt
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,3 @@
 | 
				
			|||||||
 | 
					# https://www.robotstxt.org/robotstxt.html
 | 
				
			||||||
 | 
					User-agent: *
 | 
				
			||||||
 | 
					Disallow:
 | 
				
			||||||
							
								
								
									
										85
									
								
								random.html
									
									
									
									
									
								
							
							
						
						
									
										85
									
								
								random.html
									
									
									
									
									
								
							@@ -1,85 +0,0 @@
 | 
				
			|||||||
<!DOCTYPE html>
 | 
					 | 
				
			||||||
<html lang="en" dir="ltr">
 | 
					 | 
				
			||||||
<head>
 | 
					 | 
				
			||||||
    <meta charset="utf-8">
 | 
					 | 
				
			||||||
    <title>hub</title>
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="css/plyr.css"/>
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="css/video.css">
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="css/random.css">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Latest compiled and minified CSS -->
 | 
					 | 
				
			||||||
    <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- jQuery library -->
 | 
					 | 
				
			||||||
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Popper JS -->
 | 
					 | 
				
			||||||
    <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.16.0/umd/popper.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <!-- Latest compiled JavaScript -->
 | 
					 | 
				
			||||||
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.5.0/js/bootstrap.min.js"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script src="https://cdn.jsdelivr.net/npm/sweetalert2@9"></script>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <script src="js/plyr.js"></script>
 | 
					 | 
				
			||||||
    <script src="js/random.js"></script>
 | 
					 | 
				
			||||||
</head>
 | 
					 | 
				
			||||||
<body>
 | 
					 | 
				
			||||||
<!-- Grey with black text -->
 | 
					 | 
				
			||||||
<nav class="navbar navbar-expand-sm bg-primary navbar-dark">
 | 
					 | 
				
			||||||
    <!-- Brand -->
 | 
					 | 
				
			||||||
    <a class="navbar-brand" href="#">Lukis Tube</a>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    <ul class="navbar-nav">
 | 
					 | 
				
			||||||
        <li class="nav-item">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="index.html">Home</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li class="nav-item active">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="random.html">Random Video</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
        <li class="nav-item">
 | 
					 | 
				
			||||||
            <a class="nav-link" href="category.html">Categories</a>
 | 
					 | 
				
			||||||
        </li>
 | 
					 | 
				
			||||||
    </ul>
 | 
					 | 
				
			||||||
</nav>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="videopagewrapper hideit">
 | 
					 | 
				
			||||||
    <div class="row">
 | 
					 | 
				
			||||||
        <div class="col-sm-2">
 | 
					 | 
				
			||||||
            <div class="videoleftbanner">
 | 
					 | 
				
			||||||
                <div class="likefield">Likes: 10</div>
 | 
					 | 
				
			||||||
            </div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="col-sm-8">
 | 
					 | 
				
			||||||
            <div class="videowrapper"></div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="col-sm-2">
 | 
					 | 
				
			||||||
            <div class="closebutton">Close</div>
 | 
					 | 
				
			||||||
            <div class="videorightbanner"></div>
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
    <div class="row">
 | 
					 | 
				
			||||||
        <div class="col-sm-5">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="col-sm-2">
 | 
					 | 
				
			||||||
            <button id="likebtn">Like it!</button>
 | 
					 | 
				
			||||||
            <button id="tagbutton">Tag it!</button>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
        <div class="col-sm-5">
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        </div>
 | 
					 | 
				
			||||||
    </div>
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
<div class="previewcontainer">
 | 
					 | 
				
			||||||
</div>
 | 
					 | 
				
			||||||
<div style="width: 100%"><button type="button" id="shufflebtn" class="btn btn-success">Shuffle</button></div>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
</body>
 | 
					 | 
				
			||||||
</html>
 | 
					 | 
				
			||||||
							
								
								
									
										71
									
								
								src/App.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								src/App.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,71 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import MainBody from "./MainBody";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import 'bootstrap/dist/css/bootstrap.min.css';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class App extends React.Component {
 | 
				
			||||||
 | 
					    constructor(props, context) {
 | 
				
			||||||
 | 
					        super(props, context);
 | 
				
			||||||
 | 
					        this.state = {page: "default"};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // bind this to the method for being able to call methods such as this.setstate
 | 
				
			||||||
 | 
					        this.showVideo = this.showVideo.bind(this);
 | 
				
			||||||
 | 
					        this.hideVideo = this.hideVideo.bind(this);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <div className="App">
 | 
				
			||||||
 | 
					                <nav className="navbar navbar-expand-sm bg-primary navbar-dark">
 | 
				
			||||||
 | 
					                    <a className="navbar-brand" href="!#">Lukis Tube</a>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    <ul className="navbar-nav">
 | 
				
			||||||
 | 
					                        <li className="nav-item">
 | 
				
			||||||
 | 
					                            <a className="nav-link" onClick={() => this.loadHomePage()} href='# '>Home</a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        <li className="nav-item">
 | 
				
			||||||
 | 
					                            <a className="nav-link" onClick={() => this.loadRandomPage()} href="# ">Random Video</a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                        <li className="nav-item">
 | 
				
			||||||
 | 
					                            <a className="nav-link" onClick={() => this.loadCategoriesPage()} href="# ">Categories</a>
 | 
				
			||||||
 | 
					                        </li>
 | 
				
			||||||
 | 
					                    </ul>
 | 
				
			||||||
 | 
					                </nav>
 | 
				
			||||||
 | 
					                <MainBody viewbinding={{showVideo: this.showVideo, hideVideo: this.hideVideo}} page={this.state.page}
 | 
				
			||||||
 | 
					                          videoelement={this.element}/>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loadCategoriesPage() {
 | 
				
			||||||
 | 
					        console.log("click categories");
 | 
				
			||||||
 | 
					        this.setState({page: "categories"});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loadRandomPage() {
 | 
				
			||||||
 | 
					        console.log("click random");
 | 
				
			||||||
 | 
					        this.setState({page: "random"});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loadHomePage() {
 | 
				
			||||||
 | 
					        console.log("click default");
 | 
				
			||||||
 | 
					        this.setState({page: "default"});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    showVideo(element) {
 | 
				
			||||||
 | 
					        this.setState({
 | 
				
			||||||
 | 
					            page: "video"
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.element = element;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    hideVideo() {
 | 
				
			||||||
 | 
					        this.setState({
 | 
				
			||||||
 | 
					            page: "default"
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        this.element = null;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default App;
 | 
				
			||||||
							
								
								
									
										91
									
								
								src/HomePage.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										91
									
								
								src/HomePage.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,91 @@
 | 
				
			|||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import Preview from "./Preview";
 | 
				
			||||||
 | 
					import "./css/HomePage.css"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class HomePage extends React.Component {
 | 
				
			||||||
 | 
					    // stores all available movies
 | 
				
			||||||
 | 
					    data = null;
 | 
				
			||||||
 | 
					    // stores current index of loaded elements
 | 
				
			||||||
 | 
					    loadindex = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    constructor(props, context) {
 | 
				
			||||||
 | 
					        super(props, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.state = {
 | 
				
			||||||
 | 
					            loadeditems: []
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentDidMount() {
 | 
				
			||||||
 | 
					        document.addEventListener('scroll', this.trackScrolling);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const updateRequest = new FormData();
 | 
				
			||||||
 | 
					        updateRequest.append('action', 'getMovies');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // fetch all videos available
 | 
				
			||||||
 | 
					        fetch('/php/videoload.php', {method: 'POST', body: updateRequest})
 | 
				
			||||||
 | 
					            .then((response) => response.json())
 | 
				
			||||||
 | 
					            .then((result) => {
 | 
				
			||||||
 | 
					                this.data = result;
 | 
				
			||||||
 | 
					                this.loadPreviewBlock(12);
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentWillUnmount() {
 | 
				
			||||||
 | 
					        this.setState({});
 | 
				
			||||||
 | 
					        document.removeEventListener('scroll', this.trackScrolling);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					                <div><h1>Home page</h1></div>
 | 
				
			||||||
 | 
					                <div className='sideinfo'>
 | 
				
			||||||
 | 
					                    beep beep
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div className='maincontent'>
 | 
				
			||||||
 | 
					                    {this.state.loadeditems.map(elem => (
 | 
				
			||||||
 | 
					                        <Preview
 | 
				
			||||||
 | 
					                            key={elem.movie_id}
 | 
				
			||||||
 | 
					                            name={elem.movie_name}
 | 
				
			||||||
 | 
					                            movie_id={elem.movie_id}
 | 
				
			||||||
 | 
					                            viewbinding={this.props.viewbinding}/>
 | 
				
			||||||
 | 
					                    ))}
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div className='rightinfo'>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    loadPreviewBlock(nr) {
 | 
				
			||||||
 | 
					        console.log("loadpreviewblock called ...")
 | 
				
			||||||
 | 
					        let ret = [];
 | 
				
			||||||
 | 
					        for (let i = 0; i < nr; i++) {
 | 
				
			||||||
 | 
					            // only add if not end
 | 
				
			||||||
 | 
					            if (this.data.length > this.loadindex + i) {
 | 
				
			||||||
 | 
					                ret.push(this.data[this.loadindex + i]);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.setState({
 | 
				
			||||||
 | 
					            loadeditems: [
 | 
				
			||||||
 | 
					                ...this.state.loadeditems,
 | 
				
			||||||
 | 
					                ...ret
 | 
				
			||||||
 | 
					            ]
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.loadindex += nr;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    trackScrolling = (e) => {
 | 
				
			||||||
 | 
					        if (window.innerHeight + document.documentElement.scrollTop === document.documentElement.offsetHeight) {
 | 
				
			||||||
 | 
					            this.loadPreviewBlock(6);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default HomePage;
 | 
				
			||||||
							
								
								
									
										24
									
								
								src/MainBody.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/MainBody.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,24 @@
 | 
				
			|||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import HomePage from "./HomePage";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class MainBody extends React.Component {
 | 
				
			||||||
 | 
					    constructor(props) {
 | 
				
			||||||
 | 
					        super(props);
 | 
				
			||||||
 | 
					        this.props = props;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        let page;
 | 
				
			||||||
 | 
					        if (this.props.page === "default") {
 | 
				
			||||||
 | 
					            page = <HomePage viewbinding={this.props.viewbinding}/>;
 | 
				
			||||||
 | 
					        } else if (this.props.page === "video") {
 | 
				
			||||||
 | 
					            // show videoelement if neccessary
 | 
				
			||||||
 | 
					            page = this.props.videoelement;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            page = <div>unimplemented yet!</div>;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return (page);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default MainBody;
 | 
				
			||||||
							
								
								
									
										128
									
								
								src/Player.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										128
									
								
								src/Player.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,128 @@
 | 
				
			|||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import "./css/Player.css"
 | 
				
			||||||
 | 
					import {PlyrComponent} from 'plyr-react';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Player extends React.Component {
 | 
				
			||||||
 | 
					    constructor(props, context) {
 | 
				
			||||||
 | 
					        super(props, context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.state = {};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.props = props;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    options = {
 | 
				
			||||||
 | 
					        controls: [
 | 
				
			||||||
 | 
					            'play-large', // The large play button in the center
 | 
				
			||||||
 | 
					            'play', // Play/pause playback
 | 
				
			||||||
 | 
					            'progress', // The progress bar and scrubber for playback and buffering
 | 
				
			||||||
 | 
					            'current-time', // The current time of playback
 | 
				
			||||||
 | 
					            'duration', // The full duration of the media
 | 
				
			||||||
 | 
					            'mute', // Toggle mute
 | 
				
			||||||
 | 
					            'volume', // Volume control
 | 
				
			||||||
 | 
					            'captions', // Toggle captions
 | 
				
			||||||
 | 
					            'settings', // Settings menu
 | 
				
			||||||
 | 
					            'airplay', // Airplay (currently Safari only)
 | 
				
			||||||
 | 
					            'download', // Show a download button with a link to either the current source or a custom URL you specify in your options
 | 
				
			||||||
 | 
					            'fullscreen', // Toggle fullscreen
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentDidMount() {
 | 
				
			||||||
 | 
					        this.fetchMovieData();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <div>
 | 
				
			||||||
 | 
					                <div className="row">
 | 
				
			||||||
 | 
					                    <div className="col-sm-2">
 | 
				
			||||||
 | 
					                        <div className="videoleftbanner">
 | 
				
			||||||
 | 
					                            <div className="likefield">Likes: {this.state.likes}</div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div className="col-sm-8">
 | 
				
			||||||
 | 
					                        <div className="videowrapper">
 | 
				
			||||||
 | 
					                            <div className='myvideo'>
 | 
				
			||||||
 | 
					                                {this.state.sources ? <PlyrComponent
 | 
				
			||||||
 | 
					                                        sources={this.state.sources}
 | 
				
			||||||
 | 
					                                        options={this.options}/> :
 | 
				
			||||||
 | 
					                                    <div>not loaded yet</div>}
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div className="col-sm-2">
 | 
				
			||||||
 | 
					                        <div className="closebutton" onClick={() => {this.closebtn()}}>Close</div>
 | 
				
			||||||
 | 
					                        <div className="videorightbanner"></div>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div className="row">
 | 
				
			||||||
 | 
					                    <div className="col-sm-5">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div className="col-sm-2">
 | 
				
			||||||
 | 
					                        <button className='btn btn-primary' onClick={() => {this.likebtn()}}>Like it!</button>
 | 
				
			||||||
 | 
					                        <button className='btn btn-info' id="tagbutton">Tag it!</button>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div className="col-sm-5">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    fetchMovieData(){
 | 
				
			||||||
 | 
					        const updateRequest = new FormData();
 | 
				
			||||||
 | 
					        updateRequest.append('action', 'loadVideo');
 | 
				
			||||||
 | 
					        updateRequest.append('movieid', this.props.movie_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fetch('/php/videoload.php', {method: 'POST', body: updateRequest})
 | 
				
			||||||
 | 
					            .then((response) => response.json())
 | 
				
			||||||
 | 
					            .then((result) => {
 | 
				
			||||||
 | 
					                this.setState({
 | 
				
			||||||
 | 
					                    sources: {
 | 
				
			||||||
 | 
					                        type: 'video',
 | 
				
			||||||
 | 
					                        sources: [
 | 
				
			||||||
 | 
					                            {
 | 
				
			||||||
 | 
					                                src: result.movie_url,
 | 
				
			||||||
 | 
					                                type: 'video/mp4',
 | 
				
			||||||
 | 
					                                size: 1080,
 | 
				
			||||||
 | 
					                            }
 | 
				
			||||||
 | 
					                        ],
 | 
				
			||||||
 | 
					                        poster: result.thumbnail
 | 
				
			||||||
 | 
					                    },
 | 
				
			||||||
 | 
					                    likes: result.likes
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Click Listener */
 | 
				
			||||||
 | 
					    likebtn() {
 | 
				
			||||||
 | 
					        const updateRequest = new FormData();
 | 
				
			||||||
 | 
					        updateRequest.append('action', 'addLike');
 | 
				
			||||||
 | 
					        updateRequest.append('movieid', this.props.movie_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fetch('/php/videoload.php', {method: 'POST', body: updateRequest})
 | 
				
			||||||
 | 
					            .then((response) => response.json())
 | 
				
			||||||
 | 
					            .then((result) => {
 | 
				
			||||||
 | 
					                if(result.result === "success"){
 | 
				
			||||||
 | 
					                    this.fetchMovieData();
 | 
				
			||||||
 | 
					                }else{
 | 
				
			||||||
 | 
					                    console.log("an error occured while liking");
 | 
				
			||||||
 | 
					                    console.log(result);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    closebtn() {
 | 
				
			||||||
 | 
					        this.props.viewbinding.hideVideo();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Player;
 | 
				
			||||||
							
								
								
									
										59
									
								
								src/Preview.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										59
									
								
								src/Preview.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,59 @@
 | 
				
			|||||||
 | 
					import React from "react";
 | 
				
			||||||
 | 
					import "./css/Preview.css"
 | 
				
			||||||
 | 
					import Player from "./Player";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Preview extends React.Component {
 | 
				
			||||||
 | 
					    constructor(props, context) {
 | 
				
			||||||
 | 
					        super(props, context);
 | 
				
			||||||
 | 
					        this.props = props;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.state = {
 | 
				
			||||||
 | 
					            previewpicture: null,
 | 
				
			||||||
 | 
					            name: null
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentWillUnmount() {
 | 
				
			||||||
 | 
					        this.setState({});
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    componentDidMount() {
 | 
				
			||||||
 | 
					        this.setState({
 | 
				
			||||||
 | 
					            previewpicture: null,
 | 
				
			||||||
 | 
					            name: this.props.name
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        const updateRequest = new FormData();
 | 
				
			||||||
 | 
					        updateRequest.append('action', 'readThumbnail');
 | 
				
			||||||
 | 
					        updateRequest.append('movieid', this.props.movie_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        fetch('/php/videoload.php', {method: 'POST', body: updateRequest})
 | 
				
			||||||
 | 
					            .then((response) => response.text())
 | 
				
			||||||
 | 
					            .then((result) => {
 | 
				
			||||||
 | 
					                this.setState(prevState => ({
 | 
				
			||||||
 | 
					                    ...prevState.previewpicture, previewpicture: result
 | 
				
			||||||
 | 
					                }));
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    render() {
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            <div className='videopreview' onClick={() => this.itemClick()}>
 | 
				
			||||||
 | 
					                <div className='previewtitle'>{this.state.name}</div>
 | 
				
			||||||
 | 
					                <div className='previewpic'>
 | 
				
			||||||
 | 
					                    <img className='previewimage'
 | 
				
			||||||
 | 
					                         src={this.state.previewpicture}
 | 
				
			||||||
 | 
					                         alt='no thumbnail found'/>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    itemClick() {
 | 
				
			||||||
 | 
					        console.log("item clicked!" + this.state.name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        this.props.viewbinding.showVideo(<Player viewbinding={this.props.viewbinding} movie_id={this.props.movie_id}/>);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default Preview;
 | 
				
			||||||
							
								
								
									
										14
									
								
								src/css/HomePage.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/css/HomePage.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					.sideinfo{
 | 
				
			||||||
 | 
					    width: 20%;
 | 
				
			||||||
 | 
					    float: left;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.maincontent{
 | 
				
			||||||
 | 
					    float: left;
 | 
				
			||||||
 | 
					    width: 70%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.rightinfo{
 | 
				
			||||||
 | 
					    float: left;
 | 
				
			||||||
 | 
					    width: 10%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,7 +1,3 @@
 | 
				
			|||||||
.hideit {
 | 
					 | 
				
			||||||
    display: none;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.closebutton {
 | 
					.closebutton {
 | 
				
			||||||
    color: white;
 | 
					    color: white;
 | 
				
			||||||
    height: 35px;
 | 
					    height: 35px;
 | 
				
			||||||
@@ -35,36 +31,3 @@
 | 
				
			|||||||
    color: white;
 | 
					    color: white;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
.previewcontainer {
 | 
					 | 
				
			||||||
    margin-left: 10%;
 | 
					 | 
				
			||||||
    width: 80%;
 | 
					 | 
				
			||||||
    margin-right: 10%;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.videopreview {
 | 
					 | 
				
			||||||
    height: 300px;
 | 
					 | 
				
			||||||
    width: 30%;
 | 
					 | 
				
			||||||
    float: left;
 | 
					 | 
				
			||||||
    margin: 1%;
 | 
					 | 
				
			||||||
    background-color: #7F7F7F;
 | 
					 | 
				
			||||||
    cursor: pointer;
 | 
					 | 
				
			||||||
    opacity: 0.9;
 | 
					 | 
				
			||||||
    border: 10px;
 | 
					 | 
				
			||||||
    border-radius: 20px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.videopreview:hover {
 | 
					 | 
				
			||||||
    opacity: 1;
 | 
					 | 
				
			||||||
    transition: opacity 0.5s;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.previewtitle {
 | 
					 | 
				
			||||||
    height: 10%;
 | 
					 | 
				
			||||||
    color: white;
 | 
					 | 
				
			||||||
    text-align: center;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.previewpic {
 | 
					 | 
				
			||||||
    height: 80%;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										38
									
								
								src/css/Preview.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								src/css/Preview.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,38 @@
 | 
				
			|||||||
 | 
					.previewtitle {
 | 
				
			||||||
 | 
					    height: 10%;
 | 
				
			||||||
 | 
					    color: white;
 | 
				
			||||||
 | 
					    text-align: center;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.previewpic {
 | 
				
			||||||
 | 
					    height: 80%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.previewimage{
 | 
				
			||||||
 | 
					    width:100%;
 | 
				
			||||||
 | 
					    height:100%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.videopreview {
 | 
				
			||||||
 | 
					    height: 300px;
 | 
				
			||||||
 | 
					    width: 30%;
 | 
				
			||||||
 | 
					    float: left;
 | 
				
			||||||
 | 
					    margin: 1%;
 | 
				
			||||||
 | 
					    background-color: #7F7F7F;
 | 
				
			||||||
 | 
					    cursor: pointer;
 | 
				
			||||||
 | 
					    opacity: 0.9;
 | 
				
			||||||
 | 
					    border: 10px;
 | 
				
			||||||
 | 
					    border-radius: 20px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.videopreview:hover {
 | 
				
			||||||
 | 
					    opacity: 1;
 | 
				
			||||||
 | 
					    transition: opacity 0.5s;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* todo check if neccessary*/
 | 
				
			||||||
 | 
					.previewcontainer {
 | 
				
			||||||
 | 
					    margin-left: 10%;
 | 
				
			||||||
 | 
					    width: 80%;
 | 
				
			||||||
 | 
					    margin-right: 10%;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										13
									
								
								src/css/index.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/css/index.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					body {
 | 
				
			||||||
 | 
					    margin: 0;
 | 
				
			||||||
 | 
					    font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
 | 
				
			||||||
 | 
					    'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
 | 
				
			||||||
 | 
					    sans-serif;
 | 
				
			||||||
 | 
					    -webkit-font-smoothing: antialiased;
 | 
				
			||||||
 | 
					    -moz-osx-font-smoothing: grayscale;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					code {
 | 
				
			||||||
 | 
					    font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
 | 
				
			||||||
 | 
					    monospace;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								src/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/index.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					import React from 'react';
 | 
				
			||||||
 | 
					import ReactDOM from 'react-dom';
 | 
				
			||||||
 | 
					import './css/index.css';
 | 
				
			||||||
 | 
					import App from './App';
 | 
				
			||||||
 | 
					import * as serviceWorker from './serviceWorker';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ReactDOM.render(
 | 
				
			||||||
 | 
					  <React.StrictMode>
 | 
				
			||||||
 | 
					    <App />
 | 
				
			||||||
 | 
					  </React.StrictMode>,
 | 
				
			||||||
 | 
					  document.getElementById('root')
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// If you want your app to work offline and load faster, you can change
 | 
				
			||||||
 | 
					// unregister() to register() below. Note this comes with some pitfalls.
 | 
				
			||||||
 | 
					// Learn more about service workers: https://bit.ly/CRA-PWA
 | 
				
			||||||
 | 
					serviceWorker.register();
 | 
				
			||||||
							
								
								
									
										141
									
								
								src/serviceWorker.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/serviceWorker.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,141 @@
 | 
				
			|||||||
 | 
					// This optional code is used to register a service worker.
 | 
				
			||||||
 | 
					// register() is not called by default.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This lets the app load faster on subsequent visits in production, and gives
 | 
				
			||||||
 | 
					// it offline capabilities. However, it also means that developers (and users)
 | 
				
			||||||
 | 
					// will only see deployed updates on subsequent visits to a page, after all the
 | 
				
			||||||
 | 
					// existing tabs open on the page have been closed, since previously cached
 | 
				
			||||||
 | 
					// resources are updated in the background.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// To learn more about the benefits of this model and instructions on how to
 | 
				
			||||||
 | 
					// opt-in, read https://bit.ly/CRA-PWA
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const isLocalhost = Boolean(
 | 
				
			||||||
 | 
					  window.location.hostname === 'localhost' ||
 | 
				
			||||||
 | 
					    // [::1] is the IPv6 localhost address.
 | 
				
			||||||
 | 
					    window.location.hostname === '[::1]' ||
 | 
				
			||||||
 | 
					    // 127.0.0.0/8 are considered localhost for IPv4.
 | 
				
			||||||
 | 
					    window.location.hostname.match(
 | 
				
			||||||
 | 
					      /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function register(config) {
 | 
				
			||||||
 | 
					  if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
 | 
				
			||||||
 | 
					    // The URL constructor is available in all browsers that support SW.
 | 
				
			||||||
 | 
					    const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);
 | 
				
			||||||
 | 
					    if (publicUrl.origin !== window.location.origin) {
 | 
				
			||||||
 | 
					      // Our service worker won't work if PUBLIC_URL is on a different origin
 | 
				
			||||||
 | 
					      // from what our page is served on. This might happen if a CDN is used to
 | 
				
			||||||
 | 
					      // serve assets; see https://github.com/facebook/create-react-app/issues/2374
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    window.addEventListener('load', () => {
 | 
				
			||||||
 | 
					      const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (isLocalhost) {
 | 
				
			||||||
 | 
					        // This is running on localhost. Let's check if a service worker still exists or not.
 | 
				
			||||||
 | 
					        checkValidServiceWorker(swUrl, config);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Add some additional logging to localhost, pointing developers to the
 | 
				
			||||||
 | 
					        // service worker/PWA documentation.
 | 
				
			||||||
 | 
					        navigator.serviceWorker.ready.then(() => {
 | 
				
			||||||
 | 
					          console.log(
 | 
				
			||||||
 | 
					            'This web app is being served cache-first by a service ' +
 | 
				
			||||||
 | 
					              'worker. To learn more, visit https://bit.ly/CRA-PWA'
 | 
				
			||||||
 | 
					          );
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // Is not localhost. Just register service worker
 | 
				
			||||||
 | 
					        registerValidSW(swUrl, config);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function registerValidSW(swUrl, config) {
 | 
				
			||||||
 | 
					  navigator.serviceWorker
 | 
				
			||||||
 | 
					    .register(swUrl)
 | 
				
			||||||
 | 
					    .then(registration => {
 | 
				
			||||||
 | 
					      registration.onupdatefound = () => {
 | 
				
			||||||
 | 
					        const installingWorker = registration.installing;
 | 
				
			||||||
 | 
					        if (installingWorker == null) {
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        installingWorker.onstatechange = () => {
 | 
				
			||||||
 | 
					          if (installingWorker.state === 'installed') {
 | 
				
			||||||
 | 
					            if (navigator.serviceWorker.controller) {
 | 
				
			||||||
 | 
					              // At this point, the updated precached content has been fetched,
 | 
				
			||||||
 | 
					              // but the previous service worker will still serve the older
 | 
				
			||||||
 | 
					              // content until all client tabs are closed.
 | 
				
			||||||
 | 
					              console.log(
 | 
				
			||||||
 | 
					                'New content is available and will be used when all ' +
 | 
				
			||||||
 | 
					                  'tabs for this page are closed. See https://bit.ly/CRA-PWA.'
 | 
				
			||||||
 | 
					              );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              // Execute callback
 | 
				
			||||||
 | 
					              if (config && config.onUpdate) {
 | 
				
			||||||
 | 
					                config.onUpdate(registration);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            } else {
 | 
				
			||||||
 | 
					              // At this point, everything has been precached.
 | 
				
			||||||
 | 
					              // It's the perfect time to display a
 | 
				
			||||||
 | 
					              // "Content is cached for offline use." message.
 | 
				
			||||||
 | 
					              console.log('Content is cached for offline use.');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              // Execute callback
 | 
				
			||||||
 | 
					              if (config && config.onSuccess) {
 | 
				
			||||||
 | 
					                config.onSuccess(registration);
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .catch(error => {
 | 
				
			||||||
 | 
					      console.error('Error during service worker registration:', error);
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function checkValidServiceWorker(swUrl, config) {
 | 
				
			||||||
 | 
					  // Check if the service worker can be found. If it can't reload the page.
 | 
				
			||||||
 | 
					  fetch(swUrl, {
 | 
				
			||||||
 | 
					    headers: { 'Service-Worker': 'script' },
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					    .then(response => {
 | 
				
			||||||
 | 
					      // Ensure service worker exists, and that we really are getting a JS file.
 | 
				
			||||||
 | 
					      const contentType = response.headers.get('content-type');
 | 
				
			||||||
 | 
					      if (
 | 
				
			||||||
 | 
					        response.status === 404 ||
 | 
				
			||||||
 | 
					        (contentType != null && contentType.indexOf('javascript') === -1)
 | 
				
			||||||
 | 
					      ) {
 | 
				
			||||||
 | 
					        // No service worker found. Probably a different app. Reload the page.
 | 
				
			||||||
 | 
					        navigator.serviceWorker.ready.then(registration => {
 | 
				
			||||||
 | 
					          registration.unregister().then(() => {
 | 
				
			||||||
 | 
					            window.location.reload();
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        // Service worker found. Proceed as normal.
 | 
				
			||||||
 | 
					        registerValidSW(swUrl, config);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					    .catch(() => {
 | 
				
			||||||
 | 
					      console.log(
 | 
				
			||||||
 | 
					        'No internet connection found. App is running in offline mode.'
 | 
				
			||||||
 | 
					      );
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export function unregister() {
 | 
				
			||||||
 | 
					  if ('serviceWorker' in navigator) {
 | 
				
			||||||
 | 
					    navigator.serviceWorker.ready
 | 
				
			||||||
 | 
					      .then(registration => {
 | 
				
			||||||
 | 
					        registration.unregister();
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch(error => {
 | 
				
			||||||
 | 
					        console.error(error.message);
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5
									
								
								src/setupTests.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								src/setupTests.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					// jest-dom adds custom jest matchers for asserting on DOM nodes.
 | 
				
			||||||
 | 
					// allows you to do things like:
 | 
				
			||||||
 | 
					// expect(element).toHaveTextContent(/react/i)
 | 
				
			||||||
 | 
					// learn more: https://github.com/testing-library/jest-dom
 | 
				
			||||||
 | 
					import '@testing-library/jest-dom/extend-expect';
 | 
				
			||||||
		Reference in New Issue
	
	Block a user