mirror of
https://github.com/sigmasternchen/MyTube
synced 2025-03-15 21:08:55 +00:00
upload progress in dashboard
This commit is contained in:
parent
07f9827ed2
commit
d6197a692a
6 changed files with 135 additions and 12 deletions
|
@ -95,4 +95,26 @@
|
||||||
|
|
||||||
.link:hover a {
|
.link:hover a {
|
||||||
color: grey;
|
color: grey;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transcodingProgress {
|
||||||
|
position: absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transcodingProgress .value {
|
||||||
|
width: 100%;
|
||||||
|
color: lightgrey;
|
||||||
|
text-align: center;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 5%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.transcodingProgress .bar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
height: 2%;
|
||||||
|
background-color: lightgrey;
|
||||||
}
|
}
|
21
public/js/ajax.js
Normal file
21
public/js/ajax.js
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
function ajaxGet(url, callback) {
|
||||||
|
var http = new XMLHttpRequest();
|
||||||
|
http.open("GET", url, true);
|
||||||
|
http.onreadystatechange = function () {
|
||||||
|
if (http.readyState === 4) {
|
||||||
|
callback(http.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http.send(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
function ajaxPost(url, data, callback) {
|
||||||
|
var http = new XMLHttpRequest();
|
||||||
|
http.open("POST", url, true);
|
||||||
|
http.onreadystatechange = function () {
|
||||||
|
if (http.readyState === 4) {
|
||||||
|
callback(http.responseText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
http.send(data);
|
||||||
|
}
|
|
@ -15,8 +15,11 @@ use App\Service\VideoService;
|
||||||
use Doctrine\DBAL\Types\ConversionException;
|
use Doctrine\DBAL\Types\ConversionException;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\Component\Form\FormError;
|
use Symfony\Component\Form\FormError;
|
||||||
|
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
use Symfony\Component\HttpFoundation\Response;
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
|
||||||
|
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
|
||||||
use Symfony\Component\Routing\Annotation\Route;
|
use Symfony\Component\Routing\Annotation\Route;
|
||||||
|
|
||||||
class DashboardController extends AbstractController
|
class DashboardController extends AbstractController
|
||||||
|
@ -94,6 +97,36 @@ class DashboardController extends AbstractController
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Route("/upload/{videoId}", name="app_upload_status")
|
||||||
|
*/
|
||||||
|
public function uploadStatus($videoId): Response
|
||||||
|
{
|
||||||
|
if (!$this->isGranted("ROLE_USER")) {
|
||||||
|
// not logged in
|
||||||
|
return $this->redirectToRoute("app_login");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
$videoId = $this->uuidMapper->fromString($videoId);
|
||||||
|
} catch (ConversionException $e) {
|
||||||
|
throw new BadRequestHttpException();
|
||||||
|
}
|
||||||
|
|
||||||
|
$video = $this->videoService->get($videoId);
|
||||||
|
|
||||||
|
if ($video == null || $video->getUploader() != $this->userService->getLoggedInUser()) {
|
||||||
|
throw new AccessDeniedHttpException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return new JsonResponse([
|
||||||
|
"id" => $this->uuidMapper->toString($video->getId()),
|
||||||
|
"state" => $video->getStateString(),
|
||||||
|
"stateId" => $video->getState(),
|
||||||
|
"progress" => $video->getTranscodingProgress()
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @Route("/links", name="app_links")
|
* @Route("/links", name="app_links")
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -73,9 +73,9 @@ class Video
|
||||||
private $length;
|
private $length;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @ORM\Column(type="integer", nullable=true)
|
* @ORM\Column(type="integer")
|
||||||
*/
|
*/
|
||||||
private $transcodingProgress;
|
private $transcodingProgress = 0;
|
||||||
|
|
||||||
public function __construct()
|
public function __construct()
|
||||||
{
|
{
|
||||||
|
|
|
@ -70,6 +70,7 @@
|
||||||
<script src="{{ asset("js/mdb.min.js") }}"></script>
|
<script src="{{ asset("js/mdb.min.js") }}"></script>
|
||||||
<script src="{{ asset("js/clipboard.js") }}"></script>
|
<script src="{{ asset("js/clipboard.js") }}"></script>
|
||||||
<script src="{{ asset("js/toasts.js") }}"></script>
|
<script src="{{ asset("js/toasts.js") }}"></script>
|
||||||
|
<script src="{{ asset("js/ajax.js") }}"></script>
|
||||||
{% block javascripts %}{% endblock %}
|
{% block javascripts %}{% endblock %}
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -5,26 +5,63 @@
|
||||||
<link rel="stylesheet" href="{{ asset("css/dashboard.css") }}">
|
<link rel="stylesheet" href="{{ asset("css/dashboard.css") }}">
|
||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block javascripts %}
|
||||||
|
<script>
|
||||||
|
(function () {
|
||||||
|
let intervalIds = [];
|
||||||
|
for (let id in autoupdate) {
|
||||||
|
intervalIds[id] = setInterval(function () {
|
||||||
|
ajaxGet(autoupdate[id], function (data) {
|
||||||
|
data = JSON.parse(data);
|
||||||
|
|
||||||
|
let element = document.getElementById("video-" + id);
|
||||||
|
if (data.stateId === {{ constant("App\\Entity\\Video::DONE") }}) {
|
||||||
|
element.getElementsByClassName("disable")[0].remove();
|
||||||
|
clearInterval(intervalIds[id]);
|
||||||
|
} else {
|
||||||
|
|
||||||
|
if (data.stateId > {{ constant("App\\Entity\\Video::PROCESSING_THUMBNAIL") }}) {
|
||||||
|
let image = element.getElementsByClassName("thumbnail")[0].getElementsByTagName("img")[0];
|
||||||
|
if (image.hasAttribute("data-src")) {
|
||||||
|
image.src = image.getAttribute("data-src");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
element.getElementsByClassName("state")[0].innerText = data.state;
|
||||||
|
|
||||||
|
let progress = element.getElementsByClassName("transcodingProgress")[0];
|
||||||
|
progress.getElementsByClassName("value")[0].innerText = data.progress + " %";
|
||||||
|
progress.getElementsByClassName("bar")[0].style.width = data.progress + "%";
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 2000);
|
||||||
|
}
|
||||||
|
})();
|
||||||
|
</script>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
{% block body %}
|
{% block body %}
|
||||||
<div class="grid-container">
|
<div class="grid-container">
|
||||||
|
<script>var autoupdate = [];</script>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
{% for video in videos %}
|
{% for video in videos %}
|
||||||
{% set disabled = video.state != constant("App\\Entity\\Video::DONE") %}
|
{% set disabled = video.state != constant("App\\Entity\\Video::DONE") %}
|
||||||
<div class="video-tile col-md-4">
|
<div class="video-tile col-md-4" id="video-{{ video.customId }}">
|
||||||
<div class="tile-content bg-light shadow-5-strong">
|
<div class="tile-content bg-light shadow-5-strong">
|
||||||
<div class="thumbnail" onclick="location.href = '{{ path("app_watch_page", {
|
<div class="thumbnail" onclick="location.href = '{{ path("app_watch_page", {
|
||||||
linkId: constant("App\\Controller\\WatchController::OWNER_LINK_ID"),
|
linkId: constant("App\\Controller\\WatchController::OWNER_LINK_ID"),
|
||||||
videoId: video.customId
|
videoId: video.customId
|
||||||
}) }}'">
|
}) }}'">
|
||||||
{% if disabled == false %}
|
<img alt="Thumbnail"
|
||||||
<img alt="Thumbnail" src="{{ path("app_watch_thumbnail", {
|
{{ video.state > constant("App\\Entity\\Video::PROCESSING_THUMBNAIL") ? "src" : "data-src" }}
|
||||||
linkId: constant("App\\Controller\\WatchController::OWNER_LINK_ID"),
|
="{{ path("app_watch_thumbnail", {
|
||||||
videoId: video.customId
|
linkId: constant("App\\Controller\\WatchController::OWNER_LINK_ID"),
|
||||||
}) }}"/>
|
videoId: video.customId
|
||||||
<div class="play-button">
|
}) }}"/>
|
||||||
<i class="fas fa-play"></i>
|
<div class="play-button">
|
||||||
</div>
|
<i class="fas fa-play"></i>
|
||||||
{% endif %}
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<div class="link">
|
<div class="link">
|
||||||
|
@ -38,6 +75,11 @@
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
{% if disabled %}
|
{% if disabled %}
|
||||||
|
<script>
|
||||||
|
autoupdate["{{ video.customId }}"] = "{{ path("app_upload_status", {
|
||||||
|
videoId: video.customId
|
||||||
|
}) }}";
|
||||||
|
</script>
|
||||||
<div class="disable">
|
<div class="disable">
|
||||||
<div class="spinner spinner-border" role="status">
|
<div class="spinner spinner-border" role="status">
|
||||||
<span class="visually-hidden">Loading...</span>
|
<span class="visually-hidden">Loading...</span>
|
||||||
|
@ -45,6 +87,10 @@
|
||||||
<div class="state">
|
<div class="state">
|
||||||
{{ video.getStateString() }}
|
{{ video.getStateString() }}
|
||||||
</div>
|
</div>
|
||||||
|
<div class="transcodingProgress">
|
||||||
|
<div class="value">{{ video.transcodingProgress }} %</div>
|
||||||
|
<div class="bar" style="width: {{ video.transcodingProgress }}%;"></div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in a new issue