Add back native browser option for PDF

This commit is contained in:
Hillel Coren 2023-03-23 15:59:10 +02:00
parent 1250782897
commit 9f01a2b8f6
6 changed files with 116 additions and 31 deletions

View File

@ -9,7 +9,9 @@ import 'package:flutter/services.dart';
// Package imports: // Package imports:
import 'package:built_collection/built_collection.dart'; 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: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:invoiceninja_flutter/utils/dialogs.dart';
import 'package:printing/printing.dart'; import 'package:printing/printing.dart';
import 'package:url_launcher/url_launcher.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/localization.dart';
import 'package:invoiceninja_flutter/utils/platforms.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 { class DesignEdit extends StatefulWidget {
const DesignEdit({ const DesignEdit({
Key key, Key key,
@ -601,8 +606,32 @@ class PdfDesignPreview extends StatefulWidget {
} }
class _PdfDesignPreviewState extends State<PdfDesignPreview> { class _PdfDesignPreviewState extends State<PdfDesignPreview> {
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 @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final store = StoreProvider.of<AppState>(context);
final state = store.state;
return Container( return Container(
color: Colors.grey, color: Colors.grey,
alignment: Alignment.center, alignment: Alignment.center,
@ -611,6 +640,8 @@ class _PdfDesignPreviewState extends State<PdfDesignPreview> {
children: <Widget>[ children: <Widget>[
if (widget.pdfBytes == null) if (widget.pdfBytes == null)
SizedBox() SizedBox()
else if (kIsWeb && state.prefState.enableNativeBrowser)
HtmlElementView(viewType: _pdfString)
else if (widget.pdfBytes != null) else if (widget.pdfBytes != null)
PdfPreview( PdfPreview(
build: (format) => widget.pdfBytes, build: (format) => widget.pdfBytes,

View File

@ -2,6 +2,7 @@
import 'dart:convert'; import 'dart:convert';
// Flutter imports: // Flutter imports:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// Package imports: // 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:material_design_icons_flutter/material_design_icons_flutter.dart';
import 'package:printing/printing.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 { class InvoiceEditDesktop extends StatefulWidget {
const InvoiceEditDesktop({ const InvoiceEditDesktop({
Key key, Key key,
@ -1157,6 +1161,7 @@ class __PdfPreviewState extends State<_PdfPreview> {
int _pageCount = 1; int _pageCount = 1;
int _currentPage = 1; int _currentPage = 1;
String _pdfString;
http.Response _response; http.Response _response;
bool _isLoading = false; bool _isLoading = false;
bool _pendingLoad = false; bool _pendingLoad = false;
@ -1243,6 +1248,12 @@ class __PdfPreviewState extends State<_PdfPreview> {
_currentPage = _pageCount; _currentPage = _pageCount;
} }
if (kIsWeb && state.prefState.enableNativeBrowser) {
_pdfString =
'data:application/pdf;base64,' + base64Encode(response.bodyBytes);
WebUtils.registerWebView(_pdfString);
}
if (_pendingLoad) { if (_pendingLoad) {
_pendingLoad = false; _pendingLoad = false;
_loadPdf(); _loadPdf();
@ -1269,7 +1280,8 @@ class __PdfPreviewState extends State<_PdfPreview> {
Column( Column(
crossAxisAlignment: CrossAxisAlignment.stretch, crossAxisAlignment: CrossAxisAlignment.stretch,
children: [ children: [
if (_pageCount > 1) if (_pageCount > 1 &&
(!kIsWeb || !state.prefState.enableNativeBrowser))
Padding( Padding(
padding: const EdgeInsets.only(bottom: 16), padding: const EdgeInsets.only(bottom: 16),
child: Row( child: Row(
@ -1306,6 +1318,8 @@ class __PdfPreviewState extends State<_PdfPreview> {
? Container( ? Container(
color: Colors.grey.shade300, color: Colors.grey.shade300,
) )
: (kIsWeb && state.prefState.enableNativeBrowser)
? HtmlElementView(viewType: _pdfString)
: PdfPreview( : PdfPreview(
build: (format) => _response.bodyBytes, build: (format) => _response.bodyBytes,
canChangeOrientation: false, canChangeOrientation: false,

View File

@ -2,6 +2,7 @@
import 'dart:convert'; import 'dart:convert';
// Flutter imports: // Flutter imports:
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
// Project imports: // 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/ui/invoice/edit/invoice_edit_pdf_vm.dart';
import 'package:invoiceninja_flutter/utils/localization.dart'; import 'package:invoiceninja_flutter/utils/localization.dart';
import 'package:printing/printing.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 { class InvoiceEditPDF extends StatefulWidget {
const InvoiceEditPDF({ const InvoiceEditPDF({
@ -28,6 +31,7 @@ class InvoiceEditPDF extends StatefulWidget {
class InvoiceEditPDFState extends State<InvoiceEditPDF> { class InvoiceEditPDFState extends State<InvoiceEditPDF> {
bool _isLoading = false; bool _isLoading = false;
String _pdfString;
http.Response _response; http.Response _response;
@override @override
@ -73,6 +77,12 @@ class InvoiceEditPDFState extends State<InvoiceEditPDF> {
setState(() { setState(() {
_isLoading = false; _isLoading = false;
_response = response; _response = response;
if (kIsWeb && state.prefState.enableNativeBrowser) {
_pdfString =
'data:application/pdf;base64,' + base64Encode(response.bodyBytes);
WebUtils.registerWebView(_pdfString);
}
}); });
}).catchError((dynamic error) { }).catchError((dynamic error) {
setState(() { setState(() {
@ -83,6 +93,8 @@ class InvoiceEditPDFState extends State<InvoiceEditPDF> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final state = widget.viewModel.state;
if (!widget.viewModel.invoice.hasClient) { if (!widget.viewModel.invoice.hasClient) {
return HelpText(AppLocalization.of(context).noClientSelected); return HelpText(AppLocalization.of(context).noClientSelected);
} }
@ -94,7 +106,9 @@ class InvoiceEditPDFState extends State<InvoiceEditPDF> {
} }
return Center( return Center(
child: PdfPreview( child: kIsWeb && state.prefState.enableNativeBrowser
? HtmlElementView(viewType: _pdfString)
: PdfPreview(
build: (format) => _response.bodyBytes, build: (format) => _response.bodyBytes,
canChangeOrientation: false, canChangeOrientation: false,
canChangePageFormat: false, canChangePageFormat: false,

View File

@ -55,6 +55,7 @@ class _InvoicePdfViewState extends State<InvoicePdfView> {
bool _isLoading = true; bool _isLoading = true;
bool _isDeliveryNote = false; bool _isDeliveryNote = false;
String _activityId; String _activityId;
String _pdfString;
http.Response _response; http.Response _response;
//int _pageCount = 1; //int _pageCount = 1;
//int _currentPage = 1; //int _currentPage = 1;
@ -75,6 +76,7 @@ class _InvoicePdfViewState extends State<InvoicePdfView> {
void loadPdf() { void loadPdf() {
final viewModel = widget.viewModel; final viewModel = widget.viewModel;
final invoice = viewModel.invoice; final invoice = viewModel.invoice;
final state = viewModel.state;
if (invoice.invitations.isEmpty) { if (invoice.invitations.isEmpty) {
return; return;
@ -93,6 +95,12 @@ class _InvoicePdfViewState extends State<InvoicePdfView> {
setState(() { setState(() {
_response = response; _response = response;
_isLoading = false; _isLoading = false;
if (kIsWeb && state.prefState.enableNativeBrowser) {
_pdfString =
'data:application/pdf;base64,' + base64Encode(response.bodyBytes);
WebUtils.registerWebView(_pdfString);
}
}); });
}).catchError((Object error) { }).catchError((Object error) {
setState(() { setState(() {
@ -301,13 +309,16 @@ class _InvoicePdfViewState extends State<InvoicePdfView> {
: null, : null,
body: _isLoading || _response == null body: _isLoading || _response == null
? LoadingIndicator() ? LoadingIndicator()
: (kIsWeb && state.prefState.enableNativeBrowser)
? HtmlElementView(viewType: _pdfString)
: PdfPreview( : PdfPreview(
build: (format) => _response.bodyBytes, build: (format) => _response.bodyBytes,
canChangeOrientation: false, canChangeOrientation: false,
canChangePageFormat: false, canChangePageFormat: false,
canDebug: false, canDebug: false,
maxPageWidth: 800, maxPageWidth: 800,
pdfFileName: localization.lookup(invoice.entityType.snakeCase) + pdfFileName:
localization.lookup(invoice.entityType.snakeCase) +
'_' + '_' +
invoice.number + invoice.number +
'.pdf', '.pdf',

View File

@ -196,6 +196,16 @@ class _DeviceSettingsState extends State<DeviceSettings>
activeColor: Theme.of(context).colorScheme.secondary, activeColor: Theme.of(context).colorScheme.secondary,
secondary: Icon(MdiIcons.filePdfBox), 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), SizedBox(height: 10),
BoolDropdownButton( BoolDropdownButton(
label: localization.previewLocation, label: localization.previewLocation,

View File

@ -54,6 +54,7 @@ class DeviceSettingsVM {
@required this.onPersistDataChanged, @required this.onPersistDataChanged,
@required this.onPersistUiChanged, @required this.onPersistUiChanged,
@required this.onShowPdfChanged, @required this.onShowPdfChanged,
@required this.onEnableNativeBrowserChanged,
@required this.onShowPdfSideBySideChanged, @required this.onShowPdfSideBySideChanged,
@required this.onTapSelectedChanged, @required this.onTapSelectedChanged,
@required this.onTextScaleFactorChanged, @required this.onTextScaleFactorChanged,
@ -112,6 +113,9 @@ class DeviceSettingsVM {
onShowPdfChanged: (context, value) { onShowPdfChanged: (context, value) {
store.dispatch(UpdateUserPreferences(showPdfPreview: value)); store.dispatch(UpdateUserPreferences(showPdfPreview: value));
}, },
onEnableNativeBrowserChanged: (context, value) {
store.dispatch(UpdateUserPreferences(enableNativeBrowser: value));
},
onShowPdfSideBySideChanged: (context, value) { onShowPdfSideBySideChanged: (context, value) {
store.dispatch(UpdateUserPreferences(showPdfPreviewSideBySide: value)); store.dispatch(UpdateUserPreferences(showPdfPreviewSideBySide: value));
}, },
@ -214,6 +218,7 @@ class DeviceSettingsVM {
final Function(BuildContext, bool) onPersistDataChanged; final Function(BuildContext, bool) onPersistDataChanged;
final Function(BuildContext, bool) onPersistUiChanged; final Function(BuildContext, bool) onPersistUiChanged;
final Function(BuildContext, bool) onShowPdfChanged; final Function(BuildContext, bool) onShowPdfChanged;
final Function(BuildContext, bool) onEnableNativeBrowserChanged;
final Function(BuildContext, bool) onShowPdfSideBySideChanged; final Function(BuildContext, bool) onShowPdfSideBySideChanged;
final Function(BuildContext, bool) onEnableTouchEventsChanged; final Function(BuildContext, bool) onEnableTouchEventsChanged;
final Function(BuildContext, bool) onEnableTooltipsChanged; final Function(BuildContext, bool) onEnableTooltipsChanged;