2
0
mirror of https://github.com/inventree/inventree-app.git synced 2025-06-13 02:35:27 +00:00

Barcode scan refactor (#651)

* Build file changes

Lots of changes required to meet compatibility of new mobile_scanner lib

* Increase build memory

* Refactor camera controller

- Use MobileScanner now
- Much better UX / feedback

* Cleanup

* Move test sheet file

* Update release notes

* Move actions to floating action buttons

* Tweak deps

* tweak github actions

* Updates
This commit is contained in:
Oliver
2025-06-06 14:54:03 +10:00
committed by GitHub
parent c3f390eddc
commit 1ab171f619
20 changed files with 330 additions and 224 deletions

View File

@ -23,13 +23,13 @@ jobs:
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.3'
flutter-version: '3.32.2'
channel: 'stable'
- run: flutter --version
- name: Setup Gradle
uses: gradle/gradle-build-action@v2.4.2
with:
gradle-version: 8.5
gradle-version: 8.7
- name: Collect Translation Files
run: |
cd lib/l10n

View File

@ -37,7 +37,7 @@ jobs:
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.3'
flutter-version: '3.32.2'
- name: Collect Translation Files
run: |
cd lib/l10n

View File

@ -25,7 +25,7 @@ jobs:
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: '3.24.3'
flutter-version: '3.32.2'
channel: 'stable'
- name: Collect Translation Files
run: |

View File

@ -29,7 +29,8 @@ if (keystorePropertiesFile.exists()) {
}
android {
compileSdkVersion 34
namespace "inventree.inventree_app"
compileSdkVersion 35
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
@ -56,7 +57,7 @@ android {
defaultConfig {
applicationId "inventree.inventree_app"
minSdkVersion 21
targetSdkVersion 34
targetSdkVersion 35
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

View File

@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="inventree.inventree_app">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->

View File

@ -2,7 +2,7 @@ org.gradle.daemon=true
org.gradle.parallel=true
org.gradle.configureondemand=true
org.gradle.caching=true
org.gradle.jvmargs=-Xmx1536M
org.gradle.jvmargs=-Xmx4096M
android.enableD8=true
android.enableJetifier=true
android.useAndroidX=true

View File

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-all.zip
networkTimeout=10000
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-all.zip
networkTimeout=30000
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -18,8 +18,8 @@ pluginManagement {
plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id "com.android.application" version "7.4.1" apply false
id "org.jetbrains.kotlin.android" version "1.8.10" apply false
id "com.android.application" version "8.6.0" apply false
id "org.jetbrains.kotlin.android" version "1.9.25" apply false
}
include ":app"

View File

@ -1,3 +1,7 @@
### 0.19.0 - June 2025
---
- Replace barcode scanning library for better performance
### 0.18.1 - April 2025
---
- Fix bug associated with handling invalid URLs

View File

@ -0,0 +1,32 @@
#
# Generated file, do not edit.
#
import lldb
def handle_new_rx_page(frame: lldb.SBFrame, bp_loc, extra_args, intern_dict):
"""Intercept NOTIFY_DEBUGGER_ABOUT_RX_PAGES and touch the pages."""
base = frame.register["x0"].GetValueAsAddress()
page_len = frame.register["x1"].GetValueAsUnsigned()
# Note: NOTIFY_DEBUGGER_ABOUT_RX_PAGES will check contents of the
# first page to see if handled it correctly. This makes diagnosing
# misconfiguration (e.g. missing breakpoint) easier.
data = bytearray(page_len)
data[0:8] = b'IHELPED!'
error = lldb.SBError()
frame.GetThread().GetProcess().WriteMemory(base, data, error)
if not error.Success():
print(f'Failed to write into {base}[+{page_len}]', error)
return
def __lldb_init_module(debugger: lldb.SBDebugger, _):
target = debugger.GetDummyTarget()
# Caveat: must use BreakpointCreateByRegEx here and not
# BreakpointCreateByName. For some reasons callback function does not
# get carried over from dummy target for the later.
bp = target.BreakpointCreateByRegex("^NOTIFY_DEBUGGER_ABOUT_RX_PAGES$")
bp.SetScriptCallbackFunction('{}.handle_new_rx_page'.format(__name__))
bp.SetAutoContinue(True)
print("-- LLDB integration loaded --")

View File

@ -0,0 +1,5 @@
#
# Generated file, do not edit.
#
command script import --relative-to-command-file flutter_lldb_helper.py

View File

@ -3,14 +3,15 @@ import "dart:typed_data";
import "package:camera/camera.dart";
import "package:flutter/material.dart";
import "package:flutter_speed_dial/flutter_speed_dial.dart";
import "package:flutter_tabler_icons/flutter_tabler_icons.dart";
import "package:inventree/app_colors.dart";
import "package:inventree/inventree/sentry.dart";
import "package:inventree/preferences.dart";
import "package:inventree/widget/snacks.dart";
import "package:mobile_scanner/mobile_scanner.dart";
import "package:one_context/one_context.dart";
import "package:wakelock_plus/wakelock_plus.dart";
import "package:flutter_zxing/flutter_zxing.dart";
import "package:inventree/l10.dart";
@ -37,9 +38,14 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
int scan_delay = 500;
bool single_scanning = false;
bool scanning_paused = false;
bool multiple_barcodes = false;
String scanned_code = "";
final MobileScannerController controller = MobileScannerController(
autoZoom: true
);
@override
void initState() {
super.initState();
@ -74,6 +80,7 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
@override
Future<void> pauseScan() async {
if (mounted) {
setState(() {
scanning_paused = true;
@ -83,6 +90,9 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
@override
Future<void> resumeScan() async {
controller.start();
if (mounted) {
setState(() {
scanning_paused = false;
@ -93,46 +103,71 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
/*
* Callback function when a barcode is scanned
*/
Future<void> onScanSuccess(Code? code) async {
if (scanning_paused) {
Future<void> onScanSuccess(BarcodeCapture result) async {
if (!mounted || scanning_paused) {
return;
}
Uint8List raw_data = code?.rawBytes ?? Uint8List(0);
// TODO: Display outline of barcodes on the screen?
if (result.barcodes.isEmpty) {
setState(() {
multiple_barcodes = false;
});
}
else if (result.barcodes.length > 1) {
setState(() {
multiple_barcodes = true;
});
return;
} else {
setState(() {
multiple_barcodes = false;
});
}
Uint8List rawData = result.barcodes.first.rawBytes ?? Uint8List(0);
// Reconstruct barcode from raw data
String barcode;
if (raw_data.isNotEmpty) {
barcode = "";
if (rawData.isNotEmpty) {
final buffer = StringBuffer();
for (int i = 0; i < raw_data.length; i++) {
buffer.writeCharCode(raw_data[i]);
for (int ii = 0; ii < rawData.length; ii++) {
buffer.writeCharCode(rawData[ii]);
}
barcode = buffer.toString();
print(barcode);
} else {
barcode = code?.text ?? "";
// Fall back to text value
barcode = result.barcodes.first.rawValue ?? "";
}
if (barcode.isEmpty) {
// TODO: Error message "empty barcode"
return;
}
setState(() {
scanned_code = barcode;
});
pauseScan();
await handleBarcodeData(barcode).then((_) {
if (!single_scanning && mounted) {
resumeScan();
}
});
resumeScan();
if (mounted) {
setState(() {
scanned_code = barcode;
});
}
if (barcode.isNotEmpty) {
pauseScan();
await handleBarcodeData(barcode).then((_) {
if (!single_scanning && mounted) {
resumeScan();
}
scanned_code = "";
multiple_barcodes = false;
});
}
}
@ -159,22 +194,40 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
}
}
/*
* Build the barcode scanner overlay
*/
FixedScannerOverlay BarcodeOverlay(BuildContext context) {
Widget BarcodeOverlay(BuildContext context) {
// Note: Copied from reader_widget.dart:ReaderWidget.build
final Size size = MediaQuery.of(context).size;
final double cropSize = min(size.width, size.height) * 0.5;
final Size screenSize = MediaQuery.of(context).size;
final double width = screenSize.width;
final double height = screenSize.height;
return FixedScannerOverlay(
borderColor: scanning_paused ? COLOR_WARNING : COLOR_ACTION,
overlayColor: Colors.black45,
borderRadius: 1,
borderLength: 15,
borderWidth: 8,
cutOutSize: cropSize,
final double D = min(width, height) * 0.8;
// Color for the barcode scan?
Color overlayColor = COLOR_ACTION;
if (multiple_barcodes) {
overlayColor = COLOR_DANGER;
} else if (scanned_code.isNotEmpty) {
overlayColor = COLOR_SUCCESS;
} else if (scanning_paused) {
overlayColor = COLOR_WARNING;
}
return Stack(
children: [
Center(
child: Container(
width: D,
height: D,
decoration: BoxDecoration(
border: Border.all(
color: overlayColor,
width: 4,
),
),
)
)
]
);
}
@ -183,24 +236,25 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
*/
Widget BarcodeReader(BuildContext context) {
return ReaderWidget(
onScan: onScanSuccess,
isMultiScan: false,
tryHarder: true,
tryInverted: true,
tryRotate: true,
showGallery: false,
onControllerCreated: onControllerCreated,
scanDelay: Duration(milliseconds: scan_delay),
resolution: ResolutionPreset.high,
lensDirection: CameraLensDirection.back,
flashOnIcon: const Icon(Icons.flash_on),
flashOffIcon: const Icon(Icons.flash_off),
toggleCameraIcon: const Icon(TablerIcons.camera_rotate),
actionButtonsBackgroundBorderRadius:
BorderRadius.circular(40),
scannerOverlay: BarcodeOverlay(context),
actionButtonsBackgroundColor: Colors.black.withOpacity(0.7),
final Size screenSize = MediaQuery.of(context).size;
final double width = screenSize.width;
final double height = screenSize.height;
final double D = min(width, height) * 0.8;
return MobileScanner(
controller: controller,
overlayBuilder: (context, constraints) {
return BarcodeOverlay(context);
},
scanWindow: Rect.fromCenter(
center: Offset(width / 2, height / 2),
width: D,
height: D
),
onDetect: (result) {
onScanSuccess(result);
},
);
}
@ -262,33 +316,33 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
);
}
Widget? buildActions(BuildContext context) {
/*
* Display an overlay at the bottom right of the screen
*/
Widget bottomRightOverlay() {
return SafeArea(
child: Align(
alignment: Alignment.bottomRight,
child: Padding(
padding: EdgeInsets.all(10),
child: ClipRRect(
borderRadius: BorderRadius.circular(40),
child: ColoredBox(
color: Colors.black45,
child: Row(
mainAxisSize: MainAxisSize.min,
children: scanning_paused ? [] : [
CircularProgressIndicator(
value: null
)
// actionIcon,
]
)
)
)
)
)
List<SpeedDialChild> actions = [
SpeedDialChild(
child: Icon(flash_status ? TablerIcons.bulb_off : TablerIcons.bulb),
label: L10().toggleTorch,
onTap: () async {
controller.toggleTorch();
if (mounted) {
setState(() {
flash_status = !flash_status;
});
}
}
),
SpeedDialChild(
child: Icon(TablerIcons.camera),
label: L10().switchCamera,
onTap: () async {
controller.switchCamera();
}
)
];
return SpeedDial(
icon: Icons.more_horiz,
children: actions,
);
}
@ -300,11 +354,15 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
backgroundColor: COLOR_APP_BAR,
title: Text(L10().scanBarcode),
),
floatingActionButton: buildActions(context),
body: GestureDetector(
onTap: () async {
setState(() {
scanning_paused = !scanning_paused;
});
if (mounted) {
setState(() {
// Toggle the 'scan paused' state
scanning_paused = !scanning_paused;
});
}
},
child: Stack(
children: <Widget>[
@ -316,8 +374,7 @@ class _CameraBarcodeControllerState extends InvenTreeBarcodeControllerState {
],
),
topCenterOverlay(),
bottomCenterOverlay(),
bottomRightOverlay(),
bottomCenterOverlay()
],
),
),

View File

@ -105,7 +105,7 @@ class _WedgeBarcodeControllerState extends InvenTreeBarcodeControllerState {
backgroundColor: COLOR_APP_BAR,
title: Text(L10().scanBarcode),
),
backgroundColor: Colors.black.withOpacity(0.9),
backgroundColor: Colors.black.withValues(alpha: 0.9),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,

View File

@ -1,5 +1,5 @@
import "package:flutter_gen/gen_l10n/app_localizations.dart";
import "package:flutter_gen/gen_l10n/app_localizations_en.dart";
import "package:inventree/l10n/collected/app_localizations.dart";
import "package:inventree/l10n/collected/app_localizations_en.dart";
import "package:one_context/one_context.dart";
import "package:flutter/material.dart";

View File

@ -1446,6 +1446,9 @@
"supplierReference": "Supplier Reference",
"@supplierReference": {},
"switchCamera": "Switch Camera",
"@switchCamera": {},
"takePicture": "Take Picture",
"@takePicture": {},
@ -1492,6 +1495,9 @@
"description": ""
},
"toggleTorch": "Toggle Torch",
"@toggleTorch": {},
"tokenError": "Token Error",
"@tokenError": {},

View File

@ -4,17 +4,17 @@ import "package:flutter/material.dart";
import "package:flutter/services.dart";
import "package:adaptive_theme/adaptive_theme.dart";
import "package:flutter_gen/gen_l10n/app_localizations.dart";
import "package:flutter_localizations/flutter_localizations.dart";
import "package:flutter_localized_locales/flutter_localized_locales.dart";
import "package:one_context/one_context.dart";
import "package:package_info_plus/package_info_plus.dart";
import "package:sentry_flutter/sentry_flutter.dart";
import "package:inventree/dsn.dart";
import "package:inventree/preferences.dart";
import "package:inventree/inventree/sentry.dart";
import "package:inventree/l10n/supported_locales.dart";
import "package:inventree/l10n/collected/app_localizations.dart";
import "package:inventree/settings/release.dart";
import "package:inventree/widget/home.dart";

View File

@ -362,7 +362,7 @@ class _InvenTreeHomePageState extends State<InvenTreeHomePage> with BaseWidgetPr
Spacer(),
Image.asset(
"assets/image/logo_transparent.png",
color: Colors.white.withOpacity(0.05),
color: Colors.white.withValues(alpha: 0.05),
colorBlendMode: BlendMode.modulate,
scale: 0.5,
),

View File

@ -5,15 +5,10 @@ packages:
dependency: transitive
description:
name: _fe_analyzer_shared
sha256: f256b0c0ba6c7577c15e2e4e114755640a875e885099367bf6e012b19314c834
sha256: e55636ed79578b9abca5fecf9437947798f5ef7456308b5cb85720b793eac92f
url: "https://pub.dev"
source: hosted
version: "72.0.0"
_macros:
dependency: transitive
description: dart
source: sdk
version: "0.3.2"
version: "82.0.0"
adaptive_theme:
dependency: "direct main"
description:
@ -26,10 +21,10 @@ packages:
dependency: transitive
description:
name: analyzer
sha256: b652861553cd3990d8ed361f7979dc6d7053a9ac8843fa73820ab68ce5410139
sha256: "904ae5bb474d32c38fb9482e2d925d5454cda04ddd0e55d2e6826bc72f6ba8c0"
url: "https://pub.dev"
source: hosted
version: "6.7.0"
version: "7.4.5"
archive:
dependency: transitive
description:
@ -50,10 +45,10 @@ packages:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
sha256: "758e6d74e971c3e5aceb4110bfd6698efc7f501675bcfe0c775459a8140750eb"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
version: "2.13.0"
audioplayers:
dependency: "direct main"
description:
@ -122,10 +117,10 @@ packages:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
sha256: "8aab1771e1243a5063b8b0ff68042d67334e3feab9e95b9490f9a6ebf73b42ea"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
version: "2.1.2"
cached_network_image:
dependency: "direct main"
description:
@ -154,34 +149,34 @@ packages:
dependency: "direct main"
description:
name: camera
sha256: dfa8fc5a1adaeb95e7a54d86a5bd56f4bb0e035515354c8ac6d262e35cec2ec8
sha256: "413d2b34fe28496c35c69ede5b232fb9dd5ca2c3a4cb606b14efc1c7546cc8cb"
url: "https://pub.dev"
source: hosted
version: "0.10.6"
camera_android:
version: "0.11.1"
camera_android_camerax:
dependency: transitive
description:
name: camera_android
sha256: "32f04948a284b71d938fe275616faf4957d07f9b3aab8021bfc8c418301a289e"
name: camera_android_camerax
sha256: "0bd3d1645df00af2540a22df13ba466ac5fb2838a09bce4089cecdb1712a9e94"
url: "https://pub.dev"
source: hosted
version: "0.10.9+11"
version: "0.6.18"
camera_avfoundation:
dependency: transitive
description:
name: camera_avfoundation
sha256: "7c28969a975a7eb2349bc2cb2dfe3ad218a33dba9968ecfb181ce08c87486655"
sha256: fdc0e668f65c8ddfb3be6c10ef4737fb6274cd04d8053a9525d410642f7989c0
url: "https://pub.dev"
source: hosted
version: "0.9.17+3"
version: "0.9.19+1"
camera_platform_interface:
dependency: transitive
description:
name: camera_platform_interface
sha256: b3ede1f171532e0d83111fe0980b46d17f1aa9788a07a2fbed07366bbdbb9061
sha256: "2f757024a48696ff4814a789b0bd90f5660c0fb25f393ab4564fb483327930e2"
url: "https://pub.dev"
source: hosted
version: "2.8.0"
version: "2.10.0"
camera_web:
dependency: transitive
description:
@ -194,10 +189,10 @@ packages:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
url: "https://pub.dev"
source: hosted
version: "1.3.0"
version: "1.4.0"
checked_yaml:
dependency: transitive
description:
@ -206,6 +201,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.0.3"
cli_config:
dependency: transitive
description:
name: cli_config
sha256: ac20a183a07002b700f0c25e61b7ee46b23c309d76ab7b7640a028f18e4d99ec
url: "https://pub.dev"
source: hosted
version: "0.2.0"
cli_util:
dependency: transitive
description:
@ -218,18 +221,18 @@ packages:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
sha256: fddb70d9b5277016c77a80201021d40a2247104d9f4aa7bab7157b7e3f05b84b
url: "https://pub.dev"
source: hosted
version: "1.1.1"
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
sha256: "2f5709ae4d3d59dd8f7cd309b4e023046b57d8a6c82130785d2b0e5868084e76"
url: "https://pub.dev"
source: hosted
version: "1.18.0"
version: "1.19.1"
convert:
dependency: transitive
description:
@ -242,10 +245,10 @@ packages:
dependency: transitive
description:
name: coverage
sha256: c1fb2dce3c0085f39dc72668e85f8e0210ec7de05345821ff58530567df345a5
sha256: "4b8701e48a58f7712492c9b1f7ba0bb9d525644dd66d023b62e1fc8cdb560c8a"
url: "https://pub.dev"
source: hosted
version: "1.9.2"
version: "1.14.0"
cross_file:
dependency: transitive
description:
@ -274,10 +277,10 @@ packages:
dependency: "direct main"
description:
name: currency_formatter
sha256: "8d4e1762e226289e4abe902075d167029617553c913309b34a227c52c61dd063"
sha256: c2a32f8ab74649fa8df22e6d2e0288fdcddd733655bb95ccbabbf181e98f280a
url: "https://pub.dev"
source: hosted
version: "2.2.1"
version: "2.3.0"
datetime_picker_formfield:
dependency: "direct main"
description:
@ -290,10 +293,10 @@ packages:
dependency: transitive
description:
name: dbus
sha256: "365c771ac3b0e58845f39ec6deebc76e3276aa9922b0cc60840712094d9047ac"
sha256: "79e0c23480ff85dc68de79e2cd6334add97e48f7f4865d17686dd6ea81a47e8c"
url: "https://pub.dev"
source: hosted
version: "0.7.10"
version: "0.7.11"
device_info_plus:
dependency: "direct main"
description:
@ -322,10 +325,10 @@ packages:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
sha256: "5368f224a74523e8d2e7399ea1638b37aecfca824a3cc4dfdf77bf1fa905ac44"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
version: "1.3.3"
ffi:
dependency: transitive
description:
@ -474,14 +477,6 @@ packages:
description: flutter
source: sdk
version: "0.0.0"
flutter_zxing:
dependency: "direct main"
description:
name: flutter_zxing
sha256: "5b2670f151a6d96643204ff3a781e073739c23a91ef5fc39742bf13fb8287b4c"
url: "https://pub.dev"
source: hosted
version: "1.8.2"
frontend_server_client:
dependency: transitive
description:
@ -502,10 +497,10 @@ packages:
dependency: "direct main"
description:
name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b"
url: "https://pub.dev"
source: hosted
version: "1.2.2"
version: "1.4.0"
http_multi_server:
dependency: transitive
description:
@ -606,10 +601,10 @@ packages:
dependency: "direct main"
description:
name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
sha256: "3df61194eb431efc39c4ceba583b95633a403f46c9fd341e550ce0bfa50e9aa5"
url: "https://pub.dev"
source: hosted
version: "0.19.0"
version: "0.20.2"
io:
dependency: transitive
description:
@ -638,18 +633,18 @@ packages:
dependency: transitive
description:
name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0"
url: "https://pub.dev"
source: hosted
version: "10.0.5"
version: "10.0.9"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573
url: "https://pub.dev"
source: hosted
version: "3.0.5"
version: "3.0.9"
leak_tracker_testing:
dependency: transitive
description:
@ -674,14 +669,6 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.2.0"
macros:
dependency: transitive
description:
name: macros
sha256: "0acaed5d6b7eab89f63350bccd82119e6c602df0f391260d0e32b5e23db79536"
url: "https://pub.dev"
source: hosted
version: "0.1.2-main.4"
markdown:
dependency: transitive
description:
@ -694,10 +681,10 @@ packages:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
version: "0.12.17"
material_color_utilities:
dependency: transitive
description:
@ -710,10 +697,10 @@ packages:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
url: "https://pub.dev"
source: hosted
version: "1.15.0"
version: "1.16.0"
mime:
dependency: transitive
description:
@ -722,6 +709,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.0.6"
mobile_scanner:
dependency: "direct main"
description:
name: mobile_scanner
sha256: "54005bdea7052d792d35b4fef0f84ec5ddc3a844b250ecd48dc192fb9b4ebc95"
url: "https://pub.dev"
source: hosted
version: "7.0.1"
node_preamble:
dependency: transitive
description:
@ -750,10 +745,10 @@ packages:
dependency: "direct main"
description:
name: open_filex
sha256: dcb7bd3d32db8db5260253a62f1564c02c2c8df64bc0187cd213f65f827519bd
sha256: "9976da61b6a72302cf3b1efbce259200cd40232643a467aac7370addf94d6900"
url: "https://pub.dev"
source: hosted
version: "4.6.0"
version: "4.7.0"
package_config:
dependency: transitive
description:
@ -782,18 +777,18 @@ packages:
dependency: "direct main"
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
sha256: "75cca69d1490965be98c73ceaea117e8a04dd21217b37b292c9ddbec0d955bc5"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
version: "1.9.1"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
sha256: "50c5dd5b6e1aaf6fb3a78b33f6aa3afca52bf903a8a5298f53101fdaee55bbcd"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
version: "2.1.5"
path_provider_android:
dependency: transitive
description:
@ -874,6 +869,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
pubspec_parse:
dependency: transitive
description:
name: pubspec_parse
sha256: "0560ba233314abbed0a48a2956f7f022cce7c3e1e73df540277da7544cad4082"
url: "https://pub.dev"
source: hosted
version: "1.5.0"
rxdart:
dependency: transitive
description:
@ -894,18 +897,18 @@ packages:
dependency: transitive
description:
name: sentry
sha256: "033287044a6644a93498969449d57c37907e56f5cedb17b88a3ff20a882261dd"
sha256: "599701ca0693a74da361bc780b0752e1abc98226cf5095f6b069648116c896bb"
url: "https://pub.dev"
source: hosted
version: "8.9.0"
version: "8.14.2"
sentry_flutter:
dependency: "direct main"
description:
name: sentry_flutter
sha256: "3780b5a0bb6afd476857cfbc6c7444d969c29a4d9bd1aa5b6960aa76c65b737a"
sha256: "5ba2cf40646a77d113b37a07bd69f61bb3ec8a73cbabe5537b05a7c89d2656f8"
url: "https://pub.dev"
source: hosted
version: "8.9.0"
version: "8.14.2"
shared_preferences:
dependency: transitive
description:
@ -998,7 +1001,7 @@ packages:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
version: "0.0.0"
sliver_tools:
dependency: transitive
description:
@ -1027,10 +1030,10 @@ packages:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
sha256: "254ee5351d6cb365c859e20ee823c3bb479bf4a293c22d17a9f1bf144ce86f7c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
version: "1.10.1"
sqflite:
dependency: transitive
description:
@ -1051,18 +1054,18 @@ packages:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
sha256: "8b27215b45d22309b5cddda1aa2b19bdfec9df0e765f2de506401c071d38d1b1"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
version: "1.12.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
sha256: "969e04c80b8bcdf826f8f16579c7b14d780458bd97f56d107d3950fdbeef059d"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
version: "2.1.4"
stream_transform:
dependency: transitive
description:
@ -1075,10 +1078,10 @@ packages:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
sha256: "921cd31725b72fe181906c6a94d987c78e3b98c2e205b397ea399d4054872b43"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
version: "1.4.1"
synchronized:
dependency: transitive
description:
@ -1091,34 +1094,34 @@ packages:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
sha256: "7f554798625ea768a7518313e58f83891c7f5024f88e46e7182a4558850a4b8e"
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.2"
test:
dependency: "direct dev"
description:
name: test
sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e"
sha256: "301b213cd241ca982e9ba50266bd3f5bd1ea33f1455554c5abb85d1be0e2d87e"
url: "https://pub.dev"
source: hosted
version: "1.25.7"
version: "1.25.15"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd
url: "https://pub.dev"
source: hosted
version: "0.7.2"
version: "0.7.4"
test_core:
dependency: transitive
description:
name: test_core
sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696"
sha256: "84d17c3486c8dfdbe5e12a50c8ae176d15e2a771b96909a9442b40173649ccaa"
url: "https://pub.dev"
source: hosted
version: "0.6.4"
version: "0.6.8"
typed_data:
dependency: transitive
description:
@ -1131,10 +1134,10 @@ packages:
dependency: "direct main"
description:
name: url_launcher
sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
sha256: "9d06212b1362abc2f0f0d78e6f09f726608c74e3b9462e8368bb03314aa8d603"
url: "https://pub.dev"
source: hosted
version: "6.3.0"
version: "6.3.1"
url_launcher_android:
dependency: transitive
description:
@ -1211,26 +1214,26 @@ packages:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02
url: "https://pub.dev"
source: hosted
version: "14.2.5"
version: "15.0.0"
wakelock_plus:
dependency: "direct main"
description:
name: wakelock_plus
sha256: bf4ee6f17a2fa373ed3753ad0e602b7603f8c75af006d5b9bdade263928c0484
sha256: a474e314c3e8fb5adef1f9ae2d247e57467ad557fa7483a2b895bc1b421c5678
url: "https://pub.dev"
source: hosted
version: "1.2.8"
version: "1.3.2"
wakelock_plus_platform_interface:
dependency: transitive
description:
name: wakelock_plus_platform_interface
sha256: "422d1cdbb448079a8a62a5a770b69baa489f8f7ca21aef47800c726d404f9d16"
sha256: e10444072e50dbc4999d7316fd303f7ea53d31c824aa5eb05d7ccbdd98985207
url: "https://pub.dev"
source: hosted
version: "1.2.1"
version: "1.2.3"
watcher:
dependency: transitive
description:
@ -1275,10 +1278,10 @@ packages:
dependency: transitive
description:
name: win32
sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
sha256: "329edf97fdd893e0f1e3b9e88d6a0e627128cc17cc316a8d67fda8f1451178ba"
url: "https://pub.dev"
source: hosted
version: "5.5.4"
version: "5.13.0"
win32_registry:
dependency: transitive
description:
@ -1312,5 +1315,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
dart: ">=3.5.0 <3.13.0"
flutter: ">=3.24.0"
dart: ">=3.7.0 <3.32.2"
flutter: ">=3.29.0"

View File

@ -4,13 +4,13 @@ description: InvenTree stock management
version: 0.18.1+98
environment:
sdk: ">=2.19.5 <3.13.0"
sdk: ">=2.19.5 <3.32.2"
dependencies:
adaptive_theme: ^3.3.0 # Theme management (e.g. dark mode)
audioplayers: ^6.1.0 # Play audio files
cached_network_image: ^3.3.1 # Download and cache remote images
camera: ^0.10.3 # Camera
camera: ^0.11.1 # Camera
cupertino_icons: ^1.0.8
currency_formatter: ^2.2.1 # Currency formatting
datetime_picker_formfield: ^2.0.1 # Date / time picker
@ -20,27 +20,27 @@ dependencies:
flutter:
sdk: flutter
flutter_cache_manager: ^3.3.0
flutter_localizations:
flutter_localizations:
sdk: flutter
flutter_localized_locales: ^2.0.4
flutter_localized_locales: ^2.0.5
flutter_markdown: ^0.6.19 # Rendering markdown
flutter_overlay_loader: ^2.0.0 # Overlay screen support
flutter_speed_dial: ^6.2.0 # Speed dial / FAB implementation
flutter_tabler_icons: ^1.35.0
flutter_zxing: ^1.8.2 # Barcode scanning
http: ^1.2.2
flutter_tabler_icons: ^1.43.0
http: ^1.4.0
image_picker: ^1.1.2 # Select or take photos
infinite_scroll_pagination: ^4.0.0 # Let the server do all the work!
intl: ^0.19.0
intl: ^0.20.2
mobile_scanner: ^7.0.1 # Barcode scanning support
one_context: ^4.0.0 # Dialogs without requiring context
open_filex: ^4.6.0 # Open local files
open_filex: ^4.7.0 # Open local files
package_info_plus: ^8.1.1 # App information introspection
path: ^1.9.0
path_provider: ^2.1.3 # Local file storage
path_provider: ^2.1.5 # Local file storage
sembast: ^3.6.0 # NoSQL data storage
sentry_flutter: 8.9.0 # Error reporting
url_launcher: ^6.3.0 # Open link in system browser
wakelock_plus: ^1.2.8 # Prevent device from sleeping
sentry_flutter: 8.14.2 # Error reporting
url_launcher: ^6.3.1 # Open link in system browser
wakelock_plus: ^1.3.2 # Prevent device from sleeping
dev_dependencies:
flutter_launcher_icons: ^0.14.1
@ -60,7 +60,6 @@ flutter_icons:
# The following section is specific to Flutter.
flutter:
uses-material-design: true
generate: true
assets:

BIN
test/fixtures/barcodes/test_sheet.png vendored Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 KiB