wip: adds downloads page, makes DownloadList a widget or a full page list

This commit is contained in:
2025-05-13 11:18:08 -05:00
parent 8967d407cb
commit e230913c89
10 changed files with 103 additions and 17 deletions

View File

@@ -15,7 +15,7 @@ export default class extends Controller {
}
download() {
fetch('/download', {
fetch('/api/download', {
method: 'POST',
headers: {
'Content-Type': 'application/json',

View File

@@ -14,6 +14,14 @@ controllersUser:
defaults:
schemes: ['https']
controllersDownload:
resource:
path: ../src/Download/Framework/Controller
namespace: App\Download\Framework\Controller
type: attribute
defaults:
schemes: [ 'https' ]
controllersMonitor:
resource:
path: ../src/Monitor/Framework/Controller

View File

@@ -1,6 +1,6 @@
<?php
namespace App\Controller;
namespace App\Download\Framework\Controller;
use App\Download\Action\Input\DownloadMediaInput;
use App\Download\Framework\Repository\DownloadRepository;
@@ -12,7 +12,7 @@ use Symfony\Component\Mercure\Update;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Routing\Attribute\Route;
class DownloadController extends AbstractController
class ApiController extends AbstractController
{
public function __construct(
private DownloadRepository $downloadRepository,
@@ -20,7 +20,7 @@ class DownloadController extends AbstractController
private readonly HubInterface $hub,
) {}
#[Route('/download', name: 'app_download', methods: ['POST'])]
#[Route('/api/download', name: 'api_download', methods: ['POST'])]
public function download(
Request $request,
DownloadMediaInput $input,

View 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');
}
}

View File

@@ -6,6 +6,7 @@ use App\Download\Framework\Repository\DownloadRepository;
use App\Util\Paginator;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\UX\LiveComponent\Attribute\AsLiveComponent;
use Symfony\UX\LiveComponent\Attribute\LiveProp;
use Symfony\UX\LiveComponent\DefaultActionTrait;
#[AsLiveComponent]
@@ -15,6 +16,13 @@ final class DownloadList extends AbstractController
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 function __construct(
@@ -24,9 +32,9 @@ final class DownloadList extends AbstractController
public function getDownloads()
{
if ($this->type === "active") {
return $this->downloadRepository->getActivePaginated($this->getUser());
return $this->downloadRepository->getActivePaginated($this->getUser(), $this->pageNumber, $this->perPage);
} elseif ($this->type === "complete") {
return $this->downloadRepository->getCompletePaginated($this->getUser());
return $this->downloadRepository->getCompletePaginated($this->getUser(), $this->pageNumber, $this->perPage);
}
return [];

View File

@@ -19,7 +19,7 @@
</div>
<div class="col-span-5 h-screen overflow-y-scroll">
<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 %}
</div>
</div>

View File

@@ -1,12 +1,24 @@
<div{{ attributes.defaults(stimulus_controller('download_list')) }} class="min-w-48" >
{% 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>
<tr class="bg-orange-500 bg-filter bg-blur-lg bg-opacity-80 text-gray-950">
<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
</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"
class="px-6 py-3 text-start text-xs font-medium text-gray-500 uppercase dark:text-stone-800">
Progress
@@ -17,9 +29,19 @@
{% if this.downloads.items|length > 0 %}
{% for download in this.downloads.items %}
<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 }}
</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">
{% 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">
@@ -31,16 +53,16 @@
</td>
</tr>
{% endfor %}
{% if this.downloads.items|length > 5 %}
<tr id="monitor_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">
<a href="#">View All Monitors</a>
{% if this.isWidget == true and this.downloads.items|length > this.perPage %}
<tr id="download_view_all">
<td class="py-2 whitespace-nowrap bg-orange-500 uppercase text-sm font-medium text-center text-white truncate" colspan="100%">
<a href="{{ path('app_downloads') }}">View All Downloads</a>
</td>
</tr>
{% endif %}
{% else %}
<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
</td>
</tr>

View File

@@ -39,7 +39,7 @@
</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">
Complete
</a>

View File

@@ -0,0 +1,18 @@
{% extends 'base.html.twig' %}
{% block title %}Downloads &mdash; 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 %}

View File

@@ -2,6 +2,9 @@
{% set _currentRoute = app.request.attributes.get('_route') %}
{% set _lastPage = paginator.lastPage %}
{% 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 %}
<nav>