import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:flux/core/utils/functions.dart'; import 'package:pdfx/pdfx.dart'; import 'package:internet_file/internet_file.dart'; class PdfViewerWidget extends StatefulWidget { final String? storagePath; final Uint8List? bytes; const PdfViewerWidget({super.key, this.storagePath, this.bytes}) : assert( (storagePath != null && storagePath != '') || bytes != null, 'Errore: Devi fornire un URL valido o i bytes del file!', ); @override State createState() => _PdfViewerWidgetState(); } class _PdfViewerWidgetState extends State { late PdfControllerPinch _pdfController; bool _isLoading = true; String? _errorMessage; @override void initState() { super.initState(); _initPdf(); } Future _initPdf() async { try { Uint8List pdfData; if (widget.bytes != null) { // SCENARIO 1: Pratica in bozza, file appena scelto (Locale) pdfData = widget.bytes!; } else if (widget.storagePath != null && widget.storagePath!.isNotEmpty) { // SCENARIO 2: Pratica salvata, scarichiamo da Supabase (Remoto) final signedUrl = await getSignedUrl(widget.storagePath!); pdfData = await InternetFile.get(signedUrl); } else { throw Exception("Nessun documento trovato"); } _pdfController = PdfControllerPinch( document: PdfDocument.openData(pdfData), ); if (mounted) setState(() => _isLoading = false); } catch (e) { if (mounted) { setState(() { _isLoading = false; _errorMessage = e.toString(); }); } } } @override void dispose() { _pdfController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { if (_isLoading) { return const Scaffold(body: Center(child: CircularProgressIndicator())); } if (_errorMessage != null) { return Scaffold( appBar: AppBar(leading: const CloseButton()), body: Center(child: Text("Errore: $_errorMessage")), ); } return Scaffold( appBar: AppBar( title: const Text("Anteprima PDF"), leading: IconButton( icon: const Icon(Icons.close), onPressed: () => Navigator.pop(context), ), ), body: PdfViewPinch(controller: _pdfController), ); } }