147 lines
4.5 KiB
Dart
147 lines
4.5 KiB
Dart
// lib/widgets/cast/cast_controller.dart
|
|
// NUOVA VERSIONE MODULARE
|
|
// - Orchestratore leggero
|
|
// - Nessuna logica Google/DLNA/FAST
|
|
// - Delega tutto ai backend specializzati
|
|
|
|
import 'package:flutter/material.dart';
|
|
import 'package:aves/model/entry/entry.dart';
|
|
|
|
import 'backends/google_cast_backend.dart';
|
|
import 'backends/fast_cast_backend.dart';
|
|
import 'backends/dlna_cast_backend.dart';
|
|
|
|
import 'google_cast_controller.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
enum CastBackend { google, fast, dlna }
|
|
enum CastIconState { idle, connecting, connected }
|
|
|
|
class CastController {
|
|
CastController._();
|
|
static final CastController instance = CastController._();
|
|
|
|
static const _prefBackend = 'cast_backend';
|
|
|
|
// Stato UI unificato (rimane qui)
|
|
final castIconState = ValueNotifier(CastIconState.idle);
|
|
final isCastingNotifier = ValueNotifier(false);
|
|
final currentIndexNotifier = ValueNotifier(0);
|
|
|
|
final isPlayingNotifier = ValueNotifier(false);
|
|
final isBufferingNotifier = ValueNotifier(false);
|
|
final positionNotifier = ValueNotifier(Duration.zero);
|
|
final durationNotifier = ValueNotifier(Duration.zero);
|
|
|
|
final volumeNotifier = ValueNotifier(1.0);
|
|
final isMutedNotifier = ValueNotifier(false);
|
|
|
|
// Backend selezionato (persistenza opzionale)
|
|
final backendNotifier = ValueNotifier(CastBackend.google);
|
|
|
|
// Backend attivo
|
|
late CastBackendBase backend;
|
|
|
|
// ------------------------------------------------------------
|
|
// SELEZIONE BACKEND
|
|
// ------------------------------------------------------------
|
|
Future<void> setBackend(CastBackend type) async {
|
|
backendNotifier.value = type;
|
|
|
|
// Persistenza
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.setString(_prefBackend, type.name);
|
|
|
|
// Ricrea backend
|
|
switch (type) {
|
|
case CastBackend.google:
|
|
backend = GoogleCastBackend(this);
|
|
GoogleCastController.instance.activateMethodChannelHandler();
|
|
break;
|
|
|
|
case CastBackend.fast:
|
|
backend = FastCastBackend(this);
|
|
// FAST non deve toccare il MethodChannel Google
|
|
break;
|
|
|
|
case CastBackend.dlna:
|
|
backend = DlnaCastBackend(this);
|
|
// DLNA non deve toccare il MethodChannel Google
|
|
break;
|
|
}
|
|
|
|
// Reset stato icona
|
|
castIconState.value = CastIconState.idle;
|
|
isCastingNotifier.value = false;
|
|
}
|
|
|
|
Future<void> loadSavedBackend() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final saved = prefs.getString(_prefBackend);
|
|
|
|
CastBackend type;
|
|
|
|
switch (saved) {
|
|
case 'google':
|
|
type = CastBackend.google;
|
|
break;
|
|
case 'fast':
|
|
type = CastBackend.fast;
|
|
break;
|
|
case 'dlna':
|
|
type = CastBackend.dlna;
|
|
break;
|
|
default:
|
|
type = CastBackend.google;
|
|
}
|
|
|
|
await setBackend(type);
|
|
}
|
|
|
|
// ------------------------------------------------------------
|
|
// API UNIFICATA (DELEGA AI BACKEND)
|
|
// ------------------------------------------------------------
|
|
|
|
Future<void> startCast(List<AvesEntry> entries, int index) =>
|
|
backend.startCast(entries, index);
|
|
|
|
Future<void> startFullscreen(List<AvesEntry> entries, int index) =>
|
|
backend.startFullscreen(entries, index);
|
|
|
|
Future<void> startSlideshow(List<AvesEntry> entries, int index) =>
|
|
backend.startSlideshow(entries, index);
|
|
|
|
Future<void> startManualQueue(List<AvesEntry> entries, int index) =>
|
|
backend.startManualQueue(entries, index);
|
|
|
|
Future<void> nextManual() => backend.nextManual();
|
|
|
|
Future<void> prevManual() => backend.prevManual();
|
|
|
|
Future<void> stopCast() => backend.stopCast();
|
|
|
|
// ------------------------------------------------------------
|
|
// Accesso diretto al controller Google Cast (per dialog Android)
|
|
// ------------------------------------------------------------
|
|
GoogleCastController get google => GoogleCastController.instance;
|
|
}
|
|
|
|
// ------------------------------------------------------------
|
|
// CLASSE BASE PER TUTTI I BACKEND
|
|
// ------------------------------------------------------------
|
|
abstract class CastBackendBase {
|
|
final CastController controller;
|
|
CastBackendBase(this.controller);
|
|
|
|
Future<void> startCast(List<AvesEntry> entries, int index);
|
|
Future<void> startFullscreen(List<AvesEntry> entries, int index);
|
|
Future<void> startSlideshow(List<AvesEntry> entries, int index);
|
|
Future<void> startManualQueue(List<AvesEntry> entries, int index);
|
|
|
|
Future<void> nextManual();
|
|
Future<void> prevManual();
|
|
Future<void> stopCast();
|
|
|
|
// PATCH: ogni backend decide il delay dello slideshow
|
|
Duration? getNextDelay(AvesEntry entry);
|
|
}
|