From 9f01a2b8f66201ec32f60cb92df43f520bf56a62 Mon Sep 17 00:00:00 2001 From: Hillel Coren Date: Thu, 23 Mar 2023 15:59:10 +0200 Subject: [PATCH] Add back native browser option for PDF --- lib/ui/design/edit/design_edit.dart | 31 ++++++++++++++++ lib/ui/invoice/edit/invoice_edit_desktop.dart | 36 +++++++++++++------ lib/ui/invoice/edit/invoice_edit_pdf.dart | 32 ++++++++++++----- lib/ui/invoice/invoice_pdf.dart | 33 +++++++++++------ lib/ui/settings/device_settings.dart | 10 ++++++ lib/ui/settings/device_settings_vm.dart | 5 +++ 6 files changed, 116 insertions(+), 31 deletions(-) diff --git a/lib/ui/design/edit/design_edit.dart b/lib/ui/design/edit/design_edit.dart index af12bf018..5fcaeaf01 100644 --- a/lib/ui/design/edit/design_edit.dart +++ b/lib/ui/design/edit/design_edit.dart @@ -9,7 +9,9 @@ import 'package:flutter/services.dart'; // Package imports: import 'package:built_collection/built_collection.dart'; +import 'package:flutter_redux/flutter_redux.dart'; import 'package:flutter_styled_toast/flutter_styled_toast.dart'; +import 'package:invoiceninja_flutter/redux/app/app_state.dart'; import 'package:invoiceninja_flutter/utils/dialogs.dart'; import 'package:printing/printing.dart'; import 'package:url_launcher/url_launcher.dart'; @@ -32,6 +34,9 @@ import 'package:invoiceninja_flutter/utils/designs.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/platforms.dart'; +import 'package:invoiceninja_flutter/utils/web_stub.dart' + if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart'; + class DesignEdit extends StatefulWidget { const DesignEdit({ Key key, @@ -601,8 +606,32 @@ class PdfDesignPreview extends StatefulWidget { } class _PdfDesignPreviewState extends State { + String get _pdfString { + if (widget.pdfBytes == null) { + return ''; + } + + return 'data:application/pdf;base64,' + base64Encode(widget.pdfBytes); + } + + @override + void didUpdateWidget(oldWidget) { + super.didUpdateWidget(oldWidget); + + if (oldWidget.pdfBytes == widget.pdfBytes) { + return; + } + + if (kIsWeb) { + WebUtils.registerWebView(_pdfString); + } + } + @override Widget build(BuildContext context) { + final store = StoreProvider.of(context); + final state = store.state; + return Container( color: Colors.grey, alignment: Alignment.center, @@ -611,6 +640,8 @@ class _PdfDesignPreviewState extends State { children: [ if (widget.pdfBytes == null) SizedBox() + else if (kIsWeb && state.prefState.enableNativeBrowser) + HtmlElementView(viewType: _pdfString) else if (widget.pdfBytes != null) PdfPreview( build: (format) => widget.pdfBytes, diff --git a/lib/ui/invoice/edit/invoice_edit_desktop.dart b/lib/ui/invoice/edit/invoice_edit_desktop.dart index ffbd3e56b..30cd66b08 100644 --- a/lib/ui/invoice/edit/invoice_edit_desktop.dart +++ b/lib/ui/invoice/edit/invoice_edit_desktop.dart @@ -2,6 +2,7 @@ import 'dart:convert'; // Flutter imports: +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; // Package imports: @@ -57,6 +58,9 @@ import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:material_design_icons_flutter/material_design_icons_flutter.dart'; import 'package:printing/printing.dart'; +import 'package:invoiceninja_flutter/utils/web_stub.dart' + if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart'; + class InvoiceEditDesktop extends StatefulWidget { const InvoiceEditDesktop({ Key key, @@ -1157,6 +1161,7 @@ class __PdfPreviewState extends State<_PdfPreview> { int _pageCount = 1; int _currentPage = 1; + String _pdfString; http.Response _response; bool _isLoading = false; bool _pendingLoad = false; @@ -1243,6 +1248,12 @@ class __PdfPreviewState extends State<_PdfPreview> { _currentPage = _pageCount; } + if (kIsWeb && state.prefState.enableNativeBrowser) { + _pdfString = + 'data:application/pdf;base64,' + base64Encode(response.bodyBytes); + WebUtils.registerWebView(_pdfString); + } + if (_pendingLoad) { _pendingLoad = false; _loadPdf(); @@ -1269,7 +1280,8 @@ class __PdfPreviewState extends State<_PdfPreview> { Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ - if (_pageCount > 1) + if (_pageCount > 1 && + (!kIsWeb || !state.prefState.enableNativeBrowser)) Padding( padding: const EdgeInsets.only(bottom: 16), child: Row( @@ -1306,16 +1318,18 @@ class __PdfPreviewState extends State<_PdfPreview> { ? Container( color: Colors.grey.shade300, ) - : PdfPreview( - build: (format) => _response.bodyBytes, - canChangeOrientation: false, - canChangePageFormat: false, - allowPrinting: false, - allowSharing: false, - canDebug: false, - pages: [_currentPage - 1], - maxPageWidth: 800, - ), + : (kIsWeb && state.prefState.enableNativeBrowser) + ? HtmlElementView(viewType: _pdfString) + : PdfPreview( + build: (format) => _response.bodyBytes, + canChangeOrientation: false, + canChangePageFormat: false, + allowPrinting: false, + allowSharing: false, + canDebug: false, + pages: [_currentPage - 1], + maxPageWidth: 800, + ), ), ], ), diff --git a/lib/ui/invoice/edit/invoice_edit_pdf.dart b/lib/ui/invoice/edit/invoice_edit_pdf.dart index 0a9013542..e2ce715fb 100644 --- a/lib/ui/invoice/edit/invoice_edit_pdf.dart +++ b/lib/ui/invoice/edit/invoice_edit_pdf.dart @@ -2,6 +2,7 @@ import 'dart:convert'; // Flutter imports: +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; // Project imports: @@ -13,6 +14,8 @@ import 'package:invoiceninja_flutter/ui/app/help_text.dart'; import 'package:invoiceninja_flutter/ui/invoice/edit/invoice_edit_pdf_vm.dart'; import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:printing/printing.dart'; +import 'package:invoiceninja_flutter/utils/web_stub.dart' + if (dart.library.html) 'package:invoiceninja_flutter/utils/web.dart'; class InvoiceEditPDF extends StatefulWidget { const InvoiceEditPDF({ @@ -28,6 +31,7 @@ class InvoiceEditPDF extends StatefulWidget { class InvoiceEditPDFState extends State { bool _isLoading = false; + String _pdfString; http.Response _response; @override @@ -73,6 +77,12 @@ class InvoiceEditPDFState extends State { setState(() { _isLoading = false; _response = response; + + if (kIsWeb && state.prefState.enableNativeBrowser) { + _pdfString = + 'data:application/pdf;base64,' + base64Encode(response.bodyBytes); + WebUtils.registerWebView(_pdfString); + } }); }).catchError((dynamic error) { setState(() { @@ -83,6 +93,8 @@ class InvoiceEditPDFState extends State { @override Widget build(BuildContext context) { + final state = widget.viewModel.state; + if (!widget.viewModel.invoice.hasClient) { return HelpText(AppLocalization.of(context).noClientSelected); } @@ -94,15 +106,17 @@ class InvoiceEditPDFState extends State { } return Center( - child: PdfPreview( - build: (format) => _response.bodyBytes, - canChangeOrientation: false, - canChangePageFormat: false, - allowPrinting: false, - allowSharing: false, - canDebug: false, - maxPageWidth: 800, - ), + child: kIsWeb && state.prefState.enableNativeBrowser + ? HtmlElementView(viewType: _pdfString) + : PdfPreview( + build: (format) => _response.bodyBytes, + canChangeOrientation: false, + canChangePageFormat: false, + allowPrinting: false, + allowSharing: false, + canDebug: false, + maxPageWidth: 800, + ), ); } } diff --git a/lib/ui/invoice/invoice_pdf.dart b/lib/ui/invoice/invoice_pdf.dart index 99492e593..f2880927a 100644 --- a/lib/ui/invoice/invoice_pdf.dart +++ b/lib/ui/invoice/invoice_pdf.dart @@ -55,6 +55,7 @@ class _InvoicePdfViewState extends State { bool _isLoading = true; bool _isDeliveryNote = false; String _activityId; + String _pdfString; http.Response _response; //int _pageCount = 1; //int _currentPage = 1; @@ -75,6 +76,7 @@ class _InvoicePdfViewState extends State { void loadPdf() { final viewModel = widget.viewModel; final invoice = viewModel.invoice; + final state = viewModel.state; if (invoice.invitations.isEmpty) { return; @@ -93,6 +95,12 @@ class _InvoicePdfViewState extends State { setState(() { _response = response; _isLoading = false; + + if (kIsWeb && state.prefState.enableNativeBrowser) { + _pdfString = + 'data:application/pdf;base64,' + base64Encode(response.bodyBytes); + WebUtils.registerWebView(_pdfString); + } }); }).catchError((Object error) { setState(() { @@ -301,17 +309,20 @@ class _InvoicePdfViewState extends State { : null, body: _isLoading || _response == null ? LoadingIndicator() - : PdfPreview( - build: (format) => _response.bodyBytes, - canChangeOrientation: false, - canChangePageFormat: false, - canDebug: false, - maxPageWidth: 800, - pdfFileName: localization.lookup(invoice.entityType.snakeCase) + - '_' + - invoice.number + - '.pdf', - )); + : (kIsWeb && state.prefState.enableNativeBrowser) + ? HtmlElementView(viewType: _pdfString) + : PdfPreview( + build: (format) => _response.bodyBytes, + canChangeOrientation: false, + canChangePageFormat: false, + canDebug: false, + maxPageWidth: 800, + pdfFileName: + localization.lookup(invoice.entityType.snakeCase) + + '_' + + invoice.number + + '.pdf', + )); } } diff --git a/lib/ui/settings/device_settings.dart b/lib/ui/settings/device_settings.dart index 42a3dcfbb..33c28ae3f 100644 --- a/lib/ui/settings/device_settings.dart +++ b/lib/ui/settings/device_settings.dart @@ -196,6 +196,16 @@ class _DeviceSettingsState extends State activeColor: Theme.of(context).colorScheme.secondary, secondary: Icon(MdiIcons.filePdfBox), ), + if (kIsWeb || !kReleaseMode) + SwitchListTile( + title: Text(localization.browserPdfViewer), + subtitle: Text(localization.browserPdfViewerHelp), + value: prefState.enableNativeBrowser, + onChanged: (value) => viewModel + .onEnableNativeBrowserChanged(context, !value), + activeColor: Theme.of(context).colorScheme.secondary, + secondary: Icon(MdiIcons.filePdfBox), + ), SizedBox(height: 10), BoolDropdownButton( label: localization.previewLocation, diff --git a/lib/ui/settings/device_settings_vm.dart b/lib/ui/settings/device_settings_vm.dart index 7478317f0..d5afe0e8a 100644 --- a/lib/ui/settings/device_settings_vm.dart +++ b/lib/ui/settings/device_settings_vm.dart @@ -54,6 +54,7 @@ class DeviceSettingsVM { @required this.onPersistDataChanged, @required this.onPersistUiChanged, @required this.onShowPdfChanged, + @required this.onEnableNativeBrowserChanged, @required this.onShowPdfSideBySideChanged, @required this.onTapSelectedChanged, @required this.onTextScaleFactorChanged, @@ -112,6 +113,9 @@ class DeviceSettingsVM { onShowPdfChanged: (context, value) { store.dispatch(UpdateUserPreferences(showPdfPreview: value)); }, + onEnableNativeBrowserChanged: (context, value) { + store.dispatch(UpdateUserPreferences(enableNativeBrowser: value)); + }, onShowPdfSideBySideChanged: (context, value) { store.dispatch(UpdateUserPreferences(showPdfPreviewSideBySide: value)); }, @@ -214,6 +218,7 @@ class DeviceSettingsVM { final Function(BuildContext, bool) onPersistDataChanged; final Function(BuildContext, bool) onPersistUiChanged; final Function(BuildContext, bool) onShowPdfChanged; + final Function(BuildContext, bool) onEnableNativeBrowserChanged; final Function(BuildContext, bool) onShowPdfSideBySideChanged; final Function(BuildContext, bool) onEnableTouchEventsChanged; final Function(BuildContext, bool) onEnableTooltipsChanged;