flutter-freaccess-hub/lib/shared/widgets/read_view.dart

182 lines
5.1 KiB
Dart

import 'dart:developer';
import 'dart:io';
import 'package:flutter/material.dart';
// Removed unnecessary import
import 'package:hub/flutter_flow/index.dart';
import 'package:hub/shared/utils/dialog_util.dart';
import 'package:hub/shared/widgets.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pdfx/pdfx.dart';
import 'package:share_plus/share_plus.dart';
import 'package:http/http.dart' as http;
typedef ReadViewController = PdfController;
typedef DocumentType = PdfDocument;
abstract interface class Viewer extends StatelessComponent {
final String src;
const Viewer({
super.key,
required this.src,
});
@override
Widget build(BuildContext context) {
return buildViewer(context);
}
Widget buildViewer(BuildContext context);
}
class ReadView extends StatefulWidget {
final String url;
final String title;
final VoidCallback onError;
const ReadView({
super.key,
required this.onError,
required this.url,
required this.title,
});
@override
State<ReadView> createState() => ReadViewState();
}
class ReadViewState extends State<ReadView> {
Future<ReadViewController> _initializePdf() async {
try {
final file = await downloadPdf(widget.url);
final Future<DocumentType> document = DocumentType.openFile(file.path);
return ReadViewController(document: document);
} catch (e) {
final message = FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao baixar o PDF',
enText: 'Error downloading PDF',
);
return Future.error(message);
}
}
Future<File> downloadPdf(String url) async {
try {
final response = await http.get(Uri.parse(url));
if (response.statusCode == 200) {
final bytes = response.bodyBytes;
final dir = await getTemporaryDirectory();
final file = File('${dir.path}/downloaded.pdf');
await file.writeAsBytes(bytes);
return file;
} else {
throw Exception('Falha ao baixar o PDF');
}
} catch (e) {
final message = FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao baixar o PDF',
enText: 'Error downloading PDF',
);
await throwError(message, e);
rethrow;
}
}
Future<void> throwError(String message, dynamic error) async {
log('$message: $error');
await DialogUtil.error(context, message)
.whenComplete(() => widget.onError());
}
@override
Widget build(BuildContext context) {
return Stack(
children: [
_buildPDFViewer(context),
buildShareButton(context),
],
);
}
Positioned buildShareButton(BuildContext context) {
final theme = FlutterFlowTheme.of(context);
return Positioned(
bottom: 10,
right: 10,
child: IconButton(
icon: Icon(
Icons.share,
color: theme.primaryText,
),
color: theme.primaryText,
onPressed: onShare,
),
);
}
Future<void> onShare() async {
try {
final Uri uri = Uri.parse(widget.url);
final response = await http.get(uri);
if (response.statusCode == 200) {
final XFile xfile = XFile.fromData(response.bodyBytes,
name: '${widget.title}.pdf', mimeType: 'application/pdf');
await Share.shareXFiles([xfile], text: 'Confira este PDF!');
} else {
throw Exception(
'Erro ao compartilhar o arquivo: ${response.statusCode}');
}
} catch (e) {
final message = FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao compartilhar o arquivo',
enText: 'Error sharing file',
);
await throwError(message, e);
}
}
Widget buildLoadingIndicator(BuildContext context) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 15),
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
),
);
}
Widget _buildPDFViewer(BuildContext context) => Padding(
padding: EdgeInsets.all(10),
child: FutureBuilder<ReadViewController>(
future: _initializePdf(),
builder: (context, snapshot) {
if (!snapshot.hasData) return buildLoadingIndicator(context);
if (snapshot.error != null) {
return buildLoadingIndicator(context);
}
if (snapshot.connectionState == ConnectionState.waiting) {
return buildLoadingIndicator(context);
}
return PdfView(
controller: snapshot.data!,
renderer: (PdfPage page) => page.render(
width: page.width * 2,
height: page.height * 2,
cropRect: Rect.fromLTWH(
10.0, 10.0, page.width * 2, page.height * 2),
forPrint: false,
quality: 100,
format: PdfPageImageFormat.jpeg,
backgroundColor: '#ffffff',
),
scrollDirection: Axis.vertical,
);
}),
);
}