Files
iptvnator/apps/web/src/app/shared/components/header/header.component.html
T
4gray 53cbd64575 feat(header): add home styling, search output and host binding
Enhance the header component to support a distinct "home" appearance
and emit search updates. Add a HostBinding that toggles a home-header
class from the isHome flag so styles can target the home state.
Expose a searchQuery output and wire an onSearchQueryUpdate method to
emit the search text, enabling parent components to react to user
searches.
Refactor imports to include HostBinding and output. Tidy toolbar metrics
and adjust element sizing for a compact brand block and pulsing logo.
Introduce comprehensive SCSS for the home header:
- gradient background, animated glow overlay, and edge accent
- brand block styling with blur, border, hover states and box-shadow
- logo sizing, pulse animation and responsive tweaks
- reduced toolbar height and overall visual polish
These changes separate home-specific styling from the default header
appearance and provide a programmatic hook for search interactions.
2025-12-06 21:44:25 +01:00

247 lines
9.9 KiB
HTML

<mat-toolbar class="modern-header">
<div class="brand-block">
<div class="logo-pulse">
<img
src="./assets/icons/icon-tv-256.png"
alt="iptvnator logo"
/>
</div>
<div class="brand-text">
<div class="title">{{ title() }}</div>
</div>
</div>
@if (isHome) {
<div class="search-container">
<mat-icon class="search-icon">search</mat-icon>
<input
#searchInput
type="search"
class="search-input"
spellcheck="false"
autocomplete="off"
[placeholder]="'HOME.PLAYLISTS.SEARCH_PLAYLISTS' | translate"
(input)="onSearchQueryUpdate(searchInput.value)"
/>
</div>
<div class="menu">
<button
mat-icon-button
class="add-playlist-btn"
[matMenuTriggerFor]="addPlaylistMenu"
[matTooltip]="'HOME.URL_UPLOAD.ADD_PLAYLIST' | translate"
data-test-id="add-playlist"
>
<mat-icon>add</mat-icon>
</button>
<!-- Sort button -->
<button
mat-icon-button
[matMenuTriggerFor]="sortMenu"
[matTooltip]="'HOME.SORT_PLAYLISTS' | translate"
data-test-id="sort-playlists"
>
<mat-icon>sort</mat-icon>
</button>
<button
mat-icon-button
[matMenuTriggerFor]="filterPlaylistMenu"
[matTooltip]="'HOME.FILTER_BY_TYPE' | translate"
data-test-id="filter-playlist-by-type"
>
<mat-icon>filter_alt</mat-icon>
</button>
@if (isDesktop) {
<button
mat-icon-button
(click)="openSettings()"
[matTooltip]="'MENU.SETTINGS' | translate"
data-test-id="open-settings"
>
<mat-icon>settings</mat-icon>
</button>
} @else {
<button
mat-icon-button
[matMenuTriggerFor]="menu"
[attr.aria-label]="'MENU.OPEN' | translate"
data-test-id="pwa-menu"
>
<mat-icon>menu</mat-icon>
</button>
<mat-menu #menu="matMenu">
@if (isHome) {
<button
mat-menu-item
[attr.aria-label]="'MENU.SETTINGS_ARIA' | translate"
(click)="openSettings()"
data-test-id="pwa-open-settings"
>
<mat-icon>settings</mat-icon>
<span>{{ 'MENU.SETTINGS' | translate }}</span>
</button>
<mat-divider></mat-divider>
}
<button
mat-menu-item
[attr.aria-label]="'MENU.SUPPORT_ARIA' | translate"
(click)="openUrl('https:///github.com/4gray/iptvnator')"
>
<mat-icon>recommend</mat-icon>
<span>GitHub</span>
</button>
<button
mat-menu-item
[attr.aria-label]="'MENU.BUG_REPORT' | translate"
(click)="
openUrl('https://github.com/4gray/iptvnator/issues')
"
>
<mat-icon>bug_report</mat-icon>
<span>{{ 'MENU.BUG_REPORT' | translate }}</span>
</button>
<mat-divider />
<button
mat-menu-item
[attr.aria-label]="'MENU.SUPPORT_PROJECT' | translate"
(click)="openUrl('https://github.com/sponsors/4gray')"
>
<mat-icon>savings</mat-icon>
<span>{{ 'MENU.SUPPORT_PROJECT' | translate }}</span>
</button>
<mat-divider></mat-divider>
<button
mat-menu-item
[attr.aria-label]="'MENU.ABOUT_ARIA' | translate"
(click)="openAboutDialog()"
>
<mat-icon>info</mat-icon>
<span>{{ 'MENU.ABOUT' | translate }}</span>
</button>
</mat-menu>
}
<!-- Sort menu -->
<mat-menu #sortMenu="matMenu">
<div
class="dropdown-menu-header"
(click)="$event.stopPropagation()"
>
{{ 'HOME.SORT_BY' | translate }}
</div>
<button
mat-menu-item
(click)="setSortOptions(SortBy.NAME, SortOrder.ASC)"
[class.active-sort]="
isSortActive(SortBy.NAME, SortOrder.ASC)
"
>
<mat-icon>sort_by_alpha</mat-icon>
<span>{{ 'HOME.SORT_OPTIONS.NAME_ASC' | translate }}</span>
</button>
<button
mat-menu-item
(click)="setSortOptions(SortBy.NAME, SortOrder.DESC)"
[class.active-sort]="
isSortActive(SortBy.NAME, SortOrder.DESC)
"
>
<mat-icon>sort_by_alpha</mat-icon>
<span>{{ 'HOME.SORT_OPTIONS.NAME_DESC' | translate }}</span>
</button>
<mat-divider></mat-divider>
<button
mat-menu-item
(click)="setSortOptions(SortBy.DATE_ADDED, SortOrder.DESC)"
[class.active-sort]="
isSortActive(SortBy.DATE_ADDED, SortOrder.DESC)
"
>
<mat-icon>date_range</mat-icon>
<span>{{ 'HOME.SORT_OPTIONS.NEWEST' | translate }}</span>
</button>
<button
mat-menu-item
(click)="setSortOptions(SortBy.DATE_ADDED, SortOrder.ASC)"
[class.active-sort]="
isSortActive(SortBy.DATE_ADDED, SortOrder.ASC)
"
>
<mat-icon>date_range</mat-icon>
<span>{{ 'HOME.SORT_OPTIONS.OLDEST' | translate }}</span>
</button>
</mat-menu>
<mat-menu #filterPlaylistMenu="matMenu">
<section
(click)="$event.stopPropagation()"
class="filter-container"
>
<div
class="dropdown-menu-header"
(click)="$event.stopPropagation()"
>
{{ 'HOME.FILTER_BY_TYPE' | translate }}
</div>
@for (type of playlistTypes; track $index) {
<p>
<mat-checkbox
(click)="$event.stopPropagation()"
[checked]="true"
(change)="onPlaylistFilterChange()"
[(ngModel)]="type.checked"
>{{ type.title }}</mat-checkbox
>
</p>
}
</section>
</mat-menu>
<mat-menu #addPlaylistMenu="matMenu">
<button
mat-menu-item
[attr.aria-label]="'HOME.TABS.FILE_UPLOAD' | translate"
(click)="opedAddPlaylistDialog('file')"
>
<mat-icon>attach_file</mat-icon>
<span>{{ 'HOME.TABS.FILE_UPLOAD' | translate }}</span>
</button>
<button
mat-menu-item
[attr.aria-label]="'HOME.TABS.URL_UPLOAD' | translate"
(click)="opedAddPlaylistDialog('url')"
>
<mat-icon>link</mat-icon>
<span>{{ 'HOME.TABS.URL_UPLOAD' | translate }}</span>
</button>
<button
mat-menu-item
[attr.aria-label]="'HOME.TABS.TEXT_IMPORT' | translate"
(click)="opedAddPlaylistDialog('text')"
>
<mat-icon>text_format</mat-icon>
<span>{{ 'HOME.TABS.TEXT_IMPORT' | translate }}</span>
</button>
<mat-divider></mat-divider>
<button
mat-menu-item
[attr.aria-label]="'HOME.TABS.XTREME_IMPORT' | translate"
(click)="opedAddPlaylistDialog('xtream')"
>
<mat-icon>video_library</mat-icon>
<span>{{ 'HOME.TABS.XTREME_IMPORT' | translate }}</span>
</button>
<button
mat-menu-item
[attr.aria-label]="
'HOME.TABS.STALKER_PORTAL_IMPORT' | translate
"
(click)="opedAddPlaylistDialog('stalker')"
>
<mat-icon>dashboard</mat-icon>
<span>{{
'HOME.TABS.STALKER_PORTAL_IMPORT' | translate
}}</span>
</button>
</mat-menu>
</div>
}
</mat-toolbar>