0 ? toggleFilterType('playlist') : playlistService.toggleSelectionMode()"
+ (click)="playlistService.allPlaylists().length > 0 ? toggleFilterType('playlist') : playlistService.toggleSelectionMode()"
class="filter-chip">
{{ playlistService.activeListName() !== null ? playlistService.activeListName() : 'Playlist' }}
- 0">
-
+ 0">
+
@@ -160,23 +160,25 @@
-
+
-
+
+
{{ activeFilterType() === 'playlist' ? item.name : item.tag_name }}
diff --git a/src/app/home/home.page.scss b/src/app/home/home.page.scss
index 0683338..13b6dd5 100644
--- a/src/app/home/home.page.scss
+++ b/src/app/home/home.page.scss
@@ -355,6 +355,17 @@ ion-title {
font-weight: 600;
border-color: var(--ion-color-secondary);
}
+
+ &.comunita-chip {
+ display: inline-flex;
+ align-items: center;
+ border-left: 3px solid rgba(var(--ion-color-secondary-rgb), 0.6);
+ background: rgba(var(--ion-color-secondary-rgb), 0.08);
+
+ &.active {
+ border-left-color: #000;
+ }
+ }
}
// Custom Item Layout
diff --git a/src/app/home/home.page.ts b/src/app/home/home.page.ts
index 96ad8e0..b612ef4 100644
--- a/src/app/home/home.page.ts
+++ b/src/app/home/home.page.ts
@@ -854,6 +854,11 @@ export class HomePage implements OnDestroy {
this.isAddingSongs.set(false);
}
+ isComunitaPlaylist(): boolean {
+ const id = this.playlistService.activePlaylistId();
+ return !!id && id.startsWith('comunita_');
+ }
+
clearSpecialList(event?: Event) {
if (event) event.stopPropagation();
this.playlistService.activeListIds.set([]);
diff --git a/src/app/services/comunita.service.ts b/src/app/services/comunita.service.ts
index 32952ee..f35f2fa 100644
--- a/src/app/services/comunita.service.ts
+++ b/src/app/services/comunita.service.ts
@@ -23,6 +23,13 @@ export interface CantiSettingsItem {
tonalita: number;
}
+export interface ComunitaScaletta {
+ id: string;
+ name: string;
+ date: string;
+ ids: string[];
+}
+
export interface GetAllAppTablesResponse {
parrocchia?: { data: ParrocchiaItem[] };
parrocchia_canti?: { data: ParrocchiaCantiItem[] };
@@ -43,6 +50,7 @@ export class ComunitaService {
public comunitaCantiInfo = signal([]);
public comunitaCantiSettings = signal([]);
public comunitaCantiPersonali = signal([]);
+ public comunitaScalette = signal([]);
public isFilterActive = signal(false);
public loading = signal(false);
public loadingProgress = signal(0);
@@ -55,6 +63,7 @@ export class ComunitaService {
const savedInfo = localStorage.getItem('comunita-canti-info');
const savedSettings = localStorage.getItem('comunita-canti-settings');
const savedCantiPersonali = localStorage.getItem('comunita-canti-personali');
+ const savedScalette = localStorage.getItem('comunita-scalette');
const savedFilterActive = localStorage.getItem('comunita-filter-active') === 'true';
if (savedCode) {
@@ -85,6 +94,9 @@ export class ComunitaService {
if (savedCantiPersonali) {
try { this.comunitaCantiPersonali.set(JSON.parse(savedCantiPersonali)); } catch (e) {}
}
+ if (savedScalette) {
+ try { this.comunitaScalette.set(JSON.parse(savedScalette)); } catch (e) {}
+ }
this.isFilterActive.set(savedFilterActive);
effect(() => {
@@ -95,6 +107,7 @@ export class ComunitaService {
localStorage.setItem('comunita-canti-info', JSON.stringify(this.comunitaCantiInfo()));
localStorage.setItem('comunita-canti-settings', JSON.stringify(this.comunitaCantiSettings()));
localStorage.setItem('comunita-canti-personali', JSON.stringify(this.comunitaCantiPersonali()));
+ localStorage.setItem('comunita-scalette', JSON.stringify(this.comunitaScalette()));
localStorage.setItem('comunita-filter-active', this.isFilterActive().toString());
});
@@ -143,6 +156,7 @@ export class ComunitaService {
this.comunitaCantiInfo.set([]);
this.comunitaCantiSettings.set([]);
this.comunitaCantiPersonali.set([]);
+ this.comunitaScalette.set([]);
this.isFilterActive.set(false);
return true;
}
@@ -182,6 +196,39 @@ export class ComunitaService {
this.comunitaCantiIds.set(cantiList.map(c => c.id_canti));
this.comunitaCantiSettings.set(settingsList);
this.comunitaCantiPersonali.set(mappedCantiPersonali);
+
+ // Parse scalette (setlists) from lista_nome + lista_esecuzione
+ const listaNomelList = (data as any).lista_nome?.data || [];
+ const listaEsecuzioneList = (data as any).lista_esecuzione?.data || [];
+
+ // Group lista_esecuzione by id_lista and keep order by progr
+ const esecuzioniByLista = new Map();
+ for (const item of listaEsecuzioneList) {
+ if (!esecuzioniByLista.has(item.id_lista)) {
+ esecuzioniByLista.set(item.id_lista, []);
+ }
+ esecuzioniByLista.get(item.id_lista)!.push({
+ id_canti: String(item.id_canti),
+ progr: Number(item.progr) || 0
+ });
+ }
+
+ // Build scalette array sorted by date (most recent first)
+ const scalette: ComunitaScaletta[] = listaNomelList
+ .map((ln: any) => {
+ const songs = esecuzioniByLista.get(ln.id_lista) || [];
+ songs.sort((a: any, b: any) => a.progr - b.progr);
+ return {
+ id: `comunita_${ln.id_lista}`,
+ name: ln.nome || 'Scaletta',
+ date: ln.progr || '',
+ ids: songs.map((s: any) => s.id_canti)
+ };
+ })
+ .filter((s: ComunitaScaletta) => s.ids.length > 0)
+ .sort((a: ComunitaScaletta, b: ComunitaScaletta) => b.date.localeCompare(a.date));
+
+ this.comunitaScalette.set(scalette);
this.isFilterActive.set(true);
this.loading.set(false);
return true;
@@ -218,6 +265,7 @@ export class ComunitaService {
this.comunitaCantiInfo.set(mockInfo);
this.comunitaCantiSettings.set([]);
this.comunitaCantiPersonali.set([]);
+ this.comunitaScalette.set([]);
this.isFilterActive.set(true);
this.loading.set(false);
return true;
diff --git a/src/app/services/playlist.service.ts b/src/app/services/playlist.service.ts
index fee6ec1..fe46ea5 100644
--- a/src/app/services/playlist.service.ts
+++ b/src/app/services/playlist.service.ts
@@ -1,6 +1,7 @@
-import { Injectable, signal, inject } from '@angular/core';
+import { Injectable, signal, inject, computed } from '@angular/core';
import { Storage } from '@ionic/storage-angular';
import { Canto, CantiService } from './canti.service';
+import { ComunitaService } from './comunita.service';
import * as QRCode from 'qrcode';
@Injectable({
@@ -9,6 +10,7 @@ import * as QRCode from 'qrcode';
export class PlaylistService {
private storage = inject(Storage);
private cantiService = inject(CantiService);
+ private comunitaService = inject(ComunitaService);
public selectionMode = signal(false);
public selectedIds = signal>(new Set());
@@ -22,6 +24,30 @@ export class PlaylistService {
private _storage: Storage | null = null;
+ // Community scalette exposed as playlists (only when community filter is active)
+ public comunitaPlaylists = computed(() => {
+ if (!this.comunitaService.comunitaCode() || !this.comunitaService.isFilterActive()) {
+ return [];
+ }
+ return this.comunitaService.comunitaScalette().map(s => ({
+ id: s.id,
+ name: s.name,
+ ids: s.ids,
+ createdAt: s.date,
+ isComunita: true
+ }));
+ });
+
+ // Merged list: personal playlists + community scalette
+ public allPlaylists = computed(() => {
+ const community = this.comunitaPlaylists();
+ const personal = this.playlists();
+ if (community.length > 0) {
+ return [...community, ...personal.map(p => ({ ...p, isComunita: false }))];
+ }
+ return personal.map(p => ({ ...p, isComunita: false }));
+ });
+
constructor() {
this.init();
}
diff --git a/src/app/version.ts b/src/app/version.ts
index a2e1727..9094611 100644
--- a/src/app/version.ts
+++ b/src/app/version.ts
@@ -1 +1 @@
-export const VERSION = '2026.05.20.1245';
+export const VERSION = '2026.05.20.1602';