Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| aa31701ac8 | |||
| 781e4dcd23 | |||
| b5cd240fbd | |||
| ce5bc525dd |
2
assets/bootstrap.js
vendored
2
assets/bootstrap.js
vendored
@@ -1,6 +1,8 @@
|
|||||||
import { startStimulusApp } from '@symfony/stimulus-bundle';
|
import { startStimulusApp } from '@symfony/stimulus-bundle';
|
||||||
import Popover from '@stimulus-components/popover'
|
import Popover from '@stimulus-components/popover'
|
||||||
|
import Dialog from '@stimulus-components/dialog'
|
||||||
|
|
||||||
const app = startStimulusApp();
|
const app = startStimulusApp();
|
||||||
// register any custom, 3rd party controllers here
|
// register any custom, 3rd party controllers here
|
||||||
app.register('popover', Popover);
|
app.register('popover', Popover);
|
||||||
|
app.register('dialog', Dialog);
|
||||||
|
|||||||
@@ -11,3 +11,40 @@
|
|||||||
font-size: var(--text-xl);
|
font-size: var(--text-xl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Prevent scrolling while dialog is open */
|
||||||
|
body:has(dialog[data-dialog-target="dialog"][open]) {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Customize the dialog backdrop */
|
||||||
|
dialog {
|
||||||
|
box-shadow: 0 0 0 100vw rgb(0 0 0 / 0.5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-in {
|
||||||
|
0% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes fade-out {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Add animations */
|
||||||
|
dialog[data-dialog-target="dialog"][open] {
|
||||||
|
animation: fade-in 200ms forwards;
|
||||||
|
}
|
||||||
|
|
||||||
|
dialog[data-dialog-target="dialog"][closing] {
|
||||||
|
animation: fade-out 200ms forwards;
|
||||||
|
}
|
||||||
|
|||||||
@@ -31,4 +31,7 @@ return [
|
|||||||
'@stimulus-components/popover' => [
|
'@stimulus-components/popover' => [
|
||||||
'version' => '7.0.0',
|
'version' => '7.0.0',
|
||||||
],
|
],
|
||||||
|
'@stimulus-components/dialog' => [
|
||||||
|
'version' => '1.0.1',
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@@ -52,13 +52,13 @@ final class TorrentioController extends AbstractController
|
|||||||
$input->episode,
|
$input->episode,
|
||||||
);
|
);
|
||||||
|
|
||||||
return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
// return $cache->get($cacheId, function (ItemInterface $item) use ($input) {
|
||||||
$item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
// $item->expiresAt(Carbon::now()->addHour()->setMinute(0)->setSecond(0));
|
||||||
$results = $this->getTvShowOptionsHandler->handle($input->toCommand());
|
$results = $this->getTvShowOptionsHandler->handle($input->toCommand());
|
||||||
return $this->render('torrentio/tvshows.html.twig', [
|
return $this->render('torrentio/tvshows.html.twig', [
|
||||||
'results' => $results,
|
'results' => $results,
|
||||||
]);
|
]);
|
||||||
});
|
// });
|
||||||
}
|
}
|
||||||
|
|
||||||
#[Route('/torrentio/tvshows/clear/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_clear_torrentio_tvshows')]
|
#[Route('/torrentio/tvshows/clear/{tmdbId}/{imdbId}/{season?}/{episode?}', name: 'app_clear_torrentio_tvshows')]
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class DownloadRepository extends ServiceEntityRepository
|
|||||||
$query = $this->createQueryBuilder('d')
|
$query = $this->createQueryBuilder('d')
|
||||||
->andWhere('d.status IN (:statuses)')
|
->andWhere('d.status IN (:statuses)')
|
||||||
->andWhere('d.user = :user')
|
->andWhere('d.user = :user')
|
||||||
->andWhere('(d.title LIKE :term OR d.imdbId LIKE :term)')
|
->andWhere('(d.title LIKE :term OR d.filename LIKE :term OR d.imdbId LIKE :term OR d.status LIKE :term OR d.mediaType LIKE :term)')
|
||||||
->orderBy('d.id', 'DESC')
|
->orderBy('d.id', 'DESC')
|
||||||
->setParameter('statuses', ['Complete'])
|
->setParameter('statuses', ['Complete'])
|
||||||
->setParameter('user', $user)
|
->setParameter('user', $user)
|
||||||
@@ -45,7 +45,7 @@ class DownloadRepository extends ServiceEntityRepository
|
|||||||
$query = $this->createQueryBuilder('d')
|
$query = $this->createQueryBuilder('d')
|
||||||
->andWhere('d.status IN (:statuses)')
|
->andWhere('d.status IN (:statuses)')
|
||||||
->andWhere('d.user = :user')
|
->andWhere('d.user = :user')
|
||||||
->andWhere('(d.title LIKE :term OR d.imdbId LIKE :term)')
|
->andWhere('(d.title LIKE :term OR d.filename LIKE :term OR d.imdbId LIKE :term OR d.status LIKE :term OR d.mediaType LIKE :term)')
|
||||||
->orderBy('d.id', 'ASC')
|
->orderBy('d.id', 'ASC')
|
||||||
->setParameter('statuses', ['New', 'In Progress'])
|
->setParameter('statuses', ['New', 'In Progress'])
|
||||||
->setParameter('user', $user)
|
->setParameter('user', $user)
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ class MonitorRepository extends ServiceEntityRepository
|
|||||||
$this->paginator = $paginator;
|
$this->paginator = $paginator;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getUserMonitorsPaginated(UserInterface $user, int $page, int $perPage): Paginator
|
public function getUserMonitorsPaginated(UserInterface $user, int $page, int $perPage, string $searchTerm): Paginator
|
||||||
{
|
{
|
||||||
$query = $this->createQueryBuilder('m')
|
$query = $this->createQueryBuilder('m')
|
||||||
->andWhere('m.status IN (:statuses)')
|
->andWhere('m.status IN (:statuses)')
|
||||||
|
|||||||
10
src/Twig/Components/Modal.php
Normal file
10
src/Twig/Components/Modal.php
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Twig\Components;
|
||||||
|
|
||||||
|
use Symfony\UX\TwigComponent\Attribute\AsTwigComponent;
|
||||||
|
|
||||||
|
#[AsTwigComponent]
|
||||||
|
final class Modal
|
||||||
|
{
|
||||||
|
}
|
||||||
@@ -17,6 +17,9 @@ final class MonitorList extends AbstractController
|
|||||||
|
|
||||||
use PaginateTrait;
|
use PaginateTrait;
|
||||||
|
|
||||||
|
#[LiveProp(writable: true)]
|
||||||
|
public string $term = "";
|
||||||
|
|
||||||
#[LiveProp(writable: true)]
|
#[LiveProp(writable: true)]
|
||||||
public string $type;
|
public string $type;
|
||||||
|
|
||||||
@@ -44,7 +47,9 @@ final class MonitorList extends AbstractController
|
|||||||
{
|
{
|
||||||
return $this->asPaginator($this->monitorRepository->createQueryBuilder('m')
|
return $this->asPaginator($this->monitorRepository->createQueryBuilder('m')
|
||||||
->andWhere('m.status IN (:statuses)')
|
->andWhere('m.status IN (:statuses)')
|
||||||
|
->andWhere('(m.title LIKE :term OR m.imdbId LIKE :term OR m.monitorType LIKE :term OR m.status LIKE :term)')
|
||||||
->setParameter('statuses', ['New', 'In Progress'])
|
->setParameter('statuses', ['New', 'In Progress'])
|
||||||
|
->setParameter('term', '%'.$this->term.'%')
|
||||||
->orderBy('m.id', 'DESC')
|
->orderBy('m.id', 'DESC')
|
||||||
->getQuery()
|
->getQuery()
|
||||||
);
|
);
|
||||||
@@ -55,7 +60,9 @@ final class MonitorList extends AbstractController
|
|||||||
{
|
{
|
||||||
return $this->asPaginator($this->monitorRepository->createQueryBuilder('m')
|
return $this->asPaginator($this->monitorRepository->createQueryBuilder('m')
|
||||||
->andWhere('m.status = :status')
|
->andWhere('m.status = :status')
|
||||||
|
->andWhere('(m.title LIKE :term OR m.imdbId LIKE :term OR m.monitorType LIKE :term OR m.status LIKE :term)')
|
||||||
->setParameter('status', 'Complete')
|
->setParameter('status', 'Complete')
|
||||||
|
->setParameter('term', '%'.$this->term.'%')
|
||||||
->orderBy('m.id', 'DESC')
|
->orderBy('m.id', 'DESC')
|
||||||
->getQuery()
|
->getQuery()
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -33,12 +33,10 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 flex flex-row align-middle justify-center">
|
<td class="px-6 py-4 flex flex-row align-middle justify-center">
|
||||||
<button {{ stimulus_action('download_list', 'deleteDownload', 'click', {id: download.id}) }}>
|
{% set delete_button = component('ux:icon', {name: 'ic:twotone-cancel', width: '18px', class: 'rounded-full align-middle text-red-600' }) %}
|
||||||
<twig:ux:icon
|
<twig:Modal heading="But wait!" button_text="{{ delete_button }}" submit_action="{{ stimulus_action('download_list', 'deleteDownload', 'click', {id: download.id}) }}" show_cancel show_submit>
|
||||||
name="ic:twotone-cancel" width="18px"
|
Are you sure you want to delete <span class="font-bold">{{ download.filename }}</span>?
|
||||||
class="rounded-full align-middle text-red-600"
|
</twig:Modal>
|
||||||
title="Remove {{ download.title }} from your Download list. This will not delete the file."
|
|
||||||
/>
|
|
||||||
</button>
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
26
templates/components/Modal.html.twig
Normal file
26
templates/components/Modal.html.twig
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<div{{ attributes }} data-controller="dialog" data-action="click->dialog#backdropClose">
|
||||||
|
<dialog data-dialog-target="dialog" class="py-3 px-4 w-[30rem] rounded-md">
|
||||||
|
<h2 class="mb-4 text-2xl font-bold">{{ heading }}</h2>
|
||||||
|
|
||||||
|
<div class="mb-4">
|
||||||
|
{% block content %}{% endblock %}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{% if show_cancel is defined or show_submit is defined %}
|
||||||
|
<div class="flex justify-end">
|
||||||
|
{% if show_cancel is defined %}
|
||||||
|
<button type="button" data-action="dialog#close" class="px-1 py-1 rounded-md self-end w-16 hover:bg-stone-100" autofocus>
|
||||||
|
{{ cancel_text|default('Cancel') }}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
{% if show_submit is defined %}
|
||||||
|
<button type="button" {{ submit_action|raw }} class="px-1 py-1 rounded-md bg-orange-500 self-end text-white w-16 ml-2 hover:bg-orange-600" autofocus>
|
||||||
|
{{ submit_text|default('Submit') }}
|
||||||
|
</button>
|
||||||
|
{% endif %}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
</dialog>
|
||||||
|
|
||||||
|
<button type="button" data-action="dialog#open">{{ button_text|raw }}</button>
|
||||||
|
</div>
|
||||||
@@ -1,4 +1,9 @@
|
|||||||
<div{{ attributes.defaults(stimulus_controller('monitor_list')) }}>
|
<div{{ attributes.defaults(stimulus_controller('monitor_list')) }}>
|
||||||
|
{% if this.isWidget == false %}
|
||||||
|
<div class="flex flex-row mb-2 justify-end">
|
||||||
|
<twig:DownloadSearch search_path="app_search" placeholder="Find one of your monitors..." />
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
<table id="monitor_list" class="divide-y divide-gray-200 bg-gray-50 overflow-hidden rounded-lg table-auto w-full" {{ turbo_stream_listen('App\\Monitor\\Framework\\Entity\\Monitor') }}>
|
<table id="monitor_list" class="divide-y divide-gray-200 bg-gray-50 overflow-hidden rounded-lg table-auto w-full" {{ turbo_stream_listen('App\\Monitor\\Framework\\Entity\\Monitor') }}>
|
||||||
<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">
|
||||||
|
|||||||
@@ -33,12 +33,41 @@
|
|||||||
{% endif %}
|
{% endif %}
|
||||||
</td>
|
</td>
|
||||||
<td class="px-6 py-4 flex flex-row align-middle justify-center">
|
<td class="px-6 py-4 flex flex-row align-middle justify-center">
|
||||||
<button {{ stimulus_action('monitor_list', 'deleteMonitor', 'click', {id: monitor.id}) }}>
|
{% set delete_button = component('ux:icon', {name: 'ic:twotone-cancel', width: '18px', class: 'rounded-full align-middle text-red-600' }) %}
|
||||||
<twig:ux:icon
|
<twig:Modal heading="But wait!" button_text="{{ delete_button }}" submit_action="{{ stimulus_action('monitor_list', 'deleteMonitor', 'click', {id: monitor.id}) }}" show_cancel show_submit>
|
||||||
name="ic:twotone-cancel" width="18px"
|
Are you sure you want to delete this monitor?<br />
|
||||||
class="rounded-full align-middle text-red-600"
|
<div class="mt-2 border-2 border-orange-500 overflow-hidden rounded-lg">
|
||||||
title="Remove {{ monitor.title }} from your Monitor list."
|
<table class="table-auto">
|
||||||
/>
|
<tr>
|
||||||
</button>
|
<td class="px-6 py-4 whitespace-nowrap text-sm font-medium text-stone-800 truncate">
|
||||||
|
{{ monitor.title }}
|
||||||
|
</td>
|
||||||
|
{% if monitor|monitor_media_id != "-" %}
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800">
|
||||||
|
{{ monitor|monitor_media_id }}
|
||||||
|
</td>
|
||||||
|
{% endif %}
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800">
|
||||||
|
{% if monitor.monitorType == "tvshow" %}
|
||||||
|
<twig:StatusBadge color="blue" number="300" text="black" status="{{ monitor.monitorType|monitor_type }}" />
|
||||||
|
{% elseif monitor.monitorType == "tvseason" %}
|
||||||
|
<twig:StatusBadge color="orange" number="300" text="black" status="{{ monitor.monitorType|monitor_type }}" />
|
||||||
|
{% else %}
|
||||||
|
<twig:StatusBadge color="fuchsia" number="300" text="black" status="{{ monitor.monitorType|monitor_type }}" />
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
<td class="px-6 py-4 whitespace-nowrap text-sm text-gray-800">
|
||||||
|
{% if monitor.status == "New" %}
|
||||||
|
<twig:StatusBadge color="orange" status="{{ monitor.status }}" />
|
||||||
|
{% elseif monitor.status == "In Progress" or monitor.status == "Active" %}
|
||||||
|
<twig:StatusBadge color="purple" status="{{ monitor.status }}" />
|
||||||
|
{% else %}
|
||||||
|
<twig:StatusBadge color="green" status="{{ monitor.status }}" />
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
</twig:Modal>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|||||||
@@ -13,11 +13,11 @@
|
|||||||
</h4>
|
</h4>
|
||||||
<p>{{ results.media.description }}</p>
|
<p>{{ results.media.description }}</p>
|
||||||
<div>
|
<div>
|
||||||
<small class="py-1 px-1.5 mr-1 grow-0 font-bold bg-green-600 rounded-lg hover:cursor-pointer hover:bg-green-700 text-white"
|
<button class="py-1 px-1.5 mr-1 grow-0 font-bold text-xs bg-green-600 rounded-lg hover:cursor-pointer hover:bg-green-700 text-white"
|
||||||
{{ stimulus_action('tv-results', 'toggleList', 'click') }}
|
{{ stimulus_action('tv-results', 'toggleList', 'click') }}
|
||||||
>
|
>
|
||||||
<span {{ stimulus_target('tv-results', 'count') }}>{{ results.results|length }}</span> results
|
<span {{ stimulus_target('tv-results', 'count') }}>{{ results.results|length }}</span> results
|
||||||
</small>
|
</button>
|
||||||
|
|
||||||
{% if results.file != false %}
|
{% if results.file != false %}
|
||||||
<span data-controller="popover">
|
<span data-controller="popover">
|
||||||
@@ -57,16 +57,13 @@
|
|||||||
<input type="checkbox"
|
<input type="checkbox"
|
||||||
{{ stimulus_target('tv-results', 'episodeSelector') }}
|
{{ stimulus_target('tv-results', 'episodeSelector') }}
|
||||||
/>
|
/>
|
||||||
<span title="You have this downloaded!">
|
|
||||||
<twig:ux:icon width="20" class="mt-2 text-green-600" name="line-md:circle-twotone" />
|
|
||||||
</span>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="flex flex-col items-end hover:cursor-pointer"
|
<button class="flex flex-col items-end"
|
||||||
{{ stimulus_action('tv-results', 'toggleList', 'click') }}>
|
{{ stimulus_action('tv-results', 'toggleList', 'click') }}>
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" viewBox="0 0 32 32">
|
<svg xmlns="http://www.w3.org/2000/svg" width="2em" height="2em" viewBox="0 0 32 32">
|
||||||
<path fill="currentColor" d="m16 10l10 10l-1.4 1.4l-8.6-8.6l-8.6 8.6L6 20z"/>
|
<path fill="currentColor" d="m16 10l10 10l-1.4 1.4l-8.6-8.6l-8.6 8.6L6 20z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="inline-block overflow-hidden rounded-lg">
|
<div class="inline-block overflow-hidden rounded-lg">
|
||||||
|
|||||||
Reference in New Issue
Block a user