diff --git a/UI/Web/src/app/app.component.scss b/UI/Web/src/app/app.component.scss
index f36dbb0c3..396539e99 100644
--- a/UI/Web/src/app/app.component.scss
+++ b/UI/Web/src/app/app.component.scss
@@ -38,3 +38,17 @@
width: auto;
}
}
+
+
+@keyframes fadeInUp {
+ 0% {
+ opacity: 0;
+ }
+ 100% {
+ opacity: 1;
+ }
+}
+
+.fadein {
+ animation: 2s fadeInUp;
+}
diff --git a/UI/Web/src/app/app.component.ts b/UI/Web/src/app/app.component.ts
index a23635277..36fac866d 100644
--- a/UI/Web/src/app/app.component.ts
+++ b/UI/Web/src/app/app.component.ts
@@ -12,17 +12,30 @@ import {ThemeService} from "./_services/theme.service";
import { SideNavComponent } from './sidenav/_components/side-nav/side-nav.component';
import {NavHeaderComponent} from "./nav/_components/nav-header/nav-header.component";
import {takeUntilDestroyed} from "@angular/core/rxjs-interop";
+import {animate, state, style, transition, trigger} from "@angular/animations";
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.scss'],
standalone: true,
+ animations: [
+ trigger('fadeIn', [
+ // the "out" style determines the "resting" state of the element when it is visible.
+ state('out', style({opacity: 0})),
+ // in state
+ state('in', style({opacity: 1})),
+
+ transition('out => in', animate('700ms ease-in')),
+ transition('in => out', animate('700ms ease-in')),
+ ])
+ ],
imports: [NgClass, NgIf, SideNavComponent, RouterOutlet, AsyncPipe, NavHeaderComponent]
})
export class AppComponent implements OnInit {
transitionState$!: Observable
;
+ fade = 'out';
private readonly destroyRef = inject(DestroyRef);
private readonly offcanvas = inject(NgbOffcanvas);
diff --git a/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.scss b/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.scss
index f9d45420e..ffc87dadc 100644
--- a/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.scss
+++ b/UI/Web/src/app/cards/card-detail-layout/card-detail-layout.component.scss
@@ -57,6 +57,7 @@
.btn {
text-decoration: none;
+ text-shadow: 1.3px 0.5px 1px rgba(255, 255, 255, 0.4); // TODO: perfect this
color: hsla(0,0%,100%,.7);
height: 25px;
text-align: center;
diff --git a/UI/Web/src/app/cards/series-info-cards/series-info-cards.component.html b/UI/Web/src/app/cards/series-info-cards/series-info-cards.component.html
index 8077add2f..5691d1ac1 100644
--- a/UI/Web/src/app/cards/series-info-cards/series-info-cards.component.html
+++ b/UI/Web/src/app/cards/series-info-cards/series-info-cards.component.html
@@ -1,5 +1,5 @@
-
+
0">
diff --git a/UI/Web/src/app/metadata-filter/metadata-filter.component.html b/UI/Web/src/app/metadata-filter/metadata-filter.component.html
index fc314f8db..3361064bb 100644
--- a/UI/Web/src/app/metadata-filter/metadata-filter.component.html
+++ b/UI/Web/src/app/metadata-filter/metadata-filter.component.html
@@ -24,7 +24,7 @@
-
+
*', [
+ style({ transform: 'translateY(-100%)' }),
+ animate(ANIMATION_SPEED)
+ ]),
+ transition('* => void', [
+ animate(ANIMATION_SPEED, style({ transform: 'translateY(-100%)' })),
+ ])
+ ]),
+ trigger('slideFromBottom', [
+ state('in', style({ transform: 'translateY(0)' })),
+ transition('void => *', [
+ style({ transform: 'translateY(100%)' }),
+ animate(ANIMATION_SPEED)
+ ]),
+ transition('* => void', [
+ animate(ANIMATION_SPEED, style({ transform: 'translateY(100%)' })),
+ ])
+ ])
+ ],
})
export class MetadataFilterComponent implements OnInit {
@@ -89,6 +114,8 @@ export class MetadataFilterComponent implements OnInit {
smartFilters!: Array;
+ isOpen = false;
+
private readonly cdRef = inject(ChangeDetectorRef);
private readonly toastr = inject(ToastrService);
@@ -114,44 +141,47 @@ export class MetadataFilterComponent implements OnInit {
this.filterOpen.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(openState => {
this.filteringCollapsed = !openState;
this.toggleService.set(!this.filteringCollapsed);
+ this.isOpen = openState;
this.cdRef.markForCheck();
});
}
+
+
this.loadFromPresetsAndSetup();
}
- loadSavedFilter(event: Select2UpdateEvent) {
- // Load the filter from the backend and update the screen
- if (event.value === undefined || typeof(event.value) === 'string') return;
- const smartFilter = event.value as SmartFilter;
- this.filterV2 = this.filterUtilitiesService.decodeSeriesFilter(smartFilter.filter);
- this.cdRef.markForCheck();
- console.log('update event: ', event);
- }
-
- createFilterValue(event: Select2AutoCreateEvent) {
- // Create a new name and filter
- if (!this.filterV2) return;
- this.filterV2.name = event.value;
- this.filterService.saveFilter(this.filterV2).subscribe(() => {
-
- const item = {
- value: {
- filter: this.filterUtilitiesService.encodeSeriesFilter(this.filterV2!),
- name: event.value,
- } as SmartFilter,
- label: event.value
- };
- this.smartFilters.push(item);
- this.sortGroup.get('name')?.setValue(item);
- this.cdRef.markForCheck();
- this.toastr.success(translate('toasts.smart-filter-updated'));
- this.apply();
- });
-
- console.log('create event: ', event);
- }
+ // loadSavedFilter(event: Select2UpdateEvent) {
+ // // Load the filter from the backend and update the screen
+ // if (event.value === undefined || typeof(event.value) === 'string') return;
+ // const smartFilter = event.value as SmartFilter;
+ // this.filterV2 = this.filterUtilitiesService.decodeSeriesFilter(smartFilter.filter);
+ // this.cdRef.markForCheck();
+ // console.log('update event: ', event);
+ // }
+ //
+ // createFilterValue(event: Select2AutoCreateEvent) {
+ // // Create a new name and filter
+ // if (!this.filterV2) return;
+ // this.filterV2.name = event.value;
+ // this.filterService.saveFilter(this.filterV2).subscribe(() => {
+ //
+ // const item = {
+ // value: {
+ // filter: this.filterUtilitiesService.encodeSeriesFilter(this.filterV2!),
+ // name: event.value,
+ // } as SmartFilter,
+ // label: event.value
+ // };
+ // this.smartFilters.push(item);
+ // this.sortGroup.get('name')?.setValue(item);
+ // this.cdRef.markForCheck();
+ // this.toastr.success(translate('toasts.smart-filter-updated'));
+ // this.apply();
+ // });
+ //
+ // console.log('create event: ', event);
+ // }
close() {
diff --git a/UI/Web/src/app/nav/_components/grouped-typeahead/grouped-typeahead.component.html b/UI/Web/src/app/nav/_components/grouped-typeahead/grouped-typeahead.component.html
index 8a7847511..ceceab2b3 100644
--- a/UI/Web/src/app/nav/_components/grouped-typeahead/grouped-typeahead.component.html
+++ b/UI/Web/src/app/nav/_components/grouped-typeahead/grouped-typeahead.component.html
@@ -15,6 +15,17 @@
+
+
+
+
+ -
+ Try batman, 2014, Ecchi
+
+
+
+
+
0">
diff --git a/UI/Web/src/app/shared/_services/filter-utilities.service.ts b/UI/Web/src/app/shared/_services/filter-utilities.service.ts
index 1dc62124d..2b5bb647d 100644
--- a/UI/Web/src/app/shared/_services/filter-utilities.service.ts
+++ b/UI/Web/src/app/shared/_services/filter-utilities.service.ts
@@ -209,9 +209,9 @@ export class FilterUtilitiesService {
}
decodeFilterStatements(encodedStatements: string): FilterStatement[] {
- const statementStrings = decodeURIComponent(encodedStatements).split(',');
+ const statementStrings = decodeURIComponent(encodedStatements).split(',').map(s => decodeURIComponent(s));
return statementStrings.map(statementString => {
- const parts = statementString.split('&');
+ const parts = statementString.split(',');
if (parts === null || parts.length < 3) return null;
const comparisonStartToken = parts.find(part => part.startsWith('comparison='));
diff --git a/UI/Web/src/app/sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component.html b/UI/Web/src/app/sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component.html
index 9f4714f3b..0203806dc 100644
--- a/UI/Web/src/app/sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component.html
+++ b/UI/Web/src/app/sidenav/_components/side-nav-companion-bar/side-nav-companion-bar.component.html
@@ -1,5 +1,5 @@
-
+
@@ -12,7 +12,7 @@
{{t('page-settings-title')}}
-