feat: gestione trattini verticali | come accordi e allineamento grafico

This commit is contained in:
David Frassi
2026-07-14 19:47:15 +02:00
parent ad9286002b
commit 0069c1a55f
25 changed files with 834 additions and 121 deletions
+32 -8
View File
@@ -5,20 +5,23 @@
<img src="assets/icon/favicon.png" class="header-logo">
<div class="header-text-group">
<span class="app-name">{{ appName }}</span>
<span class="version-badge" (click)="checkForAppUpdate($event)" style="cursor: pointer; display: inline-flex; align-items: center; gap: 4px;">
<span class="version-badge" style="cursor: default; display: inline-flex; align-items: center; gap: 4px;">
v{{ version }}<span *ngIf="settingsService.userName()"> - {{ settingsService.userName() }}</span>
<span *ngIf="hasUpdateAvailable()" style="display: inline-flex; align-items: center; justify-content: center; padding: 4px; margin-left: 2px; background: rgba(var(--ion-color-secondary-rgb), 0.25); border-radius: 50%; border: 1px solid var(--ion-color-secondary); width: 24px; height: 24px; box-shadow: 0 0 8px rgba(var(--ion-color-secondary-rgb), 0.3);">
<ion-icon name="refresh-outline" style="font-size: 1.15rem; color: var(--ion-color-secondary); font-weight: bold;"></ion-icon>
</span>
</span>
</div>
</div>
</ion-title>
<ion-buttons slot="end">
<ion-button (click)="importPlaylist()" class="add-btn">
<ion-icon slot="icon-only" name="qr-code-outline"></ion-icon>
</ion-button>
<ng-container *ngIf="hasUpdateAvailable(); else showQrBtn">
<ion-button (click)="checkForAppUpdate($event)" class="add-btn" title="Aggiornamento disponibile">
<ion-icon slot="icon-only" name="refresh-outline" color="secondary"></ion-icon>
</ion-button>
</ng-container>
<ng-template #showQrBtn>
<ion-button (click)="importPlaylist()" class="add-btn">
<ion-icon slot="icon-only" name="qr-code-outline"></ion-icon>
</ion-button>
</ng-template>
<ion-button routerLink="/settings" class="settings-btn">
<ion-icon slot="icon-only" name="settings-outline"></ion-icon>
</ion-button>
@@ -44,6 +47,10 @@
<div class="song-count-card outfit-font">
{{ filteredCanti().length }}
</div>
<div *ngIf="playlistService.activeListName() !== null && totalPlaylistDuration()" class="song-count-card outfit-font">
<ion-icon name="time-outline" style="margin-right: 4px; font-size: 1rem; color: var(--ion-color-secondary);"></ion-icon>
<span>{{ totalPlaylistDuration() }}</span>
</div>
<div class="filter-buttons">
<ion-button
[fill]="activeFilterType() === 'playlist' || playlistService.activeListName() !== null ? 'solid' : 'outline'"
@@ -317,6 +324,23 @@
</h2>
<p style="color: rgba(255,255,255,0.6); margin-bottom: 2px; display: flex; align-items: center; flex-wrap: wrap; gap: 8px;">
<span>{{ canto.autore || 'Autore sconosciuto' }}</span>
</p>
<p style="color: rgba(255,255,255,0.6); margin-bottom: 2px; display: flex; align-items: center; flex-wrap: wrap; gap: 6px;"
*ngIf="(settingsService.showDurationBpmTonality() && (canto.durata || canto.bpm || getSongTonality(canto))) || (settingsService.showUpdateDate() && canto.data_update) || (showTopTen() && getEsecuzioniCount(canto.id) !== null) || (showSuggeriti() && getMassSuggestionWeight(canto.id_canti) !== null)">
<ng-container *ngIf="settingsService.showDurationBpmTonality()">
<span *ngIf="canto.durata" style="font-size: 0.7rem; color: var(--ion-color-secondary); opacity: 0.85; background: rgba(var(--ion-color-secondary-rgb), 0.08); padding: 1px 5px; border-radius: 4px; display: inline-flex; align-items: center; gap: 2px; border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.15);">
<ion-icon name="time-outline" style="font-size: 0.75rem;"></ion-icon>
{{ canto.durata }}
</span>
<span *ngIf="canto.bpm" style="font-size: 0.7rem; color: var(--ion-color-secondary); opacity: 0.85; background: rgba(var(--ion-color-secondary-rgb), 0.08); padding: 1px 5px; border-radius: 4px; display: inline-flex; align-items: center; gap: 2px; border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.15);">
<ion-icon name="pulse-outline" style="font-size: 0.75rem;"></ion-icon>
{{ canto.bpm }} BPM
</span>
<span *ngIf="getSongTonality(canto)" style="font-size: 0.7rem; color: var(--ion-color-secondary); opacity: 0.85; background: rgba(var(--ion-color-secondary-rgb), 0.08); padding: 1px 5px; border-radius: 4px; display: inline-flex; align-items: center; gap: 2px; border: 1px solid rgba(var(--ion-color-secondary-rgb), 0.15);">
<ion-icon name="musical-note-outline" style="font-size: 0.75rem;"></ion-icon>
{{ getSongTonality(canto) }}
</span>
</ng-container>
<span *ngIf="settingsService.showUpdateDate() && canto.data_update" class="update-date-badge" style="font-size: 0.7rem; color: rgba(255, 255, 255, 0.45); font-weight: 400; display: inline-flex; align-items: center; gap: 3px;">
<ion-icon name="calendar-outline" style="font-size: 0.75rem; color: rgba(255,255,255,0.45);"></ion-icon>
agg. {{ cantiService.formatUpdateDate(canto.data_update) }}