gestione comunità

This commit is contained in:
David Frassi
2026-05-18 16:07:37 +02:00
parent 961b7ba65c
commit af12a1f2da
15 changed files with 1021 additions and 61 deletions
+194
View File
@@ -0,0 +1,194 @@
import { Injectable, signal, inject, effect } from '@angular/core';
import { HttpClient, HttpRequest, HttpEventType, HttpResponse } from '@angular/common/http';
import { SettingsService } from './settings.service';
export interface ParrocchiaItem {
id_parrocchia: number;
nome: string;
codice: string;
mail: string;
guid_parrocchia: string;
}
export interface ParrocchiaCantiItem {
id_parrocchia: number;
id_canti: number;
num_canto: number;
}
export interface CantiSettingsItem {
id_canti: number;
speed: number;
tonalita: number;
}
export interface GetAllAppTablesResponse {
parrocchia?: { data: ParrocchiaItem[] };
parrocchia_canti?: { data: ParrocchiaCantiItem[] };
canti_settings?: { data: CantiSettingsItem[] };
}
@Injectable({
providedIn: 'root'
})
export class ComunitaService {
private http = inject(HttpClient);
private settingsService = inject(SettingsService);
public comunitaCode = signal<string>('');
public comunitaNome = signal<string>('');
public comunitaMail = signal<string>('');
public comunitaCantiIds = signal<(number | string)[]>([]);
public comunitaCantiInfo = signal<ParrocchiaCantiItem[]>([]);
public comunitaCantiSettings = signal<CantiSettingsItem[]>([]);
public isFilterActive = signal<boolean>(false);
public loading = signal<boolean>(false);
public loadingProgress = signal<number>(0);
constructor() {
const savedCode = localStorage.getItem('comunita-code');
const savedNome = localStorage.getItem('comunita-nome');
const savedMail = localStorage.getItem('comunita-mail');
const savedCanti = localStorage.getItem('comunita-canti-ids');
const savedInfo = localStorage.getItem('comunita-canti-info');
const savedSettings = localStorage.getItem('comunita-canti-settings');
const savedFilterActive = localStorage.getItem('comunita-filter-active') === 'true';
if (savedCode) this.comunitaCode.set(savedCode);
if (savedNome) this.comunitaNome.set(savedNome);
if (savedMail) this.comunitaMail.set(savedMail);
if (savedCanti) {
try { this.comunitaCantiIds.set(JSON.parse(savedCanti)); } catch (e) {}
}
if (savedInfo) {
try { this.comunitaCantiInfo.set(JSON.parse(savedInfo)); } catch (e) {}
}
if (savedSettings) {
try { this.comunitaCantiSettings.set(JSON.parse(savedSettings)); } catch (e) {}
}
this.isFilterActive.set(savedFilterActive);
effect(() => {
localStorage.setItem('comunita-code', this.comunitaCode());
localStorage.setItem('comunita-nome', this.comunitaNome());
localStorage.setItem('comunita-mail', this.comunitaMail());
localStorage.setItem('comunita-canti-ids', JSON.stringify(this.comunitaCantiIds()));
localStorage.setItem('comunita-canti-info', JSON.stringify(this.comunitaCantiInfo()));
localStorage.setItem('comunita-canti-settings', JSON.stringify(this.comunitaCantiSettings()));
localStorage.setItem('comunita-filter-active', this.isFilterActive().toString());
});
effect(() => {
if (!this.settingsService.comunitaEnabled()) {
this.isFilterActive.set(false);
}
});
}
private fetchWithProgress<T>(url: string): Promise<T> {
return new Promise<T>((resolve, reject) => {
const req = new HttpRequest('GET', url, {
reportProgress: true,
responseType: 'json'
});
this.http.request<T>(req).subscribe({
next: (event) => {
if (event.type === HttpEventType.DownloadProgress) {
if (event.total && event.total > 0) {
const pct = Math.round((event.loaded / event.total) * 100);
this.loadingProgress.set(pct);
} else {
// No Content-Length header — simulate gradual progress up to 85%
const simulated = Math.min(85, this.loadingProgress() + 12);
this.loadingProgress.set(simulated);
}
} else if (event instanceof HttpResponse) {
this.loadingProgress.set(100);
resolve(event.body as T);
}
},
error: (err) => reject(err)
});
});
}
async setComunitaCode(code: string): Promise<boolean> {
const trimmedCode = code.trim();
if (!trimmedCode) {
this.comunitaCode.set('');
this.comunitaNome.set('');
this.comunitaMail.set('');
this.comunitaCantiIds.set([]);
this.comunitaCantiInfo.set([]);
this.comunitaCantiSettings.set([]);
this.isFilterActive.set(false);
return true;
}
this.loading.set(true);
this.loadingProgress.set(0);
// 1. Try to fetch from the actual production API
try {
const url = `https://libretto.mmcinet.eu/canti/api/v3/get_all_app_tables?uuid=pwa-cc-uuid&email=&platform=browser&version=1.0&gruppo=${trimmedCode}&all_song=false&t=${Date.now()}`;
const data = await this.fetchWithProgress<GetAllAppTablesResponse>(url);
if (data && data.parrocchia?.data && data.parrocchia.data.length > 0) {
const parrocchia = data.parrocchia.data[0];
const cantiList = data.parrocchia_canti?.data || [];
const settingsList = data.canti_settings?.data || [];
this.comunitaCode.set(trimmedCode);
this.comunitaNome.set(parrocchia.nome || `Comunità ${trimmedCode}`);
this.comunitaMail.set(parrocchia.mail || '');
this.comunitaCantiInfo.set(cantiList);
this.comunitaCantiIds.set(cantiList.map(c => c.id_canti));
this.comunitaCantiSettings.set(settingsList);
this.isFilterActive.set(true);
this.loading.set(false);
return true;
}
} catch (err) {
console.warn('Failed to fetch from production API, trying fallback...', err);
this.loadingProgress.set(0);
}
// 2. Fallback to static community JSON
try {
const isProduction = window.location.hostname.includes('canticristiani.it');
const origin = isProduction ? window.location.origin : 'https://www.canticristiani.it';
const fallbackUrl = `${origin}/api/comunita_${trimmedCode}.json?t=${Date.now()}`;
interface StaticComunitaData {
id_comunita: string;
nome_comunita: string;
canti: (number | string)[];
}
const staticData = await this.fetchWithProgress<StaticComunitaData>(fallbackUrl);
if (staticData && staticData.canti) {
this.comunitaCode.set(trimmedCode);
this.comunitaNome.set(staticData.nome_comunita || `Comunità ${trimmedCode}`);
this.comunitaCantiIds.set(staticData.canti);
const mockInfo = staticData.canti.map((id, index) => ({
id_parrocchia: 1,
id_canti: Number(id),
num_canto: index + 1
}));
this.comunitaCantiInfo.set(mockInfo);
this.comunitaCantiSettings.set([]);
this.isFilterActive.set(true);
this.loading.set(false);
return true;
}
} catch (err) {
console.error('All community fetch strategies failed:', err);
}
this.loading.set(false);
return false;
}
}