mirror of
https://github.com/inventree/inventree-app.git
synced 2026-02-06 12:55:50 +00:00
Image url fix (#765)
* Bump release notes * Improve URL resolution * Add URL tests * Add debug for CI * Fix stock adjustment URLs * Fix barcode URLs
This commit is contained in:
@@ -1,3 +1,8 @@
|
|||||||
|
## 0.22.1 - February 2026
|
||||||
|
---
|
||||||
|
|
||||||
|
- Fixes bug related to fetching images from remote URLs
|
||||||
|
|
||||||
### 0.22.0 - February 2026
|
### 0.22.0 - February 2026
|
||||||
---
|
---
|
||||||
|
|
||||||
|
|||||||
35
lib/api.dart
35
lib/api.dart
@@ -213,30 +213,27 @@ class InvenTreeAPI {
|
|||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
|
|
||||||
String _makeUrl(String url) {
|
// Resolve a relative or absolute URL
|
||||||
// Strip leading slash
|
String _makeUrl(String url, {String base = ""}) {
|
||||||
if (url.startsWith("/")) {
|
final baseUri = Uri.parse(base.isNotEmpty ? base : baseUrl);
|
||||||
url = url.substring(1, url.length);
|
final pathUri = Uri.parse(url);
|
||||||
|
|
||||||
|
// If path is absolute (has scheme), ignore base
|
||||||
|
if (pathUri.hasScheme) {
|
||||||
|
return pathUri.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prevent double-slash
|
return baseUri.resolveUri(pathUri).toString();
|
||||||
url = url.replaceAll("//", "/");
|
|
||||||
|
|
||||||
return baseUrl + url;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String get apiUrl => _makeUrl("/api/");
|
|
||||||
|
|
||||||
String get imageUrl => _makeUrl("/image/");
|
|
||||||
|
|
||||||
String makeApiUrl(String endpoint) {
|
String makeApiUrl(String endpoint) {
|
||||||
if (endpoint.startsWith("/api/") || endpoint.startsWith("api/")) {
|
String apiBase = makeUrl("/api/");
|
||||||
return _makeUrl(endpoint);
|
|
||||||
} else {
|
return _makeUrl(endpoint, base: apiBase);
|
||||||
return _makeUrl("/api/${endpoint}");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String get apiUrl => makeApiUrl("");
|
||||||
|
|
||||||
String makeUrl(String endpoint) => _makeUrl(endpoint);
|
String makeUrl(String endpoint) => _makeUrl(endpoint);
|
||||||
|
|
||||||
UserProfile? profile;
|
UserProfile? profile;
|
||||||
@@ -1143,7 +1140,7 @@ class InvenTreeAPI {
|
|||||||
* Perform a request to link a custom barcode to a particular item
|
* Perform a request to link a custom barcode to a particular item
|
||||||
*/
|
*/
|
||||||
Future<bool> linkBarcode(Map<String, String> body) async {
|
Future<bool> linkBarcode(Map<String, String> body) async {
|
||||||
HttpClientRequest? request = await apiRequest("/barcode/link/", "POST");
|
HttpClientRequest? request = await apiRequest("barcode/link/", "POST");
|
||||||
|
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
return false;
|
return false;
|
||||||
@@ -1162,7 +1159,7 @@ class InvenTreeAPI {
|
|||||||
* Perform a request to unlink a custom barcode from a particular item
|
* Perform a request to unlink a custom barcode from a particular item
|
||||||
*/
|
*/
|
||||||
Future<bool> unlinkBarcode(Map<String, dynamic> body) async {
|
Future<bool> unlinkBarcode(Map<String, dynamic> body) async {
|
||||||
HttpClientRequest? request = await apiRequest("/barcode/unlink/", "POST");
|
HttpClientRequest? request = await apiRequest("barcode/unlink/", "POST");
|
||||||
|
|
||||||
if (request == null) {
|
if (request == null) {
|
||||||
return false;
|
return false;
|
||||||
|
|||||||
@@ -534,19 +534,19 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> countStock(double q, {String? notes}) async {
|
Future<bool> countStock(double q, {String? notes}) async {
|
||||||
final bool result = await adjustStock("/stock/count/", q, notes: notes);
|
final bool result = await adjustStock("stock/count/", q, notes: notes);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> addStock(double q, {String? notes}) async {
|
Future<bool> addStock(double q, {String? notes}) async {
|
||||||
final bool result = await adjustStock("/stock/add/", q, notes: notes);
|
final bool result = await adjustStock("stock/add/", q, notes: notes);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> removeStock(double q, {String? notes}) async {
|
Future<bool> removeStock(double q, {String? notes}) async {
|
||||||
final bool result = await adjustStock("/stock/remove/", q, notes: notes);
|
final bool result = await adjustStock("stock/remove/", q, notes: notes);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -563,7 +563,7 @@ class InvenTreeStockItem extends InvenTreeModel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
final bool result = await adjustStock(
|
final bool result = await adjustStock(
|
||||||
"/stock/transfer/",
|
"stock/transfer/",
|
||||||
q,
|
q,
|
||||||
notes: notes,
|
notes: notes,
|
||||||
location: location,
|
location: location,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
name: inventree
|
name: inventree
|
||||||
description: InvenTree stock management
|
description: InvenTree stock management
|
||||||
|
|
||||||
version: 0.22.0+109
|
version: 0.22.1+110
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ^3.8.1
|
sdk: ^3.8.1
|
||||||
|
|||||||
@@ -23,6 +23,27 @@ void main() {
|
|||||||
assert(await UserProfileDBManager().selectProfileByName(testServerName));
|
assert(await UserProfileDBManager().selectProfileByName(testServerName));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Ensure that generated URLs are correct
|
||||||
|
group("URL Tests:", () {
|
||||||
|
test("Generate URLs", () async {
|
||||||
|
UserProfile profile = await setupServerProfile();
|
||||||
|
var api = InvenTreeAPI();
|
||||||
|
|
||||||
|
api.profile = profile;
|
||||||
|
|
||||||
|
Map<String, String> tests = {
|
||||||
|
"": "http://localhost:8000/api/",
|
||||||
|
"barcode/": "http://localhost:8000/api/barcode/",
|
||||||
|
"https://remote-server.com/media/image.png":
|
||||||
|
"https://remote-server.com/media/image.png",
|
||||||
|
};
|
||||||
|
|
||||||
|
for (var test in tests.entries) {
|
||||||
|
expect(api.makeApiUrl(test.key), equals(test.value));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
group("Login Tests:", () {
|
group("Login Tests:", () {
|
||||||
test("Disconnected", () async {
|
test("Disconnected", () async {
|
||||||
// Test that calling disconnect() does the right thing
|
// Test that calling disconnect() does the right thing
|
||||||
|
|||||||
Reference in New Issue
Block a user