184 lines
5.2 KiB
Dart
184 lines
5.2 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!',
|
|
fileNameOverrides: ['${widget.title}.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,
|
|
);
|
|
}),
|
|
);
|
|
}
|