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:
parent
4243876111
commit
e31158a966
@ -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>
|
91
lib/api.dart
91
lib/api.dart
@ -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
|
||||
*/
|
||||
|
@ -526,6 +526,12 @@ class InvenTreeAttachment extends InvenTreeModel {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> downloadAttachment() async {
|
||||
|
||||
await InvenTreeAPI().downloadFile(attachment);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
2
lib/l10n
2
lib/l10n
@ -1 +1 @@
|
||||
Subproject commit faec97124b652ca219d6c0899dd0234cf42e4fa7
|
||||
Subproject commit e6b7dd53bc43e084325c2bb414436b559d18931a
|
@ -510,8 +510,6 @@ class _PaginatedPartListState extends State<PaginatedPartList> {
|
||||
|
||||
void updateSearchTerm() {
|
||||
|
||||
print("Search Term: '${_searchTerm}'");
|
||||
|
||||
_searchTerm = searchController.text;
|
||||
_pagingController.refresh();
|
||||
}
|
||||
|
@ -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();
|
||||
},
|
||||
));
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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!
|
||||
|
Loading…
x
Reference in New Issue
Block a user