fix: filter style tweaks, loading icon patch
This commit is contained in:
@@ -14,7 +14,22 @@ export default class extends Controller {
|
|||||||
static targets = ['icon']
|
static targets = ['icon']
|
||||||
|
|
||||||
connect() {
|
connect() {
|
||||||
|
this.element.hideIcon = this.hideIcon.bind(this);
|
||||||
|
this.element.showIcon = this.showIcon.bind(this);
|
||||||
|
this.element.toggleIcon = this.toggleIcon.bind(this);
|
||||||
|
this.element.isVisibile = this.isVisible.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
isVisible() {
|
||||||
|
return !this.iconTarget.classList.contains('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
showIcon() {
|
||||||
|
this.iconTarget.classList.remove('hidden');
|
||||||
|
}
|
||||||
|
|
||||||
|
hideIcon() {
|
||||||
|
this.iconTarget.classList.add('hidden');
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleIcon() {
|
toggleIcon() {
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ export default class extends Controller {
|
|||||||
defaultOptions = '<option value="">n/a</option><option value="-">-</option>';
|
defaultOptions = '<option value="">n/a</option><option value="-">-</option>';
|
||||||
|
|
||||||
static outlets = ['tv-episode-list']
|
static outlets = ['tv-episode-list']
|
||||||
static targets = ['resolution', 'codec', 'language', 'provider', 'season', 'quality', 'selectAll', 'downloadSelected']
|
static targets = ['resolution', 'codec', 'language', 'provider', 'season', 'quality', 'loadingIcon', 'selectAll', 'downloadSelected']
|
||||||
static values = {
|
static values = {
|
||||||
'imdbId': String,
|
'imdbId': String,
|
||||||
'media-type': String,
|
'media-type': String,
|
||||||
@@ -34,19 +34,24 @@ export default class extends Controller {
|
|||||||
if (this.mediaTypeValue === "tvshows") {
|
if (this.mediaTypeValue === "tvshows") {
|
||||||
this.activeFilter['season'] = 1;
|
this.activeFilter['season'] = 1;
|
||||||
}
|
}
|
||||||
await this.filter();
|
this.filter();
|
||||||
|
this.setTimerToStopLoadingIcon();
|
||||||
|
|
||||||
document.addEventListener('optionsLoaded', this.loadOptions.bind(this));
|
document.addEventListener('optionsLoaded', this.loadOptions.bind(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setTimerToStopLoadingIcon() {
|
||||||
|
setTimeout(() => this.loadingIconTarget.hideIcon(), 10000);
|
||||||
|
}
|
||||||
|
|
||||||
// Event is fired from movies/tvshows controllers to populate this data
|
// Event is fired from movies/tvshows controllers to populate this data
|
||||||
async loadOptions({detail: { options }}) {
|
loadOptions({detail: { options }}) {
|
||||||
await options.forEach((option) => {
|
options.forEach((option) => {
|
||||||
this.addLanguages(option);
|
this.addLanguages(option);
|
||||||
this.addProviders(option);
|
this.addProviders(option);
|
||||||
this.addQualities(option);
|
this.addQualities(option);
|
||||||
})
|
})
|
||||||
await this.filter();
|
this.filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
selectAllEpisodes() {
|
selectAllEpisodes() {
|
||||||
@@ -96,7 +101,7 @@ export default class extends Controller {
|
|||||||
this.qualityTarget.tomselect.items = preferred;
|
this.qualityTarget.tomselect.items = preferred;
|
||||||
}
|
}
|
||||||
|
|
||||||
async filter() {
|
filter() {
|
||||||
const downloadSeasonSpan = document.querySelector("#downloadSeasonModal");
|
const downloadSeasonSpan = document.querySelector("#downloadSeasonModal");
|
||||||
|
|
||||||
this.activeFilter = {
|
this.activeFilter = {
|
||||||
|
|||||||
1
assets/icons/zondicons/checkmark.svg
Normal file
1
assets/icons/zondicons/checkmark.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="https://www.w3.org/2000/svg" viewBox="0 0 20 20"><path fill="currentColor" d="m0 11l2-2l5 5L18 3l2 2L7 18z"/></svg>
|
||||||
|
After Width: | Height: | Size: 127 B |
@@ -8,7 +8,10 @@ use App\User\Database\CountryLanguages;
|
|||||||
use App\User\Database\ProviderList;
|
use App\User\Database\ProviderList;
|
||||||
use App\User\Database\QualityList;
|
use App\User\Database\QualityList;
|
||||||
use App\User\Database\ResolutionList;
|
use App\User\Database\ResolutionList;
|
||||||
|
use App\User\Dto\UserPreferences;
|
||||||
|
use App\User\Dto\UserPreferencesFactory;
|
||||||
use App\User\Framework\Repository\PreferenceOptionRepository;
|
use App\User\Framework\Repository\PreferenceOptionRepository;
|
||||||
|
use Symfony\Bundle\SecurityBundle\Security;
|
||||||
use Symfony\Component\Form\AbstractType;
|
use Symfony\Component\Form\AbstractType;
|
||||||
use Symfony\Component\Form\Event\PreSetDataEvent;
|
use Symfony\Component\Form\Event\PreSetDataEvent;
|
||||||
use Symfony\Component\Form\Event\PreSubmitEvent;
|
use Symfony\Component\Form\Event\PreSubmitEvent;
|
||||||
@@ -21,9 +24,14 @@ use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
|||||||
|
|
||||||
class UserMediaPreferencesForm extends AbstractType
|
class UserMediaPreferencesForm extends AbstractType
|
||||||
{
|
{
|
||||||
|
private UserPreferences $userPreferences;
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly UrlGeneratorInterface $urlGenerator,
|
private readonly UrlGeneratorInterface $urlGenerator,
|
||||||
) {}
|
private readonly Security $security,
|
||||||
|
) {
|
||||||
|
$this->userPreferences = UserPreferencesFactory::createFromUser($security->getUser());
|
||||||
|
}
|
||||||
|
|
||||||
public function buildForm(FormBuilderInterface $builder, array $options): void
|
public function buildForm(FormBuilderInterface $builder, array $options): void
|
||||||
{
|
{
|
||||||
@@ -42,6 +50,7 @@ class UserMediaPreferencesForm extends AbstractType
|
|||||||
'data-result-filter-target' => $fieldName,
|
'data-result-filter-target' => $fieldName,
|
||||||
'data-controller' => 'symfony--ux-autocomplete--autocomplete',
|
'data-controller' => 'symfony--ux-autocomplete--autocomplete',
|
||||||
'data-symfony--ux-autocomplete--autocomplete-tom-select-options-value' => '{"highlight":false}',
|
'data-symfony--ux-autocomplete--autocomplete-tom-select-options-value' => '{"highlight":false}',
|
||||||
|
'data-preferred' => \json_encode($this->userPreferences->$fieldName),
|
||||||
],
|
],
|
||||||
'row_attr' => [
|
'row_attr' => [
|
||||||
'class' => 'filter-label'
|
'class' => 'filter-label'
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ module.exports = {
|
|||||||
"bg-orange-400",
|
"bg-orange-400",
|
||||||
"bg-blue-600",
|
"bg-blue-600",
|
||||||
"bg-rose-600",
|
"bg-rose-600",
|
||||||
|
"bg-black/20",
|
||||||
"alert-success",
|
"alert-success",
|
||||||
"alert-warning",
|
"alert-warning",
|
||||||
"font-bold",
|
"font-bold",
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
>
|
>
|
||||||
{% set preferences_form = form %}
|
{% set preferences_form = form %}
|
||||||
{{ form_start(preferences_form) }}
|
{{ form_start(preferences_form) }}
|
||||||
<div class="flex flex-row gap-2 justify-between">
|
<div class="flex flex-col md:flex-row gap-2 justify-between">
|
||||||
{{ form_row(preferences_form.resolution) }}
|
{{ form_row(preferences_form.resolution) }}
|
||||||
{{ form_row(preferences_form.codec) }}
|
{{ form_row(preferences_form.codec) }}
|
||||||
{{ form_row(preferences_form.language) }}
|
{{ form_row(preferences_form.language) }}
|
||||||
@@ -16,11 +16,11 @@
|
|||||||
{{ form_row(preferences_form.quality) }}
|
{{ form_row(preferences_form.quality) }}
|
||||||
|
|
||||||
{% if results.media.mediaType == "tvshows" %}
|
{% if results.media.mediaType == "tvshows" %}
|
||||||
<div class="filter-label">
|
<div class="flex flex-col gap-1 md:gap-3">
|
||||||
<label for="season">
|
<label for="season">
|
||||||
Season
|
Season
|
||||||
</label>
|
</label>
|
||||||
<select id="season" name="season" value="1" data-result-filter-target="season" class="px-1 mb-4 py-0.5 bg-stone-100 text-gray-800"
|
<select id="season" name="season" value="1" data-result-filter-target="season" class="px-1 mb-4 py-1 md:py-2 text-center bg-orange-500 text-white rounded-ms"
|
||||||
{{ stimulus_action('result_filter', 'setSeason', 'change') }}
|
{{ stimulus_action('result_filter', 'setSeason', 'change') }}
|
||||||
{{ stimulus_action('result_filter', 'uncheckSelectAllBtn', 'change') }}
|
{{ stimulus_action('result_filter', 'uncheckSelectAllBtn', 'change') }}
|
||||||
>
|
>
|
||||||
@@ -35,33 +35,36 @@
|
|||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<span {{ stimulus_controller('loading_icon', {total: (results.media.mediaType == "tvshows") ? results.media.episodes[1]|length : 1, count: 0}) }}
|
|
||||||
class="loading-icon">
|
|
||||||
<twig:ux:icon name="codex:loader" height="20" width="20" data-loading-icon-target="icon" class="text-end" />
|
|
||||||
</span>
|
|
||||||
{{ form_end(preferences_form) }}
|
{{ form_end(preferences_form) }}
|
||||||
|
|
||||||
|
<div class="flex flex-col md:flex-row justify-between">
|
||||||
|
<span
|
||||||
|
{{ stimulus_target('result-filter', 'loadingIcon') }}
|
||||||
|
{{ stimulus_controller('loading_icon', {total: (results.media.mediaType == "tvshows") ? results.media.episodes[1]|length : 1, count: 0}) }}
|
||||||
|
class="loading-icon">
|
||||||
|
<twig:ux:icon name="codex:loader" height="20" width="20" data-loading-icon-target="icon" class="text-end" />
|
||||||
|
</span>
|
||||||
|
|
||||||
{% if results.media.mediaType == "tvshows" %}
|
{% if results.media.mediaType == "tvshows" %}
|
||||||
<div class="flex flex-row gap-2 justify-end px-8">
|
<div class="flex flex-row gap-2 justify-end px-8">
|
||||||
<twig:Modal heading="Back up a sec!" button_text="Download Season" submit_action="{{ stimulus_action('result_filter', 'downloadSeason', 'click')|stimulus_action('dialog', 'close') }}" button_class="px-1.5 py-1 border border-green-500 bg-green-800/60 rounded-ms text-sm font-semibold" show_cancel show_submit>
|
<twig:Modal heading="Back up a sec!" button_text="Download Season" submit_action="{{ stimulus_action('result_filter', 'downloadSeason', 'click')|stimulus_action('dialog', 'close') }}" button_class="px-1.5 py-1 border border-green-500 bg-green-800/60 rounded-ms text-sm font-semibold" show_cancel show_submit>
|
||||||
Downloading an entire season this way will use the filter from your
|
Downloading an entire season this way will use the filter from your
|
||||||
<a href="{{ path('app_user_preferences') }}" class="text-underline">preferences</a> to choose
|
<a href="{{ path('app_user_preferences') }}" class="text-underline">preferences</a> to choose
|
||||||
the appropriate file(s).
|
the appropriate file(s).
|
||||||
<br /><br />
|
<br /><br />
|
||||||
Do you wish to download <strong>season <span id="downloadSeasonModal">{{ results.season }}</span></strong> of "<strong>{{ results.media.title }}</strong>"?
|
Do you wish to download <strong>season <span id="downloadSeasonModal">{{ results.season }}</span></strong> of "<strong>{{ results.media.title }}</strong>"?
|
||||||
</twig:Modal>
|
</twig:Modal>
|
||||||
|
|
||||||
<button class="px-1.5 py-1 bg-green-800/60 hover:bg-green-700/60 border border-green-500 rounded-ms text-sm font-semibold"
|
<button class="px-1.5 py-1 bg-green-800/60 hover:bg-green-700/60 border border-green-500 rounded-ms text-sm font-semibold"
|
||||||
{{ stimulus_target('result_filter', 'downloadSelected') }}
|
{{ stimulus_target('result_filter', 'downloadSelected') }}
|
||||||
{{ stimulus_action('result_filter', 'downloadSelectedEpisodes', 'click') }}
|
{{ stimulus_action('result_filter', 'downloadSelectedEpisodes', 'click') }}
|
||||||
>Download Selected</button>
|
>Download Selected</button>
|
||||||
|
|
||||||
<input type="checkbox" name="selectAll" id="selectAll"
|
<input type="checkbox" name="selectAll" id="selectAll"
|
||||||
{{ stimulus_target('result_filter', 'selectAll') }}
|
{{ stimulus_target('result_filter', 'selectAll') }}
|
||||||
{{ stimulus_action('result_filter', 'selectAllEpisodes', 'change') }}
|
{{ stimulus_action('result_filter', 'selectAllEpisodes', 'change') }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
<div class="w-full flex flex-col">
|
<div class="w-full flex flex-col">
|
||||||
<h3 class="mb-4 text-xl font-medium leading-tight font-bold text-gray-50">
|
<h3 class="mb-4 text-xl font-medium leading-tight font-bold text-gray-50">
|
||||||
{{ title }} - {{ year }}
|
{{ title }} ({{ year }})
|
||||||
</h3>
|
</h3>
|
||||||
<p class="hidden md:block md:text-gray-50">
|
<p class="hidden md:block md:text-gray-50">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
|
|||||||
8
templates/components/SubmitButton.html.twig
Normal file
8
templates/components/SubmitButton.html.twig
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<button class="submit-button flex flex-row gap-2 items-center">
|
||||||
|
{% if show_icon|default %}
|
||||||
|
<twig:ux:icon name="zondicons:checkmark" width=".8rem" class="text-green-500" />
|
||||||
|
{% endif %}
|
||||||
|
{% if false == icon_only|default(false) %}
|
||||||
|
{{ text|default('submit') }}
|
||||||
|
{% endif %}
|
||||||
|
</button>
|
||||||
@@ -19,7 +19,7 @@
|
|||||||
<div class="w-full flex flex-col">
|
<div class="w-full flex flex-col">
|
||||||
<div class="mb-4 flex flex-row gap-2 justify-between">
|
<div class="mb-4 flex flex-row gap-2 justify-between">
|
||||||
<h3 class="text-xl font-medium leading-tight font-bold text-gray-50">
|
<h3 class="text-xl font-medium leading-tight font-bold text-gray-50">
|
||||||
{{ results.media.title }} - {{ results.media.year }}
|
{{ results.media.title }} ({{ results.media.year }})
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
{% if results.media.mediaType == "tvshows" %}
|
{% if results.media.mediaType == "tvshows" %}
|
||||||
|
|||||||
@@ -7,17 +7,15 @@
|
|||||||
<twig:Card title="Media Preferences" class="w-full">
|
<twig:Card title="Media Preferences" class="w-full">
|
||||||
<p class="text-gray-50 mb-4">Define a filter to be pre-applied to your download options.</p>
|
<p class="text-gray-50 mb-4">Define a filter to be pre-applied to your download options.</p>
|
||||||
<div id="filter">
|
<div id="filter">
|
||||||
{{ form_start(preferences_form.instantiateForm) }}
|
{{ form_start(preferences_form) }}
|
||||||
<div class="flex flex-row gap-2">
|
<div class="flex flex-col md:flex-row gap-2">
|
||||||
{{ form_row(preferences_form.resolution) }}
|
{{ form_row(preferences_form.resolution) }}
|
||||||
{{ form_row(preferences_form.codec) }}
|
{{ form_row(preferences_form.codec) }}
|
||||||
{{ form_row(preferences_form.language) }}
|
{{ form_row(preferences_form.language) }}
|
||||||
{{ form_row(preferences_form.provider) }}
|
{{ form_row(preferences_form.provider) }}
|
||||||
{{ form_row(preferences_form.quality) }}
|
{{ form_row(preferences_form.quality) }}
|
||||||
</div>
|
<div class="self-end mb-4">
|
||||||
<div class="flex flex-row justify-end">
|
<twig:SubmitButton show_icon text="Save"/>
|
||||||
<div>
|
|
||||||
<button class="submit-button">Save</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ form_end(preferences_form) }}
|
{{ form_end(preferences_form) }}
|
||||||
|
|||||||
Reference in New Issue
Block a user