mirror of
https://github.com/inventree/inventree-app.git
synced 2025-04-28 05:26:47 +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.INTERNET"/>
|
||||||
<uses-permission android:name="android.permission.CAMERA"/>
|
<uses-permission android:name="android.permission.CAMERA"/>
|
||||||
<uses-permission android:name="android.permission.MICROPHONE"/>
|
<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>
|
</manifest>
|
91
lib/api.dart
91
lib/api.dart
@ -2,9 +2,11 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
|
||||||
|
import 'package:open_file/open_file.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:cached_network_image/cached_network_image.dart';
|
import 'package:cached_network_image/cached_network_image.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
@ -16,6 +18,7 @@ import 'package:inventree/l10.dart';
|
|||||||
import 'package:inventree/inventree/sentry.dart';
|
import 'package:inventree/inventree/sentry.dart';
|
||||||
import 'package:inventree/user_profile.dart';
|
import 'package:inventree/user_profile.dart';
|
||||||
import 'package:inventree/widget/snacks.dart';
|
import 'package:inventree/widget/snacks.dart';
|
||||||
|
import 'package:path_provider/path_provider.dart';
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -119,6 +122,8 @@ class InvenTreeAPI {
|
|||||||
}
|
}
|
||||||
|
|
||||||
String _makeUrl(String url) {
|
String _makeUrl(String url) {
|
||||||
|
|
||||||
|
// Strip leading slash
|
||||||
if (url.startsWith('/')) {
|
if (url.startsWith('/')) {
|
||||||
url = url.substring(1, url.length);
|
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
|
* 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() {
|
void updateSearchTerm() {
|
||||||
|
|
||||||
print("Search Term: '${_searchTerm}'");
|
|
||||||
|
|
||||||
_searchTerm = searchController.text;
|
_searchTerm = searchController.text;
|
||||||
_pagingController.refresh();
|
_pagingController.refresh();
|
||||||
}
|
}
|
||||||
|
@ -161,6 +161,9 @@ class _PartAttachmentDisplayState extends RefreshableState<PartAttachmentsWidget
|
|||||||
title: Text(attachment.filename),
|
title: Text(attachment.filename),
|
||||||
subtitle: Text(attachment.comment),
|
subtitle: Text(attachment.comment),
|
||||||
leading: FaIcon(attachment.icon),
|
leading: FaIcon(attachment.icon),
|
||||||
|
onTap: () async {
|
||||||
|
await attachment.downloadAttachment();
|
||||||
|
},
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -357,6 +357,13 @@ packages:
|
|||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0"
|
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:
|
package_info_plus:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@ -412,7 +419,7 @@ packages:
|
|||||||
name: path_provider
|
name: path_provider
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.0.1"
|
version: "2.0.2"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
@ -33,9 +33,10 @@ dependencies:
|
|||||||
image_picker: ^0.8.3 # Select or take photos
|
image_picker: ^0.8.3 # Select or take photos
|
||||||
file_picker: ^4.0.0 # Select files from the device
|
file_picker: ^4.0.0 # Select files from the device
|
||||||
url_launcher: 6.0.9 # Open link in system browser
|
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
|
flutter_markdown: ^0.6.2 # Rendering markdown
|
||||||
camera: # Camera
|
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
|
sembast: ^3.1.0+2 # NoSQL data storage
|
||||||
one_context: ^1.1.0 # Dialogs without requiring context
|
one_context: ^1.1.0 # Dialogs without requiring context
|
||||||
infinite_scroll_pagination: ^3.1.0 # Let the server do all the work!
|
infinite_scroll_pagination: ^3.1.0 # Let the server do all the work!
|
||||||
|
Loading…
x
Reference in New Issue
Block a user