Initial commit

This commit is contained in:
Anton Stubenbord
2022-10-30 14:15:37 +01:00
commit cb797df7d2
272 changed files with 16278 additions and 0 deletions

View File

@@ -0,0 +1,106 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:photo_view/photo_view.dart';
typedef DeleteCallback = void Function();
typedef OnImageOperation = void Function(File);
class GridImageItemWidget extends StatefulWidget {
final File file;
final DeleteCallback onDelete;
//final OnImageOperation onImageOperation;
final int index;
final int totalNumberOfFiles;
const GridImageItemWidget({
Key? key,
required this.file,
required this.onDelete,
required this.index,
required this.totalNumberOfFiles,
//required this.onImageOperation,
}) : super(key: key);
@override
State<GridImageItemWidget> createState() => _GridImageItemWidgetState();
}
class _GridImageItemWidgetState extends State<GridImageItemWidget> {
bool isProcessing = false;
@override
Widget build(BuildContext context) {
return GestureDetector(
onTap: () => _showImage(context),
child: _buildImageItem(context),
);
}
Card _buildImageItem(BuildContext context) {
return Card(
child: Padding(
padding: const EdgeInsets.only(bottom: 8.0),
child: Stack(
children: [
Align(alignment: Alignment.bottomCenter, child: _buildNumbering()),
Align(
alignment: Alignment.topRight,
child: IconButton(
onPressed: widget.onDelete,
icon: const Icon(Icons.close),
),
),
isProcessing
? _buildIsProcessing()
: Align(
alignment: Alignment.center,
child: AspectRatio(
aspectRatio: 4 / 3,
child: Image.file(
widget.file,
fit: BoxFit.contain,
),
),
),
],
),
),
);
}
Center _buildIsProcessing() {
return Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
crossAxisAlignment: CrossAxisAlignment.center,
children: const [
CircularProgressIndicator(),
Text(
"Processing transformation...",
textAlign: TextAlign.center,
),
],
),
);
}
void _showImage(BuildContext context) {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => Scaffold(
appBar: AppBar(
title: _buildNumbering(prefix: "Image"),
),
body: PhotoView(imageProvider: FileImage(widget.file)),
),
),
);
}
Widget _buildNumbering({String? prefix}) {
return Text(
"${prefix ?? ""} ${widget.index + 1}/${widget.totalNumberOfFiles}",
);
}
}

View File

@@ -0,0 +1,41 @@
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:permission_handler/permission_handler.dart';
typedef OnImageScannedCallback = void Function(File);
class ScannerWidget extends StatefulWidget {
final OnImageScannedCallback onImageScannedCallback;
const ScannerWidget({
Key? key,
required this.onImageScannedCallback,
}) : super(key: key);
@override
_ScannerWidgetState createState() => _ScannerWidgetState();
}
class _ScannerWidgetState extends State<ScannerWidget> {
List<File> documents = List.empty(growable: true);
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text("Scan document")),
body: FutureBuilder<PermissionStatus>(
future: Permission.camera.request(),
builder: (BuildContext context, AsyncSnapshot<PermissionStatus> snapshot) {
if (!snapshot.hasData) {
return const Center(child: CircularProgressIndicator());
}
if (snapshot.data!.isGranted) {
return Container();
}
return const Center(
child: Text("No camera permissions, please enable in settings!"),
);
}),
);
}
}

View File

@@ -0,0 +1,64 @@
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class UploadDialog extends StatefulWidget {
const UploadDialog({
Key? key,
}) : super(key: key);
@override
State<UploadDialog> createState() => _UploadDialogState();
}
class _UploadDialogState extends State<UploadDialog> {
late TextEditingController _controller;
final _formKey = GlobalKey<FormState>();
@override
void initState() {
final DateFormat format = DateFormat("yyyy_MM_dd_hh_mm_ss");
final today = format.format(DateTime.now());
_controller = TextEditingController.fromValue(TextEditingValue(text: "Scan_$today.pdf"));
super.initState();
}
@override
Widget build(BuildContext context) {
return AlertDialog(
title: const Text("Upload to paperless-ng"),
content: Form(
key: _formKey,
child: TextFormField(
controller: _controller,
validator: (text) {
if (text == null || text.isEmpty) {
return "Filename must be specified!";
}
return null;
},
),
),
actions: [
TextButton(
onPressed: () {
Navigator.of(context).pop();
},
child: const Text("Cancel"),
),
TextButton(
onPressed: () {
if (!_formKey.currentState!.validate()) {
return;
}
var txt = _controller.text;
if (!txt.endsWith(".pdf")) {
txt += ".pdf";
}
Navigator.of(context).pop(txt);
},
child: const Text("Upload"),
),
],
);
}
}