wip: adds downloads page, makes DownloadList a widget or a full page list
This commit is contained in:
@@ -15,7 +15,7 @@ export default class extends Controller {
|
|||||||
}
|
}
|
||||||
|
|
||||||
download() {
|
download() {
|
||||||
fetch('/download', {
|
fetch('/api/download', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
|
|||||||
@@ -14,6 +14,14 @@ controllersUser:
|
|||||||
defaults:
|
defaults:
|
||||||
schemes: ['https']
|
schemes: ['https']
|
||||||
|
|
||||||
|
controllersDownload:
|
||||||
|
resource:
|
||||||
|
path: ../src/Download/Framework/Controller
|
||||||
|
namespace: App\Download\Framework\Controller
|
||||||
|
type: attribute
|
||||||
|
defaults:
|
||||||
|
schemes: [ 'https' ]
|
||||||
|
|
||||||
controllersMonitor:
|
controllersMonitor:
|
||||||
resource:
|
resource:
|
||||||
path: ../src/Monitor/Framework/Controller
|
path: ../src/Monitor/Framework/Controller
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
namespace App\Controller;
|
namespace App\Download\Framework\Controller;
|
||||||
|
|
||||||
use App\Download\Action\Input\DownloadMediaInput;
|
use App\Download\Action\Input\DownloadMediaInput;
|
||||||
use App\Download\Framework\Repository\DownloadRepository;
|
use App\Download\Framework\Repository\DownloadRepository;
|
||||||
@@ -12,7 +12,7 @@ use Symfony\Component\Mercure\Update;
|
|||||||
use Symfony\Component\Messenger\MessageBusInterface;
|
use Symfony\Component\Messenger\MessageBusInterface;
|
||||||
use Symfony\Component\Routing\Attribute\Route;
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
class DownloadController extends AbstractController
|
class ApiController extends AbstractController
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private DownloadRepository $downloadRepository,
|
private DownloadRepository $downloadRepository,
|
||||||
@@ -20,7 +20,7 @@ class DownloadController extends AbstractController
|
|||||||
private readonly HubInterface $hub,
|
private readonly HubInterface $hub,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
#[Route('/download', name: 'app_download', methods: ['POST'])]
|
#[Route('/api/download', name: 'api_download', methods: ['POST'])]
|
||||||
public function download(
|
public function download(
|
||||||
Request $request,
|
Request $request,
|
||||||
DownloadMediaInput $input,
|
DownloadMediaInput $input,
|
||||||
@@ -56,4 +56,4 @@ class DownloadController extends AbstractController
|
|||||||
|
|
||||||
return $this->json(['status' => 200, 'message' => 'Added to Queue']);
|
return $this->json(['status' => 200, 'message' => 'Added to Queue']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
27
src/Download/Framework/Controller/WebController.php
Normal file
27
src/Download/Framework/Controller/WebController.php
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Download\Framework\Controller;
|
||||||
|
|
||||||
|
use App\Download\Action\Input\DownloadMediaInput;
|
||||||
|
use App\Download\Framework\Repository\DownloadRepository;
|
||||||
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
use Symfony\Component\Mercure\HubInterface;
|
||||||
|
use Symfony\Component\Mercure\Update;
|
||||||
|
use Symfony\Component\Messenger\MessageBusInterface;
|
||||||
|
use Symfony\Component\Routing\Attribute\Route;
|
||||||
|
|
||||||
|
class WebController extends AbstractController
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private DownloadRepository $downloadRepository,
|
||||||
|
private MessageBusInterface $bus,
|
||||||
|
private readonly HubInterface $hub,
|
||||||
|
) {}
|
||||||
|
|
||||||
|
#[Route('/downloads', name: 'app_downloads', methods: ['GET'])]
|
||||||
|
public function download(): Response {
|
||||||
|
return $this->render('downloads/index.html.twig');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ use App\Download\Framework\Repository\DownloadRepository;
|
|||||||
use App\Util\Paginator;
|
use App\Util\Paginator;
|
||||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||||
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
|
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
|
||||||
|
use Symfony\UX\LiveComponent\Attribute\LiveProp;
|
||||||
use Symfony\UX\LiveComponent\DefaultActionTrait;
|
use Symfony\UX\LiveComponent\DefaultActionTrait;
|
||||||
|
|
||||||
#[AsLiveComponent]
|
#[AsLiveComponent]
|
||||||
@@ -15,6 +16,13 @@ final class DownloadList extends AbstractController
|
|||||||
|
|
||||||
public string $type;
|
public string $type;
|
||||||
|
|
||||||
|
#[LiveProp(writable: true)]
|
||||||
|
public int $pageNumber = 1;
|
||||||
|
|
||||||
|
#[LiveProp(writable: true)]
|
||||||
|
public int $perPage = 5;
|
||||||
|
|
||||||
|
#[LiveProp(writable: true)]
|
||||||
public bool $isWidget = true;
|
public bool $isWidget = true;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
@@ -24,9 +32,9 @@ final class DownloadList extends AbstractController
|
|||||||
public function getDownloads()
|
public function getDownloads()
|
||||||
{
|
{
|
||||||
if ($this->type === "active") {
|
if ($this->type === "active") {
|
||||||
return $this->downloadRepository->getActivePaginated($this->getUser());
|
return $this->downloadRepository->getActivePaginated($this->getUser(), $this->pageNumber, $this->perPage);
|
||||||
} elseif ($this->type === "complete") {
|
} elseif ($this->type === "complete") {
|
||||||
return $this->downloadRepository->getCompletePaginated($this->getUser());
|
return $this->downloadRepository->getCompletePaginated($this->getUser(), $this->pageNumber, $this->perPage);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [];
|
return [];
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-span-5 h-screen overflow-y-scroll">
|
<div class="col-span-5 h-screen overflow-y-scroll">
|
||||||
<twig:Header />
|
<twig:Header />
|
||||||
<h2 class="px-2 mb-2 text-3xl font-bold text-gray-50">{% block h2 %}{% endblock %}</h2>
|
<h2 class="px-4 my-2 text-3xl font-bold text-gray-50">{% block h2 %}{% endblock %}</h2>
|
||||||
{% block body %}{% endblock %}
|
{% block body %}{% endblock %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,12 +1,24 @@
|
|||||||
<div{{ attributes.defaults(stimulus_controller('download_list')) }} class="min-w-48" >
|
<div{{ attributes.defaults(stimulus_controller('download_list')) }} class="min-w-48" >
|
||||||
{% set table_body_id = (type == "complete") ? "complete_downloads" : "active_downloads" %}
|
{% set table_body_id = (type == "complete") ? "complete_downloads" : "active_downloads" %}
|
||||||
<table id="downloads" class="divide-y divide-gray-200 bg-gray-50 overflow-hidden rounded-lg table-fixed" {{ turbo_stream_listen('App\\Download\\Framework\\Entity\\Download') }}>
|
<table id="downloads" class="divide-y divide-gray-200 bg-gray-50 overflow-hidden rounded-lg table-auto" {{ turbo_stream_listen('App\\Download\\Framework\\Entity\\Download') }}>
|
||||||
<thead>
|
<thead>
|
||||||
<tr class="bg-orange-500 bg-filter bg-blur-lg bg-opacity-80 text-gray-950">
|
<tr class="bg-orange-500 bg-filter bg-blur-lg bg-opacity-80 text-gray-950">
|
||||||
<th scope="col"
|
<th scope="col"
|
||||||
class="px-6 py-3 text-start text-xs font-medium text-stone-500 uppercase dark:text-stone-800 min-w-[45ch] max-w-[45ch] truncate">
|
class="px-6 py-3 text-start text-xs font-medium text-stone-500 uppercase dark:text-stone-800 {% if this.isWidget == true %}min-w-[45ch] max-w-[45ch]{% endif %} truncate">
|
||||||
Title
|
Title
|
||||||
</th>
|
</th>
|
||||||
|
|
||||||
|
{% if this.isWidget == false %}
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-start text-xs font-medium text-stone-500 uppercase dark:text-stone-800 truncate">
|
||||||
|
Filename
|
||||||
|
</th>
|
||||||
|
<th scope="col"
|
||||||
|
class="px-6 py-3 text-start text-xs font-medium text-stone-500 uppercase dark:text-stone-800 truncate">
|
||||||
|
Media type
|
||||||
|
</th>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<th scope="col"
|
<th scope="col"
|
||||||
class="px-6 py-3 text-start text-xs font-medium text-gray-500 uppercase dark:text-stone-800">
|
class="px-6 py-3 text-start text-xs font-medium text-gray-500 uppercase dark:text-stone-800">
|
||||||
Progress
|
Progress
|
||||||
@@ -17,9 +29,19 @@
|
|||||||
{% if this.downloads.items|length > 0 %}
|
{% if this.downloads.items|length > 0 %}
|
||||||
{% for download in this.downloads.items %}
|
{% for download in this.downloads.items %}
|
||||||
<tr id="ad_download_{{ download.id }}">
|
<tr id="ad_download_{{ download.id }}">
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-stone-800 min-w-[45ch] max-w-[45ch] truncate">
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-stone-800 {% if this.isWidget == true %}min-w-[45ch] max-w-[45ch]{% endif %} truncate">
|
||||||
{{ download.title }}
|
{{ download.title }}
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
|
{% if this.isWidget == false %}
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-stone-800 truncate">
|
||||||
|
{{ download.filename }}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-800 dark:text-stone-800 truncate">
|
||||||
|
{{ download.mediaType }}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-sm align-middle text-gray-800 dark:text-gray-50">
|
<td class="px-6 py-4 whitespace-nowrap text-sm align-middle text-gray-800 dark:text-gray-50">
|
||||||
{% if download.progress < 100 %}
|
{% if download.progress < 100 %}
|
||||||
<div class="w-[3.25ch] h-[3.25ch] bg-purple-600 rounded-full block text-center table-cell align-middle text-xs text-gray-50">
|
<div class="w-[3.25ch] h-[3.25ch] bg-purple-600 rounded-full block text-center table-cell align-middle text-xs text-gray-50">
|
||||||
@@ -31,16 +53,16 @@
|
|||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
{% if this.downloads.items|length > 5 %}
|
{% if this.isWidget == true and this.downloads.items|length > this.perPage %}
|
||||||
<tr id="monitor_view_all">
|
<tr id="download_view_all">
|
||||||
<td colspan="5" class="py-2 whitespace-nowrap bg-orange-500 uppercase text-sm font-medium text-center text-white min-w-[50ch] max-w-[50ch] truncate">
|
<td class="py-2 whitespace-nowrap bg-orange-500 uppercase text-sm font-medium text-center text-white truncate" colspan="100%">
|
||||||
<a href="#">View All Monitors</a>
|
<a href="{{ path('app_downloads') }}">View All Downloads</a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<tr id="{{ table_body_id }}_no_downloads">
|
<tr id="{{ table_body_id }}_no_downloads">
|
||||||
<td class="px-6 py-4 whitespace-nowrap text-xs uppercase text-center col-span-2 font-medium text-gray-800 dark:text-stone-800" colspan="2">
|
<td class="px-6 py-4 whitespace-nowrap text-xs uppercase text-center font-medium text-gray-800 dark:text-stone-800" colspan="100%">
|
||||||
No downloads
|
No downloads
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -39,7 +39,7 @@
|
|||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li>
|
<li>
|
||||||
<a href="{{ path('app_search') }}"
|
<a href="{{ path('app_downloads') }}"
|
||||||
class="block rounded-lg px-4 py-2 text-sm font-medium text-gray-50 hover:bg-gray-100 hover:text-stone-700">
|
class="block rounded-lg px-4 py-2 text-sm font-medium text-gray-50 hover:bg-gray-100 hover:text-stone-700">
|
||||||
Complete
|
Complete
|
||||||
</a>
|
</a>
|
||||||
|
|||||||
18
templates/downloads/index.html.twig
Normal file
18
templates/downloads/index.html.twig
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
{% extends 'base.html.twig' %}
|
||||||
|
|
||||||
|
{% block title %}Downloads — Torsearch{% endblock %}
|
||||||
|
{% block h2 %}Downloads{% endblock %}
|
||||||
|
|
||||||
|
{% block body %}
|
||||||
|
<div class="p-4">
|
||||||
|
<twig:Card title="Active Downloads">
|
||||||
|
<twig:DownloadList type="active" :isWidget="false" :perPage="5"></twig:DownloadList>
|
||||||
|
</twig:Card>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-4">
|
||||||
|
<twig:Card title="Recent Downloads">
|
||||||
|
<twig:DownloadList type="complete" :isWidget="false" :perPage="10"></twig:DownloadList>
|
||||||
|
</twig:Card>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
{% set _currentRoute = app.request.attributes.get('_route') %}
|
{% set _currentRoute = app.request.attributes.get('_route') %}
|
||||||
{% set _lastPage = paginator.lastPage %}
|
{% set _lastPage = paginator.lastPage %}
|
||||||
{% set _currentParams = app.request.query.all|merge(app.request.attributes.get('_route_params')) %}
|
{% set _currentParams = app.request.query.all|merge(app.request.attributes.get('_route_params')) %}
|
||||||
|
{% set _showingPerPage = (_currentPage == _lastPage) ? paginator.total - (this.perPage * (_lastPage - 1)) : paginator.items.query.maxResults %}
|
||||||
|
|
||||||
|
<p class="text-white mt-1">Showing {{ _showingPerPage }} of {{ paginator.total }} results</p>
|
||||||
|
|
||||||
{% if paginator.lastPage > 1 %}
|
{% if paginator.lastPage > 1 %}
|
||||||
<nav>
|
<nav>
|
||||||
|
|||||||
Reference in New Issue
Block a user