2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-04-27 21:16:48 +00:00

Download attachments and open

- Uses package "open_file"
This commit is contained in:
Oliver 2021-08-15 22:09:11 +10:00
parent 4243876111
commit e31158a966
8 changed files with 113 additions and 6 deletions

View File

@ -52,6 +52,7 @@
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.MICROPHONE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
</manifest>

View File

@ -2,9 +2,11 @@ import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'package:open_file/open_file.dart';
import 'package:flutter/cupertino.dart';
import 'package:cached_network_image/cached_network_image.dart';
import 'package:flutter/material.dart';
@ -16,6 +18,7 @@ import 'package:inventree/l10.dart';
import 'package:inventree/inventree/sentry.dart';
import 'package:inventree/user_profile.dart';
import 'package:inventree/widget/snacks.dart';
import 'package:path_provider/path_provider.dart';
/*
@ -119,6 +122,8 @@ class InvenTreeAPI {
}
String _makeUrl(String url) {
// Strip leading slash
if (url.startsWith('/')) {
url = url.substring(1, url.length);
}
@ -469,6 +474,92 @@ class InvenTreeAPI {
);
}
/*
* Download a file from the given URL
*/
Future<void> downloadFile(String url, {bool openOnDownload = true}) async {
showSnackIcon(
L10().downloading,
icon: FontAwesomeIcons.download,
success: true
);
// Find the local downlods directory
final Directory dir = await getTemporaryDirectory();
String filename = url.split("/").last;
String local_path = dir.path + "/" + filename;
Uri? _uri = Uri.tryParse(makeUrl(url));
if (_uri == null) {
showServerError(L10().invalidHost, L10().invalidHostDetails);
return;
}
if (_uri.host.isEmpty) {
showServerError(L10().invalidHost, L10().invalidHostDetails);
return;
}
HttpClientRequest? _request;
var client = createClient(true);
// Attempt to open a connection to the server
try {
_request = await client.openUrl("GET", _uri).timeout(Duration(seconds: 10));
// Set headers
_request.headers.set(HttpHeaders.authorizationHeader, _authorizationHeader());
_request.headers.set(HttpHeaders.acceptHeader, 'application/json');
_request.headers.set(HttpHeaders.contentTypeHeader, 'application/json');
_request.headers.set(HttpHeaders.acceptLanguageHeader, Intl.getCurrentLocale());
} on SocketException catch (error) {
print("SocketException at ${url}: ${error.toString()}");
showServerError(L10().connectionRefused, error.toString());
return;
} on TimeoutException {
print("TimeoutException at ${url}");
showTimeoutError();
return;
} catch (error, stackTrace) {
print("Server error at ${url}: ${error.toString()}");
showServerError(L10().serverError, error.toString());
sentryReportError(error, stackTrace);
return;
}
try {
final response = await _request.close();
if (response.statusCode == 200) {
var bytes = await consolidateHttpClientResponseBytes(response);
File localFile = File(local_path);
await localFile.writeAsBytes(bytes);
if (openOnDownload) {
OpenFile.open(local_path);
}
} else {
showStatusCodeError(response.statusCode);
}
} on SocketException catch (error) {
showServerError(L10().connectionRefused, error.toString());
} on TimeoutException {
showTimeoutError();
} catch (error, stackTrace) {
print("Error downloading image:");
print(error.toString());
showServerError(L10().downloadError, error.toString());
}
}
/*
* Upload a file to the given URL
*/

View File

@ -526,6 +526,12 @@ class InvenTreeAttachment extends InvenTreeModel {
}
}
Future<void> downloadAttachment() async {
await InvenTreeAPI().downloadFile(attachment);
}
}

@ -1 +1 @@
Subproject commit faec97124b652ca219d6c0899dd0234cf42e4fa7
Subproject commit e6b7dd53bc43e084325c2bb414436b559d18931a

View File

@ -510,8 +510,6 @@ class _PaginatedPartListState extends State<PaginatedPartList> {
void updateSearchTerm() {
print("Search Term: '${_searchTerm}'");
_searchTerm = searchController.text;
_pagingController.refresh();
}

View File

@ -161,6 +161,9 @@ class _PartAttachmentDisplayState extends RefreshableState<PartAttachmentsWidget
title: Text(attachment.filename),
subtitle: Text(attachment.comment),
leading: FaIcon(attachment.icon),
onTap: () async {
await attachment.downloadAttachment();
},
));
}

View File

@ -357,6 +357,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
open_file:
dependency: "direct main"
description:
name: open_file
url: "https://pub.dartlang.org"
source: hosted
version: "3.2.1"
package_info_plus:
dependency: "direct main"
description:
@ -412,7 +419,7 @@ packages:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
version: "2.0.2"
path_provider_linux:
dependency: transitive
description:

View File

@ -33,9 +33,10 @@ dependencies:
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
open_file: 3.2.1 # Open local files
flutter_markdown: ^0.6.2 # Rendering markdown
camera: # Camera
path_provider: 2.0.1 # Local file storage
path_provider: 2.0.2 # Local file storage
sembast: ^3.1.0+2 # NoSQL data storage
one_context: ^1.1.0 # Dialogs without requiring context
infinite_scroll_pagination: ^3.1.0 # Let the server do all the work!