feat: Add print feature, refine gradient on details page

This commit is contained in:
Anton Stubenbord
2023-05-29 17:10:33 +02:00
parent d8ee418828
commit e4df202190
7 changed files with 150 additions and 48 deletions

View File

@@ -11,6 +11,7 @@ import 'package:paperless_mobile/core/repository/label_repository.dart';
import 'package:paperless_mobile/core/service/file_description.dart';
import 'package:paperless_mobile/core/service/file_service.dart';
import 'package:paperless_mobile/features/notifications/services/local_notification_service.dart';
import 'package:printing/printing.dart';
import 'package:share_plus/share_plus.dart';
import 'package:cross_file/cross_file.dart';
@@ -98,6 +99,7 @@ class DocumentDetailsCubit extends Cubit<DocumentDetailsState> {
Future<ResultType> openDocumentInSystemViewer() async {
final cacheDir = await FileService.temporaryDirectory;
//TODO: Why is this cleared here?
await FileService.clearDirectoryContent(PaperlessDirectoryType.temporary);
if (state.metaData == null) {
await loadMetaData();
@@ -199,6 +201,26 @@ class DocumentDetailsCubit extends Cubit<DocumentDetailsState> {
);
}
Future<void> printDocument() async {
if (state.metaData == null) {
await loadMetaData();
}
final filePath = _buildDownloadFilePath(false, await FileService.temporaryDirectory);
await _api.downloadToFile(
state.document,
filePath,
original: false,
);
final file = File(filePath);
if (!file.existsSync()) {
throw Exception("An error occurred while downloading the document.");
}
Printing.layoutPdf(
name: state.document.title,
onLayout: (format) => file.readAsBytesSync(),
);
}
String _buildDownloadFilePath(bool original, Directory dir) {
final description = FileDescription.fromPath(
state.metaData!.mediaFilename.replaceAll("/", " "), // Flatten directory structure

View File

@@ -1,5 +1,7 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:open_filex/open_filex.dart';
import 'package:paperless_api/paperless_api.dart';
import 'package:paperless_mobile/core/bloc/connectivity_cubit.dart';
@@ -44,11 +46,6 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
final _pagingScrollController = ScrollController();
@override
void didChangeDependencies() {
super.didChangeDependencies();
}
@override
Widget build(BuildContext context) {
final apiVersion = context.watch<ApiVersion>();
@@ -87,22 +84,24 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
alignment: Alignment.topCenter,
children: [
BlocBuilder<DocumentDetailsCubit, DocumentDetailsState>(
builder: (context, state) => Positioned.fill(
child: DocumentPreview(
document: state.document,
fit: BoxFit.cover,
),
),
builder: (context, state) {
return Positioned.fill(
child: DocumentPreview(
document: state.document,
fit: BoxFit.cover,
),
);
},
),
Positioned.fill(
top: 0,
child: Container(
height: 100,
child: DecoratedBox(
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.black.withOpacity(0.7),
Colors.black.withOpacity(0.2),
Theme.of(context).colorScheme.background.withOpacity(0.8),
Theme.of(context).colorScheme.background.withOpacity(0.5),
Colors.transparent,
Colors.transparent,
Colors.transparent,
],
@@ -310,7 +309,7 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
IconButton(
tooltip: S.of(context)!.previewTooltip,
icon: const Icon(Icons.visibility),
onPressed: (isConnected && false) ? () => _onOpen(state.document) : null,
onPressed: (isConnected) ? () => _onOpen(state.document) : null,
).paddedOnly(right: 4.0),
IconButton(
tooltip: S.of(context)!.openInSystemViewer,
@@ -318,6 +317,11 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
onPressed: isConnected ? _onOpenFileInSystemViewer : null,
).paddedOnly(right: 4.0),
DocumentShareButton(document: state.document),
IconButton(
tooltip: "Print", //TODO: INTL
onPressed: () => context.read<DocumentDetailsCubit>().printDocument(),
icon: const Icon(Icons.print),
),
],
);
},
@@ -404,7 +408,8 @@ class _DocumentDetailsPageState extends State<DocumentDetailsPage> {
Navigator.of(context).push(
MaterialPageRoute(
builder: (_) => DocumentView(
documentBytes: context.read<PaperlessDocumentsApi>().getPreview(document.id),
documentBytes: context.read<PaperlessDocumentsApi>().download(document),
title: document.title,
),
),
);

View File

@@ -120,6 +120,7 @@ class _ScannerPageState extends State<ScannerPage> with SingleTickerProviderStat
? () => Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DocumentView(
documentBytes: _assembleFileBytes(
state,
forcePdf: true,

View File

@@ -1,12 +1,14 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
class DocumentView extends StatefulWidget {
final Future<Uint8List> documentBytes;
final String? title;
const DocumentView({
Key? key,
required this.documentBytes,
this.title,
}) : super(key: key);
@override
@@ -14,37 +16,90 @@ class DocumentView extends StatefulWidget {
}
class _DocumentViewState extends State<DocumentView> {
// late PdfController _pdfController;
@override
void initState() {
super.initState();
// _pdfController = PdfController(
// document: PdfDocument.openData(
// widget.documentBytes,
// ),
// );
}
int? _currentPage;
int? _totalPages;
PDFViewController? _controller;
@override
Widget build(BuildContext context) {
return Container();
// return Scaffold(
// appBar: AppBar(
// title: Text(S.of(context)!.preview),
// ),
// body: PdfView(
// builders: PdfViewBuilders<DefaultBuilderOptions>(
// options: const DefaultBuilderOptions(
// loaderSwitchDuration: Duration(milliseconds: 500),
// ),
// pageLoaderBuilder: (context) => const Center(
// child: CircularProgressIndicator(),
// ),
// ),
// scrollDirection: Axis.vertical,
// controller: _pdfController,
// ),
// );
final isInitialized = _controller != null && _currentPage != null && _totalPages != null;
final canGoToNextPage = isInitialized && _currentPage! + 1 < _totalPages!;
final canGoToPreviousPage = isInitialized && _currentPage! > 0;
return Scaffold(
appBar: AppBar(
title: widget.title != null ? Text(widget.title!) : null,
),
bottomNavigationBar: BottomAppBar(
child: Row(
children: [
Flexible(
child: Row(
children: [
IconButton.filled(
onPressed: canGoToPreviousPage
? () {
_controller?.setPage(_currentPage! - 1);
}
: null,
icon: const Icon(Icons.arrow_left),
),
const SizedBox(width: 16),
IconButton.filled(
onPressed: canGoToNextPage
? () {
_controller?.setPage(_currentPage! + 1);
}
: null,
icon: const Icon(Icons.arrow_right),
),
],
),
),
if (_currentPage != null && _totalPages != null)
Text(
"${_currentPage! + 1}/$_totalPages",
style: Theme.of(context).textTheme.labelLarge,
),
],
),
),
body: FutureBuilder(
future: widget.documentBytes,
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const Center(
child: CircularProgressIndicator(),
);
}
return PDFView(
pdfData: snapshot.data,
defaultPage: 0,
enableSwipe: true,
fitPolicy: FitPolicy.BOTH,
swipeHorizontal: true,
onRender: (pages) {
setState(() {
_currentPage = 0;
_totalPages = pages ?? -1;
});
},
onPageChanged: (page, total) {
setState(() {
_currentPage = page;
_totalPages = total;
});
},
onViewCreated: (controller) {
_controller = controller;
},
onError: (error) {
print(error.toString());
},
onPageError: (page, error) {
print('$page: ${error.toString()}');
},
);
}),
);
}
}

View File

@@ -74,6 +74,7 @@ Future<void> _initHive() async {
}
void main() async {
Paint.enableDithering = true;
if (kDebugMode) {
// URL: http://localhost:3131
// Login: admin:test

View File

@@ -617,6 +617,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.2.18"
flutter_pdfview:
dependency: "direct main"
description:
name: flutter_pdfview
sha256: d9735fd8991609910742a25c63a5f87060849e57e60112c677b802ddb64bed72
url: "https://pub.dev"
source: hosted
version: "1.3.1"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
@@ -1267,6 +1275,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.1"
printing:
dependency: "direct main"
description:
name: printing
sha256: e7c383dca95ee7b88c02dc1c66638628d3dcdc2fb2cc47e7a595facd47e46b56
url: "https://pub.dev"
source: hosted
version: "5.11.0"
process:
dependency: transitive
description:
@@ -1802,4 +1818,4 @@ packages:
version: "3.1.1"
sdks:
dart: ">=3.0.0 <4.0.0"
flutter: ">=3.7.0"
flutter: ">=3.10.0"

View File

@@ -94,6 +94,8 @@ dependencies:
flutter_secure_storage: ^8.0.0
sliver_tools: ^0.2.10
webview_flutter: ^4.2.1
printing: ^5.11.0
flutter_pdfview: ^1.3.1
dependency_overrides:
intl: ^0.18.0