From a5edb84723d713d0871efbfa3bcfa0c05a1e0c6f Mon Sep 17 00:00:00 2001 From: Oliver Date: Sun, 15 Aug 2021 17:27:25 +1000 Subject: [PATCH] Upload part attachnents - Select file from device - Take picture with camera --- ios/Flutter/Flutter.podspec | 18 ------ lib/inventree/model.dart | 20 +++++++ lib/l10n | 2 +- lib/widget/part_attachments_widget.dart | 77 ++++++++++++++++++++++++- pubspec.lock | 13 ++++- pubspec.yaml | 3 +- 6 files changed, 107 insertions(+), 26 deletions(-) delete mode 100644 ios/Flutter/Flutter.podspec diff --git a/ios/Flutter/Flutter.podspec b/ios/Flutter/Flutter.podspec deleted file mode 100644 index 2c4421cf..00000000 --- a/ios/Flutter/Flutter.podspec +++ /dev/null @@ -1,18 +0,0 @@ -# -# NOTE: This podspec is NOT to be published. It is only used as a local source! -# This is a generated file; do not edit or check into version control. -# - -Pod::Spec.new do |s| - s.name = 'Flutter' - s.version = '1.0.0' - s.summary = 'High-performance, high-fidelity mobile apps.' - s.homepage = 'https://flutter.io' - s.license = { :type => 'MIT' } - s.author = { 'Flutter Dev Team' => 'flutter-dev@googlegroups.com' } - s.source = { :git => 'https://github.com/flutter/engine', :tag => s.version.to_s } - s.ios.deployment_target = '8.0' - # Framework linking is handled by Flutter tooling, not CocoaPods. - # Add a placeholder to satisfy `s.dependency 'Flutter'` plugin podspecs. - s.vendored_frameworks = 'path/to/nothing' -end diff --git a/lib/inventree/model.dart b/lib/inventree/model.dart index 7c708672..7dcfa3cf 100644 --- a/lib/inventree/model.dart +++ b/lib/inventree/model.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:io'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:inventree/api.dart'; @@ -8,6 +9,7 @@ import 'package:inventree/widget/dialogs.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:path/path.dart' as path; +import 'package:http/http.dart' as http; import '../l10.dart'; import '../api_form.dart'; @@ -506,6 +508,24 @@ class InvenTreeAttachment extends InvenTreeModel { } InvenTreeAttachment.fromJson(Map json) : super.fromJson(json); + + Future uploadAttachment(File attachment, {String comment = "", Map fields = const {}}) async { + + final http.StreamedResponse response = await InvenTreeAPI().uploadFile( + URL, + attachment, + method: 'POST', + name: 'attachment', + fields: fields + ); + + if (response.statusCode == 200 || response.statusCode == 201) { + return true; + } else { + return false; + } + } + } diff --git a/lib/l10n b/lib/l10n index 20dce387..faec9712 160000 --- a/lib/l10n +++ b/lib/l10n @@ -1 +1 @@ -Subproject commit 20dce387ab4088e22b67c6ffd1fb50b6a1f252e8 +Subproject commit faec97124b652ca219d6c0899dd0234cf42e4fa7 diff --git a/lib/widget/part_attachments_widget.dart b/lib/widget/part_attachments_widget.dart index 73483f53..5e16085e 100644 --- a/lib/widget/part_attachments_widget.dart +++ b/lib/widget/part_attachments_widget.dart @@ -1,10 +1,15 @@ +import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; +import 'package:image_picker/image_picker.dart'; import 'package:inventree/inventree/part.dart'; import 'package:inventree/widget/refreshable_state.dart'; +import 'package:inventree/widget/snacks.dart'; + +import 'dart:io'; import '../api.dart'; import '../l10.dart'; @@ -36,11 +41,21 @@ class _PartAttachmentDisplayState extends RefreshableState actions = []; - if (false && InvenTreeAPI().checkPermission('part', 'change')) { + if (InvenTreeAPI().checkPermission('part', 'change')) { + + // File upload actions.add( IconButton( - icon: FaIcon(FontAwesomeIcons.plus), - onPressed: null, + icon: FaIcon(FontAwesomeIcons.fileUpload), + onPressed: uploadFile, + ) + ); + + // Upload from camera + actions.add( + IconButton( + icon: FaIcon(FontAwesomeIcons.camera), + onPressed: uploadFromCamera, ) ); } @@ -48,6 +63,62 @@ class _PartAttachmentDisplayState extends RefreshableState upload(File file) async { + final bool result = await InvenTreePartAttachment().uploadAttachment( + file, + fields: { + "part": "${part.pk}" + } + ); + + if (result) { + showSnackIcon(L10().uploadSuccess, success: true); + } else { + showSnackIcon(L10().uploadFailed, success: false); + } + + refresh(); + + } + + /* + * Select a file from the device to upload + */ + Future uploadFile() async { + + final FilePickerResult? result = await FilePicker.platform.pickFiles(); + + if (result != null) { + + String? path = result.files.single.path; + + if (path != null) { + File attachment = File(path); + + upload(attachment); + } + } + + } + + /* + * Upload an attachment by taking a new picture with the built in device camera + */ + Future uploadFromCamera() async { + + + final picker = ImagePicker(); + + final pickedImage = await picker.getImage(source: ImageSource.camera); + + if (pickedImage != null) { + File? attachment = File(pickedImage.path); + upload(attachment); + } + + refresh(); + } + @override Future request() async { diff --git a/pubspec.lock b/pubspec.lock index 3c2e9310..6ea5ee79 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -183,6 +183,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.1.2" + file_picker: + dependency: "direct main" + description: + name: file_picker + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" flutter: dependency: "direct main" description: flutter @@ -279,21 +286,21 @@ packages: name: image_picker url: "https://pub.dartlang.org" source: hosted - version: "0.8.0+3" + version: "0.8.3+2" image_picker_for_web: dependency: transitive description: name: image_picker_for_web url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.2" image_picker_platform_interface: dependency: transitive description: name: image_picker_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.2.0" infinite_scroll_pagination: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 7dba451c..ff36f4c2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -30,7 +30,8 @@ dependencies: font_awesome_flutter: ^9.1.0 # FontAwesome icon set flutter_speed_dial: ^3.0.5 # FAB menu elements sentry_flutter: 5.0.0 # Error reporting - image_picker: ^0.8.0 # Select or take photos + image_picker: ^0.8.3 # Select or take photos + file_picker: ^4.0.0 # Select files from the device url_launcher: 6.0.9 # Open link in system browser flutter_markdown: ^0.6.2 # Rendering markdown camera: # Camera